| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A combined byte and text output. | 8 * A combined byte and text output. |
| 9 * | 9 * |
| 10 * An [IOSink] combines a [StreamSink] of bytes with a [StringSink], | 10 * An [IOSink] combines a [StreamSink] of bytes with a [StringSink], |
| 11 * and allows easy output of both bytes and text. | 11 * and allows easy output of both bytes and text. |
| 12 * | 12 * |
| 13 * Writing text ([write]) and adding bytes ([add]) may be interleaved freely. | 13 * Writing text ([write]) and adding bytes ([add]) may be interleaved freely. |
| 14 * | 14 * |
| 15 * While a stream is being added using [addStream], any further attempts | 15 * While a stream is being added using [addStream], any further attempts |
| 16 * to add or write to the [IOSink] will fail until the [addStream] completes. | 16 * to add or write to the [IOSink] will fail until the [addStream] completes. |
| 17 * | 17 * |
| 18 * If data is added to the [IOSink] after the sink is closed, the data will be | 18 * It is an error to add data to the [IOSink] after the sink is closed. |
| 19 * ignored. Use the [done] future to be notified when the [IOSink] is closed. | |
| 20 */ | 19 */ |
| 21 abstract class IOSink implements StreamSink<List<int>>, StringSink { | 20 abstract class IOSink implements StreamSink<List<int>>, StringSink { |
| 22 /** | 21 /** |
| 23 * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes. | 22 * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes. |
| 24 * | 23 * |
| 25 * Text written to [StreamSink] methods is encoded to bytes using [encoding] | 24 * Text written to [StreamSink] methods is encoded to bytes using [encoding] |
| 26 * before being output on [target]. | 25 * before being output on [target]. |
| 27 */ | 26 */ |
| 28 factory IOSink(StreamConsumer<List<int>> target, {Encoding encoding: UTF8}) => | 27 factory IOSink(StreamConsumer<List<int>> target, {Encoding encoding: UTF8}) => |
| 29 new _IOSinkImpl(target, encoding); | 28 new _IOSinkImpl(target, encoding); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 final StreamConsumer<T> _target; | 139 final StreamConsumer<T> _target; |
| 141 final Completer _doneCompleter = new Completer(); | 140 final Completer _doneCompleter = new Completer(); |
| 142 StreamController<T> _controllerInstance; | 141 StreamController<T> _controllerInstance; |
| 143 Completer _controllerCompleter; | 142 Completer _controllerCompleter; |
| 144 bool _isClosed = false; | 143 bool _isClosed = false; |
| 145 bool _isBound = false; | 144 bool _isBound = false; |
| 146 bool _hasError = false; | 145 bool _hasError = false; |
| 147 | 146 |
| 148 _StreamSinkImpl(this._target); | 147 _StreamSinkImpl(this._target); |
| 149 | 148 |
| 149 void _reportClosedSink() { |
| 150 // TODO(29554): this is very brittle and depends on the layout of the |
| 151 // stderr class. |
| 152 if (this == stderr._sink) { |
| 153 // We can't report on stderr anymore (as we would otherwise |
| 154 // have an infinite recursion. |
| 155 throw new StateError("Stderr is closed."); |
| 156 } |
| 157 // TODO(29554): throw a StateError, and don't just report the problem. |
| 158 stderr.writeln("StreamSink is closed and adding to it is an error."); |
| 159 stderr.writeln(" See http://dartbug.com/29554."); |
| 160 stderr.writeln(StackTrace.current); |
| 161 } |
| 162 |
| 150 void add(T data) { | 163 void add(T data) { |
| 151 if (_isClosed) return; | 164 if (_isClosed) { |
| 165 _reportClosedSink(); |
| 166 return; |
| 167 } |
| 152 _controller.add(data); | 168 _controller.add(data); |
| 153 } | 169 } |
| 154 | 170 |
| 155 void addError(error, [StackTrace stackTrace]) { | 171 void addError(error, [StackTrace stackTrace]) { |
| 172 if (_isClosed) { |
| 173 _reportClosedSink(); |
| 174 return; |
| 175 } |
| 156 _controller.addError(error, stackTrace); | 176 _controller.addError(error, stackTrace); |
| 157 } | 177 } |
| 158 | 178 |
| 159 Future addStream(Stream<T> stream) { | 179 Future addStream(Stream<T> stream) { |
| 160 if (_isBound) { | 180 if (_isBound) { |
| 161 throw new StateError("StreamSink is already bound to a stream"); | 181 throw new StateError("StreamSink is already bound to a stream"); |
| 162 } | 182 } |
| 163 _isBound = true; | 183 _isBound = true; |
| 164 if (_hasError) return done; | 184 if (_hasError) return done; |
| 165 // Wait for any sync operations to complete. | 185 // Wait for any sync operations to complete. |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 320 |
| 301 void writeln([Object object = ""]) { | 321 void writeln([Object object = ""]) { |
| 302 write(object); | 322 write(object); |
| 303 write("\n"); | 323 write("\n"); |
| 304 } | 324 } |
| 305 | 325 |
| 306 void writeCharCode(int charCode) { | 326 void writeCharCode(int charCode) { |
| 307 write(new String.fromCharCode(charCode)); | 327 write(new String.fromCharCode(charCode)); |
| 308 } | 328 } |
| 309 } | 329 } |
| OLD | NEW |