Chromium Code Reviews| 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)); |
| + } |
| +} |