Index: sdk/lib/convert/chunked_conversion.dart |
diff --git a/sdk/lib/convert/chunked_conversion.dart b/sdk/lib/convert/chunked_conversion.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..def5a3cca537515631c94d103130d87bdb87a95a |
--- /dev/null |
+++ b/sdk/lib/convert/chunked_conversion.dart |
@@ -0,0 +1,131 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+part of dart.convert; |
+ |
+/** |
+ * A [ChunkedConversionInterface] defines an interface through which a |
+ * converter can be accessed when doing chunked conversions. |
+ * |
+ * A [ChunkedConversionInterface]s is associated with a [ChunkedConversionSink]. |
+ * It represents this sink and can adapt sinks to this interface. |
+ */ |
+abstract class ChunkedConversionInterface { |
+ const ChunkedConversionInterface(); |
+ |
+ /** |
+ * Adapts the given [sink] to the [ChunkedConversionSink] associated with |
+ * `this`. |
+ * |
+ * If `this` does not know the interface of [sink] it adapts to the |
+ * non-chunked interface [ChunkedConversionSink.INTERFACE] which is supported |
+ * by every [ChunkedConversionSink]. |
+ * |
+ * This method must not invoke the [sink]'s `adaptTo` method. |
+ */ |
+ ChunkedConversionSink adapt(ChunkedConversionSink sink); |
+} |
+ |
+/** |
+ * A [ChunkedConversionSink] is used to transmit data more efficiently between |
+ * two converters during chunked conversions. |
+ * |
+ * This base class, [ChunkedConversionSink], only supports non-chunked |
+ * conversions (using [addNonChunked]), but sub-classes are encouraged to |
+ * provide more efficient means. |
+ */ |
+abstract class ChunkedConversionSink<T, ChunkedT> { |
Søren Gjesse
2013/07/24 09:26:41
Consider moving the documentation of T and chunked
floitsch
2013/07/24 18:31:15
ChunkedT was removed.
I hope that the single gener
|
+ /** The default interface falls back to a non-chunked conversion. */ |
+ static const ChunkedConversionInterface INTERFACE = |
+ const _NonChunkedInterface(); |
+ |
+ ChunkedConversionSink(); |
+ /** |
+ * Creates a [ChunkedConversionSink] with a callback. |
+ * |
+ * The [callback] is invoked when `this` sink receives data through |
+ * [addNonChunked]. |
+ */ |
+ factory ChunkedConversionSink.withCallback(void callback(T input)) |
+ = _CallbackSink; |
+ |
+ /** |
+ * Adds data to `this` sink. |
+ * |
+ * The given [input] is received in one step, in a non-chunked way. |
+ * |
+ * This method is generally used as means of adapting two incompatible sinks |
+ * or as the entry or exit point of a sequence of converters. In that case the |
+ * conversion starts (or ends) non-chunked, but converters can use more |
+ * efficient interfaces to transmit their data from one converter to the |
+ * next. |
+ */ |
+ void addNonChunked(T input); |
+ |
+ /** |
+ * The interface this sink implements. |
+ */ |
+ ChunkedConversionInterface get interface => INTERFACE; |
+ |
+ /** |
+ * Adds chunked data to this sink. |
+ * |
+ * This method is used when converters are used as [StreamTransformer]s. |
+ * |
+ * The type [ChunkedT] may be different than [T]. For example a converter may |
+ * convert from list of strings, but the chunked interface could expects |
+ * strings directly. |
+ */ |
+ void add(ChunkedT o) { |
+ throw new UnsupportedError("Chunked conversion - add"); |
+ } |
+ |
+ /** |
+ * Adapts `this` to support the given [interface]. |
+ * |
+ * This method may use the [interface]'s `adapt` method. |
+ */ |
+ ChunkedConversionSink adaptTo(ChunkedConversionInterface interface) { |
+ if (this.interface == interface) return this; |
+ return interface.adapt(this); |
+ } |
+ |
+ /** |
+ * Closes the sink. |
+ * |
+ * This signals the end of the chunked conversion. This method is called |
+ * when converters are used as [StreamTransformer]'s. |
+ */ |
+ void close() { throw new UnsupportedError("Chunked conversion - close"); } |
+} |
+ |
+typedef void _ChunkedConversionCallback<T>(T data); |
+ |
+class _CallbackSink<T, ChunkedT> extends ChunkedConversionSink<T, dynamic> { |
+ final _ChunkedConversionCallback<T> _callback; |
+ _CallbackSink(this._callback); |
+ |
+ void addNonChunked(T input) { _callback(input); } |
+} |
+ |
+class _NonChunkedInterface extends ChunkedConversionInterface { |
+ const _NonChunkedInterface(); |
+ |
+ ChunkedConversionSink adapt(ChunkedConversionSink sink) { |
+ // Every sink is suitable as a non-chunked sink. |
+ return sink; |
+ } |
+} |
+ |
+class _NonChunkedSink<S, T> |
+ extends ChunkedConversionSink<S, dynamic> { |
+ final Converter<S, T> _converter; |
+ final ChunkedConversionSink<T, dynamic> _output; |
+ |
+ _NonChunkedSink(this._converter, this._output); |
+ |
+ void addNonChunked(S input) { |
+ _output.addNonChunked(_converter.convert(input)); |
+ } |
+} |