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 abstract class ZLibConstant { | |
Anders Johnsen
2014/02/07 08:18:04
Add class comment. Also, have we considered:
- ZL
vicb
2014/02/07 08:43:45
fixed.
I really like "ZLibOption", changed for it
| |
9 /// Minimal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits] | |
10 /// and [ZLibDecoder.windowBits]. | |
11 static const int MIN_WINDOW_BITS = 8; | |
12 /// Maximal value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits] | |
13 /// and [ZLibDecoder.windowBits]. | |
14 static const int MAX_WINDOW_BITS = 15; | |
15 /// Default value for [ZLibCodec.windowBits], [ZLibEncoder.windowBits] | |
16 /// and [ZLibDecoder.windowBits]. | |
17 static const int DEFAULT_WINDOW_BITS = 15; | |
18 | |
19 /// Minimal value for [ZLibCodec.level], [ZLibEncoder.level] | |
20 /// and [ZLibDecoder.level]. | |
21 static const int MIN_LEVEL = -1; | |
22 /// Maximal value for [ZLibCodec.level], [ZLibEncoder.level] | |
23 /// and [ZLibDecoder.level]. | |
24 static const int MAX_LEVEL = 9; | |
25 /// Default value for [ZLibCodec.level], [ZLibEncoder.level] | |
26 /// and [ZLibDecoder.level]. | |
27 static const int DEFAULT_LEVEL = 6; | |
28 | |
29 /// Minimal value for [ZLibCodec.memLevel], [ZLibEncoder.memLevel] | |
30 /// and [ZLibDecoder.memLevel]. | |
31 static const int MIN_MEM_LEVEL = 1; | |
32 /// Maximal value for [ZLibCodec.memLevel], [ZLibEncoder.memLevel] | |
33 /// and [ZLibDecoder.memLevel]. | |
34 static const int MAX_MEM_LEVEL = 9; | |
35 /// Default value for [ZLibCodec.memLevel], [ZLibEncoder.memLevel] | |
36 /// and [ZLibDecoder.memLevel]. | |
37 static const int DEFAULT_MEM_LEVEL = 8; | |
38 | |
39 | |
40 /// for data produced by a filter (or predictor) | |
Lasse Reichstein Nielsen
2014/02/07 07:56:44
Preferably use entire sentences for comments (star
vicb
2014/02/07 08:43:45
fixed
| |
41 static const int STRATEGY_FILTERED = 1; | |
42 /// to force Huffman encoding only (no string match) | |
43 static const int STRATEGY_HUFFMAN_ONLY = 2; | |
44 /// to limit match distances to one (run-length encoding) | |
45 static const int STRATEGY_RLE = 3; | |
46 /// prevents the use of dynamic Huffman codes, allowing for a simpler decoder | |
47 static const int STRATEGY_FIXED = 4; | |
48 /// for normal data | |
49 static const int STRATEGY_DEFAULT = 0; | |
50 } | |
51 | |
8 /** | 52 /** |
9 * An instance of the default implementation of the [ZLibCodec]. | 53 * An instance of the default implementation of the [ZLibCodec]. |
10 */ | 54 */ |
11 const ZLibCodec ZLIB = const ZLibCodec(); | 55 const ZLibCodec ZLIB = const ZLibCodec._default(); |
12 | |
13 | 56 |
14 /** | 57 /** |
15 * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib | 58 * The [ZLibCodec] encodes raw bytes to ZLib compressed bytes and decodes ZLib |
16 * compressed bytes to raw bytes. | 59 * compressed bytes to raw bytes. |
17 */ | 60 */ |
18 class ZLibCodec extends Codec<List<int>, List<int>> { | 61 class ZLibCodec extends Codec<List<int>, List<int>> { |
19 /** | 62 /** |
20 * The compression level of the [ZLibCodec]. | 63 * When true, `GZip` frames will be added to the compressed data. |
64 */ | |
65 final bool gzip; | |
66 | |
67 /** | |
68 * The compression-[level] can be set in the range of `-1..9`, with `6` being | |
69 * the default compression level. Levels above `6` will have higher | |
70 * compression rates at the cost of more CPU and memory usage. Levels below | |
71 * `6` will use less CPU and memory at the cost of lower compression rates. | |
21 */ | 72 */ |
22 final int level; | 73 final int level; |
23 | 74 |
24 /** | 75 /** |
25 * Get a [Converter] for encoding to `ZLib` compressed data. | 76 * Specifies how much memory should be allocated for the internal compression |
Lasse Reichstein Nielsen
2014/02/07 07:56:44
Indentation is traditionally:
/**
*
(i.e., follow
vicb
2014/02/07 08:43:45
that's must be IntelliJ playing tricks on me...
fi
| |
77 * state. `1` uses minimum memory but is slow and reduces compression ratio; | |
78 * `9` uses maximum memory for optimal speed. The default value is `8`. | |
79 * | |
80 * The memory requirements for deflate are (in bytes): | |
81 * | |
Lasse Reichstein Nielsen
2014/02/07 07:56:44
This asterisk is correct, the rest should be inden
| |
82 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) | |
83 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) | |
84 */ | |
85 final int memLevel; | |
86 | |
87 /** | |
88 * Tunes the compression algorithm. Use the value STRATEGY_DEFAULT for normal | |
89 * data, STRATEGY_FILTERED for data produced by a filter (or predictor), | |
90 * STRATEGY_HUFFMAN_ONLY to force Huffman encoding only (no string match), or | |
91 * STRATEGY_RLE to limit match distances to one (run-length encoding). | |
92 */ | |
93 final int strategy; | |
94 | |
95 /** | |
96 * Base two logarithm of the window size (the size of the history buffer). It | |
97 * should be in the range 8..15. Larger values result in better compression at | |
98 * the expense of memory usage. The default value is 15 | |
99 */ | |
100 final int windowBits; | |
101 | |
102 /** | |
103 * When true, deflate generates raw data with no zlib header or trailer, and | |
104 * will not compute an adler32 check value | |
105 */ | |
106 final bool raw; | |
107 | |
108 /** | |
109 * Initial compression dictionary. | |
110 * | |
111 * It should consist of strings (byte sequences) that are likely to be | |
112 * encountered later in the data to be compressed, with the most commonly used | |
113 * strings preferably put towards the end of the dictionary. Using a dictionary | |
114 * is most useful when the data to be compressed is short and can be predicted | |
115 * with good accuracy; the data can then be compressed better than with the | |
116 * default empty dictionary. | |
117 */ | |
118 final List<int> dictionary; | |
119 | |
120 ZLibCodec({this.level: ZLibConstant.DEFAULT_LEVEL, | |
121 this.windowBits: ZLibConstant.DEFAULT_WINDOW_BITS, | |
122 this.memLevel: ZLibConstant.DEFAULT_MEM_LEVEL, | |
123 this.strategy: ZLibConstant.STRATEGY_DEFAULT, | |
124 this.dictionary: null, | |
125 this.raw: false}) { | |
126 _validateZLibeLevel(level); | |
127 _validateZLibMemLevel(memLevel); | |
128 _validateZLibStrategy(strategy); | |
129 _validateZLibWindowBits(windowBits); | |
130 } | |
131 | |
132 const ZLibCodec._default() | |
133 : level = ZLibConstant.DEFAULT_LEVEL, | |
134 windowBits = ZLibConstant.DEFAULT_WINDOW_BITS, | |
135 memLevel = ZLibConstant.DEFAULT_MEM_LEVEL, | |
136 strategy = ZLibConstant.STRATEGY_DEFAULT, | |
137 raw = false; | |
138 | |
139 /** | |
140 * Get a [ZLibEncoder] for encoding to `ZLib` compressed data. | |
26 */ | 141 */ |
27 Converter<List<int>, List<int>> get encoder => | 142 Converter<List<int>, List<int>> get encoder => |
28 new ZLibEncoder(gzip: false, level: level); | 143 new ZLibEncoder(gzip: false, level: level, windowBits: windowBits, |
144 memLevel: memLevel, strategy: strategy, | |
145 dictionary: dictionary, raw: raw); | |
29 | 146 |
30 /** | 147 /** |
31 * Get a [Converter] for decoding `ZLib` compressed data. | 148 * Get a [ZLibDecoder] for decoding `ZLib` compressed data. |
32 */ | 149 */ |
33 Converter<List<int>, List<int>> get decoder => const ZLibDecoder(); | 150 Converter<List<int>, List<int>> get decoder => |
34 | 151 new ZLibDecoder(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 } | 152 } |
43 | 153 |
44 | 154 |
45 /** | 155 /** |
46 * An instance of the default implementation of the [GZipCodec]. | 156 * An instance of the default implementation of the [GZipCodec]. |
47 */ | 157 */ |
48 const GZipCodec GZIP = const GZipCodec(); | 158 const GZipCodec GZIP = const GZipCodec._default(); |
49 | 159 |
50 | 160 |
51 /** | 161 /** |
52 * The [GZipCodec] encodes raw bytes to GZip compressed bytes and decodes GZip | 162 * The [GZipCodec] encodes raw bytes to GZip compressed bytes and decodes GZip |
53 * compressed bytes to raw bytes. | 163 * compressed bytes to raw bytes. |
54 * | 164 * |
55 * The difference between [ZLibCodec] and [GZipCodec] is that the [GZipCodec] | 165 * The difference between [ZLibCodec] and [GZipCodec] is that the [GZipCodec] |
56 * wraps the `ZLib` compressed bytes in `GZip` frames. | 166 * wraps the `ZLib` compressed bytes in `GZip` frames. |
57 */ | 167 */ |
58 class GZipCodec extends Codec<List<int>, List<int>> { | 168 class GZipCodec extends Codec<List<int>, List<int>> { |
59 /** | 169 /** |
60 * The compression level of the [ZLibCodec]. | 170 * When true, `GZip` frames will be added to the compressed data. |
171 */ | |
172 final bool gzip; | |
173 | |
174 /** | |
175 * The compression-[level] can be set in the range of `-1..9`, with `6` being | |
176 * the default compression level. Levels above `6` will have higher | |
177 * compression rates at the cost of more CPU and memory usage. Levels below | |
178 * `6` will use less CPU and memory at the cost of lower compression rates. | |
61 */ | 179 */ |
62 final int level; | 180 final int level; |
63 | 181 |
64 /** | 182 /** |
65 * Get a [Converter] for encoding to `GZip` compressed data. | 183 * Specifies how much memory should be allocated for the internal compression |
184 * state. `1` uses minimum memory but is slow and reduces compression ratio; | |
185 * `9` uses maximum memory for optimal speed. The default value is `8`. | |
186 * | |
187 * The memory requirements for deflate are (in bytes): | |
188 * | |
189 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) | |
190 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) | |
191 */ | |
192 final int memLevel; | |
193 | |
194 /** | |
195 * Tunes the compression algorithm. Use the value | |
196 * [ZlibConstant.STRATEGY_DEFAULT] for normal data, | |
197 * [ZlibConstant.STRATEGY_FILTERED] for data produced by a filter | |
198 * (or predictor), | |
199 * [ZlibConstant.STRATEGY_HUFFMAN_ONLY] to force Huffman encoding only (no | |
200 * string match), or [ZlibConstant.STRATEGY_RLE] to limit match distances to | |
201 * one (run-length encoding). | |
202 */ | |
203 final int strategy; | |
204 | |
205 /** | |
206 * Base two logarithm of the window size (the size of the history buffer). It | |
207 * should be in the range 8..15. Larger values result in better compression at | |
208 * the expense of memory usage. The default value is 15 | |
209 */ | |
210 final int windowBits; | |
211 | |
212 /** | |
213 * Initial compression dictionary. | |
214 * | |
215 * It should consist of strings (byte sequences) that are likely to be | |
216 * encountered later in the data to be compressed, with the most commonly used | |
217 * strings preferably put towards the end of the dictionary. Using a dictionary | |
218 * is most useful when the data to be compressed is short and can be predicted | |
219 * with good accuracy; the data can then be compressed better than with the | |
220 * default empty dictionary. | |
221 */ | |
222 final List<int> dictionary; | |
223 | |
224 /** | |
225 * When true, deflate generates raw data with no zlib header or trailer, and | |
226 * will not compute an adler32 check value | |
227 */ | |
228 final bool raw; | |
229 | |
230 GZipCodec({this.level: ZLibConstant.DEFAULT_LEVEL, | |
231 this.windowBits: ZLibConstant.DEFAULT_WINDOW_BITS, | |
232 this.memLevel: ZLibConstant.DEFAULT_MEM_LEVEL, | |
233 this.strategy: ZLibConstant.STRATEGY_DEFAULT, | |
234 this.dictionary: null, | |
235 this.raw: false}) { | |
236 _validateZLibeLevel(level); | |
237 _validateZLibMemLevel(memLevel); | |
238 _validateZLibStrategy(strategy); | |
239 _validateZLibWindowBits(windowBits); | |
240 } | |
241 | |
242 const GZipCodec._default() | |
243 : level = ZLibConstant.DEFAULT_LEVEL, | |
244 windowBits = ZLibConstant.DEFAULT_WINDOW_BITS, | |
245 memLevel = ZLibConstant.DEFAULT_MEM_LEVEL, | |
246 strategy = ZLibConstant.STRATEGY_DEFAULT, | |
247 raw = false; | |
248 | |
249 /** | |
250 * Get a [ZLibEncoder] for encoding to `GZip` compressed data. | |
66 */ | 251 */ |
67 Converter<List<int>, List<int>> get encoder => | 252 Converter<List<int>, List<int>> get encoder => |
68 new ZLibEncoder(gzip: true, level: level); | 253 new ZLibEncoder(gzip: true, level: level, windowBits: windowBits, |
254 memLevel: memLevel, strategy: strategy, | |
255 dictionary: dictionary, raw: raw); | |
69 | 256 |
70 /** | 257 /** |
71 * Get a [Converter] for decoding `GZip` compressed data. | 258 * Get a [ZLibDecoder] for decoding `GZip` compressed data. |
72 */ | 259 */ |
73 Converter<List<int>, List<int>> get decoder => const ZLibDecoder(); | 260 Converter<List<int>, List<int>> get decoder => |
74 | 261 new ZLibDecoder(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 } | 262 } |
83 | 263 |
84 | |
85 /** | 264 /** |
86 * The [ZLibEncoder] is the encoder used by [ZLibCodec] and [GZipCodec] to | 265 * The [ZLibEncoder] encoder is used by [ZLibCodec] and [GZipCodec] to compress |
87 * compress data. | 266 * data. |
88 */ | 267 */ |
89 class ZLibEncoder extends Converter<List<int>, List<int>> { | 268 class ZLibEncoder extends Converter<List<int>, List<int>> { |
90 /** | 269 /** |
91 * If [gzip] is true, `GZip` frames will be added to the compressed data. | 270 * When true, `GZip` frames will be added to the compressed data. |
92 */ | 271 */ |
93 final bool gzip; | 272 final bool gzip; |
94 | 273 |
95 /** | 274 /** |
96 * The compression level used by the encoder. | 275 * The compression-[level] can be set in the range of `-1..9`, with `6` being |
276 * the default compression level. Levels above `6` will have higher | |
277 * compression rates at the cost of more CPU and memory usage. Levels below | |
278 * `6` will use less CPU and memory at the cost of lower compression rates. | |
97 */ | 279 */ |
98 final int level; | 280 final int level; |
99 | 281 |
100 /** | 282 /** |
101 * Create a new [ZLibEncoder] converter. If the [gzip] flag is set, the | 283 * Specifies how much memory should be allocated for the internal compression |
102 * encoder will wrap the encoded ZLib data in GZip frames. | 284 * state. `1` uses minimum memory but is slow and reduces compression ratio; |
285 * `9` uses maximum memory for optimal speed. The default value is `8`. | |
286 * | |
287 * The memory requirements for deflate are (in bytes): | |
288 * | |
289 * (1 << (windowBits + 2)) + (1 << (memLevel + 9)) | |
290 * that is: 128K for windowBits = 15 + 128K for memLevel = 8 (default values) | |
103 */ | 291 */ |
104 const ZLibEncoder({this.gzip: false, this.level: 6}); | 292 final int memLevel; |
293 | |
294 /** | |
295 * Tunes the compression algorithm. Use the value | |
296 * [ZlibConstant.STRATEGY_DEFAULT] for normal data, | |
297 * [ZlibConstant.STRATEGY_FILTERED] for data produced by a filter | |
298 * (or predictor), | |
299 * [ZlibConstant.STRATEGY_HUFFMAN_ONLY] to force Huffman encoding only (no | |
300 * string match), or [ZlibConstant.STRATEGY_RLE] to limit match distances to | |
301 * one (run-length encoding). | |
302 */ | |
303 final int strategy; | |
304 | |
305 /** | |
306 * Base two logarithm of the window size (the size of the history buffer). It | |
307 * should be in the range 8..15. Larger values result in better compression at | |
308 * the expense of memory usage. The default value is 15 | |
309 */ | |
310 final int windowBits; | |
311 | |
312 /** | |
313 * Initial compression dictionary. | |
314 * | |
315 * It should consist of strings (byte sequences) that are likely to be | |
316 * encountered later in the data to be compressed, with the most commonly used | |
317 * strings preferably put towards the end of the dictionary. Using a dictionary | |
318 * is most useful when the data to be compressed is short and can be predicted | |
319 * with good accuracy; the data can then be compressed better than with the | |
320 * default empty dictionary. | |
321 */ | |
322 final List<int> dictionary; | |
105 | 323 |
106 | 324 |
107 /** | 325 /** |
108 * Convert a list of bytes using the options given to the [ZLibEncoder] | 326 * When true, deflate generates raw data with no zlib header or trailer, and |
327 * will not compute an adler32 check value | |
328 */ | |
329 final bool raw; | |
330 | |
331 ZLibEncoder({this.gzip: false, | |
332 this.level: ZLibConstant.DEFAULT_LEVEL, | |
333 this.windowBits: ZLibConstant.DEFAULT_WINDOW_BITS, | |
334 this.memLevel: ZLibConstant.DEFAULT_MEM_LEVEL, | |
335 this.strategy: ZLibConstant.STRATEGY_DEFAULT, | |
336 this.dictionary: null, | |
337 this.raw: false}) { | |
338 _validateZLibeLevel(level); | |
339 _validateZLibMemLevel(memLevel); | |
340 _validateZLibStrategy(strategy); | |
341 _validateZLibWindowBits(windowBits); | |
342 } | |
343 | |
344 /** | |
345 * Convert a list of bytes using the options given to the ZLibEncoder | |
109 * constructor. | 346 * constructor. |
110 */ | 347 */ |
111 List<int> convert(List<int> bytes) { | 348 List<int> convert(List<int> bytes) { |
112 _BufferSink sink = new _BufferSink(); | 349 _BufferSink sink = new _BufferSink(); |
113 startChunkedConversion(sink) | 350 startChunkedConversion(sink)..add(bytes)..close(); |
114 ..add(bytes) | |
115 ..close(); | |
116 return sink.builder.takeBytes(); | 351 return sink.builder.takeBytes(); |
117 } | 352 } |
118 | 353 |
119 /** | 354 /** |
120 * Start a chunked conversion using the options given to the [ZLibEncoder] | 355 * Start a chunked conversion using the options given to the [ZLibEncoder] |
121 * constructor. While it accepts any [ChunkedConversionSink] taking | 356 * constructor. While it accepts any [ChunkedConversionSink] taking |
122 * [List<int>]'s, the optimal sink to be passed as [sink] is a | 357 * [List<int>]'s, the optimal sink to be passed as [sink] is a |
123 * [ByteConversionSink]. | 358 * [ByteConversionSink]. |
124 */ | 359 */ |
125 ByteConversionSink startChunkedConversion( | 360 ByteConversionSink startChunkedConversion( |
126 ChunkedConversionSink<List<int>> sink) { | 361 ChunkedConversionSink<List<int>> sink) { |
127 if (sink is! ByteConversionSink) { | 362 if (sink is! ByteConversionSink) { |
128 sink = new ByteConversionSink.from(sink); | 363 sink = new ByteConversionSink.from(sink); |
129 } | 364 } |
130 return new _ZLibEncoderSink(sink, gzip, level); | 365 |
366 return new _ZLibEncoderSink(sink, gzip, level, windowBits, memLevel, | |
367 strategy, dictionary, raw); | |
131 } | 368 } |
132 } | 369 } |
133 | 370 |
134 | 371 |
135 /** | 372 /** |
136 * The [ZLibDecoder] is the decoder used by [ZLibCodec] and [GZipCodec] to | 373 * The [ZLibDecoder] is used by [ZLibCodec] and [GZipCodec] to decompress data. |
137 * decompress data. | |
138 */ | 374 */ |
139 class ZLibDecoder extends Converter<List<int>, List<int>> { | 375 class ZLibDecoder extends Converter<List<int>, List<int>> { |
376 /** | |
377 * Base two logarithm of the window size (the size of the history buffer). It | |
378 * should be in the range 8..15. Larger values result in better compression at | |
379 * the expense of memory usage. The default value is 15 | |
380 */ | |
381 final int windowBits; | |
140 | 382 |
141 /** | 383 /** |
142 * Create a new [ZLibEncoder] converter. | 384 * Initial compression dictionary. |
143 */ | 385 * |
144 const ZLibDecoder(); | 386 * It should consist of strings (byte sequences) that are likely to be |
387 * encountered later in the data to be compressed, with the most commonly used | |
388 * strings preferably put towards the end of the dictionary. Using a dictionary | |
389 * is most useful when the data to be compressed is short and can be predicted | |
390 * with good accuracy; the data can then be compressed better than with the | |
391 * default empty dictionary. | |
392 */ | |
393 final List<int> dictionary; | |
394 | |
395 /** | |
396 * When true, deflate generates raw data with no zlib header or trailer, and | |
397 * will not compute an adler32 check value | |
398 */ | |
399 final bool raw; | |
400 | |
401 ZLibDecoder({this.windowBits: ZLibConstant.DEFAULT_WINDOW_BITS, | |
402 this.dictionary: null, this.raw: false}) { | |
403 _validateZLibWindowBits(windowBits); | |
404 } | |
145 | 405 |
146 /** | 406 /** |
147 * Convert a list of bytes using the options given to the [ZLibDecoder] | 407 * Convert a list of bytes using the options given to the [ZLibDecoder] |
148 * constructor. | 408 * constructor. |
149 */ | 409 */ |
150 List<int> convert(List<int> bytes) { | 410 List<int> convert(List<int> bytes) { |
151 _BufferSink sink = new _BufferSink(); | 411 _BufferSink sink = new _BufferSink(); |
152 startChunkedConversion(sink) | 412 startChunkedConversion(sink)..add(bytes)..close(); |
153 ..add(bytes) | |
154 ..close(); | |
155 return sink.builder.takeBytes(); | 413 return sink.builder.takeBytes(); |
156 } | 414 } |
157 | 415 |
158 /** | 416 /** |
159 * Start a chunked conversion. While it accepts any [ChunkedConversionSink] | 417 * Start a chunked conversion. While it accepts any [ChunkedConversionSink] |
160 * taking [List<int>]'s, the optimal sink to be passed as [sink] is a | 418 * taking [List<int>]'s, the optimal sink to be passed as [sink] is a |
161 * [ByteConversionSink]. | 419 * [ByteConversionSink]. |
162 */ | 420 */ |
163 ByteConversionSink startChunkedConversion( | 421 ByteConversionSink startChunkedConversion( |
164 ChunkedConversionSink<List<int>> sink) { | 422 ChunkedConversionSink<List<int>> sink) { |
165 if (sink is! ByteConversionSink) { | 423 if (sink is! ByteConversionSink) { |
166 sink = new ByteConversionSink.from(sink); | 424 sink = new ByteConversionSink.from(sink); |
167 } | 425 } |
168 return new _ZLibDecoderSink(sink); | 426 return new _ZLibDecoderSink(sink, windowBits, dictionary, raw); |
169 } | 427 } |
170 } | 428 } |
171 | 429 |
172 | 430 |
173 class _BufferSink extends ByteConversionSink { | 431 class _BufferSink extends ByteConversionSink { |
174 final BytesBuilder builder = new BytesBuilder(); | 432 final BytesBuilder builder = new BytesBuilder(); |
175 | 433 |
176 void add(List<int> chunk) { | 434 void add(List<int> chunk) { |
177 builder.add(chunk); | 435 builder.add(chunk); |
178 } | 436 } |
179 | 437 |
180 void addSlice(List<int> chunk, int start, int end, bool isLast) { | 438 void addSlice(List<int> chunk, int start, int end, bool isLast) { |
181 if (chunk is Uint8List) { | 439 if (chunk is Uint8List) { |
182 Uint8List list = chunk; | 440 Uint8List list = chunk; |
183 builder.add(new Uint8List.view(list.buffer, start, end - start)); | 441 builder.add(new Uint8List.view(list.buffer, start, end - start)); |
184 } else { | 442 } else { |
185 builder.add(chunk.sublist(start, end)); | 443 builder.add(chunk.sublist(start, end)); |
186 } | 444 } |
187 } | 445 } |
188 | 446 |
189 void close() {} | 447 void close() {} |
190 } | 448 } |
191 | 449 |
192 | 450 |
193 class _ZLibEncoderSink extends _FilterSink { | 451 class _ZLibEncoderSink extends _FilterSink { |
194 _ZLibEncoderSink(ByteConversionSink sink, bool gzip, int level) | 452 _ZLibEncoderSink(ByteConversionSink sink, bool gzip, int level, |
195 : super(sink, _Filter.newZLibDeflateFilter(gzip, level)); | 453 int windowBits, int memLevel, int strategy, |
454 List<int> dictionary, bool raw) | |
455 : super(sink, _Filter.newZLibDeflateFilter(gzip, level, windowBits, | |
456 memLevel, strategy, | |
457 dictionary, raw)); | |
458 } | |
459 | |
460 class _ZLibDecoderSink extends _FilterSink { | |
461 _ZLibDecoderSink(ByteConversionSink sink, int windowBits, | |
462 List<int> dictionary, bool raw) | |
463 : super(sink, _Filter.newZLibInflateFilter(windowBits, dictionary, raw)); | |
196 } | 464 } |
197 | 465 |
198 | 466 |
199 class _ZLibDecoderSink extends _FilterSink { | |
200 _ZLibDecoderSink(ByteConversionSink sink) | |
201 : super(sink, _Filter.newZLibInflateFilter()); | |
202 } | |
203 | |
204 | |
205 class _FilterSink extends ByteConversionSink { | 467 class _FilterSink extends ByteConversionSink { |
206 final _Filter _filter; | 468 final _Filter _filter; |
207 final ByteConversionSink _sink; | 469 final ByteConversionSink _sink; |
208 bool _closed = false; | 470 bool _closed = false; |
209 bool _empty = true; | 471 bool _empty = true; |
210 | 472 |
211 _FilterSink(ByteConversionSink this._sink, _Filter this._filter); | 473 _FilterSink(this._sink, this._filter); |
212 | 474 |
213 void add(List<int> data) { | 475 void add(List<int> data) { |
214 addSlice(data, 0, data.length, false); | 476 addSlice(data, 0, data.length, false); |
215 } | 477 } |
216 | 478 |
217 void addSlice(List<int> data, int start, int end, bool isLast) { | 479 void addSlice(List<int> data, int start, int end, bool isLast) { |
218 if (_closed) return; | 480 if (_closed) return; |
219 if (start < 0 || start > data.length) { | 481 if (start < 0 || start > data.length) { |
220 throw new ArgumentError("Invalid start position"); | 482 throw new ArgumentError("Invalid start position"); |
221 } | 483 } |
(...skipping 29 matching lines...) Expand all Loading... | |
251 _closed = true; | 513 _closed = true; |
252 throw e; | 514 throw e; |
253 } | 515 } |
254 if (!_closed) _filter.end(); | 516 if (!_closed) _filter.end(); |
255 _closed = true; | 517 _closed = true; |
256 _sink.close(); | 518 _sink.close(); |
257 } | 519 } |
258 } | 520 } |
259 | 521 |
260 | 522 |
261 | |
262 /** | 523 /** |
263 * Private helper-class to handle native filters. | 524 * Private helper-class to handle native filters. |
264 */ | 525 */ |
265 abstract class _Filter { | 526 abstract class _Filter { |
266 /** | 527 /** |
267 * Call to process a chunk of data. A call to [process] should only be made | 528 * Call to process a chunk of data. A call to [process] should only be made |
268 * when [processed] returns [:null:]. | 529 * when [processed] returns [:null:]. |
269 */ | 530 */ |
270 void process(List<int> data, int start, int end); | 531 void process(List<int> data, int start, int end); |
271 | 532 |
272 /** | 533 /** |
273 * Get a chunk of processed data. When there are no more data available, | 534 * 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 | 535 * [processed] will return [:null:]. Set [flush] to [:false:] for non-final |
275 * calls to improve performance of some filters. | 536 * calls to improve performance of some filters. |
276 * | 537 * |
277 * The last call to [processed] should have [end] set to [:true:]. This will m ake | 538 * The last call to [processed] should have [end] set to [:true:]. This will |
278 * sure a 'end' packet is written on the stream. | 539 * make sure an 'end' packet is written on the stream. |
279 */ | 540 */ |
280 List<int> processed({bool flush: true, bool end: false}); | 541 List<int> processed({bool flush: true, bool end: false}); |
281 | 542 |
282 /** | 543 /** |
283 * Mark the filter as closed. Always call this method for any filter created | 544 * 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 | 545 * to avoid leaking resources. [end] can be called at any time, but any |
285 * successive calls to [process] or [processed] will fail. | 546 * successive calls to [process] or [processed] will fail. |
286 */ | 547 */ |
287 void end(); | 548 void end(); |
288 | 549 |
289 external static _Filter newZLibDeflateFilter(bool gzip, int level); | 550 external static _Filter newZLibDeflateFilter(bool gzip, int level, |
290 external static _Filter newZLibInflateFilter(); | 551 int windowBits, int memLevel, |
552 int strategy, | |
553 List<int> dictionary, bool raw); | |
554 | |
555 external static _Filter newZLibInflateFilter(int windowBits, | |
556 List<int> dictionary, bool raw); | |
291 } | 557 } |
558 | |
559 void _validateZLibWindowBits(int windowBits) { | |
560 if (ZLibConstant.MIN_WINDOW_BITS > windowBits || | |
561 ZLibConstant.MAX_WINDOW_BITS < windowBits) { | |
562 throw new RangeError.range(windowsBits, ZLibConstant.MIN_WINDOW_BITS, | |
563 ZLibConstant.MAX_WINDOW_BITS); | |
564 } | |
565 } | |
566 | |
567 void _validateZLibeLevel(int level) { | |
568 if (ZLibConstant.MIN_LEVEL > level || | |
569 ZLibConstant.MAX_LEVEL < level) { | |
570 throw new RangeError.range(level, ZLibConstant.MIN_LEVEL, | |
571 ZLibConstant.MAX_LEVEL); | |
572 } | |
573 } | |
574 | |
575 void _validateZLibMemLevel(int memLevel) { | |
576 if (ZLibConstant.MIN_MEM_LEVEL > memLevel || | |
577 ZLibConstant.MAX_MEM_LEVEL < memLevel) { | |
578 throw new RangeError(memLvel, ZLibConstant.MIN_MEM_LEVEL, | |
579 ZLibConstant.MAX_MEM_LEVEL); | |
580 } | |
581 } | |
582 | |
583 void _validateZLibStrategy(int strategy) { | |
584 const strategies = const <int>[ZLibConstant.STRATEGY_FILTERED, | |
585 ZLibConstant.STRATEGY_HUFFMAN_ONLY, ZLibConstant.STRATEGY_RLE, | |
586 ZLibConstant.STRATEGY_FIXED, ZLibConstant.STRATEGY_DEFAULT]; | |
587 if (strategies.indexOf(strategy) == -1) { | |
588 throw new ArgumentError("Unsupported 'strategy'"); | |
589 } | |
590 } | |
OLD | NEW |