OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 part of dart.convert; |
| 6 |
| 7 /** |
| 8 * This exception is thrown when two chunked-conversion interfaces don't |
| 9 * match. |
| 10 */ |
| 11 // TODO(floitsch): better documentation. |
| 12 class ChunkedConversionInterfaceMismatchException implements Exception { |
| 13 final ChunkedConversionInterface interface1; |
| 14 final ChunkedConversionInterface interface2; |
| 15 |
| 16 // TODO(floitsch): provide constructor with the chunked conversion sink |
| 17 // that tried to be adapted. |
| 18 ChunkedConversionInterfaceMismatchException(this.interface1, this.interface2); |
| 19 |
| 20 String toString() { |
| 21 return "Chunked-conversion interfaces are incompatible: " |
| 22 "$interface1, $interface2"; |
| 23 } |
| 24 } |
| 25 |
| 26 typedef void _ChunkedConversionCallback<T>(T accumulated); |
| 27 |
| 28 /** |
| 29 * This class defines an interface through which a converter can be accessed |
| 30 * when doing chunked conversions. |
| 31 * |
| 32 * A [ChunkedConversionInterface]s is associated with a [ChunkedConversionSink]. |
| 33 * It represents this sink and can adapt sinks to this interface. |
| 34 */ |
| 35 abstract class ChunkedConversionInterface<T> { |
| 36 const ChunkedConversionInterface(); |
| 37 |
| 38 /** |
| 39 * Adapts the given [sink] to the [ChunkedConversionSink] associated with |
| 40 * `this`. |
| 41 * |
| 42 * This method must not invoke the [sink]'s `adaptTo` method. |
| 43 */ |
| 44 ChunkedConversionSink<T> adapt(ChunkedConversionSink sink); |
| 45 |
| 46 /** |
| 47 * Creates a [ChunkedConversionSink] that accumulates all incoming data. |
| 48 * |
| 49 * Invokes the given [callback] with the accumulated data when the returned |
| 50 * sink is closed. |
| 51 */ |
| 52 ChunkedConversionSink<T> createSink(void callback(accumulated)); |
| 53 } |
| 54 |
| 55 /** |
| 56 * This class represents the simple [ChunkedConversionSink] interface without |
| 57 * additional methods. It is accessed through [ChunkedConversionSink.INTERFACE] |
| 58 * or as instance field `interface` from sinks that support this interface. |
| 59 */ |
| 60 class _SimpleChunkedConversionInterface<T> |
| 61 extends ChunkedConversionInterface<T> { |
| 62 const _SimpleChunkedConversionInterface(); |
| 63 |
| 64 ChunkedConversionSink<T> adapt(ChunkedConversionSink sink) { |
| 65 // Every sink implements the simple chunked conversion sink. |
| 66 return sink; |
| 67 } |
| 68 |
| 69 /** |
| 70 * Creates a [ChunkedConversionSink] that accumulates all incoming data. |
| 71 * |
| 72 * Invokes the given [callback] with a list of the accumulated data when the |
| 73 * returned sink is closed. |
| 74 */ |
| 75 ChunkedConversionSink<T> createSink(void callback(List<T> accumulated)) { |
| 76 return new _SimpleCallbackSink<T>(callback); |
| 77 } |
| 78 } |
| 79 |
| 80 /** |
| 81 * A [ChunkedConversionSink] is used to transmit data more efficiently between |
| 82 * two converters during chunked conversions. |
| 83 */ |
| 84 abstract class ChunkedConversionSink<T> { |
| 85 static const INTERFACE = const _SimpleChunkedConversionInterface(); |
| 86 |
| 87 ChunkedConversionSink(); |
| 88 |
| 89 /** |
| 90 * The interface this sink implements. |
| 91 */ |
| 92 ChunkedConversionInterface get interface => INTERFACE; |
| 93 |
| 94 /** |
| 95 * Adds chunked data to this sink. |
| 96 * |
| 97 * This method is also used when converters are used as [StreamTransformer]s. |
| 98 */ |
| 99 void add(T chunk); |
| 100 |
| 101 /** |
| 102 * Closes the sink. |
| 103 * |
| 104 * This signals the end of the chunked conversion. This method is called |
| 105 * when converters are used as [StreamTransformer]'s. |
| 106 */ |
| 107 void close(); |
| 108 |
| 109 /** |
| 110 * Adapts `this` to support the given [interface]. |
| 111 * |
| 112 * This method may use the [interface]'s `adapt` method. |
| 113 */ |
| 114 ChunkedConversionSink adaptTo(ChunkedConversionInterface interface) { |
| 115 if (this.interface == interface) return this; |
| 116 return interface.adapt(this); |
| 117 } |
| 118 } |
| 119 |
| 120 /** |
| 121 * This class accumulates all chunks and invokes a callback with a list of |
| 122 * the chunks when the sink is closed. |
| 123 * |
| 124 * This class can be used to terminate a chunked conversion. |
| 125 */ |
| 126 class _SimpleCallbackSink<T> extends ChunkedConversionSink<T> { |
| 127 final _ChunkedConversionCallback<List<T>> _callback; |
| 128 final List<T> _accumulated = <T>[]; |
| 129 |
| 130 _SimpleCallbackSink(this._callback); |
| 131 |
| 132 void add(T chunk) { _accumulated.add(chunk); } |
| 133 void close() { _callback(_accumulated); } |
| 134 } |
OLD | NEW |