Add WebSocket.addUtf8Text to allow sending pre-encoded text without a round-trip UTF-8 conversion.

Use it to implement the vm-service, where in particular we are concerned about the space overhead of the conversion leading to the process being killed on iOS.

Closes #27129

R=johnmccutchan@google.com, lrn@google.com

Review URL: https://codereview.chromium.org/2260073002 .
This commit is contained in:
Ryan Macnak 2016-08-24 16:15:07 -07:00
parent 97da42bd45
commit aa38062a23
4 changed files with 30 additions and 10 deletions

View file

@ -4,6 +4,9 @@
* `dart:async`
* `Future.wait` now catches synchronous errors and returns them in the
returned Future.
* `dart:io`
* Added `WebSocket.addUtf8Text` to allow sending a pre-encoded text message
without a round-trip UTF-8 conversion.
## 1.19.0

View file

@ -57,10 +57,7 @@ class WebSocketClient extends Client {
// String message as external Uint8List.
assert(result is List);
Uint8List cstring = result[0];
// TODO(rmacnak): cstring may be large. Add a way to pass an encoded
// string to a web socket that will be sent as a text message to avoid
// the space overhead of converting cstring to a Dart string.
socket.add(UTF8.decode(cstring));
socket.addUtf8Text(cstring);
}
} catch (_) {
print("Ignoring error posting over WebSocket.");

View file

@ -402,6 +402,14 @@ abstract class WebSocket
* must be either `String`s, or `List<int>`s holding bytes.
*/
Future addStream(Stream stream);
/**
* Sends a text message with the text represented by [bytes].
*
* The [bytes] should be valid UTF-8 encoded Unicode characters. If they are
* not, the receiving end will close the connection.
*/
void addUtf8Text(List<int> bytes);
}
class WebSocketException implements IOException {

View file

@ -36,6 +36,11 @@ class _WebSocketOpcode {
static const int RESERVED_F = 15;
}
class _EncodedString {
final List<int> bytes;
_EncodedString(this.bytes);
}
/**
* Stores the header and integer value derived from negotiation of
* client_max_window_bits and server_max_window_bits. headerValue will be
@ -670,13 +675,14 @@ class _WebSocketOutgoingTransformer
if (message is String) {
opcode = _WebSocketOpcode.TEXT;
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>) {
opcode = _WebSocketOpcode.BINARY;
data = message;
} else {
throw new ArgumentError(message);
}
throw new ArgumentError(message);
}
if (_deflateHelper != null) {
@ -1176,6 +1182,12 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
String get closeReason => _closeReason;
void add(data) { _sink.add(data); }
void addUtf8Text(List<int> bytes) {
if (bytes is! List<int>) {
throw new ArgumentError(bytes, "bytes", "Is not a list of bytes");
}
_sink.add(new _EncodedString(bytes));
}
void addError(error, [StackTrace stackTrace]) {
_sink.addError(error, stackTrace);
}