Chromium Code Reviews| Index: sdk/lib/io/data_transformer.dart |
| diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart |
| index c7c53adc7938ef6a2558bd734441bd05f5679fa8..fe42277cd0e45b4a44578ad5e3ee37da35685c06 100644 |
| --- a/sdk/lib/io/data_transformer.dart |
| +++ b/sdk/lib/io/data_transformer.dart |
| @@ -4,95 +4,157 @@ |
| part of dart.io; |
| -/** |
| - * Private helper-class to handle native filters. |
| - */ |
| -abstract class _Filter { |
| - /** |
| - * Call to process a chunk of data. A call to [process] should only be made |
| - * when [processed] returns [null]. |
| - */ |
| - void process(List<int> data); |
| - /** |
| - * Get a chunk of processed data. When there are no more data available, |
| - * [processed] will return [null]. Set [flush] to [false] for non-final |
| - * calls to improve performance of some filters. |
| - * |
| - * The last call to [processed] should have [end] set to [true]. This will make |
| - * sure a 'end' packet is written on the stream. |
| - */ |
| - List<int> processed({bool flush: true, bool end: false}); |
| +const ZLIB = const ZLibCodec(); |
|
floitsch
2013/08/22 15:04:05
add comments.
Søren Gjesse
2013/08/22 15:10:37
Documentation for the ZLIB object?
Anders Johnsen
2013/08/22 15:58:01
Done.
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + |
| + |
| +class ZLibCodec extends Codec<List<int>, List<int>> { |
|
floitsch
2013/08/22 15:04:05
add comments and for all other classes / methods.
Søren Gjesse
2013/08/22 15:10:37
And for the codec.
Anders Johnsen
2013/08/22 15:58:01
Done.
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + final Converter<List<int>, List<int>> encoder = |
| + const ZLibEncoder(gzip: false); |
| + final Converter<List<int>, List<int>> decoder = const ZLibDecoder(); |
| + |
| + const ZLibCodec(); |
| +} |
| + |
| + |
| +const GZIP = const GZipCodec(); |
|
Søren Gjesse
2013/08/22 15:10:37
Ditto.
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + |
| + |
| +class GZipCodec extends Codec<List<int>, List<int>> { |
|
Søren Gjesse
2013/08/22 15:10:37
Ditto.
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + final Converter<List<int>, List<int>> encoder = const ZLibEncoder(gzip: true); |
| + final Converter<List<int>, List<int>> decoder = const ZLibDecoder(); |
| + |
| + const GZipCodec(); |
| +} |
| + |
| + |
| +class ZLibEncoder extends Converter<List<int>, List<int>> { |
|
floitsch
2013/08/22 15:04:05
Still misses the synchronous convert function.
You
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + final bool gzip; |
| + final int level; |
| /** |
| - * Mark the filter as closed. Always call this method for any filter created |
| - * to avoid leaking resources. [end] can be called at any time, but any |
| - * successive calls to [process] or [processed] will fail. |
| + * Create a new [ZLibEncoder] converter. If the [gzip] flag is set, the |
| + * encoder will wrap the encoded ZLib data in GZip frames. |
| */ |
| - void end(); |
| + const ZLibEncoder({this.gzip: false, this.level: 6}); |
| - external static _Filter newZLibDeflateFilter(bool gzip, int level); |
| - external static _Filter newZLibInflateFilter(); |
| + ByteConversionSink startChunkedConversion( |
|
floitsch
2013/08/22 15:04:05
Comment explaining that the function is more effic
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + ChunkedConversionSink<List<int>> sink) { |
| + if (sink is! ByteConversionSink) { |
| + sink = new ByteConversionSink.from(sink); |
| + } |
| + return new _ZLibEncoderSink(sink, gzip, level); |
| + } |
| } |
| -class _FilterTransformer extends StreamEventTransformer<List<int>, List<int>> { |
| +class ZLibDecoder extends Converter<List<int>, List<int>> { |
|
Søren Gjesse
2013/08/22 15:10:37
Add comment for this constructor as well. Currentl
Anders Johnsen
2013/08/22 15:58:01
Done.
|
| + const ZLibDecoder(); |
| + |
| + ByteConversionSink startChunkedConversion( |
| + ChunkedConversionSink<List<int>> sink) { |
| + if (sink is! ByteConversionSink) { |
| + sink = new ByteConversionSink.from(sink); |
| + } |
| + return new _ZLibDecoderSink(sink); |
| + } |
| +} |
| + |
| + |
| +class _ZLibEncoderSink extends _FilterSink { |
| + _ZLibEncoderSink(ByteConversionSink sink, bool gzip, int level) |
| + : super(sink, _Filter.newZLibDeflateFilter(gzip, level)); |
| +} |
| + |
| + |
| +class _ZLibDecoderSink extends _FilterSink { |
| + _ZLibDecoderSink(ByteConversionSink sink) |
| + : super(sink, _Filter.newZLibInflateFilter()); |
| +} |
| + |
| + |
| +class _FilterSink extends ByteConversionSink { |
| final _Filter _filter; |
| + final ByteConversionSink _sink; |
| bool _closed = false; |
| bool _empty = true; |
| - _FilterTransformer(_Filter this._filter); |
| + _FilterSink(ByteConversionSink this._sink, _Filter this._filter); |
| + |
| + void add(List<int> data) { |
| + addSlice(data, 0, data.length, false); |
| + } |
| - void handleData(List<int> data, EventSink<List<int>> sink) { |
| + void addSlice(List<int> data, int start, int end, bool isLast) { |
| if (_closed) return; |
| + if (start < 0 || start > data.length) { |
| + throw ArgumentError("Invalid start position"); |
| + } |
| + if (end < 0 || end > data.length || end < start) { |
| + throw ArgumentError("Invalid end position"); |
| + } |
| try { |
| _empty = false; |
| - _filter.process(data); |
| + _filter.process(data, start, end); |
| var out; |
| while ((out = _filter.processed(flush: false)) != null) { |
| - sink.add(out); |
| + _sink.add(out); |
| } |
| - } catch (e, s) { |
| + } catch (e) { |
| _closed = true; |
| - // TODO(floitsch): we are losing the stack trace. |
| - sink.addError(e); |
| - sink.close(); |
| + throw e; |
| } |
| + |
| + if (isLast) close(); |
| } |
| - void handleDone(EventSink<List<int>> sink) { |
| + void close() { |
| if (_closed) return; |
| - if (_empty) _filter.process(const []); |
| + if (_empty) _filter.process(const [], 0, 0); |
|
floitsch
2013/08/22 15:04:05
can't you replace this and the following lines wit
Anders Johnsen
2013/08/22 15:58:01
Added comment. And no, since we don't want to writ
|
| try { |
| var out; |
| while ((out = _filter.processed(end: true)) != null) { |
| - sink.add(out); |
| + _sink.add(out); |
| } |
| - } catch (e, s) { |
| - // TODO(floitsch): we are losing the stack trace. |
| - sink.addError(e); |
| + } catch (e) { |
| _closed = true; |
| + throw e; |
| } |
| if (!_closed) _filter.end(); |
| _closed = true; |
| - sink.close(); |
| + _sink.close(); |
| } |
| } |
| + |
| /** |
| - * ZLibDeflater class used to deflate a stream of bytes, using zlib. |
| + * Private helper-class to handle native filters. |
| */ |
| -class ZLibDeflater extends _FilterTransformer { |
| - ZLibDeflater({bool gzip: true, int level: 6}) |
| - : super(_Filter.newZLibDeflateFilter(gzip, level)); |
| -} |
| +abstract class _Filter { |
| + /** |
| + * Call to process a chunk of data. A call to [process] should only be made |
| + * when [processed] returns [null]. |
| + */ |
| + void process(List<int> data, int start, int end); |
| + /** |
| + * Get a chunk of processed data. When there are no more data available, |
| + * [processed] will return [null]. Set [flush] to [false] for non-final |
| + * calls to improve performance of some filters. |
| + * |
| + * The last call to [processed] should have [end] set to [true]. This will make |
| + * sure a 'end' packet is written on the stream. |
| + */ |
| + List<int> processed({bool flush: true, bool end: false}); |
| -/** |
| - * ZLibInflater class used to inflate a stream of bytes, using zlib. |
| - */ |
| -class ZLibInflater extends _FilterTransformer { |
| - ZLibInflater() : super(_Filter.newZLibInflateFilter()); |
| -} |
| + /** |
| + * Mark the filter as closed. Always call this method for any filter created |
| + * to avoid leaking resources. [end] can be called at any time, but any |
| + * successive calls to [process] or [processed] will fail. |
| + */ |
| + void end(); |
| + external static _Filter newZLibDeflateFilter(bool gzip, int level); |
| + external static _Filter newZLibInflateFilter(); |
| +} |