Merge remote-tracking branch 'origin/corelib_2_2_1_branch' This doesn't change the state of master. An old version of the Dart SDK depended on a commit from the branch that's being merged in, and this ensures that that commit remains reachable so that version can still be built.
diff --git a/pkgs/web_socket_channel/.travis.yml b/pkgs/web_socket_channel/.travis.yml index a24a813..3ef6c26 100644 --- a/pkgs/web_socket_channel/.travis.yml +++ b/pkgs/web_socket_channel/.travis.yml
@@ -1,14 +1,10 @@ language: dart sudo: false -dart: - - dev - - stable +dart: dev dart_task: - test: --platform vm - test: --platform firefox -j 1 - - test: --platform dartium - install_dartium: true - dartanalyzer matrix:
diff --git a/pkgs/web_socket_channel/CHANGELOG.md b/pkgs/web_socket_channel/CHANGELOG.md index 49b2eec..d50f8d0 100644 --- a/pkgs/web_socket_channel/CHANGELOG.md +++ b/pkgs/web_socket_channel/CHANGELOG.md
@@ -1,9 +1,6 @@ ## 1.0.7 -* Updates to support Dart 2.0 core library changes (wave 2.2). - See [issue 31847][sdk#31847] for details. - - [sdk#31847]: https://github.com/dart-lang/sdk/issues/31847 +* Support the latest dev SDK. ## 1.0.6
diff --git a/pkgs/web_socket_channel/lib/src/copy/bytes_builder.dart b/pkgs/web_socket_channel/lib/src/copy/bytes_builder.dart index 429e6d1..1e37093 100644 --- a/pkgs/web_socket_channel/lib/src/copy/bytes_builder.dart +++ b/pkgs/web_socket_channel/lib/src/copy/bytes_builder.dart
@@ -9,9 +9,8 @@ // Because it's copied directly, there are no modifications from the original. // // This is up-to-date as of sdk revision -// e41fb4cafd6052157dbc1490d437045240f4773f. +// 365f7b5a8b6ef900a5ee23913b7203569b81b175. -import 'dart:math'; import 'dart:typed_data'; /// Builds a list of bytes, allowing bytes and lists of bytes to be added at the @@ -46,7 +45,7 @@ /// Returns the contents of `this` and clears `this`. /// - /// The list returned is a view of the the internal buffer, limited to the + /// The list returned is a view of the internal buffer, limited to the /// [length]. List<int> takeBytes(); @@ -72,24 +71,22 @@ // Start with 1024 bytes. static const int _INIT_SIZE = 1024; + static final _emptyList = new Uint8List(0); + int _length = 0; Uint8List _buffer; + _CopyingBytesBuilder([int initialCapacity = 0]) + : _buffer = (initialCapacity <= 0) + ? _emptyList + : new Uint8List(_pow2roundup(initialCapacity)); + void add(List<int> bytes) { int bytesLength = bytes.length; if (bytesLength == 0) return; int required = _length + bytesLength; - if (_buffer == null) { - int size = _pow2roundup(required); - size = max(size, _INIT_SIZE); - _buffer = new Uint8List(size); - } else if (_buffer.length < required) { - // We will create a list in the range of 2-4 times larger than - // required. - int size = _pow2roundup(required) * 2; - var newBuffer = new Uint8List(size); - newBuffer.setRange(0, _buffer.length, _buffer); - _buffer = newBuffer; + if (_buffer.length < required) { + _grow(required); } assert(_buffer.length >= required); if (bytes is Uint8List) { @@ -103,18 +100,39 @@ } void addByte(int byte) { - add([byte]); + if (_buffer.length == _length) { + // The grow algorithm always at least doubles. + // If we added one to _length it would quadruple unnecessarily. + _grow(_length); + } + assert(_buffer.length > _length); + _buffer[_length] = byte; + _length++; + } + + void _grow(int required) { + // We will create a list in the range of 2-4 times larger than + // required. + int newSize = required * 2; + if (newSize < _INIT_SIZE) { + newSize = _INIT_SIZE; + } else { + newSize = _pow2roundup(newSize); + } + var newBuffer = new Uint8List(newSize); + newBuffer.setRange(0, _buffer.length, _buffer); + _buffer = newBuffer; } List<int> takeBytes() { - if (_buffer == null) return new Uint8List(0); + if (_length == 0) return _emptyList; var buffer = new Uint8List.view(_buffer.buffer, 0, _length); clear(); return buffer; } List<int> toBytes() { - if (_buffer == null) return new Uint8List(0); + if (_length == 0) return _emptyList; return new Uint8List.fromList( new Uint8List.view(_buffer.buffer, 0, _length)); } @@ -127,10 +145,11 @@ void clear() { _length = 0; - _buffer = null; + _buffer = _emptyList; } - int _pow2roundup(int x) { + static int _pow2roundup(int x) { + assert(x > 0); --x; x |= x >> 1; x |= x >> 2; @@ -143,24 +162,28 @@ class _BytesBuilder implements BytesBuilder { int _length = 0; - final _chunks = <List<int>>[]; + final List<Uint8List> _chunks = []; void add(List<int> bytes) { - if (bytes is! Uint8List) { - bytes = new Uint8List.fromList(bytes); + Uint8List typedBytes; + if (bytes is Uint8List) { + typedBytes = bytes; + } else { + typedBytes = new Uint8List.fromList(bytes); } - _chunks.add(bytes); - _length += bytes.length; + _chunks.add(typedBytes); + _length += typedBytes.length; } void addByte(int byte) { - add([byte]); + _chunks.add(new Uint8List(1)..[0] = byte); + _length++; } List<int> takeBytes() { - if (_chunks.length == 0) return new Uint8List(0); + if (_length == 0) return _CopyingBytesBuilder._emptyList; if (_chunks.length == 1) { - var buffer = _chunks.single; + var buffer = _chunks[0]; clear(); return buffer; } @@ -175,7 +198,7 @@ } List<int> toBytes() { - if (_chunks.length == 0) return new Uint8List(0); + if (_length == 0) return _CopyingBytesBuilder._emptyList; var buffer = new Uint8List(_length); int offset = 0; for (var chunk in _chunks) {
diff --git a/pkgs/web_socket_channel/lib/src/copy/io_sink.dart b/pkgs/web_socket_channel/lib/src/copy/io_sink.dart index dafd86b..3a51ff1 100644 --- a/pkgs/web_socket_channel/lib/src/copy/io_sink.dart +++ b/pkgs/web_socket_channel/lib/src/copy/io_sink.dart
@@ -9,7 +9,7 @@ // desired public API and to remove "dart:io" dependencies have been made. // // This is up-to-date as of sdk revision -// e41fb4cafd6052157dbc1490d437045240f4773f. +// 365f7b5a8b6ef900a5ee23913b7203569b81b175. import 'dart:async'; @@ -24,12 +24,20 @@ StreamSinkImpl(this._target); + // The _reportClosedSink method has been deleted for web_socket_channel. This + // method did nothing but print to stderr, which is unavailable here. + void add(T data) { - if (_isClosed) return; + if (_isClosed) { + return; + } _controller.add(data); } void addError(error, [StackTrace stackTrace]) { + if (_isClosed) { + return; + } _controller.addError(error, stackTrace); } @@ -37,19 +45,19 @@ if (_isBound) { throw new StateError("StreamSink is already bound to a stream"); } - _isBound = true; if (_hasError) return done; - // Wait for any sync operations to complete. - Future targetAddStream() { - return _target.addStream(stream).whenComplete(() { - _isBound = false; - }); - } - if (_controllerInstance == null) return targetAddStream(); - var future = _controllerCompleter.future; - _controllerInstance.close(); - return future.then((_) => targetAddStream()); + _isBound = true; + var future = _controllerCompleter == null + ? _target.addStream(stream) + : _controllerCompleter.future.then((_) => _target.addStream(stream)); + _controllerInstance?.close(); + + // Wait for any pending events in [_controller] to be dispatched before + // adding [stream]. + return future.whenComplete(() { + _isBound = false; + }); } Future flush() {
diff --git a/pkgs/web_socket_channel/lib/src/copy/web_socket.dart b/pkgs/web_socket_channel/lib/src/copy/web_socket.dart index c08b9ac..1928a34 100644 --- a/pkgs/web_socket_channel/lib/src/copy/web_socket.dart +++ b/pkgs/web_socket_channel/lib/src/copy/web_socket.dart
@@ -9,7 +9,7 @@ // desired public API and to remove "dart:io" dependencies have been made. // // This is up-to-date as of sdk revision -// e41fb4cafd6052157dbc1490d437045240f4773f. +// 365f7b5a8b6ef900a5ee23913b7203569b81b175. /// Web socket status codes used when closing a web socket connection. abstract class WebSocketStatus {
diff --git a/pkgs/web_socket_channel/lib/src/copy/web_socket_impl.dart b/pkgs/web_socket_channel/lib/src/copy/web_socket_impl.dart index 5c8e1b3..58bcaba 100644 --- a/pkgs/web_socket_channel/lib/src/copy/web_socket_impl.dart +++ b/pkgs/web_socket_channel/lib/src/copy/web_socket_impl.dart
@@ -10,7 +10,7 @@ // desired public API and to remove "dart:io" dependencies have been made. // // This is up-to-date as of sdk revision -// e41fb4cafd6052157dbc1490d437045240f4773f. +// 365f7b5a8b6ef900a5ee23913b7203569b81b175. import 'dart:async'; import 'dart:convert'; @@ -57,16 +57,20 @@ static const int RESERVED_F = 15; } +class _EncodedString { + final List<int> bytes; + _EncodedString(this.bytes); +} + /// The web socket protocol transformer handles the protocol byte stream -/// which is supplied through the [:handleData:]. As the protocol is processed, +/// which is supplied through the `handleData`. As the protocol is processed, /// it'll output frame data as either a List<int> or String. /// /// Important information about usage: Be sure you use cancelOnError, so the /// socket will be closed when the processor encounter an error. Not using it /// will lead to undefined behaviour. -// TODO(ajohnsen): make this transformer reusable? -class _WebSocketProtocolTransformer - extends StreamTransformerBase<List<int>, dynamic> +class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>, + dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > implements EventSink<List<int>> { static const int START = 0; static const int LEN_FIRST = 1; @@ -94,7 +98,7 @@ int closeCode = WebSocketStatus.NO_STATUS_RECEIVED; String closeReason = ""; - EventSink _eventSink; + EventSink<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > _eventSink; final bool _serverSide; final List _maskingBytes = new List(4); @@ -102,7 +106,8 @@ _WebSocketProtocolTransformer([this._serverSide = false]); - Stream bind(Stream stream) { + Stream<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > bind( + Stream<List<int>> stream) { return new Stream.eventTransformed(stream, (EventSink eventSink) { if (_eventSink != null) { throw new StateError("WebSocket transformer already used."); @@ -320,7 +325,7 @@ switch (_currentMessageType) { case _WebSocketMessageType.TEXT: - _eventSink.add(UTF8.decode(bytes)); + _eventSink.add(utf8.decode(bytes)); break; case _WebSocketMessageType.BINARY: _eventSink.add(bytes); @@ -345,7 +350,7 @@ throw new WebSocketChannelException("Protocol error"); } if (payload.length > 2) { - closeReason = UTF8.decode(payload.sublist(2)); + closeReason = utf8.decode(payload.sublist(2)); } } _state = CLOSED; @@ -400,7 +405,8 @@ _WebSocketOutgoingTransformer(this.webSocket); Stream<List<int>> bind(Stream stream) { - return new Stream.eventTransformed(stream, (eventSink) { + return new Stream<List<int>>.eventTransformed(stream, + (EventSink<List<int>> eventSink) { if (_eventSink != null) { throw new StateError("WebSocket transformer already used"); } @@ -423,14 +429,15 @@ if (message != null) { if (message is String) { opcode = _WebSocketOpcode.TEXT; - data = UTF8.encode(message); + data = utf8.encode(message); + } else if (message is List<int>) { + opcode = _WebSocketOpcode.BINARY; + data = message; + } else if (message is _EncodedString) { + opcode = _WebSocketOpcode.TEXT; + data = message.bytes; } else { - if (message is List<int>) { - data = message; - opcode = _WebSocketOpcode.BINARY; - } else { - throw new ArgumentError(message); - } + throw new ArgumentError(message); } } else { opcode = _WebSocketOpcode.TEXT; @@ -451,17 +458,24 @@ data.add((code >> 8) & 0xFF); data.add(code & 0xFF); if (reason != null) { - data.addAll(UTF8.encode(reason)); + data.addAll(utf8.encode(reason)); } } addFrame(_WebSocketOpcode.CLOSE, data); _eventSink.close(); } - void addFrame(int opcode, List<int> data) => - createFrame(opcode, data, webSocket._serverSide, false).forEach((e) { - _eventSink.add(e); - }); + void addFrame(int opcode, List<int> data) { + createFrame( + opcode, + data, + webSocket._serverSide, + // Logic around _deflateHelper was removed here, since ther ewill never + // be a deflate helper for a cross-platform WebSocket client. + false).forEach((e) { + _eventSink.add(e); + }); + } static Iterable<List<int>> createFrame( int opcode, List<int> data, bool serverSide, bool compressed) { @@ -564,7 +578,7 @@ StreamSubscription _subscription; bool _issuedPause = false; bool _closed = false; - final Completer _closeCompleter = new Completer(); + final Completer _closeCompleter = new Completer<WebSocketImpl>(); Completer _completer; _WebSocketConsumer(this.webSocket, this.sink);
diff --git a/pkgs/web_socket_channel/pubspec.yaml b/pkgs/web_socket_channel/pubspec.yaml index 08dde58..dd70f7e 100644 --- a/pkgs/web_socket_channel/pubspec.yaml +++ b/pkgs/web_socket_channel/pubspec.yaml
@@ -5,7 +5,7 @@ homepage: https://github.com/dart-lang/web_socket_channel environment: - sdk: '>=2.0.0-dev.20.0 <2.0.0' + sdk: '>=2.0.0-dev.23.0 <2.0.0' dependencies: async: '>=1.3.0 <3.0.0'