| 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.convert; | 5 part of dart.convert; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * This class provides an interface for converters to | 8 * This class provides an interface for converters to |
| 9 * efficiently transmit String data. | 9 * efficiently transmit String data. |
| 10 * | 10 * |
| 11 * Instead of limiting the interface to one non-chunked String it accepts | 11 * Instead of limiting the interface to one non-chunked String it accepts |
| 12 * partial strings or can be transformed into a byte sink that | 12 * partial strings or can be transformed into a byte sink that |
| 13 * accepts UTF-8 code units. | 13 * accepts UTF-8 code units. |
| 14 * | 14 * |
| 15 * This abstract class will likely get more methods over time. Implementers are | 15 * This abstract class will likely get more methods over time. Implementers are |
| 16 * urged to extend [StringConversionSinkBase] or to mix in | 16 * urged to extend [StringConversionSinkBase] or to mix in |
| 17 * [StringConversionSinkMixin], to ensure that their class covers the newly | 17 * [StringConversionSinkMixin], to ensure that their class covers the newly |
| 18 * added methods. | 18 * added methods. |
| 19 */ | 19 */ |
| 20 abstract class StringConversionSink | 20 abstract class StringConversionSink |
| 21 extends ChunkedConversionSink<String> { | 21 extends ChunkedConversionSink<String> { |
| 22 StringConversionSink(); | 22 StringConversionSink(); |
| 23 factory StringConversionSink.withCallback(void callback(String accumulated)) | 23 factory StringConversionSink.withCallback(void callback(String accumulated)) |
| 24 = _StringCallbackSink; | 24 = _StringCallbackSink; |
| 25 factory StringConversionSink.from(ChunkedConversionSink<String> sink) | 25 factory StringConversionSink.from(Sink<String> sink) |
| 26 = _StringAdapterSink; | 26 = _StringAdapterSink; |
| 27 | 27 |
| 28 /** | 28 /** |
| 29 * Creates a new instance wrapping the given [sink]. | 29 * Creates a new instance wrapping the given [sink]. |
| 30 * | 30 * |
| 31 * Every string that is added to the returned instance is forwarded to | 31 * Every string that is added to the returned instance is forwarded to |
| 32 * the [sink]. The instance is allowed to buffer and is not required to | 32 * the [sink]. The instance is allowed to buffer and is not required to |
| 33 * forward immediately. | 33 * forward immediately. |
| 34 */ | 34 */ |
| 35 factory StringConversionSink.fromStringSink(StringSink sink) = | 35 factory StringConversionSink.fromStringSink(StringSink sink) = |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 } | 243 } |
| 244 | 244 |
| 245 /** | 245 /** |
| 246 * This class adapts a simple [ChunkedConversionSink] to a | 246 * This class adapts a simple [ChunkedConversionSink] to a |
| 247 * [StringConversionSink]. | 247 * [StringConversionSink]. |
| 248 * | 248 * |
| 249 * All additional methods of the [StringConversionSink] (compared to the | 249 * All additional methods of the [StringConversionSink] (compared to the |
| 250 * ChunkedConversionSink) are redirected to the `add` method. | 250 * ChunkedConversionSink) are redirected to the `add` method. |
| 251 */ | 251 */ |
| 252 class _StringAdapterSink extends StringConversionSinkBase { | 252 class _StringAdapterSink extends StringConversionSinkBase { |
| 253 final ChunkedConversionSink<String> _sink; | 253 final Sink<String> _sink; |
| 254 | 254 |
| 255 _StringAdapterSink(this._sink); | 255 _StringAdapterSink(this._sink); |
| 256 | 256 |
| 257 void add(String str) => _sink.add(str); | 257 void add(String str) => _sink.add(str); |
| 258 | 258 |
| 259 void addSlice(String str, int start, int end, bool isLast) { | 259 void addSlice(String str, int start, int end, bool isLast) { |
| 260 if (start == 0 && end == str.length) { | 260 if (start == 0 && end == str.length) { |
| 261 add(str); | 261 add(str); |
| 262 } else { | 262 } else { |
| 263 add(str.substring(start, end)); | 263 add(str.substring(start, end)); |
| 264 } | 264 } |
| 265 if (isLast) close(); | 265 if (isLast) close(); |
| 266 } | 266 } |
| 267 | 267 |
| 268 void close() => _sink.close(); | 268 void close() => _sink.close(); |
| 269 } | 269 } |
| 270 | 270 |
| 271 | 271 |
| 272 /** | 272 /** |
| 273 * Decodes UTF-8 code units and stores them in a [StringSink]. | 273 * Decodes UTF-8 code units and stores them in a [StringSink]. |
| 274 */ | 274 */ |
| 275 class _Utf8StringSinkAdapter extends ByteConversionSink { | 275 class _Utf8StringSinkAdapter extends ByteConversionSink { |
| 276 final _Utf8Decoder _decoder; | 276 final _Utf8Decoder _decoder; |
| 277 final ChunkedConversionSink _chunkedSink; | 277 final Sink _sink; |
| 278 | 278 |
| 279 _Utf8StringSinkAdapter(ChunkedConversionSink chunkedSink, | 279 _Utf8StringSinkAdapter(this._sink, |
| 280 StringSink sink, bool allowMalformed) | 280 StringSink stringSink, bool allowMalformed) |
| 281 : _chunkedSink = chunkedSink, | 281 : _decoder = new _Utf8Decoder(stringSink, allowMalformed); |
| 282 _decoder = new _Utf8Decoder(sink, allowMalformed); | |
| 283 | 282 |
| 284 void close() { | 283 void close() { |
| 285 _decoder.close(); | 284 _decoder.close(); |
| 286 if(_chunkedSink != null) _chunkedSink.close(); | 285 if(_sink != null) _sink.close(); |
| 287 } | 286 } |
| 288 | 287 |
| 289 void add(List<int> chunk) { | 288 void add(List<int> chunk) { |
| 290 addSlice(chunk, 0, chunk.length, false); | 289 addSlice(chunk, 0, chunk.length, false); |
| 291 } | 290 } |
| 292 | 291 |
| 293 void addSlice(List<int> codeUnits, int startIndex, int endIndex, | 292 void addSlice(List<int> codeUnits, int startIndex, int endIndex, |
| 294 bool isLast) { | 293 bool isLast) { |
| 295 _decoder.convert(codeUnits, startIndex, endIndex); | 294 _decoder.convert(codeUnits, startIndex, endIndex); |
| 296 if (isLast) close(); | 295 if (isLast) close(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 _decoder.convert(chunk, startIndex, endIndex); | 334 _decoder.convert(chunk, startIndex, endIndex); |
| 336 if (_buffer.isNotEmpty) { | 335 if (_buffer.isNotEmpty) { |
| 337 String accumulated = _buffer.toString(); | 336 String accumulated = _buffer.toString(); |
| 338 _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast); | 337 _chunkedSink.addSlice(accumulated, 0, accumulated.length, isLast); |
| 339 _buffer.clear(); | 338 _buffer.clear(); |
| 340 return; | 339 return; |
| 341 } | 340 } |
| 342 if (isLast) close(); | 341 if (isLast) close(); |
| 343 } | 342 } |
| 344 } | 343 } |
| OLD | NEW |