Chromium Code Reviews| 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.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 | 7 |
| 8 /// Minimal value for [windowBits] | |
| 9 const int ZLIB_MIN_WINDOW_BITS = 8; | |
|
Anders Johnsen
2014/01/27 12:27:45
If these are moved to ZLibCodec as final members,
vicb
2014/01/27 15:14:19
But in the doc they'll be listed in ZLibCodec, not
| |
| 10 /// Maximal value for [windowBits] | |
| 11 const int ZLIB_MAX_WINDOW_BITS = 15; | |
| 12 /// Default value for [windowBits] | |
| 13 const int ZLIB_DFT_WINDOW_BITS = 15; | |
| 14 | |
| 15 /// Minimal value for [level] | |
| 16 const int ZLIB_MIN_LEVEL = -1; | |
| 17 /// Maximal value for [level] | |
| 18 const int ZLIB_MAX_LEVEL = 9; | |
| 19 /// Default value for [level] | |
| 20 const int ZLIB_DFT_LEVEL = 6; | |
| 21 | |
| 22 /// Minimal value for [memLevel] | |
| 23 const int ZLIB_MIN_MEM_LEVEL = 1; | |
| 24 /// Maximal value for [memLevel] | |
| 25 const int ZLIB_MAX_MEM_LEVEL = 9; | |
| 26 /// Default value for [memLevel] | |
| 27 const int ZLIB_DFT_MEM_LEVEL = 8; | |
| 28 | |
| 29 /// Compression strategies | |
| 30 const int ZLIB_STRATEGY_FILTERED = 1; | |
| 31 const int ZLIB_STRATEGY_HUFFMAN_ONLY = 2; | |
| 32 const int ZLIB_STRATEGY_RLE = 3; | |
| 33 const int ZLIB_STRATEGY_FIXED = 4; | |
| 34 const int ZLIB_STRATEGY_DEFAULT = 0; | |
| 35 | |
| 36 | |
| 8 /** | 37 /** |
| 9 * An instance of the default implementation of the [ZLibCodec]. | 38 * An instance of the default implementation of the [ZLibCodec]. |
| 10 */ | 39 */ |
| 11 const ZLibCodec ZLIB = const ZLibCodec(); | 40 final ZLibCodec ZLIB = new ZLibCodec(); |
|
Anders Johnsen
2014/01/27 12:27:45
make const.
vicb
2014/01/27 15:14:19
Can not because of the required checks
| |
| 12 | |
| 13 | 41 |
| 14 /** | 42 /** |
| 15 * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib | 43 * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib |
| 16 * compressed bytes to raw bytes. | 44 * compressed bytes to raw bytes. |
| 17 */ | 45 */ |
| 18 class ZLibCodec extends Codec<List<int>, List<int>> { | 46 class ZLibCodec extends Codec<List<int>, List<int>> { |
| 19 /** | 47 /** |
| 20 * The compression level of the [ZLibCodec]. | 48 * When true, `GZip` frames will be added to the compressed data. |
| 49 */ | |
| 50 final bool gzip; | |
| 51 | |
| 52 /** | |
| 53 * The compression-[level] can be set in the range of `-1..9`, with `6` being | |
| 54 * the default compression level. Levels above `6` will have higher compressio n | |
| 55 * rates at the cost of more CPU and memory usage. Levels below `6` will use | |
| 56 * less CPU and memory at the cost of lower compression rates. | |
| 21 */ | 57 */ |
| 22 final int level; | 58 final int level; |
| 23 | 59 |
| 24 /** | 60 /** |
| 61 * Specifies how much memory should be allocated for the internal compression | |
| 62 * state. `1` uses minimum memory but is slow and reduces compression ratio; | |
| 63 * `9` uses maximum memory for optimal speed. The default value is `8`. | |
| 64 * | |
| 65 * The memory requirements for deflate are (in bytes): | |
| 66 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) | |
| 67 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) | |
| 68 */ | |
| 69 final int memLevel; | |
| 70 | |
| 71 /** | |
| 72 * Tunes the compression algorithm. Use the value STRATEGY_DEFAULT for normal | |
| 73 * data, STRATEGY_FILTERED for data produced by a filter (or predictor), | |
| 74 * STRATEGY_HUFFMAN_ONLY to force Huffman encoding only (no string match), or | |
| 75 * STRATEGY_RLE to limit match distances to one (run-length encoding). | |
| 76 */ | |
| 77 final int strategy; | |
| 78 | |
| 79 /** | |
| 80 * Base two logarithm of the window size (the size of the history buffer). It | |
| 81 * should be in the range 8..15. Larger values result in better compression at | |
| 82 * the expense of memory usage. The default value is 15 | |
| 83 */ | |
| 84 final int windowBits; | |
| 85 | |
| 86 /** | |
| 87 * When true, deflate generates raw data with no zlib header or trailer, and | |
| 88 * will not compute an adler32 check value | |
| 89 */ | |
| 90 final bool raw; | |
| 91 | |
| 92 /** | |
| 93 * Initial compression dictionary. | |
| 94 * | |
| 95 * It should consist of strings (byte sequences) that are likely to be | |
| 96 * encountered later in the data to be compressed, with the most commonly used | |
| 97 * strings preferably put towards the end of the dictionary. Using a dictionary | |
| 98 * is most useful when the data to be compressed is short and can be predicted | |
| 99 * with good accuracy; the data can then be compressed better than with the | |
| 100 * default empty dictionary. | |
| 101 */ | |
| 102 final List<int> dictionary; | |
| 103 | |
| 104 ZLibCodec({this.level: ZLIB_DFT_LEVEL, | |
| 105 this.windowBits: ZLIB_DFT_WINDOW_BITS, | |
| 106 this.memLevel: ZLIB_DFT_MEM_LEVEL, | |
| 107 this.strategy: ZLIB_STRATEGY_DEFAULT, | |
| 108 this.dictionary: null, | |
| 109 this.raw: false}) { | |
| 110 validateZLibeLevel(level); | |
|
Anders Johnsen
2014/01/27 12:27:45
Move checks to encoder and decoder getters, or bet
vicb
2014/01/27 15:14:19
As the decoder & encoder are lazily instantiated t
| |
| 111 validateZLibMemLevel(memLevel); | |
| 112 validateZLibStrategy(strategy); | |
| 113 validateZLibWindowBits(windowBits); | |
| 114 } | |
| 115 | |
| 116 /** | |
| 25 * Get a [Converter] for encoding to `ZLib` compressed data. | 117 * Get a [Converter] for encoding to `ZLib` compressed data. |
| 26 */ | 118 */ |
| 27 Converter<List<int>, List<int>> get encoder => | 119 Converter<List<int>, List<int>> get encoder => |
| 28 new ZLibEncoder(gzip: false, level: level); | 120 new ZLibEncoder(gzip: false, level: level, windowBits: windowBits, |
| 121 memLevel: memLevel, strategy: strategy, | |
| 122 dictionary: dictionary, raw: raw); | |
| 29 | 123 |
| 30 /** | 124 /** |
| 31 * Get a [Converter] for decoding `ZLib` compressed data. | 125 * Get a [Converter] for decoding `ZLib` compressed data. |
| 32 */ | 126 */ |
| 33 Converter<List<int>, List<int>> get decoder => const ZLibDecoder(); | 127 Converter<List<int>, List<int>> get decoder => new ZLibDecoder( |
| 34 | 128 windowBits: windowBits, dictionary: dictionary, raw: raw); |
| 35 /** | |
| 36 * The compression-[level] can be set in the range of `1..10`, with `6` being | |
| 37 * the default compression level. Levels above 6 will have higher compression | |
| 38 * rates at the cost of more CPU and memory usage. Levels below 6 will use | |
| 39 * less CPU and memory, but at the cost of lower compression rates. | |
| 40 */ | |
| 41 const ZLibCodec({this.level: 6}); | |
| 42 } | 129 } |
| 43 | 130 |
| 44 | 131 |
| 45 /** | 132 /** |
| 46 * An instance of the default implementation of the [GZipCodec]. | 133 * An instance of the default implementation of the [GZipCodec]. |
| 47 */ | 134 */ |
| 48 const GZipCodec GZIP = const GZipCodec(); | 135 final GZipCodec GZIP = new GZipCodec(); |
| 49 | 136 |
| 50 | 137 |
| 51 /** | 138 /** |
| 52 * The [GZipCodec] encodes raw bytes to GZip compressed bytes and decodes GZip | 139 * The GZipCodec encodes raw bytes to GZip compressed bytes and decodes GZip |
| 53 * compressed bytes to raw bytes. | 140 * compressed bytes to raw bytes. |
| 54 * | 141 * |
| 55 * The difference between [ZLibCodec] and [GZipCodec] is that the [GZipCodec] | 142 * The difference between [ZLibCodec] and GZipCodec is that the GZipCodec wraps |
| 56 * wraps the `ZLib` compressed bytes in `GZip` frames. | 143 * the `ZLib` compressed bytes in `GZip` frames. |
| 57 */ | 144 */ |
| 58 class GZipCodec extends Codec<List<int>, List<int>> { | 145 class GZipCodec extends Codec<List<int>, List<int>> { |
| 59 /** | 146 /** |
| 60 * The compression level of the [ZLibCodec]. | 147 * When true, `GZip` frames will be added to the compressed data. |
| 148 */ | |
| 149 final bool gzip; | |
| 150 | |
| 151 /** | |
| 152 * The compression-[level] can be set in the range of `-1..9`, with `6` being | |
| 153 * the default compression level. Levels above `6` will have higher compressio n | |
| 154 * rates at the cost of more CPU and memory usage. Levels below `6` will use | |
| 155 * less CPU and memory at the cost of lower compression rates. | |
| 61 */ | 156 */ |
| 62 final int level; | 157 final int level; |
| 63 | 158 |
| 64 /** | 159 /** |
| 160 * Specifies how much memory should be allocated for the internal compression | |
| 161 * state. `1` uses minimum memory but is slow and reduces compression ratio; | |
| 162 * `9` uses maximum memory for optimal speed. The default value is `8`. | |
| 163 * | |
| 164 * The memory requirements for deflate are (in bytes): | |
| 165 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) | |
| 166 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) | |
| 167 */ | |
| 168 final int memLevel; | |
| 169 | |
| 170 /** | |
| 171 * Tunes the compression algorithm. Use the value STRATEGY_DEFAULT for normal | |
| 172 * data, STRATEGY_FILTERED for data produced by a filter (or predictor), | |
| 173 * STRATEGY_HUFFMAN_ONLY to force Huffman encoding only (no string match), or | |
| 174 * STRATEGY_RLE to limit match distances to one (run-length encoding). | |
| 175 */ | |
| 176 final int strategy; | |
| 177 | |
| 178 /** | |
| 179 * Base two logarithm of the window size (the size of the history buffer). It | |
| 180 * should be in the range 8..15. Larger values result in better compression at | |
| 181 * the expense of memory usage. The default value is 15 | |
| 182 */ | |
| 183 final int windowBits; | |
| 184 | |
| 185 /** | |
| 186 * Initial compression dictionary. | |
| 187 * | |
| 188 * It should consist of strings (byte sequences) that are likely to be | |
| 189 * encountered later in the data to be compressed, with the most commonly used | |
| 190 * strings preferably put towards the end of the dictionary. Using a dictionary | |
| 191 * is most useful when the data to be compressed is short and can be predicted | |
| 192 * with good accuracy; the data can then be compressed better than with the | |
| 193 * default empty dictionary. | |
|
Anders Johnsen
2014/01/27 12:27:45
Maybe write some more about lifeness - do we take
vicb
2014/01/27 15:14:19
I tool models on the current converters. However t
| |
| 194 */ | |
| 195 final List<int> dictionary; | |
| 196 | |
| 197 /** | |
| 198 * When true, deflate generates raw data with no zlib header or trailer, and | |
| 199 * will not compute an adler32 check value | |
| 200 */ | |
| 201 final bool raw; | |
| 202 | |
| 203 GZipCodec({this.level: ZLIB_DFT_LEVEL, | |
| 204 this.windowBits: ZLIB_DFT_WINDOW_BITS, | |
| 205 this.memLevel: ZLIB_DFT_MEM_LEVEL, | |
| 206 this.strategy: ZLIB_STRATEGY_DEFAULT, | |
| 207 this.dictionary: null, | |
| 208 raw: false}) { | |
| 209 validateZLibeLevel(level); | |
| 210 validateZLibMemLevel(memLevel); | |
| 211 validateZLibStrategy(strategy); | |
| 212 validateZLibWindowBits(windowBits); | |
| 213 } | |
| 214 | |
| 215 /** | |
| 65 * Get a [Converter] for encoding to `GZip` compressed data. | 216 * Get a [Converter] for encoding to `GZip` compressed data. |
| 66 */ | 217 */ |
| 67 Converter<List<int>, List<int>> get encoder => | 218 Converter<List<int>, List<int>> get encoder => |
| 68 new ZLibEncoder(gzip: true, level: level); | 219 new ZLibEncoder(gzip: true, level: level, windowBits: windowBits, |
| 220 memLevel: memLevel, strategy: strategy, | |
| 221 dictionary: dictionary, raw: raw); | |
| 69 | 222 |
| 70 /** | 223 /** |
| 71 * Get a [Converter] for decoding `GZip` compressed data. | 224 * Get a [Converter] for decoding `GZip` compressed data. |
| 72 */ | 225 */ |
| 73 Converter<List<int>, List<int>> get decoder => const ZLibDecoder(); | 226 Converter<List<int>, List<int>> get decoder => new ZLibDecoder( |
| 74 | 227 windowBits: windowBits, dictionary: dictionary, raw: raw); |
| 75 /** | |
| 76 * The compression-[level] can be set in the range of `1..10`, with `6` being | |
| 77 * the default compression level. Levels above 6 will have higher compression | |
| 78 * rates at the cost of more CPU and memory usage. Levels below 6 will use | |
| 79 * less CPU and memory, but at the cost of lower compression rates. | |
| 80 */ | |
| 81 const GZipCodec({this.level: 6}); | |
| 82 } | 228 } |
| 83 | 229 |
| 84 | |
| 85 /** | 230 /** |
| 86 * The [ZLibEncoder] is the encoder used by [ZLibCodec] and [GZipCodec] to | 231 * The ZLibEncoder encoder is used by [ZLibCodec] and [GZipCodec] to compress |
| 87 * compress data. | 232 * data. |
| 88 */ | 233 */ |
| 89 class ZLibEncoder extends Converter<List<int>, List<int>> { | 234 class ZLibEncoder extends Converter<List<int>, List<int>> { |
| 90 /** | 235 /** |
| 91 * If [gzip] is true, `GZip` frames will be added to the compressed data. | 236 * When true, `GZip` frames will be added to the compressed data. |
| 92 */ | 237 */ |
| 93 final bool gzip; | 238 final bool gzip; |
| 94 | 239 |
| 95 /** | 240 /** |
| 96 * The compression level used by the encoder. | 241 * The compression-[level] can be set in the range of `-1..9`, with `6` being |
| 242 * the default compression level. Levels above `6` will have higher compressio n | |
| 243 * rates at the cost of more CPU and memory usage. Levels below `6` will use | |
| 244 * less CPU and memory at the cost of lower compression rates. | |
| 97 */ | 245 */ |
| 98 final int level; | 246 final int level; |
| 99 | 247 |
| 100 /** | 248 /** |
| 101 * Create a new [ZLibEncoder] converter. If the [gzip] flag is set, the | 249 * Specifies how much memory should be allocated for the internal compression |
| 102 * encoder will wrap the encoded ZLib data in GZip frames. | 250 * state. `1` uses minimum memory but is slow and reduces compression ratio; |
| 103 */ | 251 * `9` uses maximum memory for optimal speed. The default value is `8`. |
| 104 const ZLibEncoder({this.gzip: false, this.level: 6}); | 252 * |
| 105 | 253 * The memory requirements for deflate are (in bytes): |
| 106 | 254 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) |
| 107 /** | 255 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) |
| 108 * Convert a list of bytes using the options given to the [ZLibEncoder] | 256 */ |
| 257 final int memLevel; | |
| 258 | |
| 259 /** | |
| 260 * Tunes the compression algorithm. Use the value STRATEGY_DEFAULT for normal | |
| 261 * data, STRATEGY_FILTERED for data produced by a filter (or predictor), | |
| 262 * STRATEGY_HUFFMAN_ONLY to force Huffman encoding only (no string match), or | |
| 263 * STRATEGY_RLE to limit match distances to one (run-length encoding). | |
| 264 */ | |
| 265 final int strategy; | |
| 266 | |
| 267 /** | |
| 268 * Base two logarithm of the window size (the size of the history buffer). It | |
| 269 * should be in the range 8..15. Larger values result in better compression at | |
| 270 * the expense of memory usage. The default value is 15 | |
| 271 */ | |
| 272 final int windowBits; | |
| 273 | |
| 274 /** | |
| 275 * Initial compression dictionary. | |
| 276 * | |
| 277 * It should consist of strings (byte sequences) that are likely to be | |
| 278 * encountered later in the data to be compressed, with the most commonly used | |
| 279 * strings preferably put towards the end of the dictionary. Using a dictionary | |
| 280 * is most useful when the data to be compressed is short and can be predicted | |
| 281 * with good accuracy; the data can then be compressed better than with the | |
| 282 * default empty dictionary. | |
| 283 */ | |
| 284 final List<int> dictionary; | |
| 285 | |
| 286 | |
| 287 /** | |
| 288 <<<<<<< HEAD | |
|
Anders Johnsen
2014/01/27 12:27:45
Merge stuff.
vicb
2014/01/27 15:14:19
fixed
| |
| 289 * When true, deflate generates raw data with no zlib header or trailer, and | |
| 290 * will not compute an adler32 check value | |
| 291 */ | |
| 292 final bool raw; | |
| 293 | |
| 294 ZLibEncoder({this.gzip: false, | |
| 295 this.level: ZLIB_DFT_LEVEL, | |
| 296 this.windowBits: ZLIB_DFT_WINDOW_BITS, | |
| 297 this.memLevel: ZLIB_DFT_MEM_LEVEL, | |
| 298 this.strategy: ZLIB_STRATEGY_DEFAULT, | |
| 299 this.dictionary: null, | |
| 300 this.raw: false}) { | |
| 301 validateZLibeLevel(level); | |
| 302 validateZLibMemLevel(memLevel); | |
| 303 validateZLibStrategy(strategy); | |
| 304 validateZLibWindowBits(windowBits); | |
| 305 } | |
| 306 | |
| 307 /** | |
| 308 * Convert a list of bytes using the options given to the ZLibEncoder | |
| 109 * constructor. | 309 * constructor. |
| 110 */ | 310 */ |
| 111 List<int> convert(List<int> bytes) { | 311 List<int> convert(List<int> bytes) { |
| 112 _BufferSink sink = new _BufferSink(); | 312 _BufferSink sink = new _BufferSink(); |
| 113 startChunkedConversion(sink) | 313 startChunkedConversion(sink) |
| 114 ..add(bytes) | 314 ..add(bytes) |
| 115 ..close(); | 315 ..close(); |
| 116 return sink.builder.takeBytes(); | 316 return sink.builder.takeBytes(); |
| 117 } | 317 } |
| 118 | 318 |
| 119 /** | 319 /** |
| 120 * Start a chunked conversion using the options given to the [ZLibEncoder] | 320 * Start a chunked conversion using the options given to the ZLibEncoder |
| 121 * constructor. While it accepts any [ChunkedConversionSink] taking | 321 * constructor. While it accepts any [ChunkedConversionSink] taking |
| 122 * [List<int>]'s, the optimal sink to be passed as [sink] is a | 322 * [List<int>]'s, the optimal sink to be passed as [sink] is a |
| 123 * [ByteConversionSink]. | 323 * [ByteConversionSink]. |
| 124 */ | 324 */ |
| 125 ByteConversionSink startChunkedConversion( | 325 ByteConversionSink startChunkedConversion( |
| 126 ChunkedConversionSink<List<int>> sink) { | 326 ChunkedConversionSink<List<int>> sink) { |
| 127 if (sink is! ByteConversionSink) { | 327 if (sink is! ByteConversionSink) { |
| 128 sink = new ByteConversionSink.from(sink); | 328 sink = new ByteConversionSink.from(sink); |
| 129 } | 329 } |
| 130 return new _ZLibEncoderSink(sink, gzip, level); | 330 |
| 331 print("Dart _ZLibEncoderSink"); | |
|
Anders Johnsen
2014/01/27 12:27:45
Debug stuff.
| |
| 332 return new _ZLibEncoderSink(sink, gzip, level, windowBits, memLevel, | |
| 333 strategy, dictionary, raw); | |
| 131 } | 334 } |
| 132 } | 335 } |
| 133 | 336 |
| 134 | 337 |
| 135 /** | 338 /** |
| 136 * The [ZLibDecoder] is the decoder used by [ZLibCodec] and [GZipCodec] to | 339 * The ZLibDecoder is used by [ZLibCodec] and [GZipCodec] to decompress data. |
| 137 * decompress data. | |
| 138 */ | 340 */ |
| 139 class ZLibDecoder extends Converter<List<int>, List<int>> { | 341 class ZLibDecoder extends Converter<List<int>, List<int>> { |
| 342 /** | |
| 343 * Base two logarithm of the window size (the size of the history buffer). It | |
| 344 * should be in the range 8..15. Larger values result in better compression at | |
| 345 * the expense of memory usage. The default value is 15 | |
| 346 */ | |
| 347 final int windowBits; | |
| 140 | 348 |
| 141 /** | 349 /** |
| 142 * Create a new [ZLibEncoder] converter. | 350 * Initial compression dictionary. |
| 143 */ | 351 * |
| 144 const ZLibDecoder(); | 352 * It should consist of strings (byte sequences) that are likely to be |
| 353 * encountered later in the data to be compressed, with the most commonly used | |
| 354 * strings preferably put towards the end of the dictionary. Using a dictionary | |
| 355 * is most useful when the data to be compressed is short and can be predicted | |
| 356 * with good accuracy; the data can then be compressed better than with the | |
| 357 * default empty dictionary. | |
| 358 */ | |
| 359 final List<int> dictionary; | |
| 360 | |
| 361 /** | |
| 362 * When true, deflate generates raw data with no zlib header or trailer, and | |
| 363 * will not compute an adler32 check value | |
| 364 */ | |
| 365 final bool raw; | |
| 366 | |
| 367 ZLibDecoder({this.windowBits: ZLIB_DFT_WINDOW_BITS, this.dictionary: null, | |
| 368 this.raw: false}) { | |
| 369 validateZLibWindowBits(windowBits); | |
| 370 } | |
| 145 | 371 |
| 146 /** | 372 /** |
| 147 * Convert a list of bytes using the options given to the [ZLibDecoder] | 373 * Convert a list of bytes using the options given to the [ZLibDecoder] |
| 148 * constructor. | 374 * constructor. |
| 149 */ | 375 */ |
| 150 List<int> convert(List<int> bytes) { | 376 List<int> convert(List<int> bytes) { |
| 151 _BufferSink sink = new _BufferSink(); | 377 _BufferSink sink = new _BufferSink(); |
| 152 startChunkedConversion(sink) | 378 startChunkedConversion(sink) |
| 153 ..add(bytes) | 379 ..add(bytes) |
| 154 ..close(); | 380 ..close(); |
| 155 return sink.builder.takeBytes(); | 381 return sink.builder.takeBytes(); |
| 156 } | 382 } |
| 157 | 383 |
| 158 /** | 384 /** |
| 159 * Start a chunked conversion. While it accepts any [ChunkedConversionSink] | 385 * Start a chunked conversion. While it accepts any [ChunkedConversionSink] |
| 160 * taking [List<int>]'s, the optimal sink to be passed as [sink] is a | 386 * taking [List<int>]'s, the optimal sink to be passed as [sink] is a |
| 161 * [ByteConversionSink]. | 387 * [ByteConversionSink]. |
| 162 */ | 388 */ |
| 163 ByteConversionSink startChunkedConversion( | 389 ByteConversionSink startChunkedConversion( |
| 164 ChunkedConversionSink<List<int>> sink) { | 390 ChunkedConversionSink<List<int>> sink) { |
| 165 if (sink is! ByteConversionSink) { | 391 if (sink is! ByteConversionSink) { |
| 166 sink = new ByteConversionSink.from(sink); | 392 sink = new ByteConversionSink.from(sink); |
| 167 } | 393 } |
| 168 return new _ZLibDecoderSink(sink); | 394 print("Dart _ZLibDecoderSink"); |
| 395 return new _ZLibDecoderSink(sink, windowBits, dictionary, raw); | |
| 169 } | 396 } |
| 170 } | 397 } |
| 171 | 398 |
| 172 | 399 |
| 173 class _BufferSink extends ByteConversionSink { | 400 class _BufferSink extends ByteConversionSink { |
| 174 final BytesBuilder builder = new BytesBuilder(); | 401 final BytesBuilder builder = new BytesBuilder(); |
| 175 | 402 |
| 176 void add(List<int> chunk) { | 403 void add(List<int> chunk) { |
| 177 builder.add(chunk); | 404 builder.add(chunk); |
| 178 } | 405 } |
| 179 | 406 |
| 180 void addSlice(List<int> chunk, int start, int end, bool isLast) { | 407 void addSlice(List<int> chunk, int start, int end, bool isLast) { |
| 181 if (chunk is Uint8List) { | 408 if (chunk is Uint8List) { |
| 182 Uint8List list = chunk; | 409 Uint8List list = chunk; |
| 183 builder.add(new Uint8List.view(list.buffer, start, end - start)); | 410 builder.add(new Uint8List.view(list.buffer, start, end - start)); |
| 184 } else { | 411 } else { |
| 185 builder.add(chunk.sublist(start, end)); | 412 builder.add(chunk.sublist(start, end)); |
| 186 } | 413 } |
| 187 } | 414 } |
| 188 | 415 |
| 189 void close() {} | 416 void close() {} |
| 190 } | 417 } |
| 191 | 418 |
| 192 | 419 |
| 193 class _ZLibEncoderSink extends _FilterSink { | 420 class _ZLibEncoderSink extends _FilterSink { |
| 194 _ZLibEncoderSink(ByteConversionSink sink, bool gzip, int level) | 421 _ZLibEncoderSink(ByteConversionSink sink, bool gzip, int level, |
| 195 : super(sink, _Filter.newZLibDeflateFilter(gzip, level)); | 422 int windowBits, int memLevel, int strategy, |
| 423 List<int> dictionary, bool raw) | |
| 424 : super(sink, _Filter.newZLibDeflateFilter(gzip, level, windowBits, | |
| 425 memLevel, strategy, | |
| 426 dictionary, raw)); | |
| 427 } | |
| 428 | |
| 429 class _ZLibDecoderSink extends _FilterSink { | |
| 430 _ZLibDecoderSink(ByteConversionSink sink, int windowBits, | |
| 431 List<int> dictionary, bool raw) | |
| 432 : super(sink, _Filter.newZLibInflateFilter(windowBits, dictionary, raw)); | |
| 196 } | 433 } |
| 197 | 434 |
| 198 | 435 |
| 199 class _ZLibDecoderSink extends _FilterSink { | |
| 200 _ZLibDecoderSink(ByteConversionSink sink) | |
| 201 : super(sink, _Filter.newZLibInflateFilter()); | |
| 202 } | |
| 203 | |
| 204 | |
| 205 class _FilterSink extends ByteConversionSink { | 436 class _FilterSink extends ByteConversionSink { |
| 206 final _Filter _filter; | 437 final _Filter _filter; |
| 207 final ByteConversionSink _sink; | 438 final ByteConversionSink _sink; |
| 208 bool _closed = false; | 439 bool _closed = false; |
| 209 bool _empty = true; | 440 bool _empty = true; |
| 210 | 441 |
| 211 _FilterSink(ByteConversionSink this._sink, _Filter this._filter); | 442 _FilterSink(this._sink, this._filter); |
| 212 | 443 |
| 213 void add(List<int> data) { | 444 void add(List<int> data) { |
| 214 addSlice(data, 0, data.length, false); | 445 addSlice(data, 0, data.length, false); |
| 215 } | 446 } |
| 216 | 447 |
| 217 void addSlice(List<int> data, int start, int end, bool isLast) { | 448 void addSlice(List<int> data, int start, int end, bool isLast) { |
| 218 if (_closed) return; | 449 if (_closed) return; |
| 219 if (start < 0 || start > data.length) { | 450 if (start < 0 || start > data.length) { |
| 220 throw new ArgumentError("Invalid start position"); | 451 throw new ArgumentError("Invalid start position"); |
| 221 } | 452 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 251 _closed = true; | 482 _closed = true; |
| 252 throw e; | 483 throw e; |
| 253 } | 484 } |
| 254 if (!_closed) _filter.end(); | 485 if (!_closed) _filter.end(); |
| 255 _closed = true; | 486 _closed = true; |
| 256 _sink.close(); | 487 _sink.close(); |
| 257 } | 488 } |
| 258 } | 489 } |
| 259 | 490 |
| 260 | 491 |
| 261 | |
| 262 /** | 492 /** |
| 263 * Private helper-class to handle native filters. | 493 * Private helper-class to handle native filters. |
| 264 */ | 494 */ |
| 265 abstract class _Filter { | 495 abstract class _Filter { |
| 266 /** | 496 /** |
| 267 * Call to process a chunk of data. A call to [process] should only be made | 497 * Call to process a chunk of data. A call to [process] should only be made |
| 268 * when [processed] returns [:null:]. | 498 * when [processed] returns [:null:]. |
| 269 */ | 499 */ |
| 270 void process(List<int> data, int start, int end); | 500 void process(List<int> data, int start, int end); |
| 271 | 501 |
| 272 /** | 502 /** |
| 273 * Get a chunk of processed data. When there are no more data available, | 503 * Get a chunk of processed data. When there are no more data available, |
| 274 * [processed] will return [:null:]. Set [flush] to [:false:] for non-final | 504 * [processed] will return [:null:]. Set [flush] to [:false:] for non-final |
| 275 * calls to improve performance of some filters. | 505 * calls to improve performance of some filters. |
| 276 * | 506 * |
| 277 * The last call to [processed] should have [end] set to [:true:]. This will m ake | 507 * The last call to [processed] should have [end] set to [:true:]. This will m ake |
| 278 * sure a 'end' packet is written on the stream. | 508 * sure a 'end' packet is written on the stream. |
| 279 */ | 509 */ |
| 280 List<int> processed({bool flush: true, bool end: false}); | 510 List<int> processed({bool flush: true, bool end: false}); |
| 281 | 511 |
| 282 /** | 512 /** |
| 283 * Mark the filter as closed. Always call this method for any filter created | 513 * Mark the filter as closed. Always call this method for any filter created |
| 284 * to avoid leaking resources. [end] can be called at any time, but any | 514 * to avoid leaking resources. [end] can be called at any time, but any |
| 285 * successive calls to [process] or [processed] will fail. | 515 * successive calls to [process] or [processed] will fail. |
| 286 */ | 516 */ |
| 287 void end(); | 517 void end(); |
| 288 | 518 |
| 289 external static _Filter newZLibDeflateFilter(bool gzip, int level); | 519 external static _Filter newZLibDeflateFilter(bool gzip, int level, |
| 290 external static _Filter newZLibInflateFilter(); | 520 int windowBits, int memLevel, |
| 521 int strategy, | |
| 522 List<int> dictionary, bool raw); | |
| 523 | |
| 524 external static _Filter newZLibInflateFilter(int windowBits, | |
| 525 List<int> dictionary, bool raw); | |
| 291 } | 526 } |
| 527 | |
| 528 void validateZLibWindowBits(int windowBits) { | |
|
Anders Johnsen
2014/01/27 12:27:45
Make these functions private.
vicb
2014/01/27 15:14:19
fixed
| |
| 529 if (windowBits is! int || | |
| 530 windowBits < ZLIB_MIN_WINDOW_BITS || windowBits > ZLIB_MAX_WINDOW_BITS) { | |
|
Anders Johnsen
2014/01/27 12:27:45
Move last test to next line, as well as 2 places b
vicb
2014/01/27 15:14:19
fixed
| |
| 531 throw new ArgumentError("'windowBits' must be in range " | |
| 532 "${ZLIB_MIN_WINDOW_BITS}..${ZLIB_MAX_WINDOW_BITS}"); | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 void validateZLibeLevel(int level) { | |
| 537 if (level is! int || | |
| 538 level < ZLIB_MIN_LEVEL || level > ZLIB_MAX_LEVEL) { | |
| 539 throw new ArgumentError("'level' must be in range ${ZLIB_MIN_LEVEL}.." | |
| 540 "${ZLIB_MAX_LEVEL}"); | |
| 541 } | |
| 542 } | |
| 543 | |
| 544 void validateZLibMemLevel(int memLevel) { | |
| 545 if (memLevel is! int || | |
| 546 memLevel < ZLIB_MIN_MEM_LEVEL || memLevel > ZLIB_MAX_MEM_LEVEL) { | |
| 547 throw new ArgumentError("'memLevel' must be in range " | |
| 548 "${ZLIB_MIN_MEM_LEVEL}..${ZLIB_MAX_MEM_LEVEL}"); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 void validateZLibStrategy(int strategy) { | |
| 553 var strategies = <int>[ZLIB_STRATEGY_FILTERED, ZLIB_STRATEGY_HUFFMAN_ONLY, | |
| 554 ZLIB_STRATEGY_RLE, ZLIB_STRATEGY_FIXED, ZLIB_STRATEGY_DEFAULT]; | |
| 555 if (strategies.indexOf(strategy) == -1) { | |
| 556 throw new ArgumentError("Unsupported 'strategy'"); | |
| 557 } | |
| 558 } | |
| OLD | NEW |