| 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 typedef void _ChunkedConversionCallback<T>(T accumulated); | 7 typedef void _ChunkedConversionCallback<T>(T accumulated); |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * A [ChunkedConversionSink] is used to transmit data more efficiently between | 10 * A [ChunkedConversionSink] is used to transmit data more efficiently between |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 */ | 39 */ |
| 40 class _SimpleCallbackSink<T> extends ChunkedConversionSink<T> { | 40 class _SimpleCallbackSink<T> extends ChunkedConversionSink<T> { |
| 41 final _ChunkedConversionCallback<List<T>> _callback; | 41 final _ChunkedConversionCallback<List<T>> _callback; |
| 42 final List<T> _accumulated = <T>[]; | 42 final List<T> _accumulated = <T>[]; |
| 43 | 43 |
| 44 _SimpleCallbackSink(this._callback); | 44 _SimpleCallbackSink(this._callback); |
| 45 | 45 |
| 46 void add(T chunk) { _accumulated.add(chunk); } | 46 void add(T chunk) { _accumulated.add(chunk); } |
| 47 void close() { _callback(_accumulated); } | 47 void close() { _callback(_accumulated); } |
| 48 } | 48 } |
| 49 |
| 50 /** |
| 51 * This class wraps a [Converter] for use as a [StreamTransformer]. |
| 52 */ |
| 53 class _ConverterTransformStream<S, T> extends EventTransformStream<S, T> { |
| 54 final _ConverterStreamEventTransformer<S, T> _eventTransformer; |
| 55 |
| 56 _ConverterTransformStream(Stream<S> source, Converter converter) |
| 57 : this._withEventTransformer( |
| 58 source, |
| 59 new _ConverterStreamEventTransformer<S, T>(converter)); |
| 60 |
| 61 _ConverterTransformStream._withEventTransformer( |
| 62 Stream<S> source, |
| 63 _ConverterStreamEventTransformer<S, T> eventTransformer) |
| 64 : _eventTransformer = eventTransformer, |
| 65 super(source, eventTransformer); |
| 66 |
| 67 /** |
| 68 * Starts listening to `this`. |
| 69 * |
| 70 * This starts the chunked conversion. |
| 71 */ |
| 72 StreamSubscription<T> listen(void onData(T data), |
| 73 { void onError(error), |
| 74 void onDone(), |
| 75 bool cancelOnError }) { |
| 76 _eventTransformer._startChunkedConversion(); |
| 77 return super.listen(onData, onError: onError, onDone: onDone, |
| 78 cancelOnError: cancelOnError); |
| 79 } |
| 80 } |
| 81 |
| 82 /** |
| 83 * This class converts implements the logic for a chunked conversion as a |
| 84 * stream transformer. |
| 85 * |
| 86 * It is used as strategy in the [EventTransformStream]. |
| 87 * |
| 88 * It also implements the [ChunkedConversionSink] interface so that it |
| 89 * can be used as output sink in a chunked conversion. |
| 90 */ |
| 91 class _ConverterStreamEventTransformer<S, T> |
| 92 implements ChunkedConversionSink<T>, StreamEventTransformer<S, T> { |
| 93 final Converter _converter; |
| 94 |
| 95 /** At every [handleData] this field is updated with the new event sink. */ |
| 96 EventSink<T> _eventSink; |
| 97 |
| 98 /** |
| 99 * The input sink for new data. All data that is received with |
| 100 * [handleData] is added into this sink. |
| 101 */ |
| 102 ChunkedConversionSink _chunkedSink; |
| 103 |
| 104 _ConverterStreamEventTransformer(this._converter); |
| 105 |
| 106 /** |
| 107 * Starts the chunked conversion. |
| 108 */ |
| 109 void _startChunkedConversion() { |
| 110 _chunkedSink = _converter.startChunkedConversion(this); |
| 111 } |
| 112 |
| 113 /** |
| 114 * Not supported. |
| 115 */ |
| 116 Stream bind(Stream otherStream) { |
| 117 throw new UnsupportedError("Converter streams must not call bind"); |
| 118 } |
| 119 |
| 120 void add(T o) => _eventSink.add(o); |
| 121 void close() => _eventSink.close(); |
| 122 |
| 123 void handleData(S event, EventSink<T> eventSink) { |
| 124 _eventSink = eventSink; |
| 125 try { |
| 126 _chunkedSink.add(event); |
| 127 } catch(e) { |
| 128 eventSink.addError(e); |
| 129 } finally { |
| 130 _eventSink = null; |
| 131 } |
| 132 } |
| 133 |
| 134 void handleDone(EventSink<T> eventSink) { |
| 135 _eventSink = eventSink; |
| 136 try { |
| 137 _chunkedSink.close(); |
| 138 } catch(e) { |
| 139 eventSink.addError(e); |
| 140 } finally { |
| 141 _eventSink = null; |
| 142 } |
| 143 } |
| 144 |
| 145 void handleError(var errorEvent, EventSink<T> eventSink) { |
| 146 eventSink.addError(errorEvent); |
| 147 } |
| 148 } |
| OLD | NEW |