| Index: sdk/lib/io/io_sink.dart
|
| diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
|
| index eea733d9810c76c386ca8b8fd64a3c8d8893f386..05ecf34fb0413cce1638a21259eb87c6cba4707b 100644
|
| --- a/sdk/lib/io/io_sink.dart
|
| +++ b/sdk/lib/io/io_sink.dart
|
| @@ -5,38 +5,41 @@
|
| part of dart.io;
|
|
|
| /**
|
| - * Helper class to wrap a [StreamConsumer<List<int>, T>] and provide utility
|
| - * functions for writing to the StreamConsumer directly. The [IOSink]
|
| - * buffers the input given by [add] and [addString] and will delay a [consume]
|
| - * or [addStream] until the buffer is flushed.
|
| + * Helper class to wrap a [StreamConsumer<List<int>, T>] and provide
|
| + * utility functions for writing to the StreamConsumer directly. The
|
| + * [IOSink] buffers the input given by [write], [writeAll], [writeln],
|
| + * [writeCharCode] and [writeBytes] and will delay a [consume] or
|
| + * [writeStream] until the buffer is flushed.
|
| *
|
| * When the [IOSink] is bound to a stream (through either [consume]
|
| - * or [addStream]) any call to the [IOSink] will throw a
|
| + * or [writeStream]) any call to the [IOSink] will throw a
|
| * [StateError].
|
| */
|
| -abstract class IOSink<T> implements StreamConsumer<List<int>, T> {
|
| - factory IOSink(StreamConsumer<List<int>, T> target)
|
| - => new _IOSinkImpl(target);
|
| +abstract class IOSink<T> implements StreamConsumer<List<int>, T>, StringSink {
|
| + factory IOSink(StreamConsumer<List<int>, T> target,
|
| + {Encoding encoding: Encoding.UTF_8})
|
| + => new _IOSinkImpl(target, encoding);
|
|
|
| /**
|
| - * Provide functionality for piping to the [IOSink].
|
| + * The [Encoding] used when writing strings. Depending on the
|
| + * underlying consumer this property might be mutable.
|
| */
|
| - Future<T> consume(Stream<List<int>> stream);
|
| + Encoding encoding;
|
|
|
| /**
|
| - * Like [consume], but will not close the target when done.
|
| + * Writes the bytes uninterpreted to the consumer.
|
| */
|
| - Future<T> addStream(Stream<List<int>> stream);
|
| + void writeBytes(List<int> data);
|
|
|
| /**
|
| - * Write a list of bytes to the target.
|
| + * Provide functionality for piping to the [IOSink].
|
| */
|
| - void add(List<int> data);
|
| + Future<T> consume(Stream<List<int>> stream);
|
|
|
| /**
|
| - * Write a String to the target.
|
| + * Like [consume], but will not close the target when done.
|
| */
|
| - void addString(String string, [Encoding encoding = Encoding.UTF_8]);
|
| + Future<T> writeStream(Stream<List<int>> stream);
|
|
|
| /**
|
| * Close the target.
|
| @@ -59,32 +62,69 @@ class _IOSinkImpl<T> implements IOSink<T> {
|
| Future<T> _pipeFuture;
|
| StreamSubscription<List<int>> _bindSubscription;
|
| bool _paused = true;
|
| + bool _encodingMutable = true;
|
|
|
| - _IOSinkImpl(StreamConsumer<List<int>, T> target) : _target = target;
|
| + _IOSinkImpl(StreamConsumer<List<int>, T> this._target, this._encoding);
|
|
|
| - Future<T> consume(Stream<List<int>> stream) {
|
| - if (_isBound) {
|
| - throw new StateError("IOSink is already bound to a stream");
|
| + Encoding _encoding;
|
| +
|
| + Encoding get encoding => _encoding;
|
| + void set encoding(Encoding value) {
|
| + if (!_encodingMutable) {
|
| + throw new StateError("IOSink encoding is not mutable");
|
| }
|
| - return _fillFromStream(stream);
|
| + _encoding = value;
|
| + }
|
| +
|
| + void write(Object obj) {
|
| + // This comment is copied from runtime/lib/string_buffer_patch.dart.
|
| + // TODO(srdjan): The following four lines could be replaced by
|
| + // '$obj', but apparently this is too slow on the Dart VM.
|
| + String string;
|
| + if (obj is String) {
|
| + string = obj;
|
| + } else {
|
| + string = obj.toString();
|
| + if (string is! String) {
|
| + throw new ArgumentError('toString() did not return a string');
|
| + }
|
| + }
|
| + if (string.isEmpty) return;
|
| + writeBytes(_encodeString(string, _encoding));
|
| }
|
|
|
| - Future<T> addStream(Stream<List<int>> stream) {
|
| + void writeAll(Iterable objects) {
|
| + for (Object obj in objects) write(obj);
|
| + }
|
| +
|
| + void writeln(Object obj) {
|
| + write(obj);
|
| + write("\n");
|
| + }
|
| +
|
| + void writeCharCode(int charCode) {
|
| + write(new String.fromCharCode(charCode));
|
| + }
|
| +
|
| + void writeBytes(List<int> data) {
|
| if (_isBound) {
|
| throw new StateError("IOSink is already bound to a stream");
|
| }
|
| - return _fillFromStream(stream, unbind: true);
|
| + _controller.add(data);
|
| }
|
|
|
| - void add(List<int> data) {
|
| + Future<T> consume(Stream<List<int>> stream) {
|
| if (_isBound) {
|
| throw new StateError("IOSink is already bound to a stream");
|
| }
|
| - _controller.add(data);
|
| + return _fillFromStream(stream);
|
| }
|
|
|
| - void addString(String string, [Encoding encoding = Encoding.UTF_8]) {
|
| - add(_encodeString(string, encoding));
|
| + Future<T> writeStream(Stream<List<int>> stream) {
|
| + if (_isBound) {
|
| + throw new StateError("IOSink is already bound to a stream");
|
| + }
|
| + return _fillFromStream(stream, unbind: true);
|
| }
|
|
|
| void close() {
|
|
|