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 converter that supports chunked conversions. |
| 11 */ |
| 12 // This class may be used as Mixin. |
| 13 abstract class ChunkedConverter<S, T, S2, T2> extends Converter<S, T> |
| 14 implements StreamTransformer<S2, T2> { |
| 15 |
| 16 const ChunkedConverter(); |
| 17 |
| 18 /** |
| 19 * Starts a chunked conversion. |
| 20 */ |
| 21 ChunkedConversionSink<S2> startChunkedConversion(Sink<T2> sink) { |
| 22 throw new UnsupportedError( |
| 23 "This converter does not support chunked conversions: $this"); |
| 24 } |
| 25 |
| 26 Stream<T2> bind(Stream<S2> stream) { |
| 27 return new Stream<T2>.eventTransformed( |
| 28 stream, |
| 29 (EventSink<T2> sink) => |
| 30 new _ConverterStreamEventSink<S2, T2>(this, sink)); |
| 31 } |
| 32 |
| 33 Converter<S, dynamic> fuse(Converter<T, dynamic> other) { |
| 34 if (other is ChunkedConverter<T, dynamic, T2, dynamic>) { |
| 35 return new _FusedChunkedConverter<S, T, dynamic, S2, T2, dynamic>( |
| 36 this, other); |
| 37 } |
| 38 return super.fuse(other); |
| 39 } |
| 40 } |
| 41 |
| 42 /** |
10 * A [ChunkedConversionSink] is used to transmit data more efficiently between | 43 * A [ChunkedConversionSink] is used to transmit data more efficiently between |
11 * two converters during chunked conversions. | 44 * two converters during chunked conversions. |
12 * | 45 * |
13 * The basic `ChunkedConversionSink` is just a [Sink], and converters should | 46 * The basic `ChunkedConversionSink` is just a [Sink], and converters should |
14 * work with a plain `Sink`, but may work more efficiently with certain | 47 * work with a plain `Sink`, but may work more efficiently with certain |
15 * specialized types of `ChunkedConversionSink`. | 48 * specialized types of `ChunkedConversionSink`. |
16 * | 49 * |
17 * It is recommended that implementations of `ChunkedConversionSink` extends | 50 * It is recommended that implementations of `ChunkedConversionSink` extends |
18 * this class, to inherit any further methods that may be added to the class. | 51 * this class, to inherit any further methods that may be added to the class. |
19 */ | 52 */ |
(...skipping 28 matching lines...) Expand all Loading... |
48 final _ChunkedConversionCallback<List<T>> _callback; | 81 final _ChunkedConversionCallback<List<T>> _callback; |
49 final List<T> _accumulated = <T>[]; | 82 final List<T> _accumulated = <T>[]; |
50 | 83 |
51 _SimpleCallbackSink(this._callback); | 84 _SimpleCallbackSink(this._callback); |
52 | 85 |
53 void add(T chunk) { _accumulated.add(chunk); } | 86 void add(T chunk) { _accumulated.add(chunk); } |
54 void close() { _callback(_accumulated); } | 87 void close() { _callback(_accumulated); } |
55 } | 88 } |
56 | 89 |
57 /** | 90 /** |
58 * This class converts implements the logic for a chunked conversion as a | 91 * This class implements the logic for a chunked conversion as a |
59 * stream transformer. | 92 * stream transformer. |
60 * | 93 * |
61 * It is used as strategy in the [EventTransformStream]. | 94 * It is used as strategy in the [EventTransformStream]. |
62 * | 95 * |
63 * It also implements the [ChunkedConversionSink] interface so that it | 96 * It also implements the [ChunkedConversionSink] interface so that it |
64 * can be used as output sink in a chunked conversion. | 97 * can be used as output sink in a chunked conversion. |
65 */ | 98 */ |
66 class _ConverterStreamEventSink<S, T> implements EventSink<S> { | 99 class _ConverterStreamEventSink<S, T> implements EventSink<S> { |
67 /** The output sink for the converter. */ | 100 /** The output sink for the converter. */ |
68 final EventSink<T> _eventSink; | 101 final EventSink<T> _eventSink; |
69 | 102 |
70 /** | 103 /** |
71 * The input sink for new data. All data that is received with | 104 * The input sink for new data. All data that is received with |
72 * [handleData] is added into this sink. | 105 * [handleData] is added into this sink. |
73 */ | 106 */ |
74 ChunkedConversionSink _chunkedSink; | 107 ChunkedConversionSink<S> _chunkedSink; |
75 | 108 |
76 _ConverterStreamEventSink(Converter converter, EventSink<T> sink) | 109 _ConverterStreamEventSink( |
| 110 ChunkedConverter<dynamic, dynamic, S, T> converter, EventSink<T> sink) |
77 : this._eventSink = sink, | 111 : this._eventSink = sink, |
78 _chunkedSink = converter.startChunkedConversion(sink); | 112 _chunkedSink = converter.startChunkedConversion(sink); |
79 | 113 |
80 void add(S o) => _chunkedSink.add(o); | 114 void add(S o) => _chunkedSink.add(o); |
81 void addError(Object error, [StackTrace stackTrace]) { | 115 void addError(Object error, [StackTrace stackTrace]) { |
82 _eventSink.addError(error, stackTrace); | 116 _eventSink.addError(error, stackTrace); |
83 } | 117 } |
84 void close() => _chunkedSink.close(); | 118 void close() => _chunkedSink.close(); |
85 } | 119 } |
| 120 |
| 121 /** |
| 122 * Fuses two chunked converters. |
| 123 * |
| 124 * For a non-chunked conversion converts the input in sequence. |
| 125 */ |
| 126 class _FusedChunkedConverter<S, M, T, S2, M2, T2> extends |
| 127 ChunkedConverter<S, T, S2, T2> { |
| 128 final ChunkedConverter<S, M, S2, M2> _first; |
| 129 final ChunkedConverter<M, T, M2, T2> _second; |
| 130 |
| 131 _FusedChunkedConverter(this._first, this._second); |
| 132 |
| 133 T convert(S input) => _second.convert(_first.convert(input)); |
| 134 |
| 135 ChunkedConversionSink<S2> startChunkedConversion(Sink<T2> sink) { |
| 136 return _first.startChunkedConversion(_second.startChunkedConversion(sink)); |
| 137 } |
| 138 } |
OLD | NEW |