Total Complexity | 1137 |
Complexity/F | 3.91 |
Lines of Code | 8985 |
Function Count | 291 |
Duplicated Lines | 279 |
Ratio | 3.11 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like third-party/js-xlsx/js-xlsx-0.13.5/jszip.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /* |
||
15 | (function(e){ |
||
16 | if("object"==typeof exports&&"undefined"!=typeof module&&"undefined"==typeof DO_NOT_EXPORT_JSZIP)module.exports=e(); |
||
17 | else if("function"==typeof define&&define.amd&&"undefined"==typeof DO_NOT_EXPORT_JSZIP){JSZipSync=e();define([],e);} |
||
|
|||
18 | else{ |
||
19 | var f; |
||
20 | "undefined"!=typeof window?f=window: |
||
21 | "undefined"!=typeof global?f=global: |
||
22 | "undefined"!=typeof $ && $.global?f=$.global: |
||
23 | "undefined"!=typeof self&&(f=self),f.JSZipSync=e() |
||
24 | } |
||
25 | }(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ |
||
26 | 'use strict'; |
||
27 | // private property |
||
28 | var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; |
||
29 | |||
30 | |||
31 | // public method for encoding |
||
32 | exports.encode = function(input, utf8) { |
||
33 | var output = ""; |
||
34 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; |
||
35 | var i = 0; |
||
36 | |||
37 | while (i < input.length) { |
||
38 | |||
39 | chr1 = input.charCodeAt(i++); |
||
40 | chr2 = input.charCodeAt(i++); |
||
41 | chr3 = input.charCodeAt(i++); |
||
42 | |||
43 | enc1 = chr1 >> 2; |
||
44 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); |
||
45 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); |
||
46 | enc4 = chr3 & 63; |
||
47 | |||
48 | if (isNaN(chr2)) { |
||
49 | enc3 = enc4 = 64; |
||
50 | } |
||
51 | else if (isNaN(chr3)) { |
||
52 | enc4 = 64; |
||
53 | } |
||
54 | |||
55 | output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); |
||
56 | |||
57 | } |
||
58 | |||
59 | return output; |
||
60 | }; |
||
61 | |||
62 | // public method for decoding |
||
63 | exports.decode = function(input, utf8) { |
||
64 | var output = ""; |
||
65 | var chr1, chr2, chr3; |
||
66 | var enc1, enc2, enc3, enc4; |
||
67 | var i = 0; |
||
68 | |||
69 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); |
||
70 | |||
71 | while (i < input.length) { |
||
72 | |||
73 | enc1 = _keyStr.indexOf(input.charAt(i++)); |
||
74 | enc2 = _keyStr.indexOf(input.charAt(i++)); |
||
75 | enc3 = _keyStr.indexOf(input.charAt(i++)); |
||
76 | enc4 = _keyStr.indexOf(input.charAt(i++)); |
||
77 | |||
78 | chr1 = (enc1 << 2) | (enc2 >> 4); |
||
79 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); |
||
80 | chr3 = ((enc3 & 3) << 6) | enc4; |
||
81 | |||
82 | output = output + String.fromCharCode(chr1); |
||
83 | |||
84 | if (enc3 != 64) { |
||
85 | output = output + String.fromCharCode(chr2); |
||
86 | } |
||
87 | if (enc4 != 64) { |
||
88 | output = output + String.fromCharCode(chr3); |
||
89 | } |
||
90 | |||
91 | } |
||
92 | |||
93 | return output; |
||
94 | |||
95 | }; |
||
96 | |||
97 | },{}],2:[function(_dereq_,module,exports){ |
||
98 | 'use strict'; |
||
99 | function CompressedObject() { |
||
100 | this.compressedSize = 0; |
||
101 | this.uncompressedSize = 0; |
||
102 | this.crc32 = 0; |
||
103 | this.compressionMethod = null; |
||
104 | this.compressedContent = null; |
||
105 | } |
||
106 | |||
107 | CompressedObject.prototype = { |
||
108 | /** |
||
109 | * Return the decompressed content in an unspecified format. |
||
110 | * The format will depend on the decompressor. |
||
111 | * @return {Object} the decompressed content. |
||
112 | */ |
||
113 | getContent: function() { |
||
114 | return null; // see implementation |
||
115 | }, |
||
116 | /** |
||
117 | * Return the compressed content in an unspecified format. |
||
118 | * The format will depend on the compressed conten source. |
||
119 | * @return {Object} the compressed content. |
||
120 | */ |
||
121 | getCompressedContent: function() { |
||
122 | return null; // see implementation |
||
123 | } |
||
124 | }; |
||
125 | module.exports = CompressedObject; |
||
126 | |||
127 | },{}],3:[function(_dereq_,module,exports){ |
||
128 | 'use strict'; |
||
129 | exports.STORE = { |
||
130 | magic: "\x00\x00", |
||
131 | compress: function(content) { |
||
132 | return content; // no compression |
||
133 | }, |
||
134 | uncompress: function(content) { |
||
135 | return content; // no compression |
||
136 | }, |
||
137 | compressInputType: null, |
||
138 | uncompressInputType: null |
||
139 | }; |
||
140 | exports.DEFLATE = _dereq_('./flate'); |
||
141 | |||
142 | },{"./flate":8}],4:[function(_dereq_,module,exports){ |
||
143 | 'use strict'; |
||
144 | |||
145 | var utils = _dereq_('./utils'); |
||
146 | |||
147 | var table = [ |
||
148 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, |
||
149 | 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, |
||
150 | 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, |
||
151 | 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, |
||
152 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, |
||
153 | 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, |
||
154 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, |
||
155 | 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, |
||
156 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, |
||
157 | 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, |
||
158 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, |
||
159 | 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, |
||
160 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, |
||
161 | 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, |
||
162 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, |
||
163 | 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, |
||
164 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, |
||
165 | 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, |
||
166 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, |
||
167 | 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, |
||
168 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, |
||
169 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, |
||
170 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, |
||
171 | 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, |
||
172 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, |
||
173 | 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, |
||
174 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, |
||
175 | 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, |
||
176 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, |
||
177 | 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, |
||
178 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, |
||
179 | 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, |
||
180 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, |
||
181 | 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, |
||
182 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, |
||
183 | 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, |
||
184 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, |
||
185 | 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, |
||
186 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, |
||
187 | 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, |
||
188 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, |
||
189 | 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, |
||
190 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, |
||
191 | 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, |
||
192 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, |
||
193 | 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, |
||
194 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, |
||
195 | 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, |
||
196 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, |
||
197 | 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, |
||
198 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, |
||
199 | 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, |
||
200 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, |
||
201 | 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, |
||
202 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, |
||
203 | 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, |
||
204 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, |
||
205 | 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, |
||
206 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, |
||
207 | 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, |
||
208 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, |
||
209 | 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, |
||
210 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, |
||
211 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D |
||
212 | ]; |
||
213 | |||
214 | /** |
||
215 | * |
||
216 | * Javascript crc32 |
||
217 | * http://www.webtoolkit.info/ |
||
218 | * |
||
219 | */ |
||
220 | module.exports = function crc32(input, crc) { |
||
221 | if (typeof input === "undefined" || !input.length) { |
||
222 | return 0; |
||
223 | } |
||
224 | |||
225 | var isArray = utils.getTypeOf(input) !== "string"; |
||
226 | |||
227 | if (typeof(crc) == "undefined") { |
||
228 | crc = 0; |
||
229 | } |
||
230 | var x = 0; |
||
231 | var y = 0; |
||
232 | var b = 0; |
||
233 | |||
234 | crc = crc ^ (-1); |
||
235 | for (var i = 0, iTop = input.length; i < iTop; i++) { |
||
236 | b = isArray ? input[i] : input.charCodeAt(i); |
||
237 | y = (crc ^ b) & 0xFF; |
||
238 | x = table[y]; |
||
239 | crc = (crc >>> 8) ^ x; |
||
240 | } |
||
241 | |||
242 | return crc ^ (-1); |
||
243 | }; |
||
244 | // vim: set shiftwidth=4 softtabstop=4: |
||
245 | |||
246 | },{"./utils":21}],5:[function(_dereq_,module,exports){ |
||
247 | 'use strict'; |
||
248 | var utils = _dereq_('./utils'); |
||
249 | |||
250 | function DataReader(data) { |
||
251 | this.data = null; // type : see implementation |
||
252 | this.length = 0; |
||
253 | this.index = 0; |
||
254 | } |
||
255 | DataReader.prototype = { |
||
256 | /** |
||
257 | * Check that the offset will not go too far. |
||
258 | * @param {string} offset the additional offset to check. |
||
259 | * @throws {Error} an Error if the offset is out of bounds. |
||
260 | */ |
||
261 | checkOffset: function(offset) { |
||
262 | this.checkIndex(this.index + offset); |
||
263 | }, |
||
264 | /** |
||
265 | * Check that the specifed index will not be too far. |
||
266 | * @param {string} newIndex the index to check. |
||
267 | * @throws {Error} an Error if the index is out of bounds. |
||
268 | */ |
||
269 | checkIndex: function(newIndex) { |
||
270 | if (this.length < newIndex || newIndex < 0) { |
||
271 | throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); |
||
272 | } |
||
273 | }, |
||
274 | /** |
||
275 | * Change the index. |
||
276 | * @param {number} newIndex The new index. |
||
277 | * @throws {Error} if the new index is out of the data. |
||
278 | */ |
||
279 | setIndex: function(newIndex) { |
||
280 | this.checkIndex(newIndex); |
||
281 | this.index = newIndex; |
||
282 | }, |
||
283 | /** |
||
284 | * Skip the next n bytes. |
||
285 | * @param {number} n the number of bytes to skip. |
||
286 | * @throws {Error} if the new index is out of the data. |
||
287 | */ |
||
288 | skip: function(n) { |
||
289 | this.setIndex(this.index + n); |
||
290 | }, |
||
291 | /** |
||
292 | * Get the byte at the specified index. |
||
293 | * @param {number} i the index to use. |
||
294 | * @return {number} a byte. |
||
295 | */ |
||
296 | byteAt: function(i) { |
||
297 | // see implementations |
||
298 | }, |
||
299 | /** |
||
300 | * Get the next number with a given byte size. |
||
301 | * @param {number} size the number of bytes to read. |
||
302 | * @return {number} the corresponding number. |
||
303 | */ |
||
304 | readInt: function(size) { |
||
305 | var result = 0, |
||
306 | i; |
||
307 | this.checkOffset(size); |
||
308 | for (i = this.index + size - 1; i >= this.index; i--) { |
||
309 | result = (result << 8) + this.byteAt(i); |
||
310 | } |
||
311 | this.index += size; |
||
312 | return result; |
||
313 | }, |
||
314 | /** |
||
315 | * Get the next string with a given byte size. |
||
316 | * @param {number} size the number of bytes to read. |
||
317 | * @return {string} the corresponding string. |
||
318 | */ |
||
319 | readString: function(size) { |
||
320 | return utils.transformTo("string", this.readData(size)); |
||
321 | }, |
||
322 | /** |
||
323 | * Get raw data without conversion, <size> bytes. |
||
324 | * @param {number} size the number of bytes to read. |
||
325 | * @return {Object} the raw data, implementation specific. |
||
326 | */ |
||
327 | readData: function(size) { |
||
328 | // see implementations |
||
329 | }, |
||
330 | /** |
||
331 | * Find the last occurence of a zip signature (4 bytes). |
||
332 | * @param {string} sig the signature to find. |
||
333 | * @return {number} the index of the last occurence, -1 if not found. |
||
334 | */ |
||
335 | lastIndexOfSignature: function(sig) { |
||
336 | // see implementations |
||
337 | }, |
||
338 | /** |
||
339 | * Get the next date. |
||
340 | * @return {Date} the date. |
||
341 | */ |
||
342 | readDate: function() { |
||
343 | var dostime = this.readInt(4); |
||
344 | return new Date( |
||
345 | ((dostime >> 25) & 0x7f) + 1980, // year |
||
346 | ((dostime >> 21) & 0x0f) - 1, // month |
||
347 | (dostime >> 16) & 0x1f, // day |
||
348 | (dostime >> 11) & 0x1f, // hour |
||
349 | (dostime >> 5) & 0x3f, // minute |
||
350 | (dostime & 0x1f) << 1); // second |
||
351 | } |
||
352 | }; |
||
353 | module.exports = DataReader; |
||
354 | |||
355 | },{"./utils":21}],6:[function(_dereq_,module,exports){ |
||
356 | 'use strict'; |
||
357 | exports.base64 = false; |
||
358 | exports.binary = false; |
||
359 | exports.dir = false; |
||
360 | exports.createFolders = false; |
||
361 | exports.date = null; |
||
362 | exports.compression = null; |
||
363 | exports.comment = null; |
||
364 | |||
365 | },{}],7:[function(_dereq_,module,exports){ |
||
366 | 'use strict'; |
||
367 | var utils = _dereq_('./utils'); |
||
368 | |||
369 | /** |
||
370 | * @deprecated |
||
371 | * This function will be removed in a future version without replacement. |
||
372 | */ |
||
373 | exports.string2binary = function(str) { |
||
374 | return utils.string2binary(str); |
||
375 | }; |
||
376 | |||
377 | /** |
||
378 | * @deprecated |
||
379 | * This function will be removed in a future version without replacement. |
||
380 | */ |
||
381 | exports.string2Uint8Array = function(str) { |
||
382 | return utils.transformTo("uint8array", str); |
||
383 | }; |
||
384 | |||
385 | /** |
||
386 | * @deprecated |
||
387 | * This function will be removed in a future version without replacement. |
||
388 | */ |
||
389 | exports.uint8Array2String = function(array) { |
||
390 | return utils.transformTo("string", array); |
||
391 | }; |
||
392 | |||
393 | /** |
||
394 | * @deprecated |
||
395 | * This function will be removed in a future version without replacement. |
||
396 | */ |
||
397 | exports.string2Blob = function(str) { |
||
398 | var buffer = utils.transformTo("arraybuffer", str); |
||
399 | return utils.arrayBuffer2Blob(buffer); |
||
400 | }; |
||
401 | |||
402 | /** |
||
403 | * @deprecated |
||
404 | * This function will be removed in a future version without replacement. |
||
405 | */ |
||
406 | exports.arrayBuffer2Blob = function(buffer) { |
||
407 | return utils.arrayBuffer2Blob(buffer); |
||
408 | }; |
||
409 | |||
410 | /** |
||
411 | * @deprecated |
||
412 | * This function will be removed in a future version without replacement. |
||
413 | */ |
||
414 | exports.transformTo = function(outputType, input) { |
||
415 | return utils.transformTo(outputType, input); |
||
416 | }; |
||
417 | |||
418 | /** |
||
419 | * @deprecated |
||
420 | * This function will be removed in a future version without replacement. |
||
421 | */ |
||
422 | exports.getTypeOf = function(input) { |
||
423 | return utils.getTypeOf(input); |
||
424 | }; |
||
425 | |||
426 | /** |
||
427 | * @deprecated |
||
428 | * This function will be removed in a future version without replacement. |
||
429 | */ |
||
430 | exports.checkSupport = function(type) { |
||
431 | return utils.checkSupport(type); |
||
432 | }; |
||
433 | |||
434 | /** |
||
435 | * @deprecated |
||
436 | * This value will be removed in a future version without replacement. |
||
437 | */ |
||
438 | exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; |
||
439 | |||
440 | /** |
||
441 | * @deprecated |
||
442 | * This value will be removed in a future version without replacement. |
||
443 | */ |
||
444 | exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; |
||
445 | |||
446 | |||
447 | /** |
||
448 | * @deprecated |
||
449 | * This function will be removed in a future version without replacement. |
||
450 | */ |
||
451 | exports.pretty = function(str) { |
||
452 | return utils.pretty(str); |
||
453 | }; |
||
454 | |||
455 | /** |
||
456 | * @deprecated |
||
457 | * This function will be removed in a future version without replacement. |
||
458 | */ |
||
459 | exports.findCompression = function(compressionMethod) { |
||
460 | return utils.findCompression(compressionMethod); |
||
461 | }; |
||
462 | |||
463 | /** |
||
464 | * @deprecated |
||
465 | * This function will be removed in a future version without replacement. |
||
466 | */ |
||
467 | exports.isRegExp = function (object) { |
||
468 | return utils.isRegExp(object); |
||
469 | }; |
||
470 | |||
471 | |||
472 | },{"./utils":21}],8:[function(_dereq_,module,exports){ |
||
473 | 'use strict'; |
||
474 | var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); |
||
475 | |||
476 | var pako = _dereq_("pako"); |
||
477 | exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; |
||
478 | exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; |
||
479 | |||
480 | exports.magic = "\x08\x00"; |
||
481 | exports.compress = function(input) { |
||
482 | return pako.deflateRaw(input); |
||
483 | }; |
||
484 | exports.uncompress = function(input) { |
||
485 | return pako.inflateRaw(input); |
||
486 | }; |
||
487 | |||
488 | },{"pako":24}],9:[function(_dereq_,module,exports){ |
||
489 | 'use strict'; |
||
490 | |||
491 | var base64 = _dereq_('./base64'); |
||
492 | |||
493 | /** |
||
494 | Usage: |
||
495 | zip = new JSZip(); |
||
496 | zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); |
||
497 | zip.folder("images").file("smile.gif", base64Data, {base64: true}); |
||
498 | zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); |
||
499 | zip.remove("tempfile"); |
||
500 | |||
501 | base64zip = zip.generate(); |
||
502 | |||
503 | **/ |
||
504 | |||
505 | /** |
||
506 | * Representation a of zip file in js |
||
507 | * @constructor |
||
508 | * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). |
||
509 | * @param {Object=} options the options for creating this objects (optional). |
||
510 | */ |
||
511 | function JSZipSync(data, options) { |
||
512 | // if this constructor is used without `new`, it adds `new` before itself: |
||
513 | if(!(this instanceof JSZipSync)) return new JSZipSync(data, options); |
||
514 | |||
515 | // object containing the files : |
||
516 | // { |
||
517 | // "folder/" : {...}, |
||
518 | // "folder/data.txt" : {...} |
||
519 | // } |
||
520 | this.files = {}; |
||
521 | |||
522 | this.comment = null; |
||
523 | |||
524 | // Where we are in the hierarchy |
||
525 | this.root = ""; |
||
526 | if (data) { |
||
527 | this.load(data, options); |
||
528 | } |
||
529 | this.clone = function() { |
||
530 | var newObj = new JSZipSync(); |
||
531 | for (var i in this) { |
||
532 | if (typeof this[i] !== "function") { |
||
533 | newObj[i] = this[i]; |
||
534 | } |
||
535 | } |
||
536 | return newObj; |
||
537 | }; |
||
538 | } |
||
539 | JSZipSync.prototype = _dereq_('./object'); |
||
540 | JSZipSync.prototype.load = _dereq_('./load'); |
||
541 | JSZipSync.support = _dereq_('./support'); |
||
542 | JSZipSync.defaults = _dereq_('./defaults'); |
||
543 | |||
544 | /** |
||
545 | * @deprecated |
||
546 | * This namespace will be removed in a future version without replacement. |
||
547 | */ |
||
548 | JSZipSync.utils = _dereq_('./deprecatedPublicUtils'); |
||
549 | |||
550 | JSZipSync.base64 = { |
||
551 | /** |
||
552 | * @deprecated |
||
553 | * This method will be removed in a future version without replacement. |
||
554 | */ |
||
555 | encode : function(input) { |
||
556 | return base64.encode(input); |
||
557 | }, |
||
558 | /** |
||
559 | * @deprecated |
||
560 | * This method will be removed in a future version without replacement. |
||
561 | */ |
||
562 | decode : function(input) { |
||
563 | return base64.decode(input); |
||
564 | } |
||
565 | }; |
||
566 | JSZipSync.compressions = _dereq_('./compressions'); |
||
567 | module.exports = JSZipSync; |
||
568 | |||
569 | },{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_,module,exports){ |
||
570 | 'use strict'; |
||
571 | var base64 = _dereq_('./base64'); |
||
572 | var ZipEntries = _dereq_('./zipEntries'); |
||
573 | module.exports = function(data, options) { |
||
574 | var files, zipEntries, i, input; |
||
575 | options = options || {}; |
||
576 | if (options.base64) { |
||
577 | data = base64.decode(data); |
||
578 | } |
||
579 | |||
580 | zipEntries = new ZipEntries(data, options); |
||
581 | files = zipEntries.files; |
||
582 | for (i = 0; i < files.length; i++) { |
||
583 | input = files[i]; |
||
584 | this.file(input.fileName, input.decompressed, { |
||
585 | binary: true, |
||
586 | optimizedBinaryString: true, |
||
587 | date: input.date, |
||
588 | dir: input.dir, |
||
589 | comment : input.fileComment.length ? input.fileComment : null, |
||
590 | createFolders: options.createFolders |
||
591 | }); |
||
592 | } |
||
593 | if (zipEntries.zipComment.length) { |
||
594 | this.comment = zipEntries.zipComment; |
||
595 | } |
||
596 | |||
597 | return this; |
||
598 | }; |
||
599 | |||
600 | },{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ |
||
601 | (function (Buffer){ |
||
602 | 'use strict'; |
||
603 | var Buffer_from = /*::(*/function(){}/*:: :any)*/; |
||
604 | if(typeof Buffer !== 'undefined') { |
||
605 | var nbfs = !Buffer.from; |
||
606 | if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; } |
||
607 | Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer); |
||
608 | // $FlowIgnore |
||
609 | if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; |
||
610 | } |
||
611 | module.exports = function(data, encoding){ |
||
612 | return typeof data == 'number' ? Buffer.alloc(data) : Buffer_from(data, encoding); |
||
613 | }; |
||
614 | module.exports.test = function(b){ |
||
615 | return Buffer.isBuffer(b); |
||
616 | }; |
||
617 | }).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) |
||
618 | },{}],12:[function(_dereq_,module,exports){ |
||
619 | 'use strict'; |
||
620 | var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); |
||
621 | |||
622 | function NodeBufferReader(data) { |
||
623 | this.data = data; |
||
624 | this.length = this.data.length; |
||
625 | this.index = 0; |
||
626 | } |
||
627 | NodeBufferReader.prototype = new Uint8ArrayReader(); |
||
628 | |||
629 | /** |
||
630 | * @see DataReader.readData |
||
631 | */ |
||
632 | NodeBufferReader.prototype.readData = function(size) { |
||
633 | this.checkOffset(size); |
||
634 | var result = this.data.slice(this.index, this.index + size); |
||
635 | this.index += size; |
||
636 | return result; |
||
637 | }; |
||
638 | module.exports = NodeBufferReader; |
||
639 | |||
640 | },{"./uint8ArrayReader":18}],13:[function(_dereq_,module,exports){ |
||
641 | 'use strict'; |
||
642 | var support = _dereq_('./support'); |
||
643 | var utils = _dereq_('./utils'); |
||
644 | var crc32 = _dereq_('./crc32'); |
||
645 | var signature = _dereq_('./signature'); |
||
646 | var defaults = _dereq_('./defaults'); |
||
647 | var base64 = _dereq_('./base64'); |
||
648 | var compressions = _dereq_('./compressions'); |
||
649 | var CompressedObject = _dereq_('./compressedObject'); |
||
650 | var nodeBuffer = _dereq_('./nodeBuffer'); |
||
651 | var utf8 = _dereq_('./utf8'); |
||
652 | var StringWriter = _dereq_('./stringWriter'); |
||
653 | var Uint8ArrayWriter = _dereq_('./uint8ArrayWriter'); |
||
654 | |||
655 | /** |
||
656 | * Returns the raw data of a ZipObject, decompress the content if necessary. |
||
657 | * @param {ZipObject} file the file to use. |
||
658 | * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. |
||
659 | */ |
||
660 | var getRawData = function(file) { |
||
661 | if (file._data instanceof CompressedObject) { |
||
662 | file._data = file._data.getContent(); |
||
663 | file.options.binary = true; |
||
664 | file.options.base64 = false; |
||
665 | |||
666 | if (utils.getTypeOf(file._data) === "uint8array") { |
||
667 | var copy = file._data; |
||
668 | // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. |
||
669 | // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). |
||
670 | file._data = new Uint8Array(copy.length); |
||
671 | // with an empty Uint8Array, Opera fails with a "Offset larger than array size" |
||
672 | if (copy.length !== 0) { |
||
673 | file._data.set(copy, 0); |
||
674 | } |
||
675 | } |
||
676 | } |
||
677 | return file._data; |
||
678 | }; |
||
679 | |||
680 | /** |
||
681 | * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. |
||
682 | * @param {ZipObject} file the file to use. |
||
683 | * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. |
||
684 | */ |
||
685 | var getBinaryData = function(file) { |
||
686 | var result = getRawData(file), |
||
687 | type = utils.getTypeOf(result); |
||
688 | if (type === "string") { |
||
689 | if (!file.options.binary) { |
||
690 | // unicode text ! |
||
691 | // unicode string => binary string is a painful process, check if we can avoid it. |
||
692 | if (support.nodebuffer) { |
||
693 | return nodeBuffer(result, "utf-8"); |
||
694 | } |
||
695 | } |
||
696 | return file.asBinary(); |
||
697 | } |
||
698 | return result; |
||
699 | }; |
||
700 | |||
701 | /** |
||
702 | * Transform this._data into a string. |
||
703 | * @param {function} filter a function String -> String, applied if not null on the result. |
||
704 | * @return {String} the string representing this._data. |
||
705 | */ |
||
706 | var dataToString = function(asUTF8) { |
||
707 | var result = getRawData(this); |
||
708 | if (result === null || typeof result === "undefined") { |
||
709 | return ""; |
||
710 | } |
||
711 | // if the data is a base64 string, we decode it before checking the encoding ! |
||
712 | if (this.options.base64) { |
||
713 | result = base64.decode(result); |
||
714 | } |
||
715 | if (asUTF8 && this.options.binary) { |
||
716 | // JSZip.prototype.utf8decode supports arrays as input |
||
717 | // skip to array => string step, utf8decode will do it. |
||
718 | result = out.utf8decode(result); |
||
719 | } |
||
720 | else { |
||
721 | // no utf8 transformation, do the array => string step. |
||
722 | result = utils.transformTo("string", result); |
||
723 | } |
||
724 | |||
725 | if (!asUTF8 && !this.options.binary) { |
||
726 | result = utils.transformTo("string", out.utf8encode(result)); |
||
727 | } |
||
728 | return result; |
||
729 | }; |
||
730 | /** |
||
731 | * A simple object representing a file in the zip file. |
||
732 | * @constructor |
||
733 | * @param {string} name the name of the file |
||
734 | * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data |
||
735 | * @param {Object} options the options of the file |
||
736 | */ |
||
737 | var ZipObject = function(name, data, options) { |
||
738 | this.name = name; |
||
739 | this.dir = options.dir; |
||
740 | this.date = options.date; |
||
741 | this.comment = options.comment; |
||
742 | |||
743 | this._data = data; |
||
744 | this.options = options; |
||
745 | |||
746 | /* |
||
747 | * This object contains initial values for dir and date. |
||
748 | * With them, we can check if the user changed the deprecated metadata in |
||
749 | * `ZipObject#options` or not. |
||
750 | */ |
||
751 | this._initialMetadata = { |
||
752 | dir : options.dir, |
||
753 | date : options.date |
||
754 | }; |
||
755 | }; |
||
756 | |||
757 | ZipObject.prototype = { |
||
758 | /** |
||
759 | * Return the content as UTF8 string. |
||
760 | * @return {string} the UTF8 string. |
||
761 | */ |
||
762 | asText: function() { |
||
763 | return dataToString.call(this, true); |
||
764 | }, |
||
765 | /** |
||
766 | * Returns the binary content. |
||
767 | * @return {string} the content as binary. |
||
768 | */ |
||
769 | asBinary: function() { |
||
770 | return dataToString.call(this, false); |
||
771 | }, |
||
772 | /** |
||
773 | * Returns the content as a nodejs Buffer. |
||
774 | * @return {Buffer} the content as a Buffer. |
||
775 | */ |
||
776 | asNodeBuffer: function() { |
||
777 | var result = getBinaryData(this); |
||
778 | return utils.transformTo("nodebuffer", result); |
||
779 | }, |
||
780 | /** |
||
781 | * Returns the content as an Uint8Array. |
||
782 | * @return {Uint8Array} the content as an Uint8Array. |
||
783 | */ |
||
784 | asUint8Array: function() { |
||
785 | var result = getBinaryData(this); |
||
786 | return utils.transformTo("uint8array", result); |
||
787 | }, |
||
788 | /** |
||
789 | * Returns the content as an ArrayBuffer. |
||
790 | * @return {ArrayBuffer} the content as an ArrayBufer. |
||
791 | */ |
||
792 | asArrayBuffer: function() { |
||
793 | return this.asUint8Array().buffer; |
||
794 | } |
||
795 | }; |
||
796 | |||
797 | /** |
||
798 | * Transform an integer into a string in hexadecimal. |
||
799 | * @private |
||
800 | * @param {number} dec the number to convert. |
||
801 | * @param {number} bytes the number of bytes to generate. |
||
802 | * @returns {string} the result. |
||
803 | */ |
||
804 | var decToHex = function(dec, bytes) { |
||
805 | var hex = "", |
||
806 | i; |
||
807 | for (i = 0; i < bytes; i++) { |
||
808 | hex += String.fromCharCode(dec & 0xff); |
||
809 | dec = dec >>> 8; |
||
810 | } |
||
811 | return hex; |
||
812 | }; |
||
813 | |||
814 | /** |
||
815 | * Merge the objects passed as parameters into a new one. |
||
816 | * @private |
||
817 | * @param {...Object} var_args All objects to merge. |
||
818 | * @return {Object} a new object with the data of the others. |
||
819 | */ |
||
820 | var extend = function() { |
||
821 | var result = {}, i, attr; |
||
822 | for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers |
||
823 | for (attr in arguments[i]) { |
||
824 | if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { |
||
825 | result[attr] = arguments[i][attr]; |
||
826 | } |
||
827 | } |
||
828 | } |
||
829 | return result; |
||
830 | }; |
||
831 | |||
832 | /** |
||
833 | * Transforms the (incomplete) options from the user into the complete |
||
834 | * set of options to create a file. |
||
835 | * @private |
||
836 | * @param {Object} o the options from the user. |
||
837 | * @return {Object} the complete set of options. |
||
838 | */ |
||
839 | var prepareFileAttrs = function(o) { |
||
840 | o = o || {}; |
||
841 | if (o.base64 === true && (o.binary === null || o.binary === undefined)) { |
||
842 | o.binary = true; |
||
843 | } |
||
844 | o = extend(o, defaults); |
||
845 | o.date = o.date || new Date(); |
||
846 | if (o.compression !== null) o.compression = o.compression.toUpperCase(); |
||
847 | |||
848 | return o; |
||
849 | }; |
||
850 | |||
851 | /** |
||
852 | * Add a file in the current folder. |
||
853 | * @private |
||
854 | * @param {string} name the name of the file |
||
855 | * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file |
||
856 | * @param {Object} o the options of the file |
||
857 | * @return {Object} the new file. |
||
858 | */ |
||
859 | var fileAdd = function(name, data, o) { |
||
860 | // be sure sub folders exist |
||
861 | var dataType = utils.getTypeOf(data), |
||
862 | parent; |
||
863 | |||
864 | o = prepareFileAttrs(o); |
||
865 | |||
866 | if (o.createFolders && (parent = parentFolder(name))) { |
||
867 | folderAdd.call(this, parent, true); |
||
868 | } |
||
869 | |||
870 | if (o.dir || data === null || typeof data === "undefined") { |
||
871 | o.base64 = false; |
||
872 | o.binary = false; |
||
873 | data = null; |
||
874 | } |
||
875 | else if (dataType === "string") { |
||
876 | if (o.binary && !o.base64) { |
||
877 | // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask |
||
878 | if (o.optimizedBinaryString !== true) { |
||
879 | // this is a string, not in a base64 format. |
||
880 | // Be sure that this is a correct "binary string" |
||
881 | data = utils.string2binary(data); |
||
882 | } |
||
883 | } |
||
884 | } |
||
885 | else { // arraybuffer, uint8array, ... |
||
886 | o.base64 = false; |
||
887 | o.binary = true; |
||
888 | |||
889 | if (!dataType && !(data instanceof CompressedObject)) { |
||
890 | throw new Error("The data of '" + name + "' is in an unsupported format !"); |
||
891 | } |
||
892 | |||
893 | // special case : it's way easier to work with Uint8Array than with ArrayBuffer |
||
894 | if (dataType === "arraybuffer") { |
||
895 | data = utils.transformTo("uint8array", data); |
||
896 | } |
||
897 | } |
||
898 | |||
899 | var object = new ZipObject(name, data, o); |
||
900 | this.files[name] = object; |
||
901 | return object; |
||
902 | }; |
||
903 | |||
904 | /** |
||
905 | * Find the parent folder of the path. |
||
906 | * @private |
||
907 | * @param {string} path the path to use |
||
908 | * @return {string} the parent folder, or "" |
||
909 | */ |
||
910 | var parentFolder = function (path) { |
||
911 | if (path.slice(-1) == '/') { |
||
912 | path = path.substring(0, path.length - 1); |
||
913 | } |
||
914 | var lastSlash = path.lastIndexOf('/'); |
||
915 | return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; |
||
916 | }; |
||
917 | |||
918 | /** |
||
919 | * Add a (sub) folder in the current folder. |
||
920 | * @private |
||
921 | * @param {string} name the folder's name |
||
922 | * @param {boolean=} [createFolders] If true, automatically create sub |
||
923 | * folders. Defaults to false. |
||
924 | * @return {Object} the new folder. |
||
925 | */ |
||
926 | var folderAdd = function(name, createFolders) { |
||
927 | // Check the name ends with a / |
||
928 | if (name.slice(-1) != "/") { |
||
929 | name += "/"; // IE doesn't like substr(-1) |
||
930 | } |
||
931 | |||
932 | createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; |
||
933 | |||
934 | // Does this folder already exist? |
||
935 | if (!this.files[name]) { |
||
936 | fileAdd.call(this, name, null, { |
||
937 | dir: true, |
||
938 | createFolders: createFolders |
||
939 | }); |
||
940 | } |
||
941 | return this.files[name]; |
||
942 | }; |
||
943 | |||
944 | /** |
||
945 | * Generate a JSZip.CompressedObject for a given zipOject. |
||
946 | * @param {ZipObject} file the object to read. |
||
947 | * @param {JSZip.compression} compression the compression to use. |
||
948 | * @return {JSZip.CompressedObject} the compressed result. |
||
949 | */ |
||
950 | var generateCompressedObjectFrom = function(file, compression) { |
||
951 | var result = new CompressedObject(), |
||
952 | content; |
||
953 | |||
954 | // the data has not been decompressed, we might reuse things ! |
||
955 | if (file._data instanceof CompressedObject) { |
||
956 | result.uncompressedSize = file._data.uncompressedSize; |
||
957 | result.crc32 = file._data.crc32; |
||
958 | |||
959 | if (result.uncompressedSize === 0 || file.dir) { |
||
960 | compression = compressions['STORE']; |
||
961 | result.compressedContent = ""; |
||
962 | result.crc32 = 0; |
||
963 | } |
||
964 | else if (file._data.compressionMethod === compression.magic) { |
||
965 | result.compressedContent = file._data.getCompressedContent(); |
||
966 | } |
||
967 | else { |
||
968 | content = file._data.getContent(); |
||
969 | // need to decompress / recompress |
||
970 | result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content)); |
||
971 | } |
||
972 | } |
||
973 | else { |
||
974 | // have uncompressed data |
||
975 | content = getBinaryData(file); |
||
976 | if (!content || content.length === 0 || file.dir) { |
||
977 | compression = compressions['STORE']; |
||
978 | content = ""; |
||
979 | } |
||
980 | result.uncompressedSize = content.length; |
||
981 | result.crc32 = crc32(content); |
||
982 | result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content)); |
||
983 | } |
||
984 | |||
985 | result.compressedSize = result.compressedContent.length; |
||
986 | result.compressionMethod = compression.magic; |
||
987 | |||
988 | return result; |
||
989 | }; |
||
990 | |||
991 | /** |
||
992 | * Generate the various parts used in the construction of the final zip file. |
||
993 | * @param {string} name the file name. |
||
994 | * @param {ZipObject} file the file content. |
||
995 | * @param {JSZip.CompressedObject} compressedObject the compressed object. |
||
996 | * @param {number} offset the current offset from the start of the zip file. |
||
997 | * @return {object} the zip parts. |
||
998 | */ |
||
999 | var generateZipParts = function(name, file, compressedObject, offset) { |
||
1000 | var data = compressedObject.compressedContent, |
||
1001 | utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), |
||
1002 | comment = file.comment || "", |
||
1003 | utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), |
||
1004 | useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, |
||
1005 | useUTF8ForComment = utfEncodedComment.length !== comment.length, |
||
1006 | o = file.options, |
||
1007 | dosTime, |
||
1008 | dosDate, |
||
1009 | extraFields = "", |
||
1010 | unicodePathExtraField = "", |
||
1011 | unicodeCommentExtraField = "", |
||
1012 | dir, date; |
||
1013 | |||
1014 | |||
1015 | // handle the deprecated options.dir |
||
1016 | if (file._initialMetadata.dir !== file.dir) { |
||
1017 | dir = file.dir; |
||
1018 | } else { |
||
1019 | dir = o.dir; |
||
1020 | } |
||
1021 | |||
1022 | // handle the deprecated options.date |
||
1023 | if(file._initialMetadata.date !== file.date) { |
||
1024 | date = file.date; |
||
1025 | } else { |
||
1026 | date = o.date; |
||
1027 | } |
||
1028 | |||
1029 | |||
1030 | dosTime = date.getHours(); |
||
1031 | dosTime = dosTime << 6; |
||
1032 | dosTime = dosTime | date.getMinutes(); |
||
1033 | dosTime = dosTime << 5; |
||
1034 | dosTime = dosTime | date.getSeconds() / 2; |
||
1035 | |||
1036 | dosDate = date.getFullYear() - 1980; |
||
1037 | dosDate = dosDate << 4; |
||
1038 | dosDate = dosDate | (date.getMonth() + 1); |
||
1039 | dosDate = dosDate << 5; |
||
1040 | dosDate = dosDate | date.getDate(); |
||
1041 | |||
1042 | if (useUTF8ForFileName) { |
||
1043 | // set the unicode path extra field. unzip needs at least one extra |
||
1044 | // field to correctly handle unicode path, so using the path is as good |
||
1045 | // as any other information. This could improve the situation with |
||
1046 | // other archive managers too. |
||
1047 | // This field is usually used without the utf8 flag, with a non |
||
1048 | // unicode path in the header (winrar, winzip). This helps (a bit) |
||
1049 | // with the messy Windows' default compressed folders feature but |
||
1050 | // breaks on p7zip which doesn't seek the unicode path extra field. |
||
1051 | // So for now, UTF-8 everywhere ! |
||
1052 | unicodePathExtraField = |
||
1053 | // Version |
||
1054 | decToHex(1, 1) + |
||
1055 | // NameCRC32 |
||
1056 | decToHex(crc32(utfEncodedFileName), 4) + |
||
1057 | // UnicodeName |
||
1058 | utfEncodedFileName; |
||
1059 | |||
1060 | extraFields += |
||
1061 | // Info-ZIP Unicode Path Extra Field |
||
1062 | "\x75\x70" + |
||
1063 | // size |
||
1064 | decToHex(unicodePathExtraField.length, 2) + |
||
1065 | // content |
||
1066 | unicodePathExtraField; |
||
1067 | } |
||
1068 | |||
1069 | if(useUTF8ForComment) { |
||
1070 | |||
1071 | unicodeCommentExtraField = |
||
1072 | // Version |
||
1073 | decToHex(1, 1) + |
||
1074 | // CommentCRC32 |
||
1075 | decToHex(this.crc32(utfEncodedComment), 4) + |
||
1076 | // UnicodeName |
||
1077 | utfEncodedComment; |
||
1078 | |||
1079 | extraFields += |
||
1080 | // Info-ZIP Unicode Path Extra Field |
||
1081 | "\x75\x63" + |
||
1082 | // size |
||
1083 | decToHex(unicodeCommentExtraField.length, 2) + |
||
1084 | // content |
||
1085 | unicodeCommentExtraField; |
||
1086 | } |
||
1087 | |||
1088 | var header = ""; |
||
1089 | |||
1090 | // version needed to extract |
||
1091 | header += "\x0A\x00"; |
||
1092 | // general purpose bit flag |
||
1093 | // set bit 11 if utf8 |
||
1094 | header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; |
||
1095 | // compression method |
||
1096 | header += compressedObject.compressionMethod; |
||
1097 | // last mod file time |
||
1098 | header += decToHex(dosTime, 2); |
||
1099 | // last mod file date |
||
1100 | header += decToHex(dosDate, 2); |
||
1101 | // crc-32 |
||
1102 | header += decToHex(compressedObject.crc32, 4); |
||
1103 | // compressed size |
||
1104 | header += decToHex(compressedObject.compressedSize, 4); |
||
1105 | // uncompressed size |
||
1106 | header += decToHex(compressedObject.uncompressedSize, 4); |
||
1107 | // file name length |
||
1108 | header += decToHex(utfEncodedFileName.length, 2); |
||
1109 | // extra field length |
||
1110 | header += decToHex(extraFields.length, 2); |
||
1111 | |||
1112 | |||
1113 | var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields; |
||
1114 | |||
1115 | var dirRecord = signature.CENTRAL_FILE_HEADER + |
||
1116 | // version made by (00: DOS) |
||
1117 | "\x14\x00" + |
||
1118 | // file header (common to file and central directory) |
||
1119 | header + |
||
1120 | // file comment length |
||
1121 | decToHex(utfEncodedComment.length, 2) + |
||
1122 | // disk number start |
||
1123 | "\x00\x00" + |
||
1124 | // internal file attributes TODO |
||
1125 | "\x00\x00" + |
||
1126 | // external file attributes |
||
1127 | (dir === true ? "\x10\x00\x00\x00" : "\x00\x00\x00\x00") + |
||
1128 | // relative offset of local header |
||
1129 | decToHex(offset, 4) + |
||
1130 | // file name |
||
1131 | utfEncodedFileName + |
||
1132 | // extra field |
||
1133 | extraFields + |
||
1134 | // file comment |
||
1135 | utfEncodedComment; |
||
1136 | |||
1137 | return { |
||
1138 | fileRecord: fileRecord, |
||
1139 | dirRecord: dirRecord, |
||
1140 | compressedObject: compressedObject |
||
1141 | }; |
||
1142 | }; |
||
1143 | |||
1144 | |||
1145 | // return the actual prototype of JSZip |
||
1146 | var out = { |
||
1147 | /** |
||
1148 | * Read an existing zip and merge the data in the current JSZip object. |
||
1149 | * The implementation is in jszip-load.js, don't forget to include it. |
||
1150 | * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load |
||
1151 | * @param {Object} options Options for loading the stream. |
||
1152 | * options.base64 : is the stream in base64 ? default : false |
||
1153 | * @return {JSZip} the current JSZip object |
||
1154 | */ |
||
1155 | load: function(stream, options) { |
||
1156 | throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); |
||
1157 | }, |
||
1158 | |||
1159 | /** |
||
1160 | * Filter nested files/folders with the specified function. |
||
1161 | * @param {Function} search the predicate to use : |
||
1162 | * function (relativePath, file) {...} |
||
1163 | * It takes 2 arguments : the relative path and the file. |
||
1164 | * @return {Array} An array of matching elements. |
||
1165 | */ |
||
1166 | filter: function(search) { |
||
1167 | var result = [], |
||
1168 | filename, relativePath, file, fileClone; |
||
1169 | for (filename in this.files) { |
||
1170 | if (!this.files.hasOwnProperty(filename)) { |
||
1171 | continue; |
||
1172 | } |
||
1173 | file = this.files[filename]; |
||
1174 | // return a new object, don't let the user mess with our internal objects :) |
||
1175 | fileClone = new ZipObject(file.name, file._data, extend(file.options)); |
||
1176 | relativePath = filename.slice(this.root.length, filename.length); |
||
1177 | if (filename.slice(0, this.root.length) === this.root && // the file is in the current root |
||
1178 | search(relativePath, fileClone)) { // and the file matches the function |
||
1179 | result.push(fileClone); |
||
1180 | } |
||
1181 | } |
||
1182 | return result; |
||
1183 | }, |
||
1184 | |||
1185 | /** |
||
1186 | * Add a file to the zip file, or search a file. |
||
1187 | * @param {string|RegExp} name The name of the file to add (if data is defined), |
||
1188 | * the name of the file to find (if no data) or a regex to match files. |
||
1189 | * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded |
||
1190 | * @param {Object} o File options |
||
1191 | * @return {JSZip|Object|Array} this JSZip object (when adding a file), |
||
1192 | * a file (when searching by string) or an array of files (when searching by regex). |
||
1193 | */ |
||
1194 | file: function(name, data, o) { |
||
1195 | if (arguments.length === 1) { |
||
1196 | if (utils.isRegExp(name)) { |
||
1197 | var regexp = name; |
||
1198 | return this.filter(function(relativePath, file) { |
||
1199 | return !file.dir && regexp.test(relativePath); |
||
1200 | }); |
||
1201 | } |
||
1202 | else { // text |
||
1203 | return this.filter(function(relativePath, file) { |
||
1204 | return !file.dir && relativePath === name; |
||
1205 | })[0] || null; |
||
1206 | } |
||
1207 | } |
||
1208 | else { // more than one argument : we have data ! |
||
1209 | name = this.root + name; |
||
1210 | fileAdd.call(this, name, data, o); |
||
1211 | } |
||
1212 | return this; |
||
1213 | }, |
||
1214 | |||
1215 | /** |
||
1216 | * Add a directory to the zip file, or search. |
||
1217 | * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. |
||
1218 | * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. |
||
1219 | */ |
||
1220 | folder: function(arg) { |
||
1221 | if (!arg) { |
||
1222 | return this; |
||
1223 | } |
||
1224 | |||
1225 | if (utils.isRegExp(arg)) { |
||
1226 | return this.filter(function(relativePath, file) { |
||
1227 | return file.dir && arg.test(relativePath); |
||
1228 | }); |
||
1229 | } |
||
1230 | |||
1231 | // else, name is a new folder |
||
1232 | var name = this.root + arg; |
||
1233 | var newFolder = folderAdd.call(this, name); |
||
1234 | |||
1235 | // Allow chaining by returning a new object with this folder as the root |
||
1236 | var ret = this.clone(); |
||
1237 | ret.root = newFolder.name; |
||
1238 | return ret; |
||
1239 | }, |
||
1240 | |||
1241 | /** |
||
1242 | * Delete a file, or a directory and all sub-files, from the zip |
||
1243 | * @param {string} name the name of the file to delete |
||
1244 | * @return {JSZip} this JSZip object |
||
1245 | */ |
||
1246 | remove: function(name) { |
||
1247 | name = this.root + name; |
||
1248 | var file = this.files[name]; |
||
1249 | if (!file) { |
||
1250 | // Look for any folders |
||
1251 | if (name.slice(-1) != "/") { |
||
1252 | name += "/"; |
||
1253 | } |
||
1254 | file = this.files[name]; |
||
1255 | } |
||
1256 | |||
1257 | if (file && !file.dir) { |
||
1258 | // file |
||
1259 | delete this.files[name]; |
||
1260 | } else { |
||
1261 | // maybe a folder, delete recursively |
||
1262 | var kids = this.filter(function(relativePath, file) { |
||
1263 | return file.name.slice(0, name.length) === name; |
||
1264 | }); |
||
1265 | for (var i = 0; i < kids.length; i++) { |
||
1266 | delete this.files[kids[i].name]; |
||
1267 | } |
||
1268 | } |
||
1269 | |||
1270 | return this; |
||
1271 | }, |
||
1272 | |||
1273 | /** |
||
1274 | * Generate the complete zip file |
||
1275 | * @param {Object} options the options to generate the zip file : |
||
1276 | * - base64, (deprecated, use type instead) true to generate base64. |
||
1277 | * - compression, "STORE" by default. |
||
1278 | * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. |
||
1279 | * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file |
||
1280 | */ |
||
1281 | generate: function(options) { |
||
1282 | options = extend(options || {}, { |
||
1283 | base64: true, |
||
1284 | compression: "STORE", |
||
1285 | type: "base64", |
||
1286 | comment: null |
||
1287 | }); |
||
1288 | |||
1289 | utils.checkSupport(options.type); |
||
1290 | |||
1291 | var zipData = [], |
||
1292 | localDirLength = 0, |
||
1293 | centralDirLength = 0, |
||
1294 | writer, i, |
||
1295 | utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || "")); |
||
1296 | |||
1297 | // first, generate all the zip parts. |
||
1298 | for (var name in this.files) { |
||
1299 | if (!this.files.hasOwnProperty(name)) { |
||
1300 | continue; |
||
1301 | } |
||
1302 | var file = this.files[name]; |
||
1303 | |||
1304 | var compressionName = file.options.compression || options.compression.toUpperCase(); |
||
1305 | var compression = compressions[compressionName]; |
||
1306 | if (!compression) { |
||
1307 | throw new Error(compressionName + " is not a valid compression method !"); |
||
1308 | } |
||
1309 | |||
1310 | var compressedObject = generateCompressedObjectFrom.call(this, file, compression); |
||
1311 | |||
1312 | var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength); |
||
1313 | localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; |
||
1314 | centralDirLength += zipPart.dirRecord.length; |
||
1315 | zipData.push(zipPart); |
||
1316 | } |
||
1317 | |||
1318 | var dirEnd = ""; |
||
1319 | |||
1320 | // end of central dir signature |
||
1321 | dirEnd = signature.CENTRAL_DIRECTORY_END + |
||
1322 | // number of this disk |
||
1323 | "\x00\x00" + |
||
1324 | // number of the disk with the start of the central directory |
||
1325 | "\x00\x00" + |
||
1326 | // total number of entries in the central directory on this disk |
||
1327 | decToHex(zipData.length, 2) + |
||
1328 | // total number of entries in the central directory |
||
1329 | decToHex(zipData.length, 2) + |
||
1330 | // size of the central directory 4 bytes |
||
1331 | decToHex(centralDirLength, 4) + |
||
1332 | // offset of start of central directory with respect to the starting disk number |
||
1333 | decToHex(localDirLength, 4) + |
||
1334 | // .ZIP file comment length |
||
1335 | decToHex(utfEncodedComment.length, 2) + |
||
1336 | // .ZIP file comment |
||
1337 | utfEncodedComment; |
||
1338 | |||
1339 | |||
1340 | // we have all the parts (and the total length) |
||
1341 | // time to create a writer ! |
||
1342 | var typeName = options.type.toLowerCase(); |
||
1343 | if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") { |
||
1344 | writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); |
||
1345 | }else{ |
||
1346 | writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); |
||
1347 | } |
||
1348 | |||
1349 | for (i = 0; i < zipData.length; i++) { |
||
1350 | writer.append(zipData[i].fileRecord); |
||
1351 | writer.append(zipData[i].compressedObject.compressedContent); |
||
1352 | } |
||
1353 | for (i = 0; i < zipData.length; i++) { |
||
1354 | writer.append(zipData[i].dirRecord); |
||
1355 | } |
||
1356 | |||
1357 | writer.append(dirEnd); |
||
1358 | |||
1359 | var zip = writer.finalize(); |
||
1360 | |||
1361 | |||
1362 | |||
1363 | switch(options.type.toLowerCase()) { |
||
1364 | // case "zip is an Uint8Array" |
||
1365 | case "uint8array" : |
||
1366 | case "arraybuffer" : |
||
1367 | case "nodebuffer" : |
||
1368 | return utils.transformTo(options.type.toLowerCase(), zip); |
||
1369 | case "blob" : |
||
1370 | return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip)); |
||
1371 | // case "zip is a string" |
||
1372 | case "base64" : |
||
1373 | return (options.base64) ? base64.encode(zip) : zip; |
||
1374 | default : // case "string" : |
||
1375 | return zip; |
||
1376 | } |
||
1377 | |||
1378 | }, |
||
1379 | |||
1380 | /** |
||
1381 | * @deprecated |
||
1382 | * This method will be removed in a future version without replacement. |
||
1383 | */ |
||
1384 | crc32: function (input, crc) { |
||
1385 | return crc32(input, crc); |
||
1386 | }, |
||
1387 | |||
1388 | /** |
||
1389 | * @deprecated |
||
1390 | * This method will be removed in a future version without replacement. |
||
1391 | */ |
||
1392 | utf8encode: function (string) { |
||
1393 | return utils.transformTo("string", utf8.utf8encode(string)); |
||
1394 | }, |
||
1395 | |||
1396 | /** |
||
1397 | * @deprecated |
||
1398 | * This method will be removed in a future version without replacement. |
||
1399 | */ |
||
1400 | utf8decode: function (input) { |
||
1401 | return utf8.utf8decode(input); |
||
1402 | } |
||
1403 | }; |
||
1404 | module.exports = out; |
||
1405 | |||
1406 | },{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(_dereq_,module,exports){ |
||
1407 | 'use strict'; |
||
1408 | exports.LOCAL_FILE_HEADER = "PK\x03\x04"; |
||
1409 | exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; |
||
1410 | exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; |
||
1411 | exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; |
||
1412 | exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; |
||
1413 | exports.DATA_DESCRIPTOR = "PK\x07\x08"; |
||
1414 | |||
1415 | },{}],15:[function(_dereq_,module,exports){ |
||
1416 | 'use strict'; |
||
1417 | var DataReader = _dereq_('./dataReader'); |
||
1418 | var utils = _dereq_('./utils'); |
||
1419 | |||
1420 | function StringReader(data, optimizedBinaryString) { |
||
1421 | this.data = data; |
||
1422 | if (!optimizedBinaryString) { |
||
1423 | this.data = utils.string2binary(this.data); |
||
1424 | } |
||
1425 | this.length = this.data.length; |
||
1426 | this.index = 0; |
||
1427 | } |
||
1428 | StringReader.prototype = new DataReader(); |
||
1429 | /** |
||
1430 | * @see DataReader.byteAt |
||
1431 | */ |
||
1432 | StringReader.prototype.byteAt = function(i) { |
||
1433 | return this.data.charCodeAt(i); |
||
1434 | }; |
||
1435 | /** |
||
1436 | * @see DataReader.lastIndexOfSignature |
||
1437 | */ |
||
1438 | StringReader.prototype.lastIndexOfSignature = function(sig) { |
||
1439 | return this.data.lastIndexOf(sig); |
||
1440 | }; |
||
1441 | /** |
||
1442 | * @see DataReader.readData |
||
1443 | */ |
||
1444 | StringReader.prototype.readData = function(size) { |
||
1445 | this.checkOffset(size); |
||
1446 | // this will work because the constructor applied the "& 0xff" mask. |
||
1447 | var result = this.data.slice(this.index, this.index + size); |
||
1448 | this.index += size; |
||
1449 | return result; |
||
1450 | }; |
||
1451 | module.exports = StringReader; |
||
1452 | |||
1453 | },{"./dataReader":5,"./utils":21}],16:[function(_dereq_,module,exports){ |
||
1454 | 'use strict'; |
||
1455 | |||
1456 | var utils = _dereq_('./utils'); |
||
1457 | |||
1458 | /** |
||
1459 | * An object to write any content to a string. |
||
1460 | * @constructor |
||
1461 | */ |
||
1462 | var StringWriter = function() { |
||
1463 | this.data = []; |
||
1464 | }; |
||
1465 | StringWriter.prototype = { |
||
1466 | /** |
||
1467 | * Append any content to the current string. |
||
1468 | * @param {Object} input the content to add. |
||
1469 | */ |
||
1470 | append: function(input) { |
||
1471 | input = utils.transformTo("string", input); |
||
1472 | this.data.push(input); |
||
1473 | }, |
||
1474 | /** |
||
1475 | * Finalize the construction an return the result. |
||
1476 | * @return {string} the generated string. |
||
1477 | */ |
||
1478 | finalize: function() { |
||
1479 | return this.data.join(""); |
||
1480 | } |
||
1481 | }; |
||
1482 | |||
1483 | module.exports = StringWriter; |
||
1484 | |||
1485 | },{"./utils":21}],17:[function(_dereq_,module,exports){ |
||
1486 | (function (Buffer){ |
||
1487 | 'use strict'; |
||
1488 | exports.base64 = true; |
||
1489 | exports.array = true; |
||
1490 | exports.string = true; |
||
1491 | exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; |
||
1492 | // contains true if JSZip can read/generate nodejs Buffer, false otherwise. |
||
1493 | // Browserify will provide a Buffer implementation for browsers, which is |
||
1494 | // an augmented Uint8Array (i.e., can be used as either Buffer or U8). |
||
1495 | exports.nodebuffer = typeof Buffer !== "undefined"; |
||
1496 | // contains true if JSZip can read/generate Uint8Array, false otherwise. |
||
1497 | exports.uint8array = typeof Uint8Array !== "undefined"; |
||
1498 | |||
1499 | if (typeof ArrayBuffer === "undefined") { |
||
1500 | exports.blob = false; |
||
1501 | } |
||
1502 | else { |
||
1503 | var buffer = new ArrayBuffer(0); |
||
1504 | try { |
||
1505 | exports.blob = new Blob([buffer], { |
||
1506 | type: "application/zip" |
||
1507 | }).size === 0; |
||
1508 | } |
||
1509 | catch (e) { |
||
1510 | try { |
||
1511 | var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; |
||
1512 | var builder = new Builder(); |
||
1513 | builder.append(buffer); |
||
1514 | exports.blob = builder.getBlob('application/zip').size === 0; |
||
1515 | } |
||
1516 | catch (e) { |
||
1517 | exports.blob = false; |
||
1518 | } |
||
1519 | } |
||
1520 | } |
||
1521 | |||
1522 | }).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) |
||
1523 | },{}],18:[function(_dereq_,module,exports){ |
||
1524 | 'use strict'; |
||
1525 | var DataReader = _dereq_('./dataReader'); |
||
1526 | |||
1527 | function Uint8ArrayReader(data) { |
||
1528 | if (data) { |
||
1529 | this.data = data; |
||
1530 | this.length = this.data.length; |
||
1531 | this.index = 0; |
||
1532 | } |
||
1533 | } |
||
1534 | Uint8ArrayReader.prototype = new DataReader(); |
||
1535 | /** |
||
1536 | * @see DataReader.byteAt |
||
1537 | */ |
||
1538 | Uint8ArrayReader.prototype.byteAt = function(i) { |
||
1539 | return this.data[i]; |
||
1540 | }; |
||
1541 | /** |
||
1542 | * @see DataReader.lastIndexOfSignature |
||
1543 | */ |
||
1544 | Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { |
||
1545 | var sig0 = sig.charCodeAt(0), |
||
1546 | sig1 = sig.charCodeAt(1), |
||
1547 | sig2 = sig.charCodeAt(2), |
||
1548 | sig3 = sig.charCodeAt(3); |
||
1549 | for (var i = this.length - 4; i >= 0; --i) { |
||
1550 | if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { |
||
1551 | return i; |
||
1552 | } |
||
1553 | } |
||
1554 | |||
1555 | return -1; |
||
1556 | }; |
||
1557 | /** |
||
1558 | * @see DataReader.readData |
||
1559 | */ |
||
1560 | Uint8ArrayReader.prototype.readData = function(size) { |
||
1561 | this.checkOffset(size); |
||
1562 | if(size === 0) { |
||
1563 | // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. |
||
1564 | return new Uint8Array(0); |
||
1565 | } |
||
1566 | var result = this.data.subarray(this.index, this.index + size); |
||
1567 | this.index += size; |
||
1568 | return result; |
||
1569 | }; |
||
1570 | module.exports = Uint8ArrayReader; |
||
1571 | |||
1572 | },{"./dataReader":5}],19:[function(_dereq_,module,exports){ |
||
1573 | 'use strict'; |
||
1574 | |||
1575 | var utils = _dereq_('./utils'); |
||
1576 | |||
1577 | /** |
||
1578 | * An object to write any content to an Uint8Array. |
||
1579 | * @constructor |
||
1580 | * @param {number} length The length of the array. |
||
1581 | */ |
||
1582 | var Uint8ArrayWriter = function(length) { |
||
1583 | this.data = new Uint8Array(length); |
||
1584 | this.index = 0; |
||
1585 | }; |
||
1586 | Uint8ArrayWriter.prototype = { |
||
1587 | /** |
||
1588 | * Append any content to the current array. |
||
1589 | * @param {Object} input the content to add. |
||
1590 | */ |
||
1591 | append: function(input) { |
||
1592 | if (input.length !== 0) { |
||
1593 | // with an empty Uint8Array, Opera fails with a "Offset larger than array size" |
||
1594 | input = utils.transformTo("uint8array", input); |
||
1595 | this.data.set(input, this.index); |
||
1596 | this.index += input.length; |
||
1597 | } |
||
1598 | }, |
||
1599 | /** |
||
1600 | * Finalize the construction an return the result. |
||
1601 | * @return {Uint8Array} the generated array. |
||
1602 | */ |
||
1603 | finalize: function() { |
||
1604 | return this.data; |
||
1605 | } |
||
1606 | }; |
||
1607 | |||
1608 | module.exports = Uint8ArrayWriter; |
||
1609 | |||
1610 | },{"./utils":21}],20:[function(_dereq_,module,exports){ |
||
1611 | 'use strict'; |
||
1612 | |||
1613 | var utils = _dereq_('./utils'); |
||
1614 | var support = _dereq_('./support'); |
||
1615 | var nodeBuffer = _dereq_('./nodeBuffer'); |
||
1616 | |||
1617 | /** |
||
1618 | * The following functions come from pako, from pako/lib/utils/strings |
||
1619 | * released under the MIT license, see pako https://github.com/nodeca/pako/ |
||
1620 | */ |
||
1621 | |||
1622 | // Table with utf8 lengths (calculated by first byte of sequence) |
||
1623 | // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, |
||
1624 | // because max possible codepoint is 0x10ffff |
||
1625 | var _utf8len = new Array(256); |
||
1626 | for (var i=0; i<256; i++) { |
||
1627 | _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); |
||
1628 | } |
||
1629 | _utf8len[254]=_utf8len[254]=1; // Invalid sequence start |
||
1630 | |||
1631 | // convert string to array (typed, when possible) |
||
1632 | var string2buf = function (str) { |
||
1633 | var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; |
||
1634 | |||
1635 | // count binary size |
||
1636 | View Code Duplication | for (m_pos = 0; m_pos < str_len; m_pos++) { |
|
1637 | c = str.charCodeAt(m_pos); |
||
1638 | if (((c & 0xfc00) === 0xd800) && (m_pos+1 < str_len)) { |
||
1639 | c2 = str.charCodeAt(m_pos+1); |
||
1640 | if ((c2 & 0xfc00) === 0xdc00) { |
||
1641 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
||
1642 | m_pos++; |
||
1643 | } |
||
1644 | } |
||
1645 | buf_len += (c < 0x80) ? 1 : ((c < 0x800) ? 2 : ((c < 0x10000) ? 3 : 4)); |
||
1646 | } |
||
1647 | |||
1648 | // allocate buffer |
||
1649 | if (support.uint8array) { |
||
1650 | buf = new Uint8Array(buf_len); |
||
1651 | } else { |
||
1652 | buf = new Array(buf_len); |
||
1653 | } |
||
1654 | |||
1655 | // convert |
||
1656 | View Code Duplication | for (i=0, m_pos = 0; i < buf_len; m_pos++) { |
|
1657 | c = str.charCodeAt(m_pos); |
||
1658 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { |
||
1659 | c2 = str.charCodeAt(m_pos+1); |
||
1660 | if ((c2 & 0xfc00) === 0xdc00) { |
||
1661 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
||
1662 | m_pos++; |
||
1663 | } |
||
1664 | } |
||
1665 | if (c < 0x80) { |
||
1666 | /* one byte */ |
||
1667 | buf[i++] = c; |
||
1668 | } else if (c < 0x800) { |
||
1669 | /* two bytes */ |
||
1670 | buf[i++] = 0xC0 | (c >>> 6); |
||
1671 | buf[i++] = 0x80 | (c & 0x3f); |
||
1672 | } else if (c < 0x10000) { |
||
1673 | /* three bytes */ |
||
1674 | buf[i++] = 0xE0 | (c >>> 12); |
||
1675 | buf[i++] = 0x80 | ((c >>> 6) & 0x3f); |
||
1676 | buf[i++] = 0x80 | (c & 0x3f); |
||
1677 | } else { |
||
1678 | /* four bytes */ |
||
1679 | buf[i++] = 0xf0 | (c >>> 18); |
||
1680 | buf[i++] = 0x80 | ((c >>> 12) & 0x3f); |
||
1681 | buf[i++] = 0x80 | ((c >>> 6) & 0x3f); |
||
1682 | buf[i++] = 0x80 | (c & 0x3f); |
||
1683 | } |
||
1684 | } |
||
1685 | |||
1686 | return buf; |
||
1687 | }; |
||
1688 | |||
1689 | // Calculate max possible position in utf8 buffer, |
||
1690 | // that will not break sequence. If that's not possible |
||
1691 | // - (very small limits) return max size as is. |
||
1692 | // |
||
1693 | // buf[] - utf8 bytes array |
||
1694 | // max - length limit (mandatory); |
||
1695 | View Code Duplication | var utf8border = function(buf, max) { |
|
1696 | var pos; |
||
1697 | |||
1698 | max = max || buf.length; |
||
1699 | if (max > buf.length) { max = buf.length; } |
||
1700 | |||
1701 | // go back from last position, until start of sequence found |
||
1702 | pos = max-1; |
||
1703 | while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } |
||
1704 | |||
1705 | // Fuckup - very small and broken sequence, |
||
1706 | // return max, because we should return something anyway. |
||
1707 | if (pos < 0) { return max; } |
||
1708 | |||
1709 | // If we came to start of buffer - that means vuffer is too small, |
||
1710 | // return max too. |
||
1711 | if (pos === 0) { return max; } |
||
1712 | |||
1713 | return (pos + _utf8len[buf[pos]] > max) ? pos : max; |
||
1714 | }; |
||
1715 | |||
1716 | // convert array to string |
||
1717 | var buf2string = function (buf) { |
||
1718 | var str, i, out, c, c_len; |
||
1719 | var len = buf.length; |
||
1720 | |||
1721 | // Reserve max possible length (2 words per char) |
||
1722 | // NB: by unknown reasons, Array is significantly faster for |
||
1723 | // String.fromCharCode.apply than Uint16Array. |
||
1724 | var utf16buf = new Array(len*2); |
||
1725 | |||
1726 | View Code Duplication | for (out=0, i=0; i<len;) { |
|
1727 | c = buf[i++]; |
||
1728 | // quick process ascii |
||
1729 | if (c < 0x80) { utf16buf[out++] = c; continue; } |
||
1730 | |||
1731 | c_len = _utf8len[c]; |
||
1732 | // skip 5 & 6 byte codes |
||
1733 | if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } |
||
1734 | |||
1735 | // apply mask on first byte |
||
1736 | c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; |
||
1737 | // join the rest |
||
1738 | while (c_len > 1 && i < len) { |
||
1739 | c = (c << 6) | (buf[i++] & 0x3f); |
||
1740 | c_len--; |
||
1741 | } |
||
1742 | |||
1743 | // terminated by end of string? |
||
1744 | if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } |
||
1745 | |||
1746 | if (c < 0x10000) { |
||
1747 | utf16buf[out++] = c; |
||
1748 | } else { |
||
1749 | c -= 0x10000; |
||
1750 | utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); |
||
1751 | utf16buf[out++] = 0xdc00 | (c & 0x3ff); |
||
1752 | } |
||
1753 | } |
||
1754 | |||
1755 | // shrinkBuf(utf16buf, out) |
||
1756 | if (utf16buf.length !== out) { |
||
1757 | if(utf16buf.subarray) { |
||
1758 | utf16buf = utf16buf.subarray(0, out); |
||
1759 | } else { |
||
1760 | utf16buf.length = out; |
||
1761 | } |
||
1762 | } |
||
1763 | |||
1764 | // return String.fromCharCode.apply(null, utf16buf); |
||
1765 | return utils.applyFromCharCode(utf16buf); |
||
1766 | }; |
||
1767 | |||
1768 | |||
1769 | // That's all for the pako functions. |
||
1770 | |||
1771 | |||
1772 | /** |
||
1773 | * Transform a javascript string into an array (typed if possible) of bytes, |
||
1774 | * UTF-8 encoded. |
||
1775 | * @param {String} str the string to encode |
||
1776 | * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. |
||
1777 | */ |
||
1778 | exports.utf8encode = function utf8encode(str) { |
||
1779 | if (support.nodebuffer) { |
||
1780 | return nodeBuffer(str, "utf-8"); |
||
1781 | } |
||
1782 | |||
1783 | return string2buf(str); |
||
1784 | }; |
||
1785 | |||
1786 | |||
1787 | /** |
||
1788 | * Transform a bytes array (or a representation) representing an UTF-8 encoded |
||
1789 | * string into a javascript string. |
||
1790 | * @param {Array|Uint8Array|Buffer} buf the data de decode |
||
1791 | * @return {String} the decoded string. |
||
1792 | */ |
||
1793 | exports.utf8decode = function utf8decode(buf) { |
||
1794 | if (support.nodebuffer) { |
||
1795 | return utils.transformTo("nodebuffer", buf).toString("utf-8"); |
||
1796 | } |
||
1797 | |||
1798 | buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); |
||
1799 | |||
1800 | // return buf2string(buf); |
||
1801 | // Chrome prefers to work with "small" chunks of data |
||
1802 | // for the method buf2string. |
||
1803 | // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. |
||
1804 | var result = [], k = 0, len = buf.length, chunk = 65536; |
||
1805 | while (k < len) { |
||
1806 | var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); |
||
1807 | if (support.uint8array) { |
||
1808 | result.push(buf2string(buf.subarray(k, nextBoundary))); |
||
1809 | } else { |
||
1810 | result.push(buf2string(buf.slice(k, nextBoundary))); |
||
1811 | } |
||
1812 | k = nextBoundary; |
||
1813 | } |
||
1814 | return result.join(""); |
||
1815 | |||
1816 | }; |
||
1817 | // vim: set shiftwidth=4 softtabstop=4: |
||
1818 | |||
1819 | },{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(_dereq_,module,exports){ |
||
1820 | 'use strict'; |
||
1821 | var support = _dereq_('./support'); |
||
1822 | var compressions = _dereq_('./compressions'); |
||
1823 | var nodeBuffer = _dereq_('./nodeBuffer'); |
||
1824 | /** |
||
1825 | * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. |
||
1826 | * @param {string} str the string to transform. |
||
1827 | * @return {String} the binary string. |
||
1828 | */ |
||
1829 | exports.string2binary = function(str) { |
||
1830 | var result = ""; |
||
1831 | for (var i = 0; i < str.length; i++) { |
||
1832 | result += String.fromCharCode(str.charCodeAt(i) & 0xff); |
||
1833 | } |
||
1834 | return result; |
||
1835 | }; |
||
1836 | exports.arrayBuffer2Blob = function(buffer) { |
||
1837 | exports.checkSupport("blob"); |
||
1838 | |||
1839 | try { |
||
1840 | // Blob constructor |
||
1841 | return new Blob([buffer], { |
||
1842 | type: "application/zip" |
||
1843 | }); |
||
1844 | } |
||
1845 | catch (e) { |
||
1846 | |||
1847 | try { |
||
1848 | // deprecated, browser only, old way |
||
1849 | var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; |
||
1850 | var builder = new Builder(); |
||
1851 | builder.append(buffer); |
||
1852 | return builder.getBlob('application/zip'); |
||
1853 | } |
||
1854 | catch (e) { |
||
1855 | |||
1856 | // well, fuck ?! |
||
1857 | throw new Error("Bug : can't construct the Blob."); |
||
1858 | } |
||
1859 | } |
||
1860 | |||
1861 | |||
1862 | }; |
||
1863 | /** |
||
1864 | * The identity function. |
||
1865 | * @param {Object} input the input. |
||
1866 | * @return {Object} the same input. |
||
1867 | */ |
||
1868 | function identity(input) { |
||
1869 | return input; |
||
1870 | } |
||
1871 | |||
1872 | /** |
||
1873 | * Fill in an array with a string. |
||
1874 | * @param {String} str the string to use. |
||
1875 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). |
||
1876 | * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. |
||
1877 | */ |
||
1878 | function stringToArrayLike(str, array) { |
||
1879 | for (var i = 0; i < str.length; ++i) { |
||
1880 | array[i] = str.charCodeAt(i) & 0xFF; |
||
1881 | } |
||
1882 | return array; |
||
1883 | } |
||
1884 | |||
1885 | /** |
||
1886 | * Transform an array-like object to a string. |
||
1887 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. |
||
1888 | * @return {String} the result. |
||
1889 | */ |
||
1890 | function arrayLikeToString(array) { |
||
1891 | // Performances notes : |
||
1892 | // -------------------- |
||
1893 | // String.fromCharCode.apply(null, array) is the fastest, see |
||
1894 | // see http://jsperf.com/converting-a-uint8array-to-a-string/2 |
||
1895 | // but the stack is limited (and we can get huge arrays !). |
||
1896 | // |
||
1897 | // result += String.fromCharCode(array[i]); generate too many strings ! |
||
1898 | // |
||
1899 | // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 |
||
1900 | var chunk = 65536; |
||
1901 | var result = [], |
||
1902 | len = array.length, |
||
1903 | type = exports.getTypeOf(array), |
||
1904 | k = 0, |
||
1905 | canUseApply = true; |
||
1906 | try { |
||
1907 | switch(type) { |
||
1908 | case "uint8array": |
||
1909 | String.fromCharCode.apply(null, new Uint8Array(0)); |
||
1910 | break; |
||
1911 | case "nodebuffer": |
||
1912 | String.fromCharCode.apply(null, nodeBuffer(0)); |
||
1913 | break; |
||
1914 | } |
||
1915 | } catch(e) { |
||
1916 | canUseApply = false; |
||
1917 | } |
||
1918 | |||
1919 | // no apply : slow and painful algorithm |
||
1920 | // default browser on android 4.* |
||
1921 | if (!canUseApply) { |
||
1922 | var resultStr = ""; |
||
1923 | for(var i = 0; i < array.length;i++) { |
||
1924 | resultStr += String.fromCharCode(array[i]); |
||
1925 | } |
||
1926 | return resultStr; |
||
1927 | } |
||
1928 | while (k < len && chunk > 1) { |
||
1929 | try { |
||
1930 | if (type === "array" || type === "nodebuffer") { |
||
1931 | result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); |
||
1932 | } |
||
1933 | else { |
||
1934 | result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); |
||
1935 | } |
||
1936 | k += chunk; |
||
1937 | } |
||
1938 | catch (e) { |
||
1939 | chunk = Math.floor(chunk / 2); |
||
1940 | } |
||
1941 | } |
||
1942 | return result.join(""); |
||
1943 | } |
||
1944 | |||
1945 | exports.applyFromCharCode = arrayLikeToString; |
||
1946 | |||
1947 | |||
1948 | /** |
||
1949 | * Copy the data from an array-like to an other array-like. |
||
1950 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. |
||
1951 | * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. |
||
1952 | * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. |
||
1953 | */ |
||
1954 | function arrayLikeToArrayLike(arrayFrom, arrayTo) { |
||
1955 | for (var i = 0; i < arrayFrom.length; i++) { |
||
1956 | arrayTo[i] = arrayFrom[i]; |
||
1957 | } |
||
1958 | return arrayTo; |
||
1959 | } |
||
1960 | |||
1961 | // a matrix containing functions to transform everything into everything. |
||
1962 | var transform = {}; |
||
1963 | |||
1964 | // string to ? |
||
1965 | transform["string"] = { |
||
1966 | "string": identity, |
||
1967 | "array": function(input) { |
||
1968 | return stringToArrayLike(input, new Array(input.length)); |
||
1969 | }, |
||
1970 | "arraybuffer": function(input) { |
||
1971 | return transform["string"]["uint8array"](input).buffer; |
||
1972 | }, |
||
1973 | "uint8array": function(input) { |
||
1974 | return stringToArrayLike(input, new Uint8Array(input.length)); |
||
1975 | }, |
||
1976 | "nodebuffer": function(input) { |
||
1977 | return stringToArrayLike(input, nodeBuffer(input.length)); |
||
1978 | } |
||
1979 | }; |
||
1980 | |||
1981 | // array to ? |
||
1982 | transform["array"] = { |
||
1983 | "string": arrayLikeToString, |
||
1984 | "array": identity, |
||
1985 | "arraybuffer": function(input) { |
||
1986 | return (new Uint8Array(input)).buffer; |
||
1987 | }, |
||
1988 | "uint8array": function(input) { |
||
1989 | return new Uint8Array(input); |
||
1990 | }, |
||
1991 | "nodebuffer": function(input) { |
||
1992 | return nodeBuffer(input); |
||
1993 | } |
||
1994 | }; |
||
1995 | |||
1996 | // arraybuffer to ? |
||
1997 | transform["arraybuffer"] = { |
||
1998 | "string": function(input) { |
||
1999 | return arrayLikeToString(new Uint8Array(input)); |
||
2000 | }, |
||
2001 | "array": function(input) { |
||
2002 | return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); |
||
2003 | }, |
||
2004 | "arraybuffer": identity, |
||
2005 | "uint8array": function(input) { |
||
2006 | return new Uint8Array(input); |
||
2007 | }, |
||
2008 | "nodebuffer": function(input) { |
||
2009 | return nodeBuffer(new Uint8Array(input)); |
||
2010 | } |
||
2011 | }; |
||
2012 | |||
2013 | // uint8array to ? |
||
2014 | transform["uint8array"] = { |
||
2015 | "string": arrayLikeToString, |
||
2016 | "array": function(input) { |
||
2017 | return arrayLikeToArrayLike(input, new Array(input.length)); |
||
2018 | }, |
||
2019 | "arraybuffer": function(input) { |
||
2020 | return input.buffer; |
||
2021 | }, |
||
2022 | "uint8array": identity, |
||
2023 | "nodebuffer": function(input) { |
||
2024 | return nodeBuffer(input); |
||
2025 | } |
||
2026 | }; |
||
2027 | |||
2028 | // nodebuffer to ? |
||
2029 | transform["nodebuffer"] = { |
||
2030 | "string": arrayLikeToString, |
||
2031 | "array": function(input) { |
||
2032 | return arrayLikeToArrayLike(input, new Array(input.length)); |
||
2033 | }, |
||
2034 | "arraybuffer": function(input) { |
||
2035 | return transform["nodebuffer"]["uint8array"](input).buffer; |
||
2036 | }, |
||
2037 | "uint8array": function(input) { |
||
2038 | return arrayLikeToArrayLike(input, new Uint8Array(input.length)); |
||
2039 | }, |
||
2040 | "nodebuffer": identity |
||
2041 | }; |
||
2042 | |||
2043 | /** |
||
2044 | * Transform an input into any type. |
||
2045 | * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. |
||
2046 | * If no output type is specified, the unmodified input will be returned. |
||
2047 | * @param {String} outputType the output type. |
||
2048 | * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. |
||
2049 | * @throws {Error} an Error if the browser doesn't support the requested output type. |
||
2050 | */ |
||
2051 | exports.transformTo = function(outputType, input) { |
||
2052 | if (!input) { |
||
2053 | // undefined, null, etc |
||
2054 | // an empty string won't harm. |
||
2055 | input = ""; |
||
2056 | } |
||
2057 | if (!outputType) { |
||
2058 | return input; |
||
2059 | } |
||
2060 | exports.checkSupport(outputType); |
||
2061 | var inputType = exports.getTypeOf(input); |
||
2062 | var result = transform[inputType][outputType](input); |
||
2063 | return result; |
||
2064 | }; |
||
2065 | |||
2066 | /** |
||
2067 | * Return the type of the input. |
||
2068 | * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. |
||
2069 | * @param {Object} input the input to identify. |
||
2070 | * @return {String} the (lowercase) type of the input. |
||
2071 | */ |
||
2072 | exports.getTypeOf = function(input) { |
||
2073 | if (typeof input === "string") { |
||
2074 | return "string"; |
||
2075 | } |
||
2076 | if (Object.prototype.toString.call(input) === "[object Array]") { |
||
2077 | return "array"; |
||
2078 | } |
||
2079 | if (support.nodebuffer && nodeBuffer.test(input)) { |
||
2080 | return "nodebuffer"; |
||
2081 | } |
||
2082 | if (support.uint8array && input instanceof Uint8Array) { |
||
2083 | return "uint8array"; |
||
2084 | } |
||
2085 | if (support.arraybuffer && input instanceof ArrayBuffer) { |
||
2086 | return "arraybuffer"; |
||
2087 | } |
||
2088 | }; |
||
2089 | |||
2090 | /** |
||
2091 | * Throw an exception if the type is not supported. |
||
2092 | * @param {String} type the type to check. |
||
2093 | * @throws {Error} an Error if the browser doesn't support the requested type. |
||
2094 | */ |
||
2095 | exports.checkSupport = function(type) { |
||
2096 | var supported = support[type.toLowerCase()]; |
||
2097 | if (!supported) { |
||
2098 | throw new Error(type + " is not supported by this browser"); |
||
2099 | } |
||
2100 | }; |
||
2101 | exports.MAX_VALUE_16BITS = 65535; |
||
2102 | exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 |
||
2103 | |||
2104 | /** |
||
2105 | * Prettify a string read as binary. |
||
2106 | * @param {string} str the string to prettify. |
||
2107 | * @return {string} a pretty string. |
||
2108 | */ |
||
2109 | exports.pretty = function(str) { |
||
2110 | var res = '', |
||
2111 | code, i; |
||
2112 | for (i = 0; i < (str || "").length; i++) { |
||
2113 | code = str.charCodeAt(i); |
||
2114 | res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); |
||
2115 | } |
||
2116 | return res; |
||
2117 | }; |
||
2118 | |||
2119 | /** |
||
2120 | * Find a compression registered in JSZip. |
||
2121 | * @param {string} compressionMethod the method magic to find. |
||
2122 | * @return {Object|null} the JSZip compression object, null if none found. |
||
2123 | */ |
||
2124 | exports.findCompression = function(compressionMethod) { |
||
2125 | for (var method in compressions) { |
||
2126 | if (!compressions.hasOwnProperty(method)) { |
||
2127 | continue; |
||
2128 | } |
||
2129 | if (compressions[method].magic === compressionMethod) { |
||
2130 | return compressions[method]; |
||
2131 | } |
||
2132 | } |
||
2133 | return null; |
||
2134 | }; |
||
2135 | /** |
||
2136 | * Cross-window, cross-Node-context regular expression detection |
||
2137 | * @param {Object} object Anything |
||
2138 | * @return {Boolean} true if the object is a regular expression, |
||
2139 | * false otherwise |
||
2140 | */ |
||
2141 | exports.isRegExp = function (object) { |
||
2142 | return Object.prototype.toString.call(object) === "[object RegExp]"; |
||
2143 | }; |
||
2144 | |||
2145 | |||
2146 | },{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(_dereq_,module,exports){ |
||
2147 | 'use strict'; |
||
2148 | var StringReader = _dereq_('./stringReader'); |
||
2149 | var NodeBufferReader = _dereq_('./nodeBufferReader'); |
||
2150 | var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); |
||
2151 | var utils = _dereq_('./utils'); |
||
2152 | var sig = _dereq_('./signature'); |
||
2153 | var ZipEntry = _dereq_('./zipEntry'); |
||
2154 | var support = _dereq_('./support'); |
||
2155 | var jszipProto = _dereq_('./object'); |
||
2156 | // class ZipEntries {{{ |
||
2157 | /** |
||
2158 | * All the entries in the zip file. |
||
2159 | * @constructor |
||
2160 | * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. |
||
2161 | * @param {Object} loadOptions Options for loading the stream. |
||
2162 | */ |
||
2163 | function ZipEntries(data, loadOptions) { |
||
2164 | this.files = []; |
||
2165 | this.loadOptions = loadOptions; |
||
2166 | if (data) { |
||
2167 | this.load(data); |
||
2168 | } |
||
2169 | } |
||
2170 | ZipEntries.prototype = { |
||
2171 | /** |
||
2172 | * Check that the reader is on the speficied signature. |
||
2173 | * @param {string} expectedSignature the expected signature. |
||
2174 | * @throws {Error} if it is an other signature. |
||
2175 | */ |
||
2176 | checkSignature: function(expectedSignature) { |
||
2177 | var signature = this.reader.readString(4); |
||
2178 | if (signature !== expectedSignature) { |
||
2179 | throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); |
||
2180 | } |
||
2181 | }, |
||
2182 | /** |
||
2183 | * Read the end of the central directory. |
||
2184 | */ |
||
2185 | readBlockEndOfCentral: function() { |
||
2186 | this.diskNumber = this.reader.readInt(2); |
||
2187 | this.diskWithCentralDirStart = this.reader.readInt(2); |
||
2188 | this.centralDirRecordsOnThisDisk = this.reader.readInt(2); |
||
2189 | this.centralDirRecords = this.reader.readInt(2); |
||
2190 | this.centralDirSize = this.reader.readInt(4); |
||
2191 | this.centralDirOffset = this.reader.readInt(4); |
||
2192 | |||
2193 | this.zipCommentLength = this.reader.readInt(2); |
||
2194 | // warning : the encoding depends of the system locale |
||
2195 | // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. |
||
2196 | // On a windows machine, this field is encoded with the localized windows code page. |
||
2197 | this.zipComment = this.reader.readString(this.zipCommentLength); |
||
2198 | // To get consistent behavior with the generation part, we will assume that |
||
2199 | // this is utf8 encoded. |
||
2200 | this.zipComment = jszipProto.utf8decode(this.zipComment); |
||
2201 | }, |
||
2202 | /** |
||
2203 | * Read the end of the Zip 64 central directory. |
||
2204 | * Not merged with the method readEndOfCentral : |
||
2205 | * The end of central can coexist with its Zip64 brother, |
||
2206 | * I don't want to read the wrong number of bytes ! |
||
2207 | */ |
||
2208 | readBlockZip64EndOfCentral: function() { |
||
2209 | this.zip64EndOfCentralSize = this.reader.readInt(8); |
||
2210 | this.versionMadeBy = this.reader.readString(2); |
||
2211 | this.versionNeeded = this.reader.readInt(2); |
||
2212 | this.diskNumber = this.reader.readInt(4); |
||
2213 | this.diskWithCentralDirStart = this.reader.readInt(4); |
||
2214 | this.centralDirRecordsOnThisDisk = this.reader.readInt(8); |
||
2215 | this.centralDirRecords = this.reader.readInt(8); |
||
2216 | this.centralDirSize = this.reader.readInt(8); |
||
2217 | this.centralDirOffset = this.reader.readInt(8); |
||
2218 | |||
2219 | this.zip64ExtensibleData = {}; |
||
2220 | var extraDataSize = this.zip64EndOfCentralSize - 44, |
||
2221 | index = 0, |
||
2222 | extraFieldId, |
||
2223 | extraFieldLength, |
||
2224 | extraFieldValue; |
||
2225 | while (index < extraDataSize) { |
||
2226 | extraFieldId = this.reader.readInt(2); |
||
2227 | extraFieldLength = this.reader.readInt(4); |
||
2228 | extraFieldValue = this.reader.readString(extraFieldLength); |
||
2229 | this.zip64ExtensibleData[extraFieldId] = { |
||
2230 | id: extraFieldId, |
||
2231 | length: extraFieldLength, |
||
2232 | value: extraFieldValue |
||
2233 | }; |
||
2234 | } |
||
2235 | }, |
||
2236 | /** |
||
2237 | * Read the end of the Zip 64 central directory locator. |
||
2238 | */ |
||
2239 | readBlockZip64EndOfCentralLocator: function() { |
||
2240 | this.diskWithZip64CentralDirStart = this.reader.readInt(4); |
||
2241 | this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); |
||
2242 | this.disksCount = this.reader.readInt(4); |
||
2243 | if (this.disksCount > 1) { |
||
2244 | throw new Error("Multi-volumes zip are not supported"); |
||
2245 | } |
||
2246 | }, |
||
2247 | /** |
||
2248 | * Read the local files, based on the offset read in the central part. |
||
2249 | */ |
||
2250 | readLocalFiles: function() { |
||
2251 | var i, file; |
||
2252 | for (i = 0; i < this.files.length; i++) { |
||
2253 | file = this.files[i]; |
||
2254 | this.reader.setIndex(file.localHeaderOffset); |
||
2255 | this.checkSignature(sig.LOCAL_FILE_HEADER); |
||
2256 | file.readLocalPart(this.reader); |
||
2257 | file.handleUTF8(); |
||
2258 | } |
||
2259 | }, |
||
2260 | /** |
||
2261 | * Read the central directory. |
||
2262 | */ |
||
2263 | readCentralDir: function() { |
||
2264 | var file; |
||
2265 | |||
2266 | this.reader.setIndex(this.centralDirOffset); |
||
2267 | while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { |
||
2268 | file = new ZipEntry({ |
||
2269 | zip64: this.zip64 |
||
2270 | }, this.loadOptions); |
||
2271 | file.readCentralPart(this.reader); |
||
2272 | this.files.push(file); |
||
2273 | } |
||
2274 | }, |
||
2275 | /** |
||
2276 | * Read the end of central directory. |
||
2277 | */ |
||
2278 | readEndOfCentral: function() { |
||
2279 | var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); |
||
2280 | if (offset === -1) { |
||
2281 | throw new Error("Corrupted zip : can't find end of central directory"); |
||
2282 | } |
||
2283 | this.reader.setIndex(offset); |
||
2284 | this.checkSignature(sig.CENTRAL_DIRECTORY_END); |
||
2285 | this.readBlockEndOfCentral(); |
||
2286 | |||
2287 | |||
2288 | /* extract from the zip spec : |
||
2289 | 4) If one of the fields in the end of central directory |
||
2290 | record is too small to hold required data, the field |
||
2291 | should be set to -1 (0xFFFF or 0xFFFFFFFF) and the |
||
2292 | ZIP64 format record should be created. |
||
2293 | 5) The end of central directory record and the |
||
2294 | Zip64 end of central directory locator record must |
||
2295 | reside on the same disk when splitting or spanning |
||
2296 | an archive. |
||
2297 | */ |
||
2298 | if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { |
||
2299 | this.zip64 = true; |
||
2300 | |||
2301 | /* |
||
2302 | Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from |
||
2303 | the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents |
||
2304 | all numbers as 64-bit double precision IEEE 754 floating point numbers. |
||
2305 | So, we have 53bits for integers and bitwise operations treat everything as 32bits. |
||
2306 | see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators |
||
2307 | and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 |
||
2308 | */ |
||
2309 | |||
2310 | // should look for a zip64 EOCD locator |
||
2311 | offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); |
||
2312 | if (offset === -1) { |
||
2313 | throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); |
||
2314 | } |
||
2315 | this.reader.setIndex(offset); |
||
2316 | this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); |
||
2317 | this.readBlockZip64EndOfCentralLocator(); |
||
2318 | |||
2319 | // now the zip64 EOCD record |
||
2320 | this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); |
||
2321 | this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); |
||
2322 | this.readBlockZip64EndOfCentral(); |
||
2323 | } |
||
2324 | }, |
||
2325 | prepareReader: function(data) { |
||
2326 | var type = utils.getTypeOf(data); |
||
2327 | if (type === "string" && !support.uint8array) { |
||
2328 | this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); |
||
2329 | } |
||
2330 | else if (type === "nodebuffer") { |
||
2331 | this.reader = new NodeBufferReader(data); |
||
2332 | } |
||
2333 | else { |
||
2334 | this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); |
||
2335 | } |
||
2336 | }, |
||
2337 | /** |
||
2338 | * Read a zip file and create ZipEntries. |
||
2339 | * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. |
||
2340 | */ |
||
2341 | load: function(data) { |
||
2342 | this.prepareReader(data); |
||
2343 | this.readEndOfCentral(); |
||
2344 | this.readCentralDir(); |
||
2345 | this.readLocalFiles(); |
||
2346 | } |
||
2347 | }; |
||
2348 | // }}} end of ZipEntries |
||
2349 | module.exports = ZipEntries; |
||
2350 | |||
2351 | },{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(_dereq_,module,exports){ |
||
2352 | 'use strict'; |
||
2353 | var StringReader = _dereq_('./stringReader'); |
||
2354 | var utils = _dereq_('./utils'); |
||
2355 | var CompressedObject = _dereq_('./compressedObject'); |
||
2356 | var jszipProto = _dereq_('./object'); |
||
2357 | // class ZipEntry {{{ |
||
2358 | /** |
||
2359 | * An entry in the zip file. |
||
2360 | * @constructor |
||
2361 | * @param {Object} options Options of the current file. |
||
2362 | * @param {Object} loadOptions Options for loading the stream. |
||
2363 | */ |
||
2364 | function ZipEntry(options, loadOptions) { |
||
2365 | this.options = options; |
||
2366 | this.loadOptions = loadOptions; |
||
2367 | } |
||
2368 | ZipEntry.prototype = { |
||
2369 | /** |
||
2370 | * say if the file is encrypted. |
||
2371 | * @return {boolean} true if the file is encrypted, false otherwise. |
||
2372 | */ |
||
2373 | isEncrypted: function() { |
||
2374 | // bit 1 is set |
||
2375 | return (this.bitFlag & 0x0001) === 0x0001; |
||
2376 | }, |
||
2377 | /** |
||
2378 | * say if the file has utf-8 filename/comment. |
||
2379 | * @return {boolean} true if the filename/comment is in utf-8, false otherwise. |
||
2380 | */ |
||
2381 | useUTF8: function() { |
||
2382 | // bit 11 is set |
||
2383 | return (this.bitFlag & 0x0800) === 0x0800; |
||
2384 | }, |
||
2385 | /** |
||
2386 | * Prepare the function used to generate the compressed content from this ZipFile. |
||
2387 | * @param {DataReader} reader the reader to use. |
||
2388 | * @param {number} from the offset from where we should read the data. |
||
2389 | * @param {number} length the length of the data to read. |
||
2390 | * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). |
||
2391 | */ |
||
2392 | prepareCompressedContent: function(reader, from, length) { |
||
2393 | return function() { |
||
2394 | var previousIndex = reader.index; |
||
2395 | reader.setIndex(from); |
||
2396 | var compressedFileData = reader.readData(length); |
||
2397 | reader.setIndex(previousIndex); |
||
2398 | |||
2399 | return compressedFileData; |
||
2400 | }; |
||
2401 | }, |
||
2402 | /** |
||
2403 | * Prepare the function used to generate the uncompressed content from this ZipFile. |
||
2404 | * @param {DataReader} reader the reader to use. |
||
2405 | * @param {number} from the offset from where we should read the data. |
||
2406 | * @param {number} length the length of the data to read. |
||
2407 | * @param {JSZip.compression} compression the compression used on this file. |
||
2408 | * @param {number} uncompressedSize the uncompressed size to expect. |
||
2409 | * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). |
||
2410 | */ |
||
2411 | prepareContent: function(reader, from, length, compression, uncompressedSize) { |
||
2412 | return function() { |
||
2413 | |||
2414 | var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); |
||
2415 | var uncompressedFileData = compression.uncompress(compressedFileData); |
||
2416 | |||
2417 | if (uncompressedFileData.length !== uncompressedSize) { |
||
2418 | throw new Error("Bug : uncompressed data size mismatch"); |
||
2419 | } |
||
2420 | |||
2421 | return uncompressedFileData; |
||
2422 | }; |
||
2423 | }, |
||
2424 | /** |
||
2425 | * Read the local part of a zip file and add the info in this object. |
||
2426 | * @param {DataReader} reader the reader to use. |
||
2427 | */ |
||
2428 | readLocalPart: function(reader) { |
||
2429 | var compression, localExtraFieldsLength; |
||
2430 | |||
2431 | // we already know everything from the central dir ! |
||
2432 | // If the central dir data are false, we are doomed. |
||
2433 | // On the bright side, the local part is scary : zip64, data descriptors, both, etc. |
||
2434 | // The less data we get here, the more reliable this should be. |
||
2435 | // Let's skip the whole header and dash to the data ! |
||
2436 | reader.skip(22); |
||
2437 | // in some zip created on windows, the filename stored in the central dir contains \ instead of /. |
||
2438 | // Strangely, the filename here is OK. |
||
2439 | // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes |
||
2440 | // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... |
||
2441 | // Search "unzip mismatching "local" filename continuing with "central" filename version" on |
||
2442 | // the internet. |
||
2443 | // |
||
2444 | // I think I see the logic here : the central directory is used to display |
||
2445 | // content and the local directory is used to extract the files. Mixing / and \ |
||
2446 | // may be used to display \ to windows users and use / when extracting the files. |
||
2447 | // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 |
||
2448 | this.fileNameLength = reader.readInt(2); |
||
2449 | localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir |
||
2450 | this.fileName = reader.readString(this.fileNameLength); |
||
2451 | reader.skip(localExtraFieldsLength); |
||
2452 | |||
2453 | if (this.compressedSize == -1 || this.uncompressedSize == -1) { |
||
2454 | throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); |
||
2455 | } |
||
2456 | |||
2457 | compression = utils.findCompression(this.compressionMethod); |
||
2458 | if (compression === null) { // no compression found |
||
2459 | throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")"); |
||
2460 | } |
||
2461 | this.decompressed = new CompressedObject(); |
||
2462 | this.decompressed.compressedSize = this.compressedSize; |
||
2463 | this.decompressed.uncompressedSize = this.uncompressedSize; |
||
2464 | this.decompressed.crc32 = this.crc32; |
||
2465 | this.decompressed.compressionMethod = this.compressionMethod; |
||
2466 | this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); |
||
2467 | this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); |
||
2468 | |||
2469 | // we need to compute the crc32... |
||
2470 | if (this.loadOptions.checkCRC32) { |
||
2471 | this.decompressed = utils.transformTo("string", this.decompressed.getContent()); |
||
2472 | if (jszipProto.crc32(this.decompressed) !== this.crc32) { |
||
2473 | throw new Error("Corrupted zip : CRC32 mismatch"); |
||
2474 | } |
||
2475 | } |
||
2476 | }, |
||
2477 | |||
2478 | /** |
||
2479 | * Read the central part of a zip file and add the info in this object. |
||
2480 | * @param {DataReader} reader the reader to use. |
||
2481 | */ |
||
2482 | readCentralPart: function(reader) { |
||
2483 | this.versionMadeBy = reader.readString(2); |
||
2484 | this.versionNeeded = reader.readInt(2); |
||
2485 | this.bitFlag = reader.readInt(2); |
||
2486 | this.compressionMethod = reader.readString(2); |
||
2487 | this.date = reader.readDate(); |
||
2488 | this.crc32 = reader.readInt(4); |
||
2489 | this.compressedSize = reader.readInt(4); |
||
2490 | this.uncompressedSize = reader.readInt(4); |
||
2491 | this.fileNameLength = reader.readInt(2); |
||
2492 | this.extraFieldsLength = reader.readInt(2); |
||
2493 | this.fileCommentLength = reader.readInt(2); |
||
2494 | this.diskNumberStart = reader.readInt(2); |
||
2495 | this.internalFileAttributes = reader.readInt(2); |
||
2496 | this.externalFileAttributes = reader.readInt(4); |
||
2497 | this.localHeaderOffset = reader.readInt(4); |
||
2498 | |||
2499 | if (this.isEncrypted()) { |
||
2500 | throw new Error("Encrypted zip are not supported"); |
||
2501 | } |
||
2502 | |||
2503 | this.fileName = reader.readString(this.fileNameLength); |
||
2504 | this.readExtraFields(reader); |
||
2505 | this.parseZIP64ExtraField(reader); |
||
2506 | this.fileComment = reader.readString(this.fileCommentLength); |
||
2507 | |||
2508 | // warning, this is true only for zip with madeBy == DOS (plateform dependent feature) |
||
2509 | this.dir = this.externalFileAttributes & 0x00000010 ? true : false; |
||
2510 | }, |
||
2511 | /** |
||
2512 | * Parse the ZIP64 extra field and merge the info in the current ZipEntry. |
||
2513 | * @param {DataReader} reader the reader to use. |
||
2514 | */ |
||
2515 | parseZIP64ExtraField: function(reader) { |
||
2516 | |||
2517 | if (!this.extraFields[0x0001]) { |
||
2518 | return; |
||
2519 | } |
||
2520 | |||
2521 | // should be something, preparing the extra reader |
||
2522 | var extraReader = new StringReader(this.extraFields[0x0001].value); |
||
2523 | |||
2524 | // I really hope that these 64bits integer can fit in 32 bits integer, because js |
||
2525 | // won't let us have more. |
||
2526 | if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { |
||
2527 | this.uncompressedSize = extraReader.readInt(8); |
||
2528 | } |
||
2529 | if (this.compressedSize === utils.MAX_VALUE_32BITS) { |
||
2530 | this.compressedSize = extraReader.readInt(8); |
||
2531 | } |
||
2532 | if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { |
||
2533 | this.localHeaderOffset = extraReader.readInt(8); |
||
2534 | } |
||
2535 | if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { |
||
2536 | this.diskNumberStart = extraReader.readInt(4); |
||
2537 | } |
||
2538 | }, |
||
2539 | /** |
||
2540 | * Read the central part of a zip file and add the info in this object. |
||
2541 | * @param {DataReader} reader the reader to use. |
||
2542 | */ |
||
2543 | readExtraFields: function(reader) { |
||
2544 | var start = reader.index, |
||
2545 | extraFieldId, |
||
2546 | extraFieldLength, |
||
2547 | extraFieldValue; |
||
2548 | |||
2549 | this.extraFields = this.extraFields || {}; |
||
2550 | |||
2551 | while (reader.index < start + this.extraFieldsLength) { |
||
2552 | extraFieldId = reader.readInt(2); |
||
2553 | extraFieldLength = reader.readInt(2); |
||
2554 | extraFieldValue = reader.readString(extraFieldLength); |
||
2555 | |||
2556 | this.extraFields[extraFieldId] = { |
||
2557 | id: extraFieldId, |
||
2558 | length: extraFieldLength, |
||
2559 | value: extraFieldValue |
||
2560 | }; |
||
2561 | } |
||
2562 | }, |
||
2563 | /** |
||
2564 | * Apply an UTF8 transformation if needed. |
||
2565 | */ |
||
2566 | handleUTF8: function() { |
||
2567 | if (this.useUTF8()) { |
||
2568 | this.fileName = jszipProto.utf8decode(this.fileName); |
||
2569 | this.fileComment = jszipProto.utf8decode(this.fileComment); |
||
2570 | } else { |
||
2571 | var upath = this.findExtraFieldUnicodePath(); |
||
2572 | if (upath !== null) { |
||
2573 | this.fileName = upath; |
||
2574 | } |
||
2575 | var ucomment = this.findExtraFieldUnicodeComment(); |
||
2576 | if (ucomment !== null) { |
||
2577 | this.fileComment = ucomment; |
||
2578 | } |
||
2579 | } |
||
2580 | }, |
||
2581 | |||
2582 | /** |
||
2583 | * Find the unicode path declared in the extra field, if any. |
||
2584 | * @return {String} the unicode path, null otherwise. |
||
2585 | */ |
||
2586 | findExtraFieldUnicodePath: function() { |
||
2587 | var upathField = this.extraFields[0x7075]; |
||
2588 | if (upathField) { |
||
2589 | var extraReader = new StringReader(upathField.value); |
||
2590 | |||
2591 | // wrong version |
||
2592 | if (extraReader.readInt(1) !== 1) { |
||
2593 | return null; |
||
2594 | } |
||
2595 | |||
2596 | // the crc of the filename changed, this field is out of date. |
||
2597 | if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { |
||
2598 | return null; |
||
2599 | } |
||
2600 | |||
2601 | return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); |
||
2602 | } |
||
2603 | return null; |
||
2604 | }, |
||
2605 | |||
2606 | /** |
||
2607 | * Find the unicode comment declared in the extra field, if any. |
||
2608 | * @return {String} the unicode comment, null otherwise. |
||
2609 | */ |
||
2610 | findExtraFieldUnicodeComment: function() { |
||
2611 | var ucommentField = this.extraFields[0x6375]; |
||
2612 | if (ucommentField) { |
||
2613 | var extraReader = new StringReader(ucommentField.value); |
||
2614 | |||
2615 | // wrong version |
||
2616 | if (extraReader.readInt(1) !== 1) { |
||
2617 | return null; |
||
2618 | } |
||
2619 | |||
2620 | // the crc of the comment changed, this field is out of date. |
||
2621 | if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { |
||
2622 | return null; |
||
2623 | } |
||
2624 | |||
2625 | return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); |
||
2626 | } |
||
2627 | return null; |
||
2628 | } |
||
2629 | }; |
||
2630 | module.exports = ZipEntry; |
||
2631 | |||
2632 | },{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(_dereq_,module,exports){ |
||
2633 | // Top level file is just a mixin of submodules & constants |
||
2634 | 'use strict'; |
||
2635 | |||
2636 | var assign = _dereq_('./lib/utils/common').assign; |
||
2637 | |||
2638 | var deflate = _dereq_('./lib/deflate'); |
||
2639 | var inflate = _dereq_('./lib/inflate'); |
||
2640 | var constants = _dereq_('./lib/zlib/constants'); |
||
2641 | |||
2642 | var pako = {}; |
||
2643 | |||
2644 | assign(pako, deflate, inflate, constants); |
||
2645 | |||
2646 | module.exports = pako; |
||
2647 | },{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(_dereq_,module,exports){ |
||
2648 | 'use strict'; |
||
2649 | |||
2650 | |||
2651 | var zlib_deflate = _dereq_('./zlib/deflate.js'); |
||
2652 | var utils = _dereq_('./utils/common'); |
||
2653 | var strings = _dereq_('./utils/strings'); |
||
2654 | var msg = _dereq_('./zlib/messages'); |
||
2655 | var zstream = _dereq_('./zlib/zstream'); |
||
2656 | |||
2657 | |||
2658 | /* Public constants ==========================================================*/ |
||
2659 | /* ===========================================================================*/ |
||
2660 | |||
2661 | var Z_NO_FLUSH = 0; |
||
2662 | var Z_FINISH = 4; |
||
2663 | |||
2664 | var Z_OK = 0; |
||
2665 | var Z_STREAM_END = 1; |
||
2666 | |||
2667 | var Z_DEFAULT_COMPRESSION = -1; |
||
2668 | |||
2669 | var Z_DEFAULT_STRATEGY = 0; |
||
2670 | |||
2671 | var Z_DEFLATED = 8; |
||
2672 | |||
2673 | /* ===========================================================================*/ |
||
2674 | |||
2675 | |||
2676 | /** |
||
2677 | * class Deflate |
||
2678 | * |
||
2679 | * Generic JS-style wrapper for zlib calls. If you don't need |
||
2680 | * streaming behaviour - use more simple functions: [[deflate]], |
||
2681 | * [[deflateRaw]] and [[gzip]]. |
||
2682 | **/ |
||
2683 | |||
2684 | /* internal |
||
2685 | * Deflate.chunks -> Array |
||
2686 | * |
||
2687 | * Chunks of output data, if [[Deflate#onData]] not overriden. |
||
2688 | **/ |
||
2689 | |||
2690 | /** |
||
2691 | * Deflate.result -> Uint8Array|Array |
||
2692 | * |
||
2693 | * Compressed result, generated by default [[Deflate#onData]] |
||
2694 | * and [[Deflate#onEnd]] handlers. Filled after you push last chunk |
||
2695 | * (call [[Deflate#push]] with `Z_FINISH` / `true` param). |
||
2696 | **/ |
||
2697 | |||
2698 | /** |
||
2699 | * Deflate.err -> Number |
||
2700 | * |
||
2701 | * Error code after deflate finished. 0 (Z_OK) on success. |
||
2702 | * You will not need it in real life, because deflate errors |
||
2703 | * are possible only on wrong options or bad `onData` / `onEnd` |
||
2704 | * custom handlers. |
||
2705 | **/ |
||
2706 | |||
2707 | /** |
||
2708 | * Deflate.msg -> String |
||
2709 | * |
||
2710 | * Error message, if [[Deflate.err]] != 0 |
||
2711 | **/ |
||
2712 | |||
2713 | |||
2714 | /** |
||
2715 | * new Deflate(options) |
||
2716 | * - options (Object): zlib deflate options. |
||
2717 | * |
||
2718 | * Creates new deflator instance with specified params. Throws exception |
||
2719 | * on bad params. Supported options: |
||
2720 | * |
||
2721 | * - `level` |
||
2722 | * - `windowBits` |
||
2723 | * - `memLevel` |
||
2724 | * - `strategy` |
||
2725 | * |
||
2726 | * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) |
||
2727 | * for more information on these. |
||
2728 | * |
||
2729 | * Additional options, for internal needs: |
||
2730 | * |
||
2731 | * - `chunkSize` - size of generated data chunks (16K by default) |
||
2732 | * - `raw` (Boolean) - do raw deflate |
||
2733 | * - `gzip` (Boolean) - create gzip wrapper |
||
2734 | * - `to` (String) - if equal to 'string', then result will be "binary string" |
||
2735 | * (each char code [0..255]) |
||
2736 | * - `header` (Object) - custom header for gzip |
||
2737 | * - `text` (Boolean) - true if compressed data believed to be text |
||
2738 | * - `time` (Number) - modification time, unix timestamp |
||
2739 | * - `os` (Number) - operation system code |
||
2740 | * - `extra` (Array) - array of bytes with extra data (max 65536) |
||
2741 | * - `name` (String) - file name (binary string) |
||
2742 | * - `comment` (String) - comment (binary string) |
||
2743 | * - `hcrc` (Boolean) - true if header crc should be added |
||
2744 | * |
||
2745 | * ##### Example: |
||
2746 | * |
||
2747 | * ```javascript |
||
2748 | * var pako = require('pako') |
||
2749 | * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) |
||
2750 | * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); |
||
2751 | * |
||
2752 | * var deflate = new pako.Deflate({ level: 3}); |
||
2753 | * |
||
2754 | * deflate.push(chunk1, false); |
||
2755 | * deflate.push(chunk2, true); // true -> last chunk |
||
2756 | * |
||
2757 | * if (deflate.err) { throw new Error(deflate.err); } |
||
2758 | * |
||
2759 | * console.log(deflate.result); |
||
2760 | * ``` |
||
2761 | **/ |
||
2762 | var Deflate = function(options) { |
||
2763 | |||
2764 | this.options = utils.assign({ |
||
2765 | level: Z_DEFAULT_COMPRESSION, |
||
2766 | method: Z_DEFLATED, |
||
2767 | chunkSize: 16384, |
||
2768 | windowBits: 15, |
||
2769 | memLevel: 8, |
||
2770 | strategy: Z_DEFAULT_STRATEGY, |
||
2771 | to: '' |
||
2772 | }, options || {}); |
||
2773 | |||
2774 | var opt = this.options; |
||
2775 | |||
2776 | if (opt.raw && (opt.windowBits > 0)) { |
||
2777 | opt.windowBits = -opt.windowBits; |
||
2778 | } |
||
2779 | |||
2780 | else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { |
||
2781 | opt.windowBits += 16; |
||
2782 | } |
||
2783 | |||
2784 | this.err = 0; // error code, if happens (0 = Z_OK) |
||
2785 | this.msg = ''; // error message |
||
2786 | this.ended = false; // used to avoid multiple onEnd() calls |
||
2787 | this.chunks = []; // chunks of compressed data |
||
2788 | |||
2789 | this.strm = new zstream(); |
||
2790 | this.strm.avail_out = 0; |
||
2791 | |||
2792 | var status = zlib_deflate.deflateInit2( |
||
2793 | this.strm, |
||
2794 | opt.level, |
||
2795 | opt.method, |
||
2796 | opt.windowBits, |
||
2797 | opt.memLevel, |
||
2798 | opt.strategy |
||
2799 | ); |
||
2800 | |||
2801 | if (status !== Z_OK) { |
||
2802 | throw new Error(msg[status]); |
||
2803 | } |
||
2804 | |||
2805 | if (opt.header) { |
||
2806 | zlib_deflate.deflateSetHeader(this.strm, opt.header); |
||
2807 | } |
||
2808 | }; |
||
2809 | |||
2810 | /** |
||
2811 | * Deflate#push(data[, mode]) -> Boolean |
||
2812 | * - data (Uint8Array|Array|String): input data. Strings will be converted to |
||
2813 | * utf8 byte sequence. |
||
2814 | * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. |
||
2815 | * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. |
||
2816 | * |
||
2817 | * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with |
||
2818 | * new compressed chunks. Returns `true` on success. The last data block must have |
||
2819 | * mode Z_FINISH (or `true`). That flush internal pending buffers and call |
||
2820 | * [[Deflate#onEnd]]. |
||
2821 | * |
||
2822 | * On fail call [[Deflate#onEnd]] with error code and return false. |
||
2823 | * |
||
2824 | * We strongly recommend to use `Uint8Array` on input for best speed (output |
||
2825 | * array format is detected automatically). Also, don't skip last param and always |
||
2826 | * use the same type in your code (boolean or number). That will improve JS speed. |
||
2827 | * |
||
2828 | * For regular `Array`-s make sure all elements are [0..255]. |
||
2829 | * |
||
2830 | * ##### Example |
||
2831 | * |
||
2832 | * ```javascript |
||
2833 | * push(chunk, false); // push one of data chunks |
||
2834 | * ... |
||
2835 | * push(chunk, true); // push last chunk |
||
2836 | * ``` |
||
2837 | **/ |
||
2838 | Deflate.prototype.push = function(data, mode) { |
||
2839 | var strm = this.strm; |
||
2840 | var chunkSize = this.options.chunkSize; |
||
2841 | var status, _mode; |
||
2842 | |||
2843 | if (this.ended) { return false; } |
||
2844 | |||
2845 | _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH); |
||
2846 | |||
2847 | // Convert data if needed |
||
2848 | if (typeof data === 'string') { |
||
2849 | // If we need to compress text, change encoding to utf8. |
||
2850 | strm.input = strings.string2buf(data); |
||
2851 | } else { |
||
2852 | strm.input = data; |
||
2853 | } |
||
2854 | |||
2855 | strm.next_in = 0; |
||
2856 | strm.avail_in = strm.input.length; |
||
2857 | |||
2858 | do { |
||
2859 | if (strm.avail_out === 0) { |
||
2860 | strm.output = new utils.Buf8(chunkSize); |
||
2861 | strm.next_out = 0; |
||
2862 | strm.avail_out = chunkSize; |
||
2863 | } |
||
2864 | status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ |
||
2865 | |||
2866 | if (status !== Z_STREAM_END && status !== Z_OK) { |
||
2867 | this.onEnd(status); |
||
2868 | this.ended = true; |
||
2869 | return false; |
||
2870 | } |
||
2871 | if (strm.avail_out === 0 || (strm.avail_in === 0 && _mode === Z_FINISH)) { |
||
2872 | if (this.options.to === 'string') { |
||
2873 | this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); |
||
2874 | } else { |
||
2875 | this.onData(utils.shrinkBuf(strm.output, strm.next_out)); |
||
2876 | } |
||
2877 | } |
||
2878 | } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END); |
||
2879 | |||
2880 | // Finalize on the last chunk. |
||
2881 | if (_mode === Z_FINISH) { |
||
2882 | status = zlib_deflate.deflateEnd(this.strm); |
||
2883 | this.onEnd(status); |
||
2884 | this.ended = true; |
||
2885 | return status === Z_OK; |
||
2886 | } |
||
2887 | |||
2888 | return true; |
||
2889 | }; |
||
2890 | |||
2891 | |||
2892 | /** |
||
2893 | * Deflate#onData(chunk) -> Void |
||
2894 | * - chunk (Uint8Array|Array|String): ouput data. Type of array depends |
||
2895 | * on js engine support. When string output requested, each chunk |
||
2896 | * will be string. |
||
2897 | * |
||
2898 | * By default, stores data blocks in `chunks[]` property and glue |
||
2899 | * those in `onEnd`. Override this handler, if you need another behaviour. |
||
2900 | **/ |
||
2901 | Deflate.prototype.onData = function(chunk) { |
||
2902 | this.chunks.push(chunk); |
||
2903 | }; |
||
2904 | |||
2905 | |||
2906 | /** |
||
2907 | * Deflate#onEnd(status) -> Void |
||
2908 | * - status (Number): deflate status. 0 (Z_OK) on success, |
||
2909 | * other if not. |
||
2910 | * |
||
2911 | * Called once after you tell deflate that input stream complete |
||
2912 | * or error happenned. By default - join collected chunks, |
||
2913 | * free memory and fill `results` / `err` properties. |
||
2914 | **/ |
||
2915 | Deflate.prototype.onEnd = function(status) { |
||
2916 | // On success - join |
||
2917 | if (status === Z_OK) { |
||
2918 | if (this.options.to === 'string') { |
||
2919 | this.result = this.chunks.join(''); |
||
2920 | } else { |
||
2921 | this.result = utils.flattenChunks(this.chunks); |
||
2922 | } |
||
2923 | } |
||
2924 | this.chunks = []; |
||
2925 | this.err = status; |
||
2926 | this.msg = this.strm.msg; |
||
2927 | }; |
||
2928 | |||
2929 | |||
2930 | /** |
||
2931 | * deflate(data[, options]) -> Uint8Array|Array|String |
||
2932 | * - data (Uint8Array|Array|String): input data to compress. |
||
2933 | * - options (Object): zlib deflate options. |
||
2934 | * |
||
2935 | * Compress `data` with deflate alrorythm and `options`. |
||
2936 | * |
||
2937 | * Supported options are: |
||
2938 | * |
||
2939 | * - level |
||
2940 | * - windowBits |
||
2941 | * - memLevel |
||
2942 | * - strategy |
||
2943 | * |
||
2944 | * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) |
||
2945 | * for more information on these. |
||
2946 | * |
||
2947 | * Sugar (options): |
||
2948 | * |
||
2949 | * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify |
||
2950 | * negative windowBits implicitly. |
||
2951 | * - `to` (String) - if equal to 'string', then result will be "binary string" |
||
2952 | * (each char code [0..255]) |
||
2953 | * |
||
2954 | * ##### Example: |
||
2955 | * |
||
2956 | * ```javascript |
||
2957 | * var pako = require('pako') |
||
2958 | * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); |
||
2959 | * |
||
2960 | * console.log(pako.deflate(data)); |
||
2961 | * ``` |
||
2962 | **/ |
||
2963 | function deflate(input, options) { |
||
2964 | var deflator = new Deflate(options); |
||
2965 | |||
2966 | deflator.push(input, true); |
||
2967 | |||
2968 | // That will never happens, if you don't cheat with options :) |
||
2969 | if (deflator.err) { throw deflator.msg; } |
||
2970 | |||
2971 | return deflator.result; |
||
2972 | } |
||
2973 | |||
2974 | |||
2975 | /** |
||
2976 | * deflateRaw(data[, options]) -> Uint8Array|Array|String |
||
2977 | * - data (Uint8Array|Array|String): input data to compress. |
||
2978 | * - options (Object): zlib deflate options. |
||
2979 | * |
||
2980 | * The same as [[deflate]], but creates raw data, without wrapper |
||
2981 | * (header and adler32 crc). |
||
2982 | **/ |
||
2983 | function deflateRaw(input, options) { |
||
2984 | options = options || {}; |
||
2985 | options.raw = true; |
||
2986 | return deflate(input, options); |
||
2987 | } |
||
2988 | |||
2989 | |||
2990 | /** |
||
2991 | * gzip(data[, options]) -> Uint8Array|Array|String |
||
2992 | * - data (Uint8Array|Array|String): input data to compress. |
||
2993 | * - options (Object): zlib deflate options. |
||
2994 | * |
||
2995 | * The same as [[deflate]], but create gzip wrapper instead of |
||
2996 | * deflate one. |
||
2997 | **/ |
||
2998 | function gzip(input, options) { |
||
2999 | options = options || {}; |
||
3000 | options.gzip = true; |
||
3001 | return deflate(input, options); |
||
3002 | } |
||
3003 | |||
3004 | |||
3005 | exports.Deflate = Deflate; |
||
3006 | exports.deflate = deflate; |
||
3007 | exports.deflateRaw = deflateRaw; |
||
3008 | exports.gzip = gzip; |
||
3009 | },{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(_dereq_,module,exports){ |
||
3010 | 'use strict'; |
||
3011 | |||
3012 | |||
3013 | var zlib_inflate = _dereq_('./zlib/inflate.js'); |
||
3014 | var utils = _dereq_('./utils/common'); |
||
3015 | var strings = _dereq_('./utils/strings'); |
||
3016 | var c = _dereq_('./zlib/constants'); |
||
3017 | var msg = _dereq_('./zlib/messages'); |
||
3018 | var zstream = _dereq_('./zlib/zstream'); |
||
3019 | var gzheader = _dereq_('./zlib/gzheader'); |
||
3020 | |||
3021 | |||
3022 | /** |
||
3023 | * class Inflate |
||
3024 | * |
||
3025 | * Generic JS-style wrapper for zlib calls. If you don't need |
||
3026 | * streaming behaviour - use more simple functions: [[inflate]] |
||
3027 | * and [[inflateRaw]]. |
||
3028 | **/ |
||
3029 | |||
3030 | /* internal |
||
3031 | * inflate.chunks -> Array |
||
3032 | * |
||
3033 | * Chunks of output data, if [[Inflate#onData]] not overriden. |
||
3034 | **/ |
||
3035 | |||
3036 | /** |
||
3037 | * Inflate.result -> Uint8Array|Array|String |
||
3038 | * |
||
3039 | * Uncompressed result, generated by default [[Inflate#onData]] |
||
3040 | * and [[Inflate#onEnd]] handlers. Filled after you push last chunk |
||
3041 | * (call [[Inflate#push]] with `Z_FINISH` / `true` param). |
||
3042 | **/ |
||
3043 | |||
3044 | /** |
||
3045 | * Inflate.err -> Number |
||
3046 | * |
||
3047 | * Error code after inflate finished. 0 (Z_OK) on success. |
||
3048 | * Should be checked if broken data possible. |
||
3049 | **/ |
||
3050 | |||
3051 | /** |
||
3052 | * Inflate.msg -> String |
||
3053 | * |
||
3054 | * Error message, if [[Inflate.err]] != 0 |
||
3055 | **/ |
||
3056 | |||
3057 | |||
3058 | /** |
||
3059 | * new Inflate(options) |
||
3060 | * - options (Object): zlib inflate options. |
||
3061 | * |
||
3062 | * Creates new inflator instance with specified params. Throws exception |
||
3063 | * on bad params. Supported options: |
||
3064 | * |
||
3065 | * - `windowBits` |
||
3066 | * |
||
3067 | * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) |
||
3068 | * for more information on these. |
||
3069 | * |
||
3070 | * Additional options, for internal needs: |
||
3071 | * |
||
3072 | * - `chunkSize` - size of generated data chunks (16K by default) |
||
3073 | * - `raw` (Boolean) - do raw inflate |
||
3074 | * - `to` (String) - if equal to 'string', then result will be converted |
||
3075 | * from utf8 to utf16 (javascript) string. When string output requested, |
||
3076 | * chunk length can differ from `chunkSize`, depending on content. |
||
3077 | * |
||
3078 | * By default, when no options set, autodetect deflate/gzip data format via |
||
3079 | * wrapper header. |
||
3080 | * |
||
3081 | * ##### Example: |
||
3082 | * |
||
3083 | * ```javascript |
||
3084 | * var pako = require('pako') |
||
3085 | * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) |
||
3086 | * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); |
||
3087 | * |
||
3088 | * var inflate = new pako.Inflate({ level: 3}); |
||
3089 | * |
||
3090 | * inflate.push(chunk1, false); |
||
3091 | * inflate.push(chunk2, true); // true -> last chunk |
||
3092 | * |
||
3093 | * if (inflate.err) { throw new Error(inflate.err); } |
||
3094 | * |
||
3095 | * console.log(inflate.result); |
||
3096 | * ``` |
||
3097 | **/ |
||
3098 | var Inflate = function(options) { |
||
3099 | |||
3100 | this.options = utils.assign({ |
||
3101 | chunkSize: 16384, |
||
3102 | windowBits: 0, |
||
3103 | to: '' |
||
3104 | }, options || {}); |
||
3105 | |||
3106 | var opt = this.options; |
||
3107 | |||
3108 | // Force window size for `raw` data, if not set directly, |
||
3109 | // because we have no header for autodetect. |
||
3110 | if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { |
||
3111 | opt.windowBits = -opt.windowBits; |
||
3112 | if (opt.windowBits === 0) { opt.windowBits = -15; } |
||
3113 | } |
||
3114 | |||
3115 | // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate |
||
3116 | if ((opt.windowBits >= 0) && (opt.windowBits < 16) && |
||
3117 | !(options && options.windowBits)) { |
||
3118 | opt.windowBits += 32; |
||
3119 | } |
||
3120 | |||
3121 | // Gzip header has no info about windows size, we can do autodetect only |
||
3122 | // for deflate. So, if window size not set, force it to max when gzip possible |
||
3123 | if ((opt.windowBits > 15) && (opt.windowBits < 48)) { |
||
3124 | // bit 3 (16) -> gzipped data |
||
3125 | // bit 4 (32) -> autodetect gzip/deflate |
||
3126 | if ((opt.windowBits & 15) === 0) { |
||
3127 | opt.windowBits |= 15; |
||
3128 | } |
||
3129 | } |
||
3130 | |||
3131 | this.err = 0; // error code, if happens (0 = Z_OK) |
||
3132 | this.msg = ''; // error message |
||
3133 | this.ended = false; // used to avoid multiple onEnd() calls |
||
3134 | this.chunks = []; // chunks of compressed data |
||
3135 | |||
3136 | this.strm = new zstream(); |
||
3137 | this.strm.avail_out = 0; |
||
3138 | |||
3139 | var status = zlib_inflate.inflateInit2( |
||
3140 | this.strm, |
||
3141 | opt.windowBits |
||
3142 | ); |
||
3143 | |||
3144 | if (status !== c.Z_OK) { |
||
3145 | throw new Error(msg[status]); |
||
3146 | } |
||
3147 | |||
3148 | this.header = new gzheader(); |
||
3149 | |||
3150 | zlib_inflate.inflateGetHeader(this.strm, this.header); |
||
3151 | }; |
||
3152 | |||
3153 | /** |
||
3154 | * Inflate#push(data[, mode]) -> Boolean |
||
3155 | * - data (Uint8Array|Array|String): input data |
||
3156 | * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. |
||
3157 | * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. |
||
3158 | * |
||
3159 | * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with |
||
3160 | * new output chunks. Returns `true` on success. The last data block must have |
||
3161 | * mode Z_FINISH (or `true`). That flush internal pending buffers and call |
||
3162 | * [[Inflate#onEnd]]. |
||
3163 | * |
||
3164 | * On fail call [[Inflate#onEnd]] with error code and return false. |
||
3165 | * |
||
3166 | * We strongly recommend to use `Uint8Array` on input for best speed (output |
||
3167 | * format is detected automatically). Also, don't skip last param and always |
||
3168 | * use the same type in your code (boolean or number). That will improve JS speed. |
||
3169 | * |
||
3170 | * For regular `Array`-s make sure all elements are [0..255]. |
||
3171 | * |
||
3172 | * ##### Example |
||
3173 | * |
||
3174 | * ```javascript |
||
3175 | * push(chunk, false); // push one of data chunks |
||
3176 | * ... |
||
3177 | * push(chunk, true); // push last chunk |
||
3178 | * ``` |
||
3179 | **/ |
||
3180 | Inflate.prototype.push = function(data, mode) { |
||
3181 | var strm = this.strm; |
||
3182 | var chunkSize = this.options.chunkSize; |
||
3183 | var status, _mode; |
||
3184 | var next_out_utf8, tail, utf8str; |
||
3185 | |||
3186 | if (this.ended) { return false; } |
||
3187 | _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH); |
||
3188 | |||
3189 | // Convert data if needed |
||
3190 | if (typeof data === 'string') { |
||
3191 | // Only binary strings can be decompressed on practice |
||
3192 | strm.input = strings.binstring2buf(data); |
||
3193 | } else { |
||
3194 | strm.input = data; |
||
3195 | } |
||
3196 | |||
3197 | strm.next_in = 0; |
||
3198 | strm.avail_in = strm.input.length; |
||
3199 | |||
3200 | do { |
||
3201 | if (strm.avail_out === 0) { |
||
3202 | strm.output = new utils.Buf8(chunkSize); |
||
3203 | strm.next_out = 0; |
||
3204 | strm.avail_out = chunkSize; |
||
3205 | } |
||
3206 | |||
3207 | status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ |
||
3208 | |||
3209 | if (status !== c.Z_STREAM_END && status !== c.Z_OK) { |
||
3210 | this.onEnd(status); |
||
3211 | this.ended = true; |
||
3212 | return false; |
||
3213 | } |
||
3214 | |||
3215 | if (strm.next_out) { |
||
3216 | if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && _mode === c.Z_FINISH)) { |
||
3217 | |||
3218 | if (this.options.to === 'string') { |
||
3219 | |||
3220 | next_out_utf8 = strings.utf8border(strm.output, strm.next_out); |
||
3221 | |||
3222 | tail = strm.next_out - next_out_utf8; |
||
3223 | utf8str = strings.buf2string(strm.output, next_out_utf8); |
||
3224 | |||
3225 | // move tail |
||
3226 | strm.next_out = tail; |
||
3227 | strm.avail_out = chunkSize - tail; |
||
3228 | if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } |
||
3229 | |||
3230 | this.onData(utf8str); |
||
3231 | |||
3232 | } else { |
||
3233 | this.onData(utils.shrinkBuf(strm.output, strm.next_out)); |
||
3234 | } |
||
3235 | } |
||
3236 | } |
||
3237 | } while ((strm.avail_in > 0) && status !== c.Z_STREAM_END); |
||
3238 | |||
3239 | if (status === c.Z_STREAM_END) { |
||
3240 | _mode = c.Z_FINISH; |
||
3241 | } |
||
3242 | // Finalize on the last chunk. |
||
3243 | if (_mode === c.Z_FINISH) { |
||
3244 | status = zlib_inflate.inflateEnd(this.strm); |
||
3245 | this.onEnd(status); |
||
3246 | this.ended = true; |
||
3247 | return status === c.Z_OK; |
||
3248 | } |
||
3249 | |||
3250 | return true; |
||
3251 | }; |
||
3252 | |||
3253 | |||
3254 | /** |
||
3255 | * Inflate#onData(chunk) -> Void |
||
3256 | * - chunk (Uint8Array|Array|String): ouput data. Type of array depends |
||
3257 | * on js engine support. When string output requested, each chunk |
||
3258 | * will be string. |
||
3259 | * |
||
3260 | * By default, stores data blocks in `chunks[]` property and glue |
||
3261 | * those in `onEnd`. Override this handler, if you need another behaviour. |
||
3262 | **/ |
||
3263 | Inflate.prototype.onData = function(chunk) { |
||
3264 | this.chunks.push(chunk); |
||
3265 | }; |
||
3266 | |||
3267 | |||
3268 | /** |
||
3269 | * Inflate#onEnd(status) -> Void |
||
3270 | * - status (Number): inflate status. 0 (Z_OK) on success, |
||
3271 | * other if not. |
||
3272 | * |
||
3273 | * Called once after you tell inflate that input stream complete |
||
3274 | * or error happenned. By default - join collected chunks, |
||
3275 | * free memory and fill `results` / `err` properties. |
||
3276 | **/ |
||
3277 | Inflate.prototype.onEnd = function(status) { |
||
3278 | // On success - join |
||
3279 | if (status === c.Z_OK) { |
||
3280 | if (this.options.to === 'string') { |
||
3281 | // Glue & convert here, until we teach pako to send |
||
3282 | // utf8 alligned strings to onData |
||
3283 | this.result = this.chunks.join(''); |
||
3284 | } else { |
||
3285 | this.result = utils.flattenChunks(this.chunks); |
||
3286 | } |
||
3287 | } |
||
3288 | this.chunks = []; |
||
3289 | this.err = status; |
||
3290 | this.msg = this.strm.msg; |
||
3291 | }; |
||
3292 | |||
3293 | |||
3294 | /** |
||
3295 | * inflate(data[, options]) -> Uint8Array|Array|String |
||
3296 | * - data (Uint8Array|Array|String): input data to decompress. |
||
3297 | * - options (Object): zlib inflate options. |
||
3298 | * |
||
3299 | * Decompress `data` with inflate/ungzip and `options`. Autodetect |
||
3300 | * format via wrapper header by default. That's why we don't provide |
||
3301 | * separate `ungzip` method. |
||
3302 | * |
||
3303 | * Supported options are: |
||
3304 | * |
||
3305 | * - windowBits |
||
3306 | * |
||
3307 | * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) |
||
3308 | * for more information. |
||
3309 | * |
||
3310 | * Sugar (options): |
||
3311 | * |
||
3312 | * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify |
||
3313 | * negative windowBits implicitly. |
||
3314 | * - `to` (String) - if equal to 'string', then result will be converted |
||
3315 | * from utf8 to utf16 (javascript) string. When string output requested, |
||
3316 | * chunk length can differ from `chunkSize`, depending on content. |
||
3317 | * |
||
3318 | * |
||
3319 | * ##### Example: |
||
3320 | * |
||
3321 | * ```javascript |
||
3322 | * var pako = require('pako') |
||
3323 | * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) |
||
3324 | * , output; |
||
3325 | * |
||
3326 | * try { |
||
3327 | * output = pako.inflate(input); |
||
3328 | * } catch (err) |
||
3329 | * console.log(err); |
||
3330 | * } |
||
3331 | * ``` |
||
3332 | **/ |
||
3333 | function inflate(input, options) { |
||
3334 | var inflator = new Inflate(options); |
||
3335 | |||
3336 | inflator.push(input, true); |
||
3337 | |||
3338 | // That will never happens, if you don't cheat with options :) |
||
3339 | if (inflator.err) { throw inflator.msg; } |
||
3340 | |||
3341 | return inflator.result; |
||
3342 | } |
||
3343 | |||
3344 | |||
3345 | /** |
||
3346 | * inflateRaw(data[, options]) -> Uint8Array|Array|String |
||
3347 | * - data (Uint8Array|Array|String): input data to decompress. |
||
3348 | * - options (Object): zlib inflate options. |
||
3349 | * |
||
3350 | * The same as [[inflate]], but creates raw data, without wrapper |
||
3351 | * (header and adler32 crc). |
||
3352 | **/ |
||
3353 | function inflateRaw(input, options) { |
||
3354 | options = options || {}; |
||
3355 | options.raw = true; |
||
3356 | return inflate(input, options); |
||
3357 | } |
||
3358 | |||
3359 | |||
3360 | /** |
||
3361 | * ungzip(data[, options]) -> Uint8Array|Array|String |
||
3362 | * - data (Uint8Array|Array|String): input data to decompress. |
||
3363 | * - options (Object): zlib inflate options. |
||
3364 | * |
||
3365 | * Just shortcut to [[inflate]], because it autodetects format |
||
3366 | * by header.content. Done for convenience. |
||
3367 | **/ |
||
3368 | |||
3369 | |||
3370 | exports.Inflate = Inflate; |
||
3371 | exports.inflate = inflate; |
||
3372 | exports.inflateRaw = inflateRaw; |
||
3373 | exports.ungzip = inflate; |
||
3374 | |||
3375 | },{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(_dereq_,module,exports){ |
||
3376 | 'use strict'; |
||
3377 | |||
3378 | |||
3379 | var TYPED_OK = (typeof Uint8Array !== 'undefined') && |
||
3380 | (typeof Uint16Array !== 'undefined') && |
||
3381 | (typeof Int32Array !== 'undefined'); |
||
3382 | |||
3383 | |||
3384 | exports.assign = function (obj /*from1, from2, from3, ...*/) { |
||
3385 | var sources = Array.prototype.slice.call(arguments, 1); |
||
3386 | while (sources.length) { |
||
3387 | var source = sources.shift(); |
||
3388 | if (!source) { continue; } |
||
3389 | |||
3390 | if (typeof(source) !== 'object') { |
||
3391 | throw new TypeError(source + 'must be non-object'); |
||
3392 | } |
||
3393 | |||
3394 | for (var p in source) { |
||
3395 | if (source.hasOwnProperty(p)) { |
||
3396 | obj[p] = source[p]; |
||
3397 | } |
||
3398 | } |
||
3399 | } |
||
3400 | |||
3401 | return obj; |
||
3402 | }; |
||
3403 | |||
3404 | |||
3405 | // reduce buffer size, avoiding mem copy |
||
3406 | exports.shrinkBuf = function (buf, size) { |
||
3407 | if (buf.length === size) { return buf; } |
||
3408 | if (buf.subarray) { return buf.subarray(0, size); } |
||
3409 | buf.length = size; |
||
3410 | return buf; |
||
3411 | }; |
||
3412 | |||
3413 | |||
3414 | var fnTyped = { |
||
3415 | arraySet: function (dest, src, src_offs, len, dest_offs) { |
||
3416 | if (src.subarray && dest.subarray) { |
||
3417 | dest.set(src.subarray(src_offs, src_offs+len), dest_offs); |
||
3418 | return; |
||
3419 | } |
||
3420 | // Fallback to ordinary array |
||
3421 | for(var i=0; i<len; i++) { |
||
3422 | dest[dest_offs + i] = src[src_offs + i]; |
||
3423 | } |
||
3424 | }, |
||
3425 | // Join array of chunks to single array. |
||
3426 | flattenChunks: function(chunks) { |
||
3427 | var i, l, len, pos, chunk, result; |
||
3428 | |||
3429 | // calculate data length |
||
3430 | len = 0; |
||
3431 | for (i=0, l=chunks.length; i<l; i++) { |
||
3432 | len += chunks[i].length; |
||
3433 | } |
||
3434 | |||
3435 | // join chunks |
||
3436 | result = new Uint8Array(len); |
||
3437 | pos = 0; |
||
3438 | for (i=0, l=chunks.length; i<l; i++) { |
||
3439 | chunk = chunks[i]; |
||
3440 | result.set(chunk, pos); |
||
3441 | pos += chunk.length; |
||
3442 | } |
||
3443 | |||
3444 | return result; |
||
3445 | } |
||
3446 | }; |
||
3447 | |||
3448 | var fnUntyped = { |
||
3449 | arraySet: function (dest, src, src_offs, len, dest_offs) { |
||
3450 | for(var i=0; i<len; i++) { |
||
3451 | dest[dest_offs + i] = src[src_offs + i]; |
||
3452 | } |
||
3453 | }, |
||
3454 | // Join array of chunks to single array. |
||
3455 | flattenChunks: function(chunks) { |
||
3456 | return [].concat.apply([], chunks); |
||
3457 | } |
||
3458 | }; |
||
3459 | |||
3460 | |||
3461 | // Enable/Disable typed arrays use, for testing |
||
3462 | // |
||
3463 | exports.setTyped = function (on) { |
||
3464 | if (on) { |
||
3465 | exports.Buf8 = Uint8Array; |
||
3466 | exports.Buf16 = Uint16Array; |
||
3467 | exports.Buf32 = Int32Array; |
||
3468 | exports.assign(exports, fnTyped); |
||
3469 | } else { |
||
3470 | exports.Buf8 = Array; |
||
3471 | exports.Buf16 = Array; |
||
3472 | exports.Buf32 = Array; |
||
3473 | exports.assign(exports, fnUntyped); |
||
3474 | } |
||
3475 | }; |
||
3476 | |||
3477 | exports.setTyped(TYPED_OK); |
||
3478 | },{}],28:[function(_dereq_,module,exports){ |
||
3479 | // String encode/decode helpers |
||
3480 | 'use strict'; |
||
3481 | |||
3482 | |||
3483 | var utils = _dereq_('./common'); |
||
3484 | |||
3485 | |||
3486 | // Quick check if we can use fast array to bin string conversion |
||
3487 | // |
||
3488 | // - apply(Array) can fail on Android 2.2 |
||
3489 | // - apply(Uint8Array) can fail on iOS 5.1 Safary |
||
3490 | // |
||
3491 | var STR_APPLY_OK = true; |
||
3492 | var STR_APPLY_UIA_OK = true; |
||
3493 | |||
3494 | try { String.fromCharCode.apply(null, [0]); } catch(__) { STR_APPLY_OK = false; } |
||
3495 | try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch(__) { STR_APPLY_UIA_OK = false; } |
||
3496 | |||
3497 | |||
3498 | // Table with utf8 lengths (calculated by first byte of sequence) |
||
3499 | // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, |
||
3500 | // because max possible codepoint is 0x10ffff |
||
3501 | var _utf8len = new utils.Buf8(256); |
||
3502 | for (var i=0; i<256; i++) { |
||
3503 | _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); |
||
3504 | } |
||
3505 | _utf8len[254]=_utf8len[254]=1; // Invalid sequence start |
||
3506 | |||
3507 | |||
3508 | // convert string to array (typed, when possible) |
||
3509 | exports.string2buf = function (str) { |
||
3510 | var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; |
||
3511 | |||
3512 | // count binary size |
||
3513 | View Code Duplication | for (m_pos = 0; m_pos < str_len; m_pos++) { |
|
3514 | c = str.charCodeAt(m_pos); |
||
3515 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { |
||
3516 | c2 = str.charCodeAt(m_pos+1); |
||
3517 | if ((c2 & 0xfc00) === 0xdc00) { |
||
3518 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
||
3519 | m_pos++; |
||
3520 | } |
||
3521 | } |
||
3522 | buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; |
||
3523 | } |
||
3524 | |||
3525 | // allocate buffer |
||
3526 | buf = new utils.Buf8(buf_len); |
||
3527 | |||
3528 | // convert |
||
3529 | View Code Duplication | for (i=0, m_pos = 0; i < buf_len; m_pos++) { |
|
3530 | c = str.charCodeAt(m_pos); |
||
3531 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { |
||
3532 | c2 = str.charCodeAt(m_pos+1); |
||
3533 | if ((c2 & 0xfc00) === 0xdc00) { |
||
3534 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
||
3535 | m_pos++; |
||
3536 | } |
||
3537 | } |
||
3538 | if (c < 0x80) { |
||
3539 | /* one byte */ |
||
3540 | buf[i++] = c; |
||
3541 | } else if (c < 0x800) { |
||
3542 | /* two bytes */ |
||
3543 | buf[i++] = 0xC0 | (c >>> 6); |
||
3544 | buf[i++] = 0x80 | (c & 0x3f); |
||
3545 | } else if (c < 0x10000) { |
||
3546 | /* three bytes */ |
||
3547 | buf[i++] = 0xE0 | (c >>> 12); |
||
3548 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); |
||
3549 | buf[i++] = 0x80 | (c & 0x3f); |
||
3550 | } else { |
||
3551 | /* four bytes */ |
||
3552 | buf[i++] = 0xf0 | (c >>> 18); |
||
3553 | buf[i++] = 0x80 | (c >>> 12 & 0x3f); |
||
3554 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); |
||
3555 | buf[i++] = 0x80 | (c & 0x3f); |
||
3556 | } |
||
3557 | } |
||
3558 | |||
3559 | return buf; |
||
3560 | }; |
||
3561 | |||
3562 | // Helper (used in 2 places) |
||
3563 | function buf2binstring(buf, len) { |
||
3564 | // use fallback for big arrays to avoid stack overflow |
||
3565 | if (len < 65537) { |
||
3566 | if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { |
||
3567 | return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); |
||
3568 | } |
||
3569 | } |
||
3570 | |||
3571 | var result = ''; |
||
3572 | for(var i=0; i < len; i++) { |
||
3573 | result += String.fromCharCode(buf[i]); |
||
3574 | } |
||
3575 | return result; |
||
3576 | } |
||
3577 | |||
3578 | |||
3579 | // Convert byte array to binary string |
||
3580 | exports.buf2binstring = function(buf) { |
||
3581 | return buf2binstring(buf, buf.length); |
||
3582 | }; |
||
3583 | |||
3584 | |||
3585 | // Convert binary string (typed, when possible) |
||
3586 | exports.binstring2buf = function(str) { |
||
3587 | var buf = new utils.Buf8(str.length); |
||
3588 | for(var i=0, len=buf.length; i < len; i++) { |
||
3589 | buf[i] = str.charCodeAt(i); |
||
3590 | } |
||
3591 | return buf; |
||
3592 | }; |
||
3593 | |||
3594 | |||
3595 | // convert array to string |
||
3596 | exports.buf2string = function (buf, max) { |
||
3597 | var i, out, c, c_len; |
||
3598 | var len = max || buf.length; |
||
3599 | |||
3600 | // Reserve max possible length (2 words per char) |
||
3601 | // NB: by unknown reasons, Array is significantly faster for |
||
3602 | // String.fromCharCode.apply than Uint16Array. |
||
3603 | var utf16buf = new Array(len*2); |
||
3604 | |||
3605 | View Code Duplication | for (out=0, i=0; i<len;) { |
|
3606 | c = buf[i++]; |
||
3607 | // quick process ascii |
||
3608 | if (c < 0x80) { utf16buf[out++] = c; continue; } |
||
3609 | |||
3610 | c_len = _utf8len[c]; |
||
3611 | // skip 5 & 6 byte codes |
||
3612 | if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } |
||
3613 | |||
3614 | // apply mask on first byte |
||
3615 | c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; |
||
3616 | // join the rest |
||
3617 | while (c_len > 1 && i < len) { |
||
3618 | c = (c << 6) | (buf[i++] & 0x3f); |
||
3619 | c_len--; |
||
3620 | } |
||
3621 | |||
3622 | // terminated by end of string? |
||
3623 | if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } |
||
3624 | |||
3625 | if (c < 0x10000) { |
||
3626 | utf16buf[out++] = c; |
||
3627 | } else { |
||
3628 | c -= 0x10000; |
||
3629 | utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); |
||
3630 | utf16buf[out++] = 0xdc00 | (c & 0x3ff); |
||
3631 | } |
||
3632 | } |
||
3633 | |||
3634 | return buf2binstring(utf16buf, out); |
||
3635 | }; |
||
3636 | |||
3637 | |||
3638 | // Calculate max possible position in utf8 buffer, |
||
3639 | // that will not break sequence. If that's not possible |
||
3640 | // - (very small limits) return max size as is. |
||
3641 | // |
||
3642 | // buf[] - utf8 bytes array |
||
3643 | // max - length limit (mandatory); |
||
3644 | View Code Duplication | exports.utf8border = function(buf, max) { |
|
3645 | var pos; |
||
3646 | |||
3647 | max = max || buf.length; |
||
3648 | if (max > buf.length) { max = buf.length; } |
||
3649 | |||
3650 | // go back from last position, until start of sequence found |
||
3651 | pos = max-1; |
||
3652 | while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } |
||
3653 | |||
3654 | // Fuckup - very small and broken sequence, |
||
3655 | // return max, because we should return something anyway. |
||
3656 | if (pos < 0) { return max; } |
||
3657 | |||
3658 | // If we came to start of buffer - that means vuffer is too small, |
||
3659 | // return max too. |
||
3660 | if (pos === 0) { return max; } |
||
3661 | |||
3662 | return (pos + _utf8len[buf[pos]] > max) ? pos : max; |
||
3663 | }; |
||
3664 | |||
3665 | },{"./common":27}],29:[function(_dereq_,module,exports){ |
||
3666 | 'use strict'; |
||
3667 | |||
3668 | // Note: adler32 takes 12% for level 0 and 2% for level 6. |
||
3669 | // It doesn't worth to make additional optimizationa as in original. |
||
3670 | // Small size is preferable. |
||
3671 | |||
3672 | function adler32(adler, buf, len, pos) { |
||
3673 | var s1 = (adler & 0xffff) |0 |
||
3674 | , s2 = ((adler >>> 16) & 0xffff) |0 |
||
3675 | , n = 0; |
||
3676 | |||
3677 | while (len !== 0) { |
||
3678 | // Set limit ~ twice less than 5552, to keep |
||
3679 | // s2 in 31-bits, because we force signed ints. |
||
3680 | // in other case %= will fail. |
||
3681 | n = len > 2000 ? 2000 : len; |
||
3682 | len -= n; |
||
3683 | |||
3684 | do { |
||
3685 | s1 = (s1 + buf[pos++]) |0; |
||
3686 | s2 = (s2 + s1) |0; |
||
3687 | } while (--n); |
||
3688 | |||
3689 | s1 %= 65521; |
||
3690 | s2 %= 65521; |
||
3691 | } |
||
3692 | |||
3693 | return (s1 | (s2 << 16)) |0; |
||
3694 | } |
||
3695 | |||
3696 | |||
3697 | module.exports = adler32; |
||
3698 | },{}],30:[function(_dereq_,module,exports){ |
||
3699 | module.exports = { |
||
3700 | |||
3701 | /* Allowed flush values; see deflate() and inflate() below for details */ |
||
3702 | Z_NO_FLUSH: 0, |
||
3703 | Z_PARTIAL_FLUSH: 1, |
||
3704 | Z_SYNC_FLUSH: 2, |
||
3705 | Z_FULL_FLUSH: 3, |
||
3706 | Z_FINISH: 4, |
||
3707 | Z_BLOCK: 5, |
||
3708 | Z_TREES: 6, |
||
3709 | |||
3710 | /* Return codes for the compression/decompression functions. Negative values |
||
3711 | * are errors, positive values are used for special but normal events. |
||
3712 | */ |
||
3713 | Z_OK: 0, |
||
3714 | Z_STREAM_END: 1, |
||
3715 | Z_NEED_DICT: 2, |
||
3716 | Z_ERRNO: -1, |
||
3717 | Z_STREAM_ERROR: -2, |
||
3718 | Z_DATA_ERROR: -3, |
||
3719 | //Z_MEM_ERROR: -4, |
||
3720 | Z_BUF_ERROR: -5, |
||
3721 | //Z_VERSION_ERROR: -6, |
||
3722 | |||
3723 | /* compression levels */ |
||
3724 | Z_NO_COMPRESSION: 0, |
||
3725 | Z_BEST_SPEED: 1, |
||
3726 | Z_BEST_COMPRESSION: 9, |
||
3727 | Z_DEFAULT_COMPRESSION: -1, |
||
3728 | |||
3729 | |||
3730 | Z_FILTERED: 1, |
||
3731 | Z_HUFFMAN_ONLY: 2, |
||
3732 | Z_RLE: 3, |
||
3733 | Z_FIXED: 4, |
||
3734 | Z_DEFAULT_STRATEGY: 0, |
||
3735 | |||
3736 | /* Possible values of the data_type field (though see inflate()) */ |
||
3737 | Z_BINARY: 0, |
||
3738 | Z_TEXT: 1, |
||
3739 | //Z_ASCII: 1, // = Z_TEXT (deprecated) |
||
3740 | Z_UNKNOWN: 2, |
||
3741 | |||
3742 | /* The deflate compression method */ |
||
3743 | Z_DEFLATED: 8 |
||
3744 | //Z_NULL: null // Use -1 or null inline, depending on var type |
||
3745 | }; |
||
3746 | },{}],31:[function(_dereq_,module,exports){ |
||
3747 | 'use strict'; |
||
3748 | |||
3749 | // Note: we can't get significant speed boost here. |
||
3750 | // So write code to minimize size - no pregenerated tables |
||
3751 | // and array tools dependencies. |
||
3752 | |||
3753 | |||
3754 | // Use ordinary array, since untyped makes no boost here |
||
3755 | function makeTable() { |
||
3756 | var c, table = []; |
||
3757 | |||
3758 | for(var n =0; n < 256; n++){ |
||
3759 | c = n; |
||
3760 | for(var k =0; k < 8; k++){ |
||
3761 | c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); |
||
3762 | } |
||
3763 | table[n] = c; |
||
3764 | } |
||
3765 | |||
3766 | return table; |
||
3767 | } |
||
3768 | |||
3769 | // Create table on load. Just 255 signed longs. Not a problem. |
||
3770 | var crcTable = makeTable(); |
||
3771 | |||
3772 | |||
3773 | function crc32(crc, buf, len, pos) { |
||
3774 | var t = crcTable |
||
3775 | , end = pos + len; |
||
3776 | |||
3777 | crc = crc ^ (-1); |
||
3778 | |||
3779 | for (var i = pos; i < end; i++ ) { |
||
3780 | crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; |
||
3781 | } |
||
3782 | |||
3783 | return (crc ^ (-1)); // >>> 0; |
||
3784 | } |
||
3785 | |||
3786 | |||
3787 | module.exports = crc32; |
||
3788 | },{}],32:[function(_dereq_,module,exports){ |
||
3789 | 'use strict'; |
||
3790 | |||
3791 | var utils = _dereq_('../utils/common'); |
||
3792 | var trees = _dereq_('./trees'); |
||
3793 | var adler32 = _dereq_('./adler32'); |
||
3794 | var crc32 = _dereq_('./crc32'); |
||
3795 | var msg = _dereq_('./messages'); |
||
3796 | |||
3797 | /* Public constants ==========================================================*/ |
||
3798 | /* ===========================================================================*/ |
||
3799 | |||
3800 | |||
3801 | /* Allowed flush values; see deflate() and inflate() below for details */ |
||
3802 | var Z_NO_FLUSH = 0; |
||
3803 | var Z_PARTIAL_FLUSH = 1; |
||
3804 | //var Z_SYNC_FLUSH = 2; |
||
3805 | var Z_FULL_FLUSH = 3; |
||
3806 | var Z_FINISH = 4; |
||
3807 | var Z_BLOCK = 5; |
||
3808 | //var Z_TREES = 6; |
||
3809 | |||
3810 | |||
3811 | /* Return codes for the compression/decompression functions. Negative values |
||
3812 | * are errors, positive values are used for special but normal events. |
||
3813 | */ |
||
3814 | var Z_OK = 0; |
||
3815 | var Z_STREAM_END = 1; |
||
3816 | //var Z_NEED_DICT = 2; |
||
3817 | //var Z_ERRNO = -1; |
||
3818 | var Z_STREAM_ERROR = -2; |
||
3819 | var Z_DATA_ERROR = -3; |
||
3820 | //var Z_MEM_ERROR = -4; |
||
3821 | var Z_BUF_ERROR = -5; |
||
3822 | //var Z_VERSION_ERROR = -6; |
||
3823 | |||
3824 | |||
3825 | /* compression levels */ |
||
3826 | //var Z_NO_COMPRESSION = 0; |
||
3827 | //var Z_BEST_SPEED = 1; |
||
3828 | //var Z_BEST_COMPRESSION = 9; |
||
3829 | var Z_DEFAULT_COMPRESSION = -1; |
||
3830 | |||
3831 | |||
3832 | var Z_FILTERED = 1; |
||
3833 | var Z_HUFFMAN_ONLY = 2; |
||
3834 | var Z_RLE = 3; |
||
3835 | var Z_FIXED = 4; |
||
3836 | var Z_DEFAULT_STRATEGY = 0; |
||
3837 | |||
3838 | /* Possible values of the data_type field (though see inflate()) */ |
||
3839 | //var Z_BINARY = 0; |
||
3840 | //var Z_TEXT = 1; |
||
3841 | //var Z_ASCII = 1; // = Z_TEXT |
||
3842 | var Z_UNKNOWN = 2; |
||
3843 | |||
3844 | |||
3845 | /* The deflate compression method */ |
||
3846 | var Z_DEFLATED = 8; |
||
3847 | |||
3848 | /*============================================================================*/ |
||
3849 | |||
3850 | |||
3851 | var MAX_MEM_LEVEL = 9; |
||
3852 | /* Maximum value for memLevel in deflateInit2 */ |
||
3853 | var MAX_WBITS = 15; |
||
3854 | /* 32K LZ77 window */ |
||
3855 | var DEF_MEM_LEVEL = 8; |
||
3856 | |||
3857 | |||
3858 | var LENGTH_CODES = 29; |
||
3859 | /* number of length codes, not counting the special END_BLOCK code */ |
||
3860 | var LITERALS = 256; |
||
3861 | /* number of literal bytes 0..255 */ |
||
3862 | var L_CODES = LITERALS + 1 + LENGTH_CODES; |
||
3863 | /* number of Literal or Length codes, including the END_BLOCK code */ |
||
3864 | var D_CODES = 30; |
||
3865 | /* number of distance codes */ |
||
3866 | var BL_CODES = 19; |
||
3867 | /* number of codes used to transfer the bit lengths */ |
||
3868 | var HEAP_SIZE = 2*L_CODES + 1; |
||
3869 | /* maximum heap size */ |
||
3870 | var MAX_BITS = 15; |
||
3871 | /* All codes must not exceed MAX_BITS bits */ |
||
3872 | |||
3873 | var MIN_MATCH = 3; |
||
3874 | var MAX_MATCH = 258; |
||
3875 | var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); |
||
3876 | |||
3877 | var PRESET_DICT = 0x20; |
||
3878 | |||
3879 | var INIT_STATE = 42; |
||
3880 | var EXTRA_STATE = 69; |
||
3881 | var NAME_STATE = 73; |
||
3882 | var COMMENT_STATE = 91; |
||
3883 | var HCRC_STATE = 103; |
||
3884 | var BUSY_STATE = 113; |
||
3885 | var FINISH_STATE = 666; |
||
3886 | |||
3887 | var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ |
||
3888 | var BS_BLOCK_DONE = 2; /* block flush performed */ |
||
3889 | var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ |
||
3890 | var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ |
||
3891 | |||
3892 | var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. |
||
3893 | |||
3894 | function err(strm, errorCode) { |
||
3895 | strm.msg = msg[errorCode]; |
||
3896 | return errorCode; |
||
3897 | } |
||
3898 | |||
3899 | function rank(f) { |
||
3900 | return ((f) << 1) - ((f) > 4 ? 9 : 0); |
||
3901 | } |
||
3902 | |||
3903 | function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } |
||
3904 | |||
3905 | |||
3906 | /* ========================================================================= |
||
3907 | * Flush as much pending output as possible. All deflate() output goes |
||
3908 | * through this function so some applications may wish to modify it |
||
3909 | * to avoid allocating a large strm->output buffer and copying into it. |
||
3910 | * (See also read_buf()). |
||
3911 | */ |
||
3912 | function flush_pending(strm) { |
||
3913 | var s = strm.state; |
||
3914 | |||
3915 | //_tr_flush_bits(s); |
||
3916 | var len = s.pending; |
||
3917 | if (len > strm.avail_out) { |
||
3918 | len = strm.avail_out; |
||
3919 | } |
||
3920 | if (len === 0) { return; } |
||
3921 | |||
3922 | utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); |
||
3923 | strm.next_out += len; |
||
3924 | s.pending_out += len; |
||
3925 | strm.total_out += len; |
||
3926 | strm.avail_out -= len; |
||
3927 | s.pending -= len; |
||
3928 | if (s.pending === 0) { |
||
3929 | s.pending_out = 0; |
||
3930 | } |
||
3931 | } |
||
3932 | |||
3933 | |||
3934 | function flush_block_only (s, last) { |
||
3935 | trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); |
||
3936 | s.block_start = s.strstart; |
||
3937 | flush_pending(s.strm); |
||
3938 | } |
||
3939 | |||
3940 | |||
3941 | function put_byte(s, b) { |
||
3942 | s.pending_buf[s.pending++] = b; |
||
3943 | } |
||
3944 | |||
3945 | |||
3946 | /* ========================================================================= |
||
3947 | * Put a short in the pending buffer. The 16-bit value is put in MSB order. |
||
3948 | * IN assertion: the stream state is correct and there is enough room in |
||
3949 | * pending_buf. |
||
3950 | */ |
||
3951 | function putShortMSB(s, b) { |
||
3952 | // put_byte(s, (Byte)(b >> 8)); |
||
3953 | // put_byte(s, (Byte)(b & 0xff)); |
||
3954 | s.pending_buf[s.pending++] = (b >>> 8) & 0xff; |
||
3955 | s.pending_buf[s.pending++] = b & 0xff; |
||
3956 | } |
||
3957 | |||
3958 | |||
3959 | /* =========================================================================== |
||
3960 | * Read a new buffer from the current input stream, update the adler32 |
||
3961 | * and total number of bytes read. All deflate() input goes through |
||
3962 | * this function so some applications may wish to modify it to avoid |
||
3963 | * allocating a large strm->input buffer and copying from it. |
||
3964 | * (See also flush_pending()). |
||
3965 | */ |
||
3966 | function read_buf(strm, buf, start, size) { |
||
3967 | var len = strm.avail_in; |
||
3968 | |||
3969 | if (len > size) { len = size; } |
||
3970 | if (len === 0) { return 0; } |
||
3971 | |||
3972 | strm.avail_in -= len; |
||
3973 | |||
3974 | utils.arraySet(buf, strm.input, strm.next_in, len, start); |
||
3975 | if (strm.state.wrap === 1) { |
||
3976 | strm.adler = adler32(strm.adler, buf, len, start); |
||
3977 | } |
||
3978 | |||
3979 | else if (strm.state.wrap === 2) { |
||
3980 | strm.adler = crc32(strm.adler, buf, len, start); |
||
3981 | } |
||
3982 | |||
3983 | strm.next_in += len; |
||
3984 | strm.total_in += len; |
||
3985 | |||
3986 | return len; |
||
3987 | } |
||
3988 | |||
3989 | |||
3990 | /* =========================================================================== |
||
3991 | * Set match_start to the longest match starting at the given string and |
||
3992 | * return its length. Matches shorter or equal to prev_length are discarded, |
||
3993 | * in which case the result is equal to prev_length and match_start is |
||
3994 | * garbage. |
||
3995 | * IN assertions: cur_match is the head of the hash chain for the current |
||
3996 | * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 |
||
3997 | * OUT assertion: the match length is not greater than s->lookahead. |
||
3998 | */ |
||
3999 | function longest_match(s, cur_match) { |
||
4000 | var chain_length = s.max_chain_length; /* max hash chain length */ |
||
4001 | var scan = s.strstart; /* current string */ |
||
4002 | var match; /* matched string */ |
||
4003 | var len; /* length of current match */ |
||
4004 | var best_len = s.prev_length; /* best match length so far */ |
||
4005 | var nice_match = s.nice_match; /* stop if match long enough */ |
||
4006 | var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? |
||
4007 | s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; |
||
4008 | |||
4009 | var _win = s.window; // shortcut |
||
4010 | |||
4011 | var wmask = s.w_mask; |
||
4012 | var prev = s.prev; |
||
4013 | |||
4014 | /* Stop when cur_match becomes <= limit. To simplify the code, |
||
4015 | * we prevent matches with the string of window index 0. |
||
4016 | */ |
||
4017 | |||
4018 | var strend = s.strstart + MAX_MATCH; |
||
4019 | var scan_end1 = _win[scan + best_len - 1]; |
||
4020 | var scan_end = _win[scan + best_len]; |
||
4021 | |||
4022 | /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. |
||
4023 | * It is easy to get rid of this optimization if necessary. |
||
4024 | */ |
||
4025 | // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
||
4026 | |||
4027 | /* Do not waste too much time if we already have a good match: */ |
||
4028 | if (s.prev_length >= s.good_match) { |
||
4029 | chain_length >>= 2; |
||
4030 | } |
||
4031 | /* Do not look for matches beyond the end of the input. This is necessary |
||
4032 | * to make deflate deterministic. |
||
4033 | */ |
||
4034 | if (nice_match > s.lookahead) { nice_match = s.lookahead; } |
||
4035 | |||
4036 | // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
||
4037 | |||
4038 | do { |
||
4039 | // Assert(cur_match < s->strstart, "no future"); |
||
4040 | match = cur_match; |
||
4041 | |||
4042 | /* Skip to next match if the match length cannot increase |
||
4043 | * or if the match length is less than 2. Note that the checks below |
||
4044 | * for insufficient lookahead only occur occasionally for performance |
||
4045 | * reasons. Therefore uninitialized memory will be accessed, and |
||
4046 | * conditional jumps will be made that depend on those values. |
||
4047 | * However the length of the match is limited to the lookahead, so |
||
4048 | * the output of deflate is not affected by the uninitialized values. |
||
4049 | */ |
||
4050 | |||
4051 | if (_win[match + best_len] !== scan_end || |
||
4052 | _win[match + best_len - 1] !== scan_end1 || |
||
4053 | _win[match] !== _win[scan] || |
||
4054 | _win[++match] !== _win[scan + 1]) { |
||
4055 | continue; |
||
4056 | } |
||
4057 | |||
4058 | /* The check at best_len-1 can be removed because it will be made |
||
4059 | * again later. (This heuristic is not always a win.) |
||
4060 | * It is not necessary to compare scan[2] and match[2] since they |
||
4061 | * are always equal when the other bytes match, given that |
||
4062 | * the hash keys are equal and that HASH_BITS >= 8. |
||
4063 | */ |
||
4064 | scan += 2; |
||
4065 | match++; |
||
4066 | // Assert(*scan == *match, "match[2]?"); |
||
4067 | |||
4068 | /* We check for insufficient lookahead only every 8th comparison; |
||
4069 | * the 256th check will be made at strstart+258. |
||
4070 | */ |
||
4071 | do { |
||
4072 | /*jshint noempty:false*/ |
||
4073 | } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
||
4074 | _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
||
4075 | _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
||
4076 | _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
||
4077 | scan < strend); |
||
4078 | |||
4079 | // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
||
4080 | |||
4081 | len = MAX_MATCH - (strend - scan); |
||
4082 | scan = strend - MAX_MATCH; |
||
4083 | |||
4084 | if (len > best_len) { |
||
4085 | s.match_start = cur_match; |
||
4086 | best_len = len; |
||
4087 | if (len >= nice_match) { |
||
4088 | break; |
||
4089 | } |
||
4090 | scan_end1 = _win[scan + best_len - 1]; |
||
4091 | scan_end = _win[scan + best_len]; |
||
4092 | } |
||
4093 | } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); |
||
4094 | |||
4095 | if (best_len <= s.lookahead) { |
||
4096 | return best_len; |
||
4097 | } |
||
4098 | return s.lookahead; |
||
4099 | } |
||
4100 | |||
4101 | |||
4102 | /* =========================================================================== |
||
4103 | * Fill the window when the lookahead becomes insufficient. |
||
4104 | * Updates strstart and lookahead. |
||
4105 | * |
||
4106 | * IN assertion: lookahead < MIN_LOOKAHEAD |
||
4107 | * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD |
||
4108 | * At least one byte has been read, or avail_in == 0; reads are |
||
4109 | * performed for at least two bytes (required for the zip translate_eol |
||
4110 | * option -- not supported here). |
||
4111 | */ |
||
4112 | function fill_window(s) { |
||
4113 | var _w_size = s.w_size; |
||
4114 | var p, n, m, more, str; |
||
4115 | |||
4116 | //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); |
||
4117 | |||
4118 | do { |
||
4119 | more = s.window_size - s.lookahead - s.strstart; |
||
4120 | |||
4121 | // JS ints have 32 bit, block below not needed |
||
4122 | /* Deal with !@#$% 64K limit: */ |
||
4123 | //if (sizeof(int) <= 2) { |
||
4124 | // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { |
||
4125 | // more = wsize; |
||
4126 | // |
||
4127 | // } else if (more == (unsigned)(-1)) { |
||
4128 | // /* Very unlikely, but possible on 16 bit machine if |
||
4129 | // * strstart == 0 && lookahead == 1 (input done a byte at time) |
||
4130 | // */ |
||
4131 | // more--; |
||
4132 | // } |
||
4133 | //} |
||
4134 | |||
4135 | |||
4136 | /* If the window is almost full and there is insufficient lookahead, |
||
4137 | * move the upper half to the lower one to make room in the upper half. |
||
4138 | */ |
||
4139 | if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { |
||
4140 | |||
4141 | utils.arraySet(s.window, s.window, _w_size, _w_size, 0); |
||
4142 | s.match_start -= _w_size; |
||
4143 | s.strstart -= _w_size; |
||
4144 | /* we now have strstart >= MAX_DIST */ |
||
4145 | s.block_start -= _w_size; |
||
4146 | |||
4147 | /* Slide the hash table (could be avoided with 32 bit values |
||
4148 | at the expense of memory usage). We slide even when level == 0 |
||
4149 | to keep the hash table consistent if we switch back to level > 0 |
||
4150 | later. (Using level 0 permanently is not an optimal usage of |
||
4151 | zlib, so we don't care about this pathological case.) |
||
4152 | */ |
||
4153 | |||
4154 | n = s.hash_size; |
||
4155 | p = n; |
||
4156 | do { |
||
4157 | m = s.head[--p]; |
||
4158 | s.head[p] = (m >= _w_size ? m - _w_size : 0); |
||
4159 | } while (--n); |
||
4160 | |||
4161 | n = _w_size; |
||
4162 | p = n; |
||
4163 | do { |
||
4164 | m = s.prev[--p]; |
||
4165 | s.prev[p] = (m >= _w_size ? m - _w_size : 0); |
||
4166 | /* If n is not on any hash chain, prev[n] is garbage but |
||
4167 | * its value will never be used. |
||
4168 | */ |
||
4169 | } while (--n); |
||
4170 | |||
4171 | more += _w_size; |
||
4172 | } |
||
4173 | if (s.strm.avail_in === 0) { |
||
4174 | break; |
||
4175 | } |
||
4176 | |||
4177 | /* If there was no sliding: |
||
4178 | * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && |
||
4179 | * more == window_size - lookahead - strstart |
||
4180 | * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) |
||
4181 | * => more >= window_size - 2*WSIZE + 2 |
||
4182 | * In the BIG_MEM or MMAP case (not yet supported), |
||
4183 | * window_size == input_size + MIN_LOOKAHEAD && |
||
4184 | * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. |
||
4185 | * Otherwise, window_size == 2*WSIZE so more >= 2. |
||
4186 | * If there was sliding, more >= WSIZE. So in all cases, more >= 2. |
||
4187 | */ |
||
4188 | //Assert(more >= 2, "more < 2"); |
||
4189 | n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); |
||
4190 | s.lookahead += n; |
||
4191 | |||
4192 | /* Initialize the hash value now that we have some input: */ |
||
4193 | if (s.lookahead + s.insert >= MIN_MATCH) { |
||
4194 | str = s.strstart - s.insert; |
||
4195 | s.ins_h = s.window[str]; |
||
4196 | |||
4197 | /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ |
||
4198 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; |
||
4199 | //#if MIN_MATCH != 3 |
||
4200 | // Call update_hash() MIN_MATCH-3 more times |
||
4201 | //#endif |
||
4202 | while (s.insert) { |
||
4203 | /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ |
||
4204 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; |
||
4205 | |||
4206 | s.prev[str & s.w_mask] = s.head[s.ins_h]; |
||
4207 | s.head[s.ins_h] = str; |
||
4208 | str++; |
||
4209 | s.insert--; |
||
4210 | if (s.lookahead + s.insert < MIN_MATCH) { |
||
4211 | break; |
||
4212 | } |
||
4213 | } |
||
4214 | } |
||
4215 | /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, |
||
4216 | * but this is not important since only literal bytes will be emitted. |
||
4217 | */ |
||
4218 | |||
4219 | } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); |
||
4220 | |||
4221 | /* If the WIN_INIT bytes after the end of the current data have never been |
||
4222 | * written, then zero those bytes in order to avoid memory check reports of |
||
4223 | * the use of uninitialized (or uninitialised as Julian writes) bytes by |
||
4224 | * the longest match routines. Update the high water mark for the next |
||
4225 | * time through here. WIN_INIT is set to MAX_MATCH since the longest match |
||
4226 | * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. |
||
4227 | */ |
||
4228 | // if (s.high_water < s.window_size) { |
||
4229 | // var curr = s.strstart + s.lookahead; |
||
4230 | // var init = 0; |
||
4231 | // |
||
4232 | // if (s.high_water < curr) { |
||
4233 | // /* Previous high water mark below current data -- zero WIN_INIT |
||
4234 | // * bytes or up to end of window, whichever is less. |
||
4235 | // */ |
||
4236 | // init = s.window_size - curr; |
||
4237 | // if (init > WIN_INIT) |
||
4238 | // init = WIN_INIT; |
||
4239 | // zmemzero(s->window + curr, (unsigned)init); |
||
4240 | // s->high_water = curr + init; |
||
4241 | // } |
||
4242 | // else if (s->high_water < (ulg)curr + WIN_INIT) { |
||
4243 | // /* High water mark at or above current data, but below current data |
||
4244 | // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up |
||
4245 | // * to end of window, whichever is less. |
||
4246 | // */ |
||
4247 | // init = (ulg)curr + WIN_INIT - s->high_water; |
||
4248 | // if (init > s->window_size - s->high_water) |
||
4249 | // init = s->window_size - s->high_water; |
||
4250 | // zmemzero(s->window + s->high_water, (unsigned)init); |
||
4251 | // s->high_water += init; |
||
4252 | // } |
||
4253 | // } |
||
4254 | // |
||
4255 | // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, |
||
4256 | // "not enough room for search"); |
||
4257 | } |
||
4258 | |||
4259 | /* =========================================================================== |
||
4260 | * Copy without compression as much as possible from the input stream, return |
||
4261 | * the current block state. |
||
4262 | * This function does not insert new strings in the dictionary since |
||
4263 | * uncompressible data is probably not useful. This function is used |
||
4264 | * only for the level=0 compression option. |
||
4265 | * NOTE: this function should be optimized to avoid extra copying from |
||
4266 | * window to pending_buf. |
||
4267 | */ |
||
4268 | function deflate_stored(s, flush) { |
||
4269 | /* Stored blocks are limited to 0xffff bytes, pending_buf is limited |
||
4270 | * to pending_buf_size, and each stored block has a 5 byte header: |
||
4271 | */ |
||
4272 | var max_block_size = 0xffff; |
||
4273 | |||
4274 | if (max_block_size > s.pending_buf_size - 5) { |
||
4275 | max_block_size = s.pending_buf_size - 5; |
||
4276 | } |
||
4277 | |||
4278 | /* Copy as much as possible from input to output: */ |
||
4279 | for (;;) { |
||
4280 | /* Fill the window as much as possible: */ |
||
4281 | if (s.lookahead <= 1) { |
||
4282 | |||
4283 | //Assert(s->strstart < s->w_size+MAX_DIST(s) || |
||
4284 | // s->block_start >= (long)s->w_size, "slide too late"); |
||
4285 | // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || |
||
4286 | // s.block_start >= s.w_size)) { |
||
4287 | // throw new Error("slide too late"); |
||
4288 | // } |
||
4289 | |||
4290 | fill_window(s); |
||
4291 | if (s.lookahead === 0 && flush === Z_NO_FLUSH) { |
||
4292 | return BS_NEED_MORE; |
||
4293 | } |
||
4294 | |||
4295 | if (s.lookahead === 0) { |
||
4296 | break; |
||
4297 | } |
||
4298 | /* flush the current block */ |
||
4299 | } |
||
4300 | //Assert(s->block_start >= 0L, "block gone"); |
||
4301 | // if (s.block_start < 0) throw new Error("block gone"); |
||
4302 | |||
4303 | s.strstart += s.lookahead; |
||
4304 | s.lookahead = 0; |
||
4305 | |||
4306 | /* Emit a stored block if pending_buf will be full: */ |
||
4307 | var max_start = s.block_start + max_block_size; |
||
4308 | |||
4309 | if (s.strstart === 0 || s.strstart >= max_start) { |
||
4310 | /* strstart == 0 is possible when wraparound on 16-bit machine */ |
||
4311 | s.lookahead = s.strstart - max_start; |
||
4312 | s.strstart = max_start; |
||
4313 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4314 | flush_block_only(s, false); |
||
4315 | if (s.strm.avail_out === 0) { |
||
4316 | return BS_NEED_MORE; |
||
4317 | } |
||
4318 | /***/ |
||
4319 | |||
4320 | |||
4321 | } |
||
4322 | /* Flush if we may have to slide, otherwise block_start may become |
||
4323 | * negative and the data will be gone: |
||
4324 | */ |
||
4325 | if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { |
||
4326 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4327 | flush_block_only(s, false); |
||
4328 | if (s.strm.avail_out === 0) { |
||
4329 | return BS_NEED_MORE; |
||
4330 | } |
||
4331 | /***/ |
||
4332 | } |
||
4333 | } |
||
4334 | |||
4335 | s.insert = 0; |
||
4336 | |||
4337 | if (flush === Z_FINISH) { |
||
4338 | /*** FLUSH_BLOCK(s, 1); ***/ |
||
4339 | flush_block_only(s, true); |
||
4340 | if (s.strm.avail_out === 0) { |
||
4341 | return BS_FINISH_STARTED; |
||
4342 | } |
||
4343 | /***/ |
||
4344 | return BS_FINISH_DONE; |
||
4345 | } |
||
4346 | |||
4347 | if (s.strstart > s.block_start) { |
||
4348 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4349 | flush_block_only(s, false); |
||
4350 | if (s.strm.avail_out === 0) { |
||
4351 | return BS_NEED_MORE; |
||
4352 | } |
||
4353 | /***/ |
||
4354 | } |
||
4355 | |||
4356 | return BS_NEED_MORE; |
||
4357 | } |
||
4358 | |||
4359 | /* =========================================================================== |
||
4360 | * Compress as much as possible from the input stream, return the current |
||
4361 | * block state. |
||
4362 | * This function does not perform lazy evaluation of matches and inserts |
||
4363 | * new strings in the dictionary only for unmatched strings or for short |
||
4364 | * matches. It is used only for the fast compression options. |
||
4365 | */ |
||
4366 | function deflate_fast(s, flush) { |
||
4367 | var hash_head; /* head of the hash chain */ |
||
4368 | var bflush; /* set if current block must be flushed */ |
||
4369 | |||
4370 | for (;;) { |
||
4371 | /* Make sure that we always have enough lookahead, except |
||
4372 | * at the end of the input file. We need MAX_MATCH bytes |
||
4373 | * for the next match, plus MIN_MATCH bytes to insert the |
||
4374 | * string following the next match. |
||
4375 | */ |
||
4376 | if (s.lookahead < MIN_LOOKAHEAD) { |
||
4377 | fill_window(s); |
||
4378 | if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { |
||
4379 | return BS_NEED_MORE; |
||
4380 | } |
||
4381 | if (s.lookahead === 0) { |
||
4382 | break; /* flush the current block */ |
||
4383 | } |
||
4384 | } |
||
4385 | |||
4386 | /* Insert the string window[strstart .. strstart+2] in the |
||
4387 | * dictionary, and set hash_head to the head of the hash chain: |
||
4388 | */ |
||
4389 | hash_head = 0/*NIL*/; |
||
4390 | if (s.lookahead >= MIN_MATCH) { |
||
4391 | /*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
||
4392 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
||
4393 | hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
||
4394 | s.head[s.ins_h] = s.strstart; |
||
4395 | /***/ |
||
4396 | } |
||
4397 | |||
4398 | /* Find the longest match, discarding those <= prev_length. |
||
4399 | * At this point we have always match_length < MIN_MATCH |
||
4400 | */ |
||
4401 | if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { |
||
4402 | /* To simplify the code, we prevent matches with the string |
||
4403 | * of window index 0 (in particular we have to avoid a match |
||
4404 | * of the string with itself at the start of the input file). |
||
4405 | */ |
||
4406 | s.match_length = longest_match(s, hash_head); |
||
4407 | /* longest_match() sets match_start */ |
||
4408 | } |
||
4409 | if (s.match_length >= MIN_MATCH) { |
||
4410 | // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only |
||
4411 | |||
4412 | /*** _tr_tally_dist(s, s.strstart - s.match_start, |
||
4413 | s.match_length - MIN_MATCH, bflush); ***/ |
||
4414 | bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); |
||
4415 | |||
4416 | s.lookahead -= s.match_length; |
||
4417 | |||
4418 | /* Insert new strings in the hash table only if the match length |
||
4419 | * is not too large. This saves time but degrades compression. |
||
4420 | */ |
||
4421 | if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { |
||
4422 | s.match_length--; /* string at strstart already in table */ |
||
4423 | do { |
||
4424 | s.strstart++; |
||
4425 | /*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
||
4426 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
||
4427 | hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
||
4428 | s.head[s.ins_h] = s.strstart; |
||
4429 | /***/ |
||
4430 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are |
||
4431 | * always MIN_MATCH bytes ahead. |
||
4432 | */ |
||
4433 | } while (--s.match_length !== 0); |
||
4434 | s.strstart++; |
||
4435 | } else |
||
4436 | { |
||
4437 | s.strstart += s.match_length; |
||
4438 | s.match_length = 0; |
||
4439 | s.ins_h = s.window[s.strstart]; |
||
4440 | /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ |
||
4441 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; |
||
4442 | |||
4443 | //#if MIN_MATCH != 3 |
||
4444 | // Call UPDATE_HASH() MIN_MATCH-3 more times |
||
4445 | //#endif |
||
4446 | /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not |
||
4447 | * matter since it will be recomputed at next deflate call. |
||
4448 | */ |
||
4449 | } |
||
4450 | } else { |
||
4451 | /* No match, output a literal byte */ |
||
4452 | //Tracevv((stderr,"%c", s.window[s.strstart])); |
||
4453 | /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
||
4454 | bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
||
4455 | |||
4456 | s.lookahead--; |
||
4457 | s.strstart++; |
||
4458 | } |
||
4459 | if (bflush) { |
||
4460 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4461 | flush_block_only(s, false); |
||
4462 | if (s.strm.avail_out === 0) { |
||
4463 | return BS_NEED_MORE; |
||
4464 | } |
||
4465 | /***/ |
||
4466 | } |
||
4467 | } |
||
4468 | s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1); |
||
4469 | if (flush === Z_FINISH) { |
||
4470 | /*** FLUSH_BLOCK(s, 1); ***/ |
||
4471 | flush_block_only(s, true); |
||
4472 | if (s.strm.avail_out === 0) { |
||
4473 | return BS_FINISH_STARTED; |
||
4474 | } |
||
4475 | /***/ |
||
4476 | return BS_FINISH_DONE; |
||
4477 | } |
||
4478 | if (s.last_lit) { |
||
4479 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4480 | flush_block_only(s, false); |
||
4481 | if (s.strm.avail_out === 0) { |
||
4482 | return BS_NEED_MORE; |
||
4483 | } |
||
4484 | /***/ |
||
4485 | } |
||
4486 | return BS_BLOCK_DONE; |
||
4487 | } |
||
4488 | |||
4489 | /* =========================================================================== |
||
4490 | * Same as above, but achieves better compression. We use a lazy |
||
4491 | * evaluation for matches: a match is finally adopted only if there is |
||
4492 | * no better match at the next window position. |
||
4493 | */ |
||
4494 | function deflate_slow(s, flush) { |
||
4495 | var hash_head; /* head of hash chain */ |
||
4496 | var bflush; /* set if current block must be flushed */ |
||
4497 | |||
4498 | var max_insert; |
||
4499 | |||
4500 | /* Process the input block. */ |
||
4501 | for (;;) { |
||
4502 | /* Make sure that we always have enough lookahead, except |
||
4503 | * at the end of the input file. We need MAX_MATCH bytes |
||
4504 | * for the next match, plus MIN_MATCH bytes to insert the |
||
4505 | * string following the next match. |
||
4506 | */ |
||
4507 | if (s.lookahead < MIN_LOOKAHEAD) { |
||
4508 | fill_window(s); |
||
4509 | if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { |
||
4510 | return BS_NEED_MORE; |
||
4511 | } |
||
4512 | if (s.lookahead === 0) { break; } /* flush the current block */ |
||
4513 | } |
||
4514 | |||
4515 | /* Insert the string window[strstart .. strstart+2] in the |
||
4516 | * dictionary, and set hash_head to the head of the hash chain: |
||
4517 | */ |
||
4518 | hash_head = 0/*NIL*/; |
||
4519 | if (s.lookahead >= MIN_MATCH) { |
||
4520 | /*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
||
4521 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
||
4522 | hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
||
4523 | s.head[s.ins_h] = s.strstart; |
||
4524 | /***/ |
||
4525 | } |
||
4526 | |||
4527 | /* Find the longest match, discarding those <= prev_length. |
||
4528 | */ |
||
4529 | s.prev_length = s.match_length; |
||
4530 | s.prev_match = s.match_start; |
||
4531 | s.match_length = MIN_MATCH-1; |
||
4532 | |||
4533 | if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && |
||
4534 | s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { |
||
4535 | /* To simplify the code, we prevent matches with the string |
||
4536 | * of window index 0 (in particular we have to avoid a match |
||
4537 | * of the string with itself at the start of the input file). |
||
4538 | */ |
||
4539 | s.match_length = longest_match(s, hash_head); |
||
4540 | /* longest_match() sets match_start */ |
||
4541 | |||
4542 | if (s.match_length <= 5 && |
||
4543 | (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { |
||
4544 | |||
4545 | /* If prev_match is also MIN_MATCH, match_start is garbage |
||
4546 | * but we will ignore the current match anyway. |
||
4547 | */ |
||
4548 | s.match_length = MIN_MATCH-1; |
||
4549 | } |
||
4550 | } |
||
4551 | /* If there was a match at the previous step and the current |
||
4552 | * match is not better, output the previous match: |
||
4553 | */ |
||
4554 | if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { |
||
4555 | max_insert = s.strstart + s.lookahead - MIN_MATCH; |
||
4556 | /* Do not insert strings in hash table beyond this. */ |
||
4557 | |||
4558 | //check_match(s, s.strstart-1, s.prev_match, s.prev_length); |
||
4559 | |||
4560 | /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, |
||
4561 | s.prev_length - MIN_MATCH, bflush);***/ |
||
4562 | bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH); |
||
4563 | /* Insert in hash table all strings up to the end of the match. |
||
4564 | * strstart-1 and strstart are already inserted. If there is not |
||
4565 | * enough lookahead, the last two strings are not inserted in |
||
4566 | * the hash table. |
||
4567 | */ |
||
4568 | s.lookahead -= s.prev_length-1; |
||
4569 | s.prev_length -= 2; |
||
4570 | do { |
||
4571 | if (++s.strstart <= max_insert) { |
||
4572 | /*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
||
4573 | s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
||
4574 | hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
||
4575 | s.head[s.ins_h] = s.strstart; |
||
4576 | /***/ |
||
4577 | } |
||
4578 | } while (--s.prev_length !== 0); |
||
4579 | s.match_available = 0; |
||
4580 | s.match_length = MIN_MATCH-1; |
||
4581 | s.strstart++; |
||
4582 | |||
4583 | if (bflush) { |
||
4584 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4585 | flush_block_only(s, false); |
||
4586 | if (s.strm.avail_out === 0) { |
||
4587 | return BS_NEED_MORE; |
||
4588 | } |
||
4589 | /***/ |
||
4590 | } |
||
4591 | |||
4592 | } else if (s.match_available) { |
||
4593 | /* If there was no match at the previous position, output a |
||
4594 | * single literal. If there was a match but the current match |
||
4595 | * is longer, truncate the previous match to a single literal. |
||
4596 | */ |
||
4597 | //Tracevv((stderr,"%c", s->window[s->strstart-1])); |
||
4598 | /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ |
||
4599 | bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); |
||
4600 | |||
4601 | if (bflush) { |
||
4602 | /*** FLUSH_BLOCK_ONLY(s, 0) ***/ |
||
4603 | flush_block_only(s, false); |
||
4604 | /***/ |
||
4605 | } |
||
4606 | s.strstart++; |
||
4607 | s.lookahead--; |
||
4608 | if (s.strm.avail_out === 0) { |
||
4609 | return BS_NEED_MORE; |
||
4610 | } |
||
4611 | } else { |
||
4612 | /* There is no previous match to compare with, wait for |
||
4613 | * the next step to decide. |
||
4614 | */ |
||
4615 | s.match_available = 1; |
||
4616 | s.strstart++; |
||
4617 | s.lookahead--; |
||
4618 | } |
||
4619 | } |
||
4620 | //Assert (flush != Z_NO_FLUSH, "no flush?"); |
||
4621 | if (s.match_available) { |
||
4622 | //Tracevv((stderr,"%c", s->window[s->strstart-1])); |
||
4623 | /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ |
||
4624 | bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); |
||
4625 | |||
4626 | s.match_available = 0; |
||
4627 | } |
||
4628 | s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1; |
||
4629 | if (flush === Z_FINISH) { |
||
4630 | /*** FLUSH_BLOCK(s, 1); ***/ |
||
4631 | flush_block_only(s, true); |
||
4632 | if (s.strm.avail_out === 0) { |
||
4633 | return BS_FINISH_STARTED; |
||
4634 | } |
||
4635 | /***/ |
||
4636 | return BS_FINISH_DONE; |
||
4637 | } |
||
4638 | if (s.last_lit) { |
||
4639 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4640 | flush_block_only(s, false); |
||
4641 | if (s.strm.avail_out === 0) { |
||
4642 | return BS_NEED_MORE; |
||
4643 | } |
||
4644 | /***/ |
||
4645 | } |
||
4646 | |||
4647 | return BS_BLOCK_DONE; |
||
4648 | } |
||
4649 | |||
4650 | |||
4651 | /* =========================================================================== |
||
4652 | * For Z_RLE, simply look for runs of bytes, generate matches only of distance |
||
4653 | * one. Do not maintain a hash table. (It will be regenerated if this run of |
||
4654 | * deflate switches away from Z_RLE.) |
||
4655 | */ |
||
4656 | function deflate_rle(s, flush) { |
||
4657 | var bflush; /* set if current block must be flushed */ |
||
4658 | var prev; /* byte at distance one to match */ |
||
4659 | var scan, strend; /* scan goes up to strend for length of run */ |
||
4660 | |||
4661 | var _win = s.window; |
||
4662 | |||
4663 | for (;;) { |
||
4664 | /* Make sure that we always have enough lookahead, except |
||
4665 | * at the end of the input file. We need MAX_MATCH bytes |
||
4666 | * for the longest run, plus one for the unrolled loop. |
||
4667 | */ |
||
4668 | if (s.lookahead <= MAX_MATCH) { |
||
4669 | fill_window(s); |
||
4670 | if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { |
||
4671 | return BS_NEED_MORE; |
||
4672 | } |
||
4673 | if (s.lookahead === 0) { break; } /* flush the current block */ |
||
4674 | } |
||
4675 | |||
4676 | /* See how many times the previous byte repeats */ |
||
4677 | s.match_length = 0; |
||
4678 | if (s.lookahead >= MIN_MATCH && s.strstart > 0) { |
||
4679 | scan = s.strstart - 1; |
||
4680 | prev = _win[scan]; |
||
4681 | if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { |
||
4682 | strend = s.strstart + MAX_MATCH; |
||
4683 | do { |
||
4684 | /*jshint noempty:false*/ |
||
4685 | } while (prev === _win[++scan] && prev === _win[++scan] && |
||
4686 | prev === _win[++scan] && prev === _win[++scan] && |
||
4687 | prev === _win[++scan] && prev === _win[++scan] && |
||
4688 | prev === _win[++scan] && prev === _win[++scan] && |
||
4689 | scan < strend); |
||
4690 | s.match_length = MAX_MATCH - (strend - scan); |
||
4691 | if (s.match_length > s.lookahead) { |
||
4692 | s.match_length = s.lookahead; |
||
4693 | } |
||
4694 | } |
||
4695 | //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); |
||
4696 | } |
||
4697 | |||
4698 | /* Emit match if have run of MIN_MATCH or longer, else emit literal */ |
||
4699 | if (s.match_length >= MIN_MATCH) { |
||
4700 | //check_match(s, s.strstart, s.strstart - 1, s.match_length); |
||
4701 | |||
4702 | /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ |
||
4703 | bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); |
||
4704 | |||
4705 | s.lookahead -= s.match_length; |
||
4706 | s.strstart += s.match_length; |
||
4707 | s.match_length = 0; |
||
4708 | } else { |
||
4709 | /* No match, output a literal byte */ |
||
4710 | //Tracevv((stderr,"%c", s->window[s->strstart])); |
||
4711 | /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
||
4712 | bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
||
4713 | |||
4714 | s.lookahead--; |
||
4715 | s.strstart++; |
||
4716 | } |
||
4717 | if (bflush) { |
||
4718 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4719 | flush_block_only(s, false); |
||
4720 | if (s.strm.avail_out === 0) { |
||
4721 | return BS_NEED_MORE; |
||
4722 | } |
||
4723 | /***/ |
||
4724 | } |
||
4725 | } |
||
4726 | s.insert = 0; |
||
4727 | if (flush === Z_FINISH) { |
||
4728 | /*** FLUSH_BLOCK(s, 1); ***/ |
||
4729 | flush_block_only(s, true); |
||
4730 | if (s.strm.avail_out === 0) { |
||
4731 | return BS_FINISH_STARTED; |
||
4732 | } |
||
4733 | /***/ |
||
4734 | return BS_FINISH_DONE; |
||
4735 | } |
||
4736 | if (s.last_lit) { |
||
4737 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4738 | flush_block_only(s, false); |
||
4739 | if (s.strm.avail_out === 0) { |
||
4740 | return BS_NEED_MORE; |
||
4741 | } |
||
4742 | /***/ |
||
4743 | } |
||
4744 | return BS_BLOCK_DONE; |
||
4745 | } |
||
4746 | |||
4747 | /* =========================================================================== |
||
4748 | * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. |
||
4749 | * (It will be regenerated if this run of deflate switches away from Huffman.) |
||
4750 | */ |
||
4751 | function deflate_huff(s, flush) { |
||
4752 | var bflush; /* set if current block must be flushed */ |
||
4753 | |||
4754 | for (;;) { |
||
4755 | /* Make sure that we have a literal to write. */ |
||
4756 | if (s.lookahead === 0) { |
||
4757 | fill_window(s); |
||
4758 | if (s.lookahead === 0) { |
||
4759 | if (flush === Z_NO_FLUSH) { |
||
4760 | return BS_NEED_MORE; |
||
4761 | } |
||
4762 | break; /* flush the current block */ |
||
4763 | } |
||
4764 | } |
||
4765 | |||
4766 | /* Output a literal byte */ |
||
4767 | s.match_length = 0; |
||
4768 | //Tracevv((stderr,"%c", s->window[s->strstart])); |
||
4769 | /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
||
4770 | bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
||
4771 | s.lookahead--; |
||
4772 | s.strstart++; |
||
4773 | if (bflush) { |
||
4774 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4775 | flush_block_only(s, false); |
||
4776 | if (s.strm.avail_out === 0) { |
||
4777 | return BS_NEED_MORE; |
||
4778 | } |
||
4779 | /***/ |
||
4780 | } |
||
4781 | } |
||
4782 | s.insert = 0; |
||
4783 | if (flush === Z_FINISH) { |
||
4784 | /*** FLUSH_BLOCK(s, 1); ***/ |
||
4785 | flush_block_only(s, true); |
||
4786 | if (s.strm.avail_out === 0) { |
||
4787 | return BS_FINISH_STARTED; |
||
4788 | } |
||
4789 | /***/ |
||
4790 | return BS_FINISH_DONE; |
||
4791 | } |
||
4792 | if (s.last_lit) { |
||
4793 | /*** FLUSH_BLOCK(s, 0); ***/ |
||
4794 | flush_block_only(s, false); |
||
4795 | if (s.strm.avail_out === 0) { |
||
4796 | return BS_NEED_MORE; |
||
4797 | } |
||
4798 | /***/ |
||
4799 | } |
||
4800 | return BS_BLOCK_DONE; |
||
4801 | } |
||
4802 | |||
4803 | /* Values for max_lazy_match, good_match and max_chain_length, depending on |
||
4804 | * the desired pack level (0..9). The values given below have been tuned to |
||
4805 | * exclude worst case performance for pathological files. Better values may be |
||
4806 | * found for specific files. |
||
4807 | */ |
||
4808 | var Config = function (good_length, max_lazy, nice_length, max_chain, func) { |
||
4809 | this.good_length = good_length; |
||
4810 | this.max_lazy = max_lazy; |
||
4811 | this.nice_length = nice_length; |
||
4812 | this.max_chain = max_chain; |
||
4813 | this.func = func; |
||
4814 | }; |
||
4815 | |||
4816 | var configuration_table; |
||
4817 | |||
4818 | configuration_table = [ |
||
4819 | /* good lazy nice chain */ |
||
4820 | new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ |
||
4821 | new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ |
||
4822 | new Config(4, 5, 16, 8, deflate_fast), /* 2 */ |
||
4823 | new Config(4, 6, 32, 32, deflate_fast), /* 3 */ |
||
4824 | |||
4825 | new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ |
||
4826 | new Config(8, 16, 32, 32, deflate_slow), /* 5 */ |
||
4827 | new Config(8, 16, 128, 128, deflate_slow), /* 6 */ |
||
4828 | new Config(8, 32, 128, 256, deflate_slow), /* 7 */ |
||
4829 | new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ |
||
4830 | new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ |
||
4831 | ]; |
||
4832 | |||
4833 | |||
4834 | /* =========================================================================== |
||
4835 | * Initialize the "longest match" routines for a new zlib stream |
||
4836 | */ |
||
4837 | function lm_init(s) { |
||
4838 | s.window_size = 2 * s.w_size; |
||
4839 | |||
4840 | /*** CLEAR_HASH(s); ***/ |
||
4841 | zero(s.head); // Fill with NIL (= 0); |
||
4842 | |||
4843 | /* Set the default configuration parameters: |
||
4844 | */ |
||
4845 | s.max_lazy_match = configuration_table[s.level].max_lazy; |
||
4846 | s.good_match = configuration_table[s.level].good_length; |
||
4847 | s.nice_match = configuration_table[s.level].nice_length; |
||
4848 | s.max_chain_length = configuration_table[s.level].max_chain; |
||
4849 | |||
4850 | s.strstart = 0; |
||
4851 | s.block_start = 0; |
||
4852 | s.lookahead = 0; |
||
4853 | s.insert = 0; |
||
4854 | s.match_length = s.prev_length = MIN_MATCH - 1; |
||
4855 | s.match_available = 0; |
||
4856 | s.ins_h = 0; |
||
4857 | } |
||
4858 | |||
4859 | |||
4860 | function DeflateState() { |
||
4861 | this.strm = null; /* pointer back to this zlib stream */ |
||
4862 | this.status = 0; /* as the name implies */ |
||
4863 | this.pending_buf = null; /* output still pending */ |
||
4864 | this.pending_buf_size = 0; /* size of pending_buf */ |
||
4865 | this.pending_out = 0; /* next pending byte to output to the stream */ |
||
4866 | this.pending = 0; /* nb of bytes in the pending buffer */ |
||
4867 | this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ |
||
4868 | this.gzhead = null; /* gzip header information to write */ |
||
4869 | this.gzindex = 0; /* where in extra, name, or comment */ |
||
4870 | this.method = Z_DEFLATED; /* can only be DEFLATED */ |
||
4871 | this.last_flush = -1; /* value of flush param for previous deflate call */ |
||
4872 | |||
4873 | this.w_size = 0; /* LZ77 window size (32K by default) */ |
||
4874 | this.w_bits = 0; /* log2(w_size) (8..16) */ |
||
4875 | this.w_mask = 0; /* w_size - 1 */ |
||
4876 | |||
4877 | this.window = null; |
||
4878 | /* Sliding window. Input bytes are read into the second half of the window, |
||
4879 | * and move to the first half later to keep a dictionary of at least wSize |
||
4880 | * bytes. With this organization, matches are limited to a distance of |
||
4881 | * wSize-MAX_MATCH bytes, but this ensures that IO is always |
||
4882 | * performed with a length multiple of the block size. |
||
4883 | */ |
||
4884 | |||
4885 | this.window_size = 0; |
||
4886 | /* Actual size of window: 2*wSize, except when the user input buffer |
||
4887 | * is directly used as sliding window. |
||
4888 | */ |
||
4889 | |||
4890 | this.prev = null; |
||
4891 | /* Link to older string with same hash index. To limit the size of this |
||
4892 | * array to 64K, this link is maintained only for the last 32K strings. |
||
4893 | * An index in this array is thus a window index modulo 32K. |
||
4894 | */ |
||
4895 | |||
4896 | this.head = null; /* Heads of the hash chains or NIL. */ |
||
4897 | |||
4898 | this.ins_h = 0; /* hash index of string to be inserted */ |
||
4899 | this.hash_size = 0; /* number of elements in hash table */ |
||
4900 | this.hash_bits = 0; /* log2(hash_size) */ |
||
4901 | this.hash_mask = 0; /* hash_size-1 */ |
||
4902 | |||
4903 | this.hash_shift = 0; |
||
4904 | /* Number of bits by which ins_h must be shifted at each input |
||
4905 | * step. It must be such that after MIN_MATCH steps, the oldest |
||
4906 | * byte no longer takes part in the hash key, that is: |
||
4907 | * hash_shift * MIN_MATCH >= hash_bits |
||
4908 | */ |
||
4909 | |||
4910 | this.block_start = 0; |
||
4911 | /* Window position at the beginning of the current output block. Gets |
||
4912 | * negative when the window is moved backwards. |
||
4913 | */ |
||
4914 | |||
4915 | this.match_length = 0; /* length of best match */ |
||
4916 | this.prev_match = 0; /* previous match */ |
||
4917 | this.match_available = 0; /* set if previous match exists */ |
||
4918 | this.strstart = 0; /* start of string to insert */ |
||
4919 | this.match_start = 0; /* start of matching string */ |
||
4920 | this.lookahead = 0; /* number of valid bytes ahead in window */ |
||
4921 | |||
4922 | this.prev_length = 0; |
||
4923 | /* Length of the best match at previous step. Matches not greater than this |
||
4924 | * are discarded. This is used in the lazy match evaluation. |
||
4925 | */ |
||
4926 | |||
4927 | this.max_chain_length = 0; |
||
4928 | /* To speed up deflation, hash chains are never searched beyond this |
||
4929 | * length. A higher limit improves compression ratio but degrades the |
||
4930 | * speed. |
||
4931 | */ |
||
4932 | |||
4933 | this.max_lazy_match = 0; |
||
4934 | /* Attempt to find a better match only when the current match is strictly |
||
4935 | * smaller than this value. This mechanism is used only for compression |
||
4936 | * levels >= 4. |
||
4937 | */ |
||
4938 | // That's alias to max_lazy_match, don't use directly |
||
4939 | //this.max_insert_length = 0; |
||
4940 | /* Insert new strings in the hash table only if the match length is not |
||
4941 | * greater than this length. This saves time but degrades compression. |
||
4942 | * max_insert_length is used only for compression levels <= 3. |
||
4943 | */ |
||
4944 | |||
4945 | this.level = 0; /* compression level (1..9) */ |
||
4946 | this.strategy = 0; /* favor or force Huffman coding*/ |
||
4947 | |||
4948 | this.good_match = 0; |
||
4949 | /* Use a faster search when the previous match is longer than this */ |
||
4950 | |||
4951 | this.nice_match = 0; /* Stop searching when current match exceeds this */ |
||
4952 | |||
4953 | /* used by trees.c: */ |
||
4954 | |||
4955 | /* Didn't use ct_data typedef below to suppress compiler warning */ |
||
4956 | |||
4957 | // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ |
||
4958 | // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ |
||
4959 | // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ |
||
4960 | |||
4961 | // Use flat array of DOUBLE size, with interleaved fata, |
||
4962 | // because JS does not support effective |
||
4963 | this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); |
||
4964 | this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); |
||
4965 | this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); |
||
4966 | zero(this.dyn_ltree); |
||
4967 | zero(this.dyn_dtree); |
||
4968 | zero(this.bl_tree); |
||
4969 | |||
4970 | this.l_desc = null; /* desc. for literal tree */ |
||
4971 | this.d_desc = null; /* desc. for distance tree */ |
||
4972 | this.bl_desc = null; /* desc. for bit length tree */ |
||
4973 | |||
4974 | //ush bl_count[MAX_BITS+1]; |
||
4975 | this.bl_count = new utils.Buf16(MAX_BITS+1); |
||
4976 | /* number of codes at each bit length for an optimal tree */ |
||
4977 | |||
4978 | //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ |
||
4979 | this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ |
||
4980 | zero(this.heap); |
||
4981 | |||
4982 | this.heap_len = 0; /* number of elements in the heap */ |
||
4983 | this.heap_max = 0; /* element of largest frequency */ |
||
4984 | /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. |
||
4985 | * The same heap array is used to build all trees. |
||
4986 | */ |
||
4987 | |||
4988 | this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; |
||
4989 | zero(this.depth); |
||
4990 | /* Depth of each subtree used as tie breaker for trees of equal frequency |
||
4991 | */ |
||
4992 | |||
4993 | this.l_buf = 0; /* buffer index for literals or lengths */ |
||
4994 | |||
4995 | this.lit_bufsize = 0; |
||
4996 | /* Size of match buffer for literals/lengths. There are 4 reasons for |
||
4997 | * limiting lit_bufsize to 64K: |
||
4998 | * - frequencies can be kept in 16 bit counters |
||
4999 | * - if compression is not successful for the first block, all input |
||
5000 | * data is still in the window so we can still emit a stored block even |
||
5001 | * when input comes from standard input. (This can also be done for |
||
5002 | * all blocks if lit_bufsize is not greater than 32K.) |
||
5003 | * - if compression is not successful for a file smaller than 64K, we can |
||
5004 | * even emit a stored file instead of a stored block (saving 5 bytes). |
||
5005 | * This is applicable only for zip (not gzip or zlib). |
||
5006 | * - creating new Huffman trees less frequently may not provide fast |
||
5007 | * adaptation to changes in the input data statistics. (Take for |
||
5008 | * example a binary file with poorly compressible code followed by |
||
5009 | * a highly compressible string table.) Smaller buffer sizes give |
||
5010 | * fast adaptation but have of course the overhead of transmitting |
||
5011 | * trees more frequently. |
||
5012 | * - I can't count above 4 |
||
5013 | */ |
||
5014 | |||
5015 | this.last_lit = 0; /* running index in l_buf */ |
||
5016 | |||
5017 | this.d_buf = 0; |
||
5018 | /* Buffer index for distances. To simplify the code, d_buf and l_buf have |
||
5019 | * the same number of elements. To use different lengths, an extra flag |
||
5020 | * array would be necessary. |
||
5021 | */ |
||
5022 | |||
5023 | this.opt_len = 0; /* bit length of current block with optimal trees */ |
||
5024 | this.static_len = 0; /* bit length of current block with static trees */ |
||
5025 | this.matches = 0; /* number of string matches in current block */ |
||
5026 | this.insert = 0; /* bytes at end of window left to insert */ |
||
5027 | |||
5028 | |||
5029 | this.bi_buf = 0; |
||
5030 | /* Output buffer. bits are inserted starting at the bottom (least |
||
5031 | * significant bits). |
||
5032 | */ |
||
5033 | this.bi_valid = 0; |
||
5034 | /* Number of valid bits in bi_buf. All bits above the last valid bit |
||
5035 | * are always zero. |
||
5036 | */ |
||
5037 | |||
5038 | // Used for window memory init. We safely ignore it for JS. That makes |
||
5039 | // sense only for pointers and memory check tools. |
||
5040 | //this.high_water = 0; |
||
5041 | /* High water mark offset in window for initialized bytes -- bytes above |
||
5042 | * this are set to zero in order to avoid memory check warnings when |
||
5043 | * longest match routines access bytes past the input. This is then |
||
5044 | * updated to the new high water mark. |
||
5045 | */ |
||
5046 | } |
||
5047 | |||
5048 | |||
5049 | function deflateResetKeep(strm) { |
||
5050 | var s; |
||
5051 | |||
5052 | if (!strm || !strm.state) { |
||
5053 | return err(strm, Z_STREAM_ERROR); |
||
5054 | } |
||
5055 | |||
5056 | strm.total_in = strm.total_out = 0; |
||
5057 | strm.data_type = Z_UNKNOWN; |
||
5058 | |||
5059 | s = strm.state; |
||
5060 | s.pending = 0; |
||
5061 | s.pending_out = 0; |
||
5062 | |||
5063 | if (s.wrap < 0) { |
||
5064 | s.wrap = -s.wrap; |
||
5065 | /* was made negative by deflate(..., Z_FINISH); */ |
||
5066 | } |
||
5067 | s.status = (s.wrap ? INIT_STATE : BUSY_STATE); |
||
5068 | strm.adler = (s.wrap === 2) ? |
||
5069 | 0 // crc32(0, Z_NULL, 0) |
||
5070 | : |
||
5071 | 1; // adler32(0, Z_NULL, 0) |
||
5072 | s.last_flush = Z_NO_FLUSH; |
||
5073 | trees._tr_init(s); |
||
5074 | return Z_OK; |
||
5075 | } |
||
5076 | |||
5077 | |||
5078 | function deflateReset(strm) { |
||
5079 | var ret = deflateResetKeep(strm); |
||
5080 | if (ret === Z_OK) { |
||
5081 | lm_init(strm.state); |
||
5082 | } |
||
5083 | return ret; |
||
5084 | } |
||
5085 | |||
5086 | |||
5087 | function deflateSetHeader(strm, head) { |
||
5088 | if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
||
5089 | if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } |
||
5090 | strm.state.gzhead = head; |
||
5091 | return Z_OK; |
||
5092 | } |
||
5093 | |||
5094 | |||
5095 | function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { |
||
5096 | if (!strm) { // === Z_NULL |
||
5097 | return Z_STREAM_ERROR; |
||
5098 | } |
||
5099 | var wrap = 1; |
||
5100 | |||
5101 | if (level === Z_DEFAULT_COMPRESSION) { |
||
5102 | level = 6; |
||
5103 | } |
||
5104 | |||
5105 | if (windowBits < 0) { /* suppress zlib wrapper */ |
||
5106 | wrap = 0; |
||
5107 | windowBits = -windowBits; |
||
5108 | } |
||
5109 | |||
5110 | else if (windowBits > 15) { |
||
5111 | wrap = 2; /* write gzip wrapper instead */ |
||
5112 | windowBits -= 16; |
||
5113 | } |
||
5114 | |||
5115 | |||
5116 | if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || |
||
5117 | windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || |
||
5118 | strategy < 0 || strategy > Z_FIXED) { |
||
5119 | return err(strm, Z_STREAM_ERROR); |
||
5120 | } |
||
5121 | |||
5122 | |||
5123 | if (windowBits === 8) { |
||
5124 | windowBits = 9; |
||
5125 | } |
||
5126 | /* until 256-byte window bug fixed */ |
||
5127 | |||
5128 | var s = new DeflateState(); |
||
5129 | |||
5130 | strm.state = s; |
||
5131 | s.strm = strm; |
||
5132 | |||
5133 | s.wrap = wrap; |
||
5134 | s.gzhead = null; |
||
5135 | s.w_bits = windowBits; |
||
5136 | s.w_size = 1 << s.w_bits; |
||
5137 | s.w_mask = s.w_size - 1; |
||
5138 | |||
5139 | s.hash_bits = memLevel + 7; |
||
5140 | s.hash_size = 1 << s.hash_bits; |
||
5141 | s.hash_mask = s.hash_size - 1; |
||
5142 | s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); |
||
5143 | |||
5144 | s.window = new utils.Buf8(s.w_size * 2); |
||
5145 | s.head = new utils.Buf16(s.hash_size); |
||
5146 | s.prev = new utils.Buf16(s.w_size); |
||
5147 | |||
5148 | // Don't need mem init magic for JS. |
||
5149 | //s.high_water = 0; /* nothing written to s->window yet */ |
||
5150 | |||
5151 | s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ |
||
5152 | |||
5153 | s.pending_buf_size = s.lit_bufsize * 4; |
||
5154 | s.pending_buf = new utils.Buf8(s.pending_buf_size); |
||
5155 | |||
5156 | s.d_buf = s.lit_bufsize >> 1; |
||
5157 | s.l_buf = (1 + 2) * s.lit_bufsize; |
||
5158 | |||
5159 | s.level = level; |
||
5160 | s.strategy = strategy; |
||
5161 | s.method = method; |
||
5162 | |||
5163 | return deflateReset(strm); |
||
5164 | } |
||
5165 | |||
5166 | function deflateInit(strm, level) { |
||
5167 | return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); |
||
5168 | } |
||
5169 | |||
5170 | |||
5171 | function deflate(strm, flush) { |
||
5172 | var old_flush, s; |
||
5173 | var beg, val; // for gzip header write only |
||
5174 | |||
5175 | if (!strm || !strm.state || |
||
5176 | flush > Z_BLOCK || flush < 0) { |
||
5177 | return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; |
||
5178 | } |
||
5179 | |||
5180 | s = strm.state; |
||
5181 | |||
5182 | if (!strm.output || |
||
5183 | (!strm.input && strm.avail_in !== 0) || |
||
5184 | (s.status === FINISH_STATE && flush !== Z_FINISH)) { |
||
5185 | return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); |
||
5186 | } |
||
5187 | |||
5188 | s.strm = strm; /* just in case */ |
||
5189 | old_flush = s.last_flush; |
||
5190 | s.last_flush = flush; |
||
5191 | |||
5192 | /* Write the header */ |
||
5193 | if (s.status === INIT_STATE) { |
||
5194 | |||
5195 | if (s.wrap === 2) { // GZIP header |
||
5196 | strm.adler = 0; //crc32(0L, Z_NULL, 0); |
||
5197 | put_byte(s, 31); |
||
5198 | put_byte(s, 139); |
||
5199 | put_byte(s, 8); |
||
5200 | if (!s.gzhead) { // s->gzhead == Z_NULL |
||
5201 | put_byte(s, 0); |
||
5202 | put_byte(s, 0); |
||
5203 | put_byte(s, 0); |
||
5204 | put_byte(s, 0); |
||
5205 | put_byte(s, 0); |
||
5206 | put_byte(s, s.level === 9 ? 2 : |
||
5207 | (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? |
||
5208 | 4 : 0)); |
||
5209 | put_byte(s, OS_CODE); |
||
5210 | s.status = BUSY_STATE; |
||
5211 | } |
||
5212 | else { |
||
5213 | put_byte(s, (s.gzhead.text ? 1 : 0) + |
||
5214 | (s.gzhead.hcrc ? 2 : 0) + |
||
5215 | (!s.gzhead.extra ? 0 : 4) + |
||
5216 | (!s.gzhead.name ? 0 : 8) + |
||
5217 | (!s.gzhead.comment ? 0 : 16) |
||
5218 | ); |
||
5219 | put_byte(s, s.gzhead.time & 0xff); |
||
5220 | put_byte(s, (s.gzhead.time >> 8) & 0xff); |
||
5221 | put_byte(s, (s.gzhead.time >> 16) & 0xff); |
||
5222 | put_byte(s, (s.gzhead.time >> 24) & 0xff); |
||
5223 | put_byte(s, s.level === 9 ? 2 : |
||
5224 | (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? |
||
5225 | 4 : 0)); |
||
5226 | put_byte(s, s.gzhead.os & 0xff); |
||
5227 | if (s.gzhead.extra && s.gzhead.extra.length) { |
||
5228 | put_byte(s, s.gzhead.extra.length & 0xff); |
||
5229 | put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); |
||
5230 | } |
||
5231 | if (s.gzhead.hcrc) { |
||
5232 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); |
||
5233 | } |
||
5234 | s.gzindex = 0; |
||
5235 | s.status = EXTRA_STATE; |
||
5236 | } |
||
5237 | } |
||
5238 | else // DEFLATE header |
||
5239 | { |
||
5240 | var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; |
||
5241 | var level_flags = -1; |
||
5242 | |||
5243 | if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { |
||
5244 | level_flags = 0; |
||
5245 | } else if (s.level < 6) { |
||
5246 | level_flags = 1; |
||
5247 | } else if (s.level === 6) { |
||
5248 | level_flags = 2; |
||
5249 | } else { |
||
5250 | level_flags = 3; |
||
5251 | } |
||
5252 | header |= (level_flags << 6); |
||
5253 | if (s.strstart !== 0) { header |= PRESET_DICT; } |
||
5254 | header += 31 - (header % 31); |
||
5255 | |||
5256 | s.status = BUSY_STATE; |
||
5257 | putShortMSB(s, header); |
||
5258 | |||
5259 | /* Save the adler32 of the preset dictionary: */ |
||
5260 | if (s.strstart !== 0) { |
||
5261 | putShortMSB(s, strm.adler >>> 16); |
||
5262 | putShortMSB(s, strm.adler & 0xffff); |
||
5263 | } |
||
5264 | strm.adler = 1; // adler32(0L, Z_NULL, 0); |
||
5265 | } |
||
5266 | } |
||
5267 | |||
5268 | //#ifdef GZIP |
||
5269 | if (s.status === EXTRA_STATE) { |
||
5270 | if (s.gzhead.extra/* != Z_NULL*/) { |
||
5271 | beg = s.pending; /* start of bytes to update crc */ |
||
5272 | |||
5273 | while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { |
||
5274 | if (s.pending === s.pending_buf_size) { |
||
5275 | if (s.gzhead.hcrc && s.pending > beg) { |
||
5276 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5277 | } |
||
5278 | flush_pending(strm); |
||
5279 | beg = s.pending; |
||
5280 | if (s.pending === s.pending_buf_size) { |
||
5281 | break; |
||
5282 | } |
||
5283 | } |
||
5284 | put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); |
||
5285 | s.gzindex++; |
||
5286 | } |
||
5287 | if (s.gzhead.hcrc && s.pending > beg) { |
||
5288 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5289 | } |
||
5290 | if (s.gzindex === s.gzhead.extra.length) { |
||
5291 | s.gzindex = 0; |
||
5292 | s.status = NAME_STATE; |
||
5293 | } |
||
5294 | } |
||
5295 | else { |
||
5296 | s.status = NAME_STATE; |
||
5297 | } |
||
5298 | } |
||
5299 | View Code Duplication | if (s.status === NAME_STATE) { |
|
5300 | if (s.gzhead.name/* != Z_NULL*/) { |
||
5301 | beg = s.pending; /* start of bytes to update crc */ |
||
5302 | //int val; |
||
5303 | |||
5304 | do { |
||
5305 | if (s.pending === s.pending_buf_size) { |
||
5306 | if (s.gzhead.hcrc && s.pending > beg) { |
||
5307 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5308 | } |
||
5309 | flush_pending(strm); |
||
5310 | beg = s.pending; |
||
5311 | if (s.pending === s.pending_buf_size) { |
||
5312 | val = 1; |
||
5313 | break; |
||
5314 | } |
||
5315 | } |
||
5316 | // JS specific: little magic to add zero terminator to end of string |
||
5317 | if (s.gzindex < s.gzhead.name.length) { |
||
5318 | val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; |
||
5319 | } else { |
||
5320 | val = 0; |
||
5321 | } |
||
5322 | put_byte(s, val); |
||
5323 | } while (val !== 0); |
||
5324 | |||
5325 | if (s.gzhead.hcrc && s.pending > beg){ |
||
5326 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5327 | } |
||
5328 | if (val === 0) { |
||
5329 | s.gzindex = 0; |
||
5330 | s.status = COMMENT_STATE; |
||
5331 | } |
||
5332 | } |
||
5333 | else { |
||
5334 | s.status = COMMENT_STATE; |
||
5335 | } |
||
5336 | } |
||
5337 | View Code Duplication | if (s.status === COMMENT_STATE) { |
|
5338 | if (s.gzhead.comment/* != Z_NULL*/) { |
||
5339 | beg = s.pending; /* start of bytes to update crc */ |
||
5340 | //int val; |
||
5341 | |||
5342 | do { |
||
5343 | if (s.pending === s.pending_buf_size) { |
||
5344 | if (s.gzhead.hcrc && s.pending > beg) { |
||
5345 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5346 | } |
||
5347 | flush_pending(strm); |
||
5348 | beg = s.pending; |
||
5349 | if (s.pending === s.pending_buf_size) { |
||
5350 | val = 1; |
||
5351 | break; |
||
5352 | } |
||
5353 | } |
||
5354 | // JS specific: little magic to add zero terminator to end of string |
||
5355 | if (s.gzindex < s.gzhead.comment.length) { |
||
5356 | val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; |
||
5357 | } else { |
||
5358 | val = 0; |
||
5359 | } |
||
5360 | put_byte(s, val); |
||
5361 | } while (val !== 0); |
||
5362 | |||
5363 | if (s.gzhead.hcrc && s.pending > beg) { |
||
5364 | strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
||
5365 | } |
||
5366 | if (val === 0) { |
||
5367 | s.status = HCRC_STATE; |
||
5368 | } |
||
5369 | } |
||
5370 | else { |
||
5371 | s.status = HCRC_STATE; |
||
5372 | } |
||
5373 | } |
||
5374 | if (s.status === HCRC_STATE) { |
||
5375 | if (s.gzhead.hcrc) { |
||
5376 | if (s.pending + 2 > s.pending_buf_size) { |
||
5377 | flush_pending(strm); |
||
5378 | } |
||
5379 | if (s.pending + 2 <= s.pending_buf_size) { |
||
5380 | put_byte(s, strm.adler & 0xff); |
||
5381 | put_byte(s, (strm.adler >> 8) & 0xff); |
||
5382 | strm.adler = 0; //crc32(0L, Z_NULL, 0); |
||
5383 | s.status = BUSY_STATE; |
||
5384 | } |
||
5385 | } |
||
5386 | else { |
||
5387 | s.status = BUSY_STATE; |
||
5388 | } |
||
5389 | } |
||
5390 | //#endif |
||
5391 | |||
5392 | /* Flush as much pending output as possible */ |
||
5393 | if (s.pending !== 0) { |
||
5394 | flush_pending(strm); |
||
5395 | if (strm.avail_out === 0) { |
||
5396 | /* Since avail_out is 0, deflate will be called again with |
||
5397 | * more output space, but possibly with both pending and |
||
5398 | * avail_in equal to zero. There won't be anything to do, |
||
5399 | * but this is not an error situation so make sure we |
||
5400 | * return OK instead of BUF_ERROR at next call of deflate: |
||
5401 | */ |
||
5402 | s.last_flush = -1; |
||
5403 | return Z_OK; |
||
5404 | } |
||
5405 | |||
5406 | /* Make sure there is something to do and avoid duplicate consecutive |
||
5407 | * flushes. For repeated and useless calls with Z_FINISH, we keep |
||
5408 | * returning Z_STREAM_END instead of Z_BUF_ERROR. |
||
5409 | */ |
||
5410 | } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && |
||
5411 | flush !== Z_FINISH) { |
||
5412 | return err(strm, Z_BUF_ERROR); |
||
5413 | } |
||
5414 | |||
5415 | /* User must not provide more input after the first FINISH: */ |
||
5416 | if (s.status === FINISH_STATE && strm.avail_in !== 0) { |
||
5417 | return err(strm, Z_BUF_ERROR); |
||
5418 | } |
||
5419 | |||
5420 | /* Start a new block or continue the current one. |
||
5421 | */ |
||
5422 | if (strm.avail_in !== 0 || s.lookahead !== 0 || |
||
5423 | (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { |
||
5424 | var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : |
||
5425 | (s.strategy === Z_RLE ? deflate_rle(s, flush) : |
||
5426 | configuration_table[s.level].func(s, flush)); |
||
5427 | |||
5428 | if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { |
||
5429 | s.status = FINISH_STATE; |
||
5430 | } |
||
5431 | if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { |
||
5432 | if (strm.avail_out === 0) { |
||
5433 | s.last_flush = -1; |
||
5434 | /* avoid BUF_ERROR next call, see above */ |
||
5435 | } |
||
5436 | return Z_OK; |
||
5437 | /* If flush != Z_NO_FLUSH && avail_out == 0, the next call |
||
5438 | * of deflate should use the same flush parameter to make sure |
||
5439 | * that the flush is complete. So we don't have to output an |
||
5440 | * empty block here, this will be done at next call. This also |
||
5441 | * ensures that for a very small output buffer, we emit at most |
||
5442 | * one empty block. |
||
5443 | */ |
||
5444 | } |
||
5445 | if (bstate === BS_BLOCK_DONE) { |
||
5446 | if (flush === Z_PARTIAL_FLUSH) { |
||
5447 | trees._tr_align(s); |
||
5448 | } |
||
5449 | else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ |
||
5450 | |||
5451 | trees._tr_stored_block(s, 0, 0, false); |
||
5452 | /* For a full flush, this empty block will be recognized |
||
5453 | * as a special marker by inflate_sync(). |
||
5454 | */ |
||
5455 | if (flush === Z_FULL_FLUSH) { |
||
5456 | /*** CLEAR_HASH(s); ***/ /* forget history */ |
||
5457 | zero(s.head); // Fill with NIL (= 0); |
||
5458 | |||
5459 | if (s.lookahead === 0) { |
||
5460 | s.strstart = 0; |
||
5461 | s.block_start = 0; |
||
5462 | s.insert = 0; |
||
5463 | } |
||
5464 | } |
||
5465 | } |
||
5466 | flush_pending(strm); |
||
5467 | if (strm.avail_out === 0) { |
||
5468 | s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ |
||
5469 | return Z_OK; |
||
5470 | } |
||
5471 | } |
||
5472 | } |
||
5473 | //Assert(strm->avail_out > 0, "bug2"); |
||
5474 | //if (strm.avail_out <= 0) { throw new Error("bug2");} |
||
5475 | |||
5476 | if (flush !== Z_FINISH) { return Z_OK; } |
||
5477 | if (s.wrap <= 0) { return Z_STREAM_END; } |
||
5478 | |||
5479 | /* Write the trailer */ |
||
5480 | if (s.wrap === 2) { |
||
5481 | put_byte(s, strm.adler & 0xff); |
||
5482 | put_byte(s, (strm.adler >> 8) & 0xff); |
||
5483 | put_byte(s, (strm.adler >> 16) & 0xff); |
||
5484 | put_byte(s, (strm.adler >> 24) & 0xff); |
||
5485 | put_byte(s, strm.total_in & 0xff); |
||
5486 | put_byte(s, (strm.total_in >> 8) & 0xff); |
||
5487 | put_byte(s, (strm.total_in >> 16) & 0xff); |
||
5488 | put_byte(s, (strm.total_in >> 24) & 0xff); |
||
5489 | } |
||
5490 | else |
||
5491 | { |
||
5492 | putShortMSB(s, strm.adler >>> 16); |
||
5493 | putShortMSB(s, strm.adler & 0xffff); |
||
5494 | } |
||
5495 | |||
5496 | flush_pending(strm); |
||
5497 | /* If avail_out is zero, the application will call deflate again |
||
5498 | * to flush the rest. |
||
5499 | */ |
||
5500 | if (s.wrap > 0) { s.wrap = -s.wrap; } |
||
5501 | /* write the trailer only once! */ |
||
5502 | return s.pending !== 0 ? Z_OK : Z_STREAM_END; |
||
5503 | } |
||
5504 | |||
5505 | function deflateEnd(strm) { |
||
5506 | var status; |
||
5507 | |||
5508 | if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { |
||
5509 | return Z_STREAM_ERROR; |
||
5510 | } |
||
5511 | |||
5512 | status = strm.state.status; |
||
5513 | if (status !== INIT_STATE && |
||
5514 | status !== EXTRA_STATE && |
||
5515 | status !== NAME_STATE && |
||
5516 | status !== COMMENT_STATE && |
||
5517 | status !== HCRC_STATE && |
||
5518 | status !== BUSY_STATE && |
||
5519 | status !== FINISH_STATE |
||
5520 | ) { |
||
5521 | return err(strm, Z_STREAM_ERROR); |
||
5522 | } |
||
5523 | |||
5524 | strm.state = null; |
||
5525 | |||
5526 | return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; |
||
5527 | } |
||
5528 | |||
5529 | /* ========================================================================= |
||
5530 | * Copy the source state to the destination state |
||
5531 | */ |
||
5532 | //function deflateCopy(dest, source) { |
||
5533 | // |
||
5534 | //} |
||
5535 | |||
5536 | exports.deflateInit = deflateInit; |
||
5537 | exports.deflateInit2 = deflateInit2; |
||
5538 | exports.deflateReset = deflateReset; |
||
5539 | exports.deflateResetKeep = deflateResetKeep; |
||
5540 | exports.deflateSetHeader = deflateSetHeader; |
||
5541 | exports.deflate = deflate; |
||
5542 | exports.deflateEnd = deflateEnd; |
||
5543 | exports.deflateInfo = 'pako deflate (from Nodeca project)'; |
||
5544 | |||
5545 | /* Not implemented |
||
5546 | exports.deflateBound = deflateBound; |
||
5547 | exports.deflateCopy = deflateCopy; |
||
5548 | exports.deflateSetDictionary = deflateSetDictionary; |
||
5549 | exports.deflateParams = deflateParams; |
||
5550 | exports.deflatePending = deflatePending; |
||
5551 | exports.deflatePrime = deflatePrime; |
||
5552 | exports.deflateTune = deflateTune; |
||
5553 | */ |
||
5554 | },{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(_dereq_,module,exports){ |
||
5555 | 'use strict'; |
||
5556 | |||
5557 | |||
5558 | function GZheader() { |
||
5559 | /* true if compressed data believed to be text */ |
||
5560 | this.text = 0; |
||
5561 | /* modification time */ |
||
5562 | this.time = 0; |
||
5563 | /* extra flags (not used when writing a gzip file) */ |
||
5564 | this.xflags = 0; |
||
5565 | /* operating system */ |
||
5566 | this.os = 0; |
||
5567 | /* pointer to extra field or Z_NULL if none */ |
||
5568 | this.extra = null; |
||
5569 | /* extra field length (valid if extra != Z_NULL) */ |
||
5570 | this.extra_len = 0; // Actually, we don't need it in JS, |
||
5571 | // but leave for few code modifications |
||
5572 | |||
5573 | // |
||
5574 | // Setup limits is not necessary because in js we should not preallocate memory |
||
5575 | // for inflate use constant limit in 65536 bytes |
||
5576 | // |
||
5577 | |||
5578 | /* space at extra (only when reading header) */ |
||
5579 | // this.extra_max = 0; |
||
5580 | /* pointer to zero-terminated file name or Z_NULL */ |
||
5581 | this.name = ''; |
||
5582 | /* space at name (only when reading header) */ |
||
5583 | // this.name_max = 0; |
||
5584 | /* pointer to zero-terminated comment or Z_NULL */ |
||
5585 | this.comment = ''; |
||
5586 | /* space at comment (only when reading header) */ |
||
5587 | // this.comm_max = 0; |
||
5588 | /* true if there was or will be a header crc */ |
||
5589 | this.hcrc = 0; |
||
5590 | /* true when done reading gzip header (not used when writing a gzip file) */ |
||
5591 | this.done = false; |
||
5592 | } |
||
5593 | |||
5594 | module.exports = GZheader; |
||
5595 | },{}],34:[function(_dereq_,module,exports){ |
||
5596 | 'use strict'; |
||
5597 | |||
5598 | // See state defs from inflate.js |
||
5599 | var BAD = 30; /* got a data error -- remain here until reset */ |
||
5600 | var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ |
||
5601 | |||
5602 | /* |
||
5603 | Decode literal, length, and distance codes and write out the resulting |
||
5604 | literal and match bytes until either not enough input or output is |
||
5605 | available, an end-of-block is encountered, or a data error is encountered. |
||
5606 | When large enough input and output buffers are supplied to inflate(), for |
||
5607 | example, a 16K input buffer and a 64K output buffer, more than 95% of the |
||
5608 | inflate execution time is spent in this routine. |
||
5609 | |||
5610 | Entry assumptions: |
||
5611 | |||
5612 | state.mode === LEN |
||
5613 | strm.avail_in >= 6 |
||
5614 | strm.avail_out >= 258 |
||
5615 | start >= strm.avail_out |
||
5616 | state.bits < 8 |
||
5617 | |||
5618 | On return, state.mode is one of: |
||
5619 | |||
5620 | LEN -- ran out of enough output space or enough available input |
||
5621 | TYPE -- reached end of block code, inflate() to interpret next block |
||
5622 | BAD -- error in block data |
||
5623 | |||
5624 | Notes: |
||
5625 | |||
5626 | - The maximum input bits used by a length/distance pair is 15 bits for the |
||
5627 | length code, 5 bits for the length extra, 15 bits for the distance code, |
||
5628 | and 13 bits for the distance extra. This totals 48 bits, or six bytes. |
||
5629 | Therefore if strm.avail_in >= 6, then there is enough input to avoid |
||
5630 | checking for available input while decoding. |
||
5631 | |||
5632 | - The maximum bytes that a single length/distance pair can output is 258 |
||
5633 | bytes, which is the maximum length that can be coded. inflate_fast() |
||
5634 | requires strm.avail_out >= 258 for each loop to avoid checking for |
||
5635 | output space. |
||
5636 | */ |
||
5637 | module.exports = function inflate_fast(strm, start) { |
||
5638 | var state; |
||
5639 | var _in; /* local strm.input */ |
||
5640 | var last; /* have enough input while in < last */ |
||
5641 | var _out; /* local strm.output */ |
||
5642 | var beg; /* inflate()'s initial strm.output */ |
||
5643 | var end; /* while out < end, enough space available */ |
||
5644 | //#ifdef INFLATE_STRICT |
||
5645 | var dmax; /* maximum distance from zlib header */ |
||
5646 | //#endif |
||
5647 | var wsize; /* window size or zero if not using window */ |
||
5648 | var whave; /* valid bytes in the window */ |
||
5649 | var wnext; /* window write index */ |
||
5650 | var window; /* allocated sliding window, if wsize != 0 */ |
||
5651 | var hold; /* local strm.hold */ |
||
5652 | var bits; /* local strm.bits */ |
||
5653 | var lcode; /* local strm.lencode */ |
||
5654 | var dcode; /* local strm.distcode */ |
||
5655 | var lmask; /* mask for first level of length codes */ |
||
5656 | var dmask; /* mask for first level of distance codes */ |
||
5657 | var here; /* retrieved table entry */ |
||
5658 | var op; /* code bits, operation, extra bits, or */ |
||
5659 | /* window position, window bytes to copy */ |
||
5660 | var len; /* match length, unused bytes */ |
||
5661 | var dist; /* match distance */ |
||
5662 | var from; /* where to copy match from */ |
||
5663 | var from_source; |
||
5664 | |||
5665 | |||
5666 | var input, output; // JS specific, because we have no pointers |
||
5667 | |||
5668 | /* copy state to local variables */ |
||
5669 | state = strm.state; |
||
5670 | //here = state.here; |
||
5671 | _in = strm.next_in; |
||
5672 | input = strm.input; |
||
5673 | last = _in + (strm.avail_in - 5); |
||
5674 | _out = strm.next_out; |
||
5675 | output = strm.output; |
||
5676 | beg = _out - (start - strm.avail_out); |
||
5677 | end = _out + (strm.avail_out - 257); |
||
5678 | //#ifdef INFLATE_STRICT |
||
5679 | dmax = state.dmax; |
||
5680 | //#endif |
||
5681 | wsize = state.wsize; |
||
5682 | whave = state.whave; |
||
5683 | wnext = state.wnext; |
||
5684 | window = state.window; |
||
5685 | hold = state.hold; |
||
5686 | bits = state.bits; |
||
5687 | lcode = state.lencode; |
||
5688 | dcode = state.distcode; |
||
5689 | lmask = (1 << state.lenbits) - 1; |
||
5690 | dmask = (1 << state.distbits) - 1; |
||
5691 | |||
5692 | |||
5693 | /* decode literals and length/distances until end-of-block or not enough |
||
5694 | input data or output space */ |
||
5695 | |||
5696 | top: |
||
5697 | do { |
||
5698 | if (bits < 15) { |
||
5699 | hold += input[_in++] << bits; |
||
5700 | bits += 8; |
||
5701 | hold += input[_in++] << bits; |
||
5702 | bits += 8; |
||
5703 | } |
||
5704 | |||
5705 | here = lcode[hold & lmask]; |
||
5706 | |||
5707 | dolen: |
||
5708 | for (;;) { // Goto emulation |
||
5709 | op = here >>> 24/*here.bits*/; |
||
5710 | hold >>>= op; |
||
5711 | bits -= op; |
||
5712 | op = (here >>> 16) & 0xff/*here.op*/; |
||
5713 | if (op === 0) { /* literal */ |
||
5714 | //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
||
5715 | // "inflate: literal '%c'\n" : |
||
5716 | // "inflate: literal 0x%02x\n", here.val)); |
||
5717 | output[_out++] = here & 0xffff/*here.val*/; |
||
5718 | } |
||
5719 | else if (op & 16) { /* length base */ |
||
5720 | len = here & 0xffff/*here.val*/; |
||
5721 | op &= 15; /* number of extra bits */ |
||
5722 | if (op) { |
||
5723 | if (bits < op) { |
||
5724 | hold += input[_in++] << bits; |
||
5725 | bits += 8; |
||
5726 | } |
||
5727 | len += hold & ((1 << op) - 1); |
||
5728 | hold >>>= op; |
||
5729 | bits -= op; |
||
5730 | } |
||
5731 | //Tracevv((stderr, "inflate: length %u\n", len)); |
||
5732 | if (bits < 15) { |
||
5733 | hold += input[_in++] << bits; |
||
5734 | bits += 8; |
||
5735 | hold += input[_in++] << bits; |
||
5736 | bits += 8; |
||
5737 | } |
||
5738 | here = dcode[hold & dmask]; |
||
5739 | |||
5740 | dodist: |
||
5741 | for (;;) { // goto emulation |
||
5742 | op = here >>> 24/*here.bits*/; |
||
5743 | hold >>>= op; |
||
5744 | bits -= op; |
||
5745 | op = (here >>> 16) & 0xff/*here.op*/; |
||
5746 | |||
5747 | if (op & 16) { /* distance base */ |
||
5748 | dist = here & 0xffff/*here.val*/; |
||
5749 | op &= 15; /* number of extra bits */ |
||
5750 | if (bits < op) { |
||
5751 | hold += input[_in++] << bits; |
||
5752 | bits += 8; |
||
5753 | if (bits < op) { |
||
5754 | hold += input[_in++] << bits; |
||
5755 | bits += 8; |
||
5756 | } |
||
5757 | } |
||
5758 | dist += hold & ((1 << op) - 1); |
||
5759 | //#ifdef INFLATE_STRICT |
||
5760 | if (dist > dmax) { |
||
5761 | strm.msg = 'invalid distance too far back'; |
||
5762 | state.mode = BAD; |
||
5763 | break top; |
||
5764 | } |
||
5765 | //#endif |
||
5766 | hold >>>= op; |
||
5767 | bits -= op; |
||
5768 | //Tracevv((stderr, "inflate: distance %u\n", dist)); |
||
5769 | op = _out - beg; /* max distance in output */ |
||
5770 | if (dist > op) { /* see if copy from window */ |
||
5771 | op = dist - op; /* distance back in window */ |
||
5772 | if (op > whave) { |
||
5773 | if (state.sane) { |
||
5774 | strm.msg = 'invalid distance too far back'; |
||
5775 | state.mode = BAD; |
||
5776 | break top; |
||
5777 | } |
||
5778 | |||
5779 | // (!) This block is disabled in zlib defailts, |
||
5780 | // don't enable it for binary compatibility |
||
5781 | //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR |
||
5782 | // if (len <= op - whave) { |
||
5783 | // do { |
||
5784 | // output[_out++] = 0; |
||
5785 | // } while (--len); |
||
5786 | // continue top; |
||
5787 | // } |
||
5788 | // len -= op - whave; |
||
5789 | // do { |
||
5790 | // output[_out++] = 0; |
||
5791 | // } while (--op > whave); |
||
5792 | // if (op === 0) { |
||
5793 | // from = _out - dist; |
||
5794 | // do { |
||
5795 | // output[_out++] = output[from++]; |
||
5796 | // } while (--len); |
||
5797 | // continue top; |
||
5798 | // } |
||
5799 | //#endif |
||
5800 | } |
||
5801 | from = 0; // window index |
||
5802 | from_source = window; |
||
5803 | if (wnext === 0) { /* very common case */ |
||
5804 | from += wsize - op; |
||
5805 | if (op < len) { /* some from window */ |
||
5806 | len -= op; |
||
5807 | do { |
||
5808 | output[_out++] = window[from++]; |
||
5809 | } while (--op); |
||
5810 | from = _out - dist; /* rest from output */ |
||
5811 | from_source = output; |
||
5812 | } |
||
5813 | } |
||
5814 | else if (wnext < op) { /* wrap around window */ |
||
5815 | from += wsize + wnext - op; |
||
5816 | op -= wnext; |
||
5817 | if (op < len) { /* some from end of window */ |
||
5818 | len -= op; |
||
5819 | do { |
||
5820 | output[_out++] = window[from++]; |
||
5821 | } while (--op); |
||
5822 | from = 0; |
||
5823 | if (wnext < len) { /* some from start of window */ |
||
5824 | op = wnext; |
||
5825 | len -= op; |
||
5826 | do { |
||
5827 | output[_out++] = window[from++]; |
||
5828 | } while (--op); |
||
5829 | from = _out - dist; /* rest from output */ |
||
5830 | from_source = output; |
||
5831 | } |
||
5832 | } |
||
5833 | } |
||
5834 | else { /* contiguous in window */ |
||
5835 | from += wnext - op; |
||
5836 | if (op < len) { /* some from window */ |
||
5837 | len -= op; |
||
5838 | do { |
||
5839 | output[_out++] = window[from++]; |
||
5840 | } while (--op); |
||
5841 | from = _out - dist; /* rest from output */ |
||
5842 | from_source = output; |
||
5843 | } |
||
5844 | } |
||
5845 | while (len > 2) { |
||
5846 | output[_out++] = from_source[from++]; |
||
5847 | output[_out++] = from_source[from++]; |
||
5848 | output[_out++] = from_source[from++]; |
||
5849 | len -= 3; |
||
5850 | } |
||
5851 | if (len) { |
||
5852 | output[_out++] = from_source[from++]; |
||
5853 | if (len > 1) { |
||
5854 | output[_out++] = from_source[from++]; |
||
5855 | } |
||
5856 | } |
||
5857 | } |
||
5858 | else { |
||
5859 | from = _out - dist; /* copy direct from output */ |
||
5860 | do { /* minimum length is three */ |
||
5861 | output[_out++] = output[from++]; |
||
5862 | output[_out++] = output[from++]; |
||
5863 | output[_out++] = output[from++]; |
||
5864 | len -= 3; |
||
5865 | } while (len > 2); |
||
5866 | if (len) { |
||
5867 | output[_out++] = output[from++]; |
||
5868 | if (len > 1) { |
||
5869 | output[_out++] = output[from++]; |
||
5870 | } |
||
5871 | } |
||
5872 | } |
||
5873 | } |
||
5874 | else if ((op & 64) === 0) { /* 2nd level distance code */ |
||
5875 | here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; |
||
5876 | continue dodist; |
||
5877 | } |
||
5878 | else { |
||
5879 | strm.msg = 'invalid distance code'; |
||
5880 | state.mode = BAD; |
||
5881 | break top; |
||
5882 | } |
||
5883 | |||
5884 | break; // need to emulate goto via "continue" |
||
5885 | } |
||
5886 | } |
||
5887 | else if ((op & 64) === 0) { /* 2nd level length code */ |
||
5888 | here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; |
||
5889 | continue dolen; |
||
5890 | } |
||
5891 | else if (op & 32) { /* end-of-block */ |
||
5892 | //Tracevv((stderr, "inflate: end of block\n")); |
||
5893 | state.mode = TYPE; |
||
5894 | break top; |
||
5895 | } |
||
5896 | else { |
||
5897 | strm.msg = 'invalid literal/length code'; |
||
5898 | state.mode = BAD; |
||
5899 | break top; |
||
5900 | } |
||
5901 | |||
5902 | break; // need to emulate goto via "continue" |
||
5903 | } |
||
5904 | } while (_in < last && _out < end); |
||
5905 | |||
5906 | /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ |
||
5907 | len = bits >> 3; |
||
5908 | _in -= len; |
||
5909 | bits -= len << 3; |
||
5910 | hold &= (1 << bits) - 1; |
||
5911 | |||
5912 | /* update state and return */ |
||
5913 | strm.next_in = _in; |
||
5914 | strm.next_out = _out; |
||
5915 | strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); |
||
5916 | strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); |
||
5917 | state.hold = hold; |
||
5918 | state.bits = bits; |
||
5919 | return; |
||
5920 | }; |
||
5921 | |||
5922 | },{}],35:[function(_dereq_,module,exports){ |
||
5923 | 'use strict'; |
||
5924 | |||
5925 | |||
5926 | var utils = _dereq_('../utils/common'); |
||
5927 | var adler32 = _dereq_('./adler32'); |
||
5928 | var crc32 = _dereq_('./crc32'); |
||
5929 | var inflate_fast = _dereq_('./inffast'); |
||
5930 | var inflate_table = _dereq_('./inftrees'); |
||
5931 | |||
5932 | var CODES = 0; |
||
5933 | var LENS = 1; |
||
5934 | var DISTS = 2; |
||
5935 | |||
5936 | /* Public constants ==========================================================*/ |
||
5937 | /* ===========================================================================*/ |
||
5938 | |||
5939 | |||
5940 | /* Allowed flush values; see deflate() and inflate() below for details */ |
||
5941 | //var Z_NO_FLUSH = 0; |
||
5942 | //var Z_PARTIAL_FLUSH = 1; |
||
5943 | //var Z_SYNC_FLUSH = 2; |
||
5944 | //var Z_FULL_FLUSH = 3; |
||
5945 | var Z_FINISH = 4; |
||
5946 | var Z_BLOCK = 5; |
||
5947 | var Z_TREES = 6; |
||
5948 | |||
5949 | |||
5950 | /* Return codes for the compression/decompression functions. Negative values |
||
5951 | * are errors, positive values are used for special but normal events. |
||
5952 | */ |
||
5953 | var Z_OK = 0; |
||
5954 | var Z_STREAM_END = 1; |
||
5955 | var Z_NEED_DICT = 2; |
||
5956 | //var Z_ERRNO = -1; |
||
5957 | var Z_STREAM_ERROR = -2; |
||
5958 | var Z_DATA_ERROR = -3; |
||
5959 | var Z_MEM_ERROR = -4; |
||
5960 | var Z_BUF_ERROR = -5; |
||
5961 | //var Z_VERSION_ERROR = -6; |
||
5962 | |||
5963 | /* The deflate compression method */ |
||
5964 | var Z_DEFLATED = 8; |
||
5965 | |||
5966 | |||
5967 | /* STATES ====================================================================*/ |
||
5968 | /* ===========================================================================*/ |
||
5969 | |||
5970 | |||
5971 | var HEAD = 1; /* i: waiting for magic header */ |
||
5972 | var FLAGS = 2; /* i: waiting for method and flags (gzip) */ |
||
5973 | var TIME = 3; /* i: waiting for modification time (gzip) */ |
||
5974 | var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ |
||
5975 | var EXLEN = 5; /* i: waiting for extra length (gzip) */ |
||
5976 | var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ |
||
5977 | var NAME = 7; /* i: waiting for end of file name (gzip) */ |
||
5978 | var COMMENT = 8; /* i: waiting for end of comment (gzip) */ |
||
5979 | var HCRC = 9; /* i: waiting for header crc (gzip) */ |
||
5980 | var DICTID = 10; /* i: waiting for dictionary check value */ |
||
5981 | var DICT = 11; /* waiting for inflateSetDictionary() call */ |
||
5982 | var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ |
||
5983 | var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ |
||
5984 | var STORED = 14; /* i: waiting for stored size (length and complement) */ |
||
5985 | var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ |
||
5986 | var COPY = 16; /* i/o: waiting for input or output to copy stored block */ |
||
5987 | var TABLE = 17; /* i: waiting for dynamic block table lengths */ |
||
5988 | var LENLENS = 18; /* i: waiting for code length code lengths */ |
||
5989 | var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ |
||
5990 | var LEN_ = 20; /* i: same as LEN below, but only first time in */ |
||
5991 | var LEN = 21; /* i: waiting for length/lit/eob code */ |
||
5992 | var LENEXT = 22; /* i: waiting for length extra bits */ |
||
5993 | var DIST = 23; /* i: waiting for distance code */ |
||
5994 | var DISTEXT = 24; /* i: waiting for distance extra bits */ |
||
5995 | var MATCH = 25; /* o: waiting for output space to copy string */ |
||
5996 | var LIT = 26; /* o: waiting for output space to write literal */ |
||
5997 | var CHECK = 27; /* i: waiting for 32-bit check value */ |
||
5998 | var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ |
||
5999 | var DONE = 29; /* finished check, done -- remain here until reset */ |
||
6000 | var BAD = 30; /* got a data error -- remain here until reset */ |
||
6001 | var MEM = 31; /* got an inflate() memory error -- remain here until reset */ |
||
6002 | var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ |
||
6003 | |||
6004 | /* ===========================================================================*/ |
||
6005 | |||
6006 | |||
6007 | |||
6008 | var ENOUGH_LENS = 852; |
||
6009 | var ENOUGH_DISTS = 592; |
||
6010 | //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); |
||
6011 | |||
6012 | var MAX_WBITS = 15; |
||
6013 | /* 32K LZ77 window */ |
||
6014 | var DEF_WBITS = MAX_WBITS; |
||
6015 | |||
6016 | |||
6017 | function ZSWAP32(q) { |
||
6018 | return (((q >>> 24) & 0xff) + |
||
6019 | ((q >>> 8) & 0xff00) + |
||
6020 | ((q & 0xff00) << 8) + |
||
6021 | ((q & 0xff) << 24)); |
||
6022 | } |
||
6023 | |||
6024 | |||
6025 | function InflateState() { |
||
6026 | this.mode = 0; /* current inflate mode */ |
||
6027 | this.last = false; /* true if processing last block */ |
||
6028 | this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ |
||
6029 | this.havedict = false; /* true if dictionary provided */ |
||
6030 | this.flags = 0; /* gzip header method and flags (0 if zlib) */ |
||
6031 | this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ |
||
6032 | this.check = 0; /* protected copy of check value */ |
||
6033 | this.total = 0; /* protected copy of output count */ |
||
6034 | // TODO: may be {} |
||
6035 | this.head = null; /* where to save gzip header information */ |
||
6036 | |||
6037 | /* sliding window */ |
||
6038 | this.wbits = 0; /* log base 2 of requested window size */ |
||
6039 | this.wsize = 0; /* window size or zero if not using window */ |
||
6040 | this.whave = 0; /* valid bytes in the window */ |
||
6041 | this.wnext = 0; /* window write index */ |
||
6042 | this.window = null; /* allocated sliding window, if needed */ |
||
6043 | |||
6044 | /* bit accumulator */ |
||
6045 | this.hold = 0; /* input bit accumulator */ |
||
6046 | this.bits = 0; /* number of bits in "in" */ |
||
6047 | |||
6048 | /* for string and stored block copying */ |
||
6049 | this.length = 0; /* literal or length of data to copy */ |
||
6050 | this.offset = 0; /* distance back to copy string from */ |
||
6051 | |||
6052 | /* for table and code decoding */ |
||
6053 | this.extra = 0; /* extra bits needed */ |
||
6054 | |||
6055 | /* fixed and dynamic code tables */ |
||
6056 | this.lencode = null; /* starting table for length/literal codes */ |
||
6057 | this.distcode = null; /* starting table for distance codes */ |
||
6058 | this.lenbits = 0; /* index bits for lencode */ |
||
6059 | this.distbits = 0; /* index bits for distcode */ |
||
6060 | |||
6061 | /* dynamic table building */ |
||
6062 | this.ncode = 0; /* number of code length code lengths */ |
||
6063 | this.nlen = 0; /* number of length code lengths */ |
||
6064 | this.ndist = 0; /* number of distance code lengths */ |
||
6065 | this.have = 0; /* number of code lengths in lens[] */ |
||
6066 | this.next = null; /* next available space in codes[] */ |
||
6067 | |||
6068 | this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ |
||
6069 | this.work = new utils.Buf16(288); /* work area for code table building */ |
||
6070 | |||
6071 | /* |
||
6072 | because we don't have pointers in js, we use lencode and distcode directly |
||
6073 | as buffers so we don't need codes |
||
6074 | */ |
||
6075 | //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ |
||
6076 | this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ |
||
6077 | this.distdyn = null; /* dynamic table for distance codes (JS specific) */ |
||
6078 | this.sane = 0; /* if false, allow invalid distance too far */ |
||
6079 | this.back = 0; /* bits back of last unprocessed length/lit */ |
||
6080 | this.was = 0; /* initial length of match */ |
||
6081 | } |
||
6082 | |||
6083 | function inflateResetKeep(strm) { |
||
6084 | var state; |
||
6085 | |||
6086 | if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
||
6087 | state = strm.state; |
||
6088 | strm.total_in = strm.total_out = state.total = 0; |
||
6089 | strm.msg = ''; /*Z_NULL*/ |
||
6090 | if (state.wrap) { /* to support ill-conceived Java test suite */ |
||
6091 | strm.adler = state.wrap & 1; |
||
6092 | } |
||
6093 | state.mode = HEAD; |
||
6094 | state.last = 0; |
||
6095 | state.havedict = 0; |
||
6096 | state.dmax = 32768; |
||
6097 | state.head = null/*Z_NULL*/; |
||
6098 | state.hold = 0; |
||
6099 | state.bits = 0; |
||
6100 | //state.lencode = state.distcode = state.next = state.codes; |
||
6101 | state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); |
||
6102 | state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); |
||
6103 | |||
6104 | state.sane = 1; |
||
6105 | state.back = -1; |
||
6106 | //Tracev((stderr, "inflate: reset\n")); |
||
6107 | return Z_OK; |
||
6108 | } |
||
6109 | |||
6110 | function inflateReset(strm) { |
||
6111 | var state; |
||
6112 | |||
6113 | if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
||
6114 | state = strm.state; |
||
6115 | state.wsize = 0; |
||
6116 | state.whave = 0; |
||
6117 | state.wnext = 0; |
||
6118 | return inflateResetKeep(strm); |
||
6119 | |||
6120 | } |
||
6121 | |||
6122 | function inflateReset2(strm, windowBits) { |
||
6123 | var wrap; |
||
6124 | var state; |
||
6125 | |||
6126 | /* get the state */ |
||
6127 | if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
||
6128 | state = strm.state; |
||
6129 | |||
6130 | /* extract wrap request from windowBits parameter */ |
||
6131 | if (windowBits < 0) { |
||
6132 | wrap = 0; |
||
6133 | windowBits = -windowBits; |
||
6134 | } |
||
6135 | else { |
||
6136 | wrap = (windowBits >> 4) + 1; |
||
6137 | if (windowBits < 48) { |
||
6138 | windowBits &= 15; |
||
6139 | } |
||
6140 | } |
||
6141 | |||
6142 | /* set number of window bits, free window if different */ |
||
6143 | if (windowBits && (windowBits < 8 || windowBits > 15)) { |
||
6144 | return Z_STREAM_ERROR; |
||
6145 | } |
||
6146 | if (state.window !== null && state.wbits !== windowBits) { |
||
6147 | state.window = null; |
||
6148 | } |
||
6149 | |||
6150 | /* update state and reset the rest of it */ |
||
6151 | state.wrap = wrap; |
||
6152 | state.wbits = windowBits; |
||
6153 | return inflateReset(strm); |
||
6154 | } |
||
6155 | |||
6156 | function inflateInit2(strm, windowBits) { |
||
6157 | var ret; |
||
6158 | var state; |
||
6159 | |||
6160 | if (!strm) { return Z_STREAM_ERROR; } |
||
6161 | //strm.msg = Z_NULL; /* in case we return an error */ |
||
6162 | |||
6163 | state = new InflateState(); |
||
6164 | |||
6165 | //if (state === Z_NULL) return Z_MEM_ERROR; |
||
6166 | //Tracev((stderr, "inflate: allocated\n")); |
||
6167 | strm.state = state; |
||
6168 | state.window = null/*Z_NULL*/; |
||
6169 | ret = inflateReset2(strm, windowBits); |
||
6170 | if (ret !== Z_OK) { |
||
6171 | strm.state = null/*Z_NULL*/; |
||
6172 | } |
||
6173 | return ret; |
||
6174 | } |
||
6175 | |||
6176 | function inflateInit(strm) { |
||
6177 | return inflateInit2(strm, DEF_WBITS); |
||
6178 | } |
||
6179 | |||
6180 | |||
6181 | /* |
||
6182 | Return state with length and distance decoding tables and index sizes set to |
||
6183 | fixed code decoding. Normally this returns fixed tables from inffixed.h. |
||
6184 | If BUILDFIXED is defined, then instead this routine builds the tables the |
||
6185 | first time it's called, and returns those tables the first time and |
||
6186 | thereafter. This reduces the size of the code by about 2K bytes, in |
||
6187 | exchange for a little execution time. However, BUILDFIXED should not be |
||
6188 | used for threaded applications, since the rewriting of the tables and virgin |
||
6189 | may not be thread-safe. |
||
6190 | */ |
||
6191 | var virgin = true; |
||
6192 | |||
6193 | var lenfix, distfix; // We have no pointers in JS, so keep tables separate |
||
6194 | |||
6195 | function fixedtables(state) { |
||
6196 | /* build fixed huffman tables if first call (may not be thread safe) */ |
||
6197 | if (virgin) { |
||
6198 | var sym; |
||
6199 | |||
6200 | lenfix = new utils.Buf32(512); |
||
6201 | distfix = new utils.Buf32(32); |
||
6202 | |||
6203 | /* literal/length table */ |
||
6204 | sym = 0; |
||
6205 | while (sym < 144) { state.lens[sym++] = 8; } |
||
6206 | while (sym < 256) { state.lens[sym++] = 9; } |
||
6207 | while (sym < 280) { state.lens[sym++] = 7; } |
||
6208 | while (sym < 288) { state.lens[sym++] = 8; } |
||
6209 | |||
6210 | inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); |
||
6211 | |||
6212 | /* distance table */ |
||
6213 | sym = 0; |
||
6214 | while (sym < 32) { state.lens[sym++] = 5; } |
||
6215 | |||
6216 | inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); |
||
6217 | |||
6218 | /* do this just once */ |
||
6219 | virgin = false; |
||
6220 | } |
||
6221 | |||
6222 | state.lencode = lenfix; |
||
6223 | state.lenbits = 9; |
||
6224 | state.distcode = distfix; |
||
6225 | state.distbits = 5; |
||
6226 | } |
||
6227 | |||
6228 | |||
6229 | /* |
||
6230 | Update the window with the last wsize (normally 32K) bytes written before |
||
6231 | returning. If window does not exist yet, create it. This is only called |
||
6232 | when a window is already in use, or when output has been written during this |
||
6233 | inflate call, but the end of the deflate stream has not been reached yet. |
||
6234 | It is also called to create a window for dictionary data when a dictionary |
||
6235 | is loaded. |
||
6236 | |||
6237 | Providing output buffers larger than 32K to inflate() should provide a speed |
||
6238 | advantage, since only the last 32K of output is copied to the sliding window |
||
6239 | upon return from inflate(), and since all distances after the first 32K of |
||
6240 | output will fall in the output data, making match copies simpler and faster. |
||
6241 | The advantage may be dependent on the size of the processor's data caches. |
||
6242 | */ |
||
6243 | function updatewindow(strm, src, end, copy) { |
||
6244 | var dist; |
||
6245 | var state = strm.state; |
||
6246 | |||
6247 | /* if it hasn't been done already, allocate space for the window */ |
||
6248 | if (state.window === null) { |
||
6249 | state.wsize = 1 << state.wbits; |
||
6250 | state.wnext = 0; |
||
6251 | state.whave = 0; |
||
6252 | |||
6253 | state.window = new utils.Buf8(state.wsize); |
||
6254 | } |
||
6255 | |||
6256 | /* copy state->wsize or less output bytes into the circular window */ |
||
6257 | if (copy >= state.wsize) { |
||
6258 | utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); |
||
6259 | state.wnext = 0; |
||
6260 | state.whave = state.wsize; |
||
6261 | } |
||
6262 | else { |
||
6263 | dist = state.wsize - state.wnext; |
||
6264 | if (dist > copy) { |
||
6265 | dist = copy; |
||
6266 | } |
||
6267 | //zmemcpy(state->window + state->wnext, end - copy, dist); |
||
6268 | utils.arraySet(state.window,src, end - copy, dist, state.wnext); |
||
6269 | copy -= dist; |
||
6270 | if (copy) { |
||
6271 | //zmemcpy(state->window, end - copy, copy); |
||
6272 | utils.arraySet(state.window,src, end - copy, copy, 0); |
||
6273 | state.wnext = copy; |
||
6274 | state.whave = state.wsize; |
||
6275 | } |
||
6276 | else { |
||
6277 | state.wnext += dist; |
||
6278 | if (state.wnext === state.wsize) { state.wnext = 0; } |
||
6279 | if (state.whave < state.wsize) { state.whave += dist; } |
||
6280 | } |
||
6281 | } |
||
6282 | return 0; |
||
6283 | } |
||
6284 | |||
6285 | function inflate(strm, flush) { |
||
6286 | var state; |
||
6287 | var input, output; // input/output buffers |
||
6288 | var next; /* next input INDEX */ |
||
6289 | var put; /* next output INDEX */ |
||
6290 | var have, left; /* available input and output */ |
||
6291 | var hold; /* bit buffer */ |
||
6292 | var bits; /* bits in bit buffer */ |
||
6293 | var _in, _out; /* save starting available input and output */ |
||
6294 | var copy; /* number of stored or match bytes to copy */ |
||
6295 | var from; /* where to copy match bytes from */ |
||
6296 | var from_source; |
||
6297 | var here = 0; /* current decoding table entry */ |
||
6298 | var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) |
||
6299 | //var last; /* parent table entry */ |
||
6300 | var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) |
||
6301 | var len; /* length to copy for repeats, bits to drop */ |
||
6302 | var ret; /* return code */ |
||
6303 | var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ |
||
6304 | var opts; |
||
6305 | |||
6306 | var n; // temporary var for NEED_BITS |
||
6307 | |||
6308 | var order = /* permutation of code lengths */ |
||
6309 | [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; |
||
6310 | |||
6311 | |||
6312 | if (!strm || !strm.state || !strm.output || |
||
6313 | (!strm.input && strm.avail_in !== 0)) { |
||
6314 | return Z_STREAM_ERROR; |
||
6315 | } |
||
6316 | |||
6317 | state = strm.state; |
||
6318 | if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ |
||
6319 | |||
6320 | |||
6321 | //--- LOAD() --- |
||
6322 | put = strm.next_out; |
||
6323 | output = strm.output; |
||
6324 | left = strm.avail_out; |
||
6325 | next = strm.next_in; |
||
6326 | input = strm.input; |
||
6327 | have = strm.avail_in; |
||
6328 | hold = state.hold; |
||
6329 | bits = state.bits; |
||
6330 | //--- |
||
6331 | |||
6332 | _in = have; |
||
6333 | _out = left; |
||
6334 | ret = Z_OK; |
||
6335 | |||
6336 | inf_leave: // goto emulation |
||
6337 | for (;;) { |
||
6338 | switch (state.mode) { |
||
6339 | case HEAD: |
||
6340 | if (state.wrap === 0) { |
||
6341 | state.mode = TYPEDO; |
||
6342 | break; |
||
6343 | } |
||
6344 | //=== NEEDBITS(16); |
||
6345 | while (bits < 16) { |
||
6346 | if (have === 0) { break inf_leave; } |
||
6347 | have--; |
||
6348 | hold += input[next++] << bits; |
||
6349 | bits += 8; |
||
6350 | } |
||
6351 | //===// |
||
6352 | if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ |
||
6353 | state.check = 0/*crc32(0L, Z_NULL, 0)*/; |
||
6354 | //=== CRC2(state.check, hold); |
||
6355 | hbuf[0] = hold & 0xff; |
||
6356 | hbuf[1] = (hold >>> 8) & 0xff; |
||
6357 | state.check = crc32(state.check, hbuf, 2, 0); |
||
6358 | //===// |
||
6359 | |||
6360 | //=== INITBITS(); |
||
6361 | hold = 0; |
||
6362 | bits = 0; |
||
6363 | //===// |
||
6364 | state.mode = FLAGS; |
||
6365 | break; |
||
6366 | } |
||
6367 | state.flags = 0; /* expect zlib header */ |
||
6368 | if (state.head) { |
||
6369 | state.head.done = false; |
||
6370 | } |
||
6371 | if (!(state.wrap & 1) || /* check if zlib header allowed */ |
||
6372 | (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { |
||
6373 | strm.msg = 'incorrect header check'; |
||
6374 | state.mode = BAD; |
||
6375 | break; |
||
6376 | } |
||
6377 | if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { |
||
6378 | strm.msg = 'unknown compression method'; |
||
6379 | state.mode = BAD; |
||
6380 | break; |
||
6381 | } |
||
6382 | //--- DROPBITS(4) ---// |
||
6383 | hold >>>= 4; |
||
6384 | bits -= 4; |
||
6385 | //---// |
||
6386 | len = (hold & 0x0f)/*BITS(4)*/ + 8; |
||
6387 | if (state.wbits === 0) { |
||
6388 | state.wbits = len; |
||
6389 | } |
||
6390 | else if (len > state.wbits) { |
||
6391 | strm.msg = 'invalid window size'; |
||
6392 | state.mode = BAD; |
||
6393 | break; |
||
6394 | } |
||
6395 | state.dmax = 1 << len; |
||
6396 | //Tracev((stderr, "inflate: zlib header ok\n")); |
||
6397 | strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; |
||
6398 | state.mode = hold & 0x200 ? DICTID : TYPE; |
||
6399 | //=== INITBITS(); |
||
6400 | hold = 0; |
||
6401 | bits = 0; |
||
6402 | //===// |
||
6403 | break; |
||
6404 | case FLAGS: |
||
6405 | //=== NEEDBITS(16); */ |
||
6406 | while (bits < 16) { |
||
6407 | if (have === 0) { break inf_leave; } |
||
6408 | have--; |
||
6409 | hold += input[next++] << bits; |
||
6410 | bits += 8; |
||
6411 | } |
||
6412 | //===// |
||
6413 | state.flags = hold; |
||
6414 | if ((state.flags & 0xff) !== Z_DEFLATED) { |
||
6415 | strm.msg = 'unknown compression method'; |
||
6416 | state.mode = BAD; |
||
6417 | break; |
||
6418 | } |
||
6419 | if (state.flags & 0xe000) { |
||
6420 | strm.msg = 'unknown header flags set'; |
||
6421 | state.mode = BAD; |
||
6422 | break; |
||
6423 | } |
||
6424 | if (state.head) { |
||
6425 | state.head.text = ((hold >> 8) & 1); |
||
6426 | } |
||
6427 | if (state.flags & 0x0200) { |
||
6428 | //=== CRC2(state.check, hold); |
||
6429 | hbuf[0] = hold & 0xff; |
||
6430 | hbuf[1] = (hold >>> 8) & 0xff; |
||
6431 | state.check = crc32(state.check, hbuf, 2, 0); |
||
6432 | //===// |
||
6433 | } |
||
6434 | //=== INITBITS(); |
||
6435 | hold = 0; |
||
6436 | bits = 0; |
||
6437 | //===// |
||
6438 | state.mode = TIME; |
||
6439 | /* falls through */ |
||
6440 | case TIME: |
||
6441 | //=== NEEDBITS(32); */ |
||
6442 | while (bits < 32) { |
||
6443 | if (have === 0) { break inf_leave; } |
||
6444 | have--; |
||
6445 | hold += input[next++] << bits; |
||
6446 | bits += 8; |
||
6447 | } |
||
6448 | //===// |
||
6449 | if (state.head) { |
||
6450 | state.head.time = hold; |
||
6451 | } |
||
6452 | if (state.flags & 0x0200) { |
||
6453 | //=== CRC4(state.check, hold) |
||
6454 | hbuf[0] = hold & 0xff; |
||
6455 | hbuf[1] = (hold >>> 8) & 0xff; |
||
6456 | hbuf[2] = (hold >>> 16) & 0xff; |
||
6457 | hbuf[3] = (hold >>> 24) & 0xff; |
||
6458 | state.check = crc32(state.check, hbuf, 4, 0); |
||
6459 | //=== |
||
6460 | } |
||
6461 | //=== INITBITS(); |
||
6462 | hold = 0; |
||
6463 | bits = 0; |
||
6464 | //===// |
||
6465 | state.mode = OS; |
||
6466 | /* falls through */ |
||
6467 | case OS: |
||
6468 | //=== NEEDBITS(16); */ |
||
6469 | while (bits < 16) { |
||
6470 | if (have === 0) { break inf_leave; } |
||
6471 | have--; |
||
6472 | hold += input[next++] << bits; |
||
6473 | bits += 8; |
||
6474 | } |
||
6475 | //===// |
||
6476 | if (state.head) { |
||
6477 | state.head.xflags = (hold & 0xff); |
||
6478 | state.head.os = (hold >> 8); |
||
6479 | } |
||
6480 | if (state.flags & 0x0200) { |
||
6481 | //=== CRC2(state.check, hold); |
||
6482 | hbuf[0] = hold & 0xff; |
||
6483 | hbuf[1] = (hold >>> 8) & 0xff; |
||
6484 | state.check = crc32(state.check, hbuf, 2, 0); |
||
6485 | //===// |
||
6486 | } |
||
6487 | //=== INITBITS(); |
||
6488 | hold = 0; |
||
6489 | bits = 0; |
||
6490 | //===// |
||
6491 | state.mode = EXLEN; |
||
6492 | /* falls through */ |
||
6493 | case EXLEN: |
||
6494 | if (state.flags & 0x0400) { |
||
6495 | //=== NEEDBITS(16); */ |
||
6496 | while (bits < 16) { |
||
6497 | if (have === 0) { break inf_leave; } |
||
6498 | have--; |
||
6499 | hold += input[next++] << bits; |
||
6500 | bits += 8; |
||
6501 | } |
||
6502 | //===// |
||
6503 | state.length = hold; |
||
6504 | if (state.head) { |
||
6505 | state.head.extra_len = hold; |
||
6506 | } |
||
6507 | if (state.flags & 0x0200) { |
||
6508 | //=== CRC2(state.check, hold); |
||
6509 | hbuf[0] = hold & 0xff; |
||
6510 | hbuf[1] = (hold >>> 8) & 0xff; |
||
6511 | state.check = crc32(state.check, hbuf, 2, 0); |
||
6512 | //===// |
||
6513 | } |
||
6514 | //=== INITBITS(); |
||
6515 | hold = 0; |
||
6516 | bits = 0; |
||
6517 | //===// |
||
6518 | } |
||
6519 | else if (state.head) { |
||
6520 | state.head.extra = null/*Z_NULL*/; |
||
6521 | } |
||
6522 | state.mode = EXTRA; |
||
6523 | /* falls through */ |
||
6524 | case EXTRA: |
||
6525 | if (state.flags & 0x0400) { |
||
6526 | copy = state.length; |
||
6527 | if (copy > have) { copy = have; } |
||
6528 | if (copy) { |
||
6529 | if (state.head) { |
||
6530 | len = state.head.extra_len - state.length; |
||
6531 | if (!state.head.extra) { |
||
6532 | // Use untyped array for more conveniend processing later |
||
6533 | state.head.extra = new Array(state.head.extra_len); |
||
6534 | } |
||
6535 | utils.arraySet( |
||
6536 | state.head.extra, |
||
6537 | input, |
||
6538 | next, |
||
6539 | // extra field is limited to 65536 bytes |
||
6540 | // - no need for additional size check |
||
6541 | copy, |
||
6542 | /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ |
||
6543 | len |
||
6544 | ); |
||
6545 | //zmemcpy(state.head.extra + len, next, |
||
6546 | // len + copy > state.head.extra_max ? |
||
6547 | // state.head.extra_max - len : copy); |
||
6548 | } |
||
6549 | if (state.flags & 0x0200) { |
||
6550 | state.check = crc32(state.check, input, copy, next); |
||
6551 | } |
||
6552 | have -= copy; |
||
6553 | next += copy; |
||
6554 | state.length -= copy; |
||
6555 | } |
||
6556 | if (state.length) { break inf_leave; } |
||
6557 | } |
||
6558 | state.length = 0; |
||
6559 | state.mode = NAME; |
||
6560 | /* falls through */ |
||
6561 | case NAME: |
||
6562 | if (state.flags & 0x0800) { |
||
6563 | if (have === 0) { break inf_leave; } |
||
6564 | copy = 0; |
||
6565 | do { |
||
6566 | // TODO: 2 or 1 bytes? |
||
6567 | len = input[next + copy++]; |
||
6568 | /* use constant limit because in js we should not preallocate memory */ |
||
6569 | if (state.head && len && |
||
6570 | (state.length < 65536 /*state.head.name_max*/)) { |
||
6571 | state.head.name += String.fromCharCode(len); |
||
6572 | } |
||
6573 | } while (len && copy < have); |
||
6574 | |||
6575 | if (state.flags & 0x0200) { |
||
6576 | state.check = crc32(state.check, input, copy, next); |
||
6577 | } |
||
6578 | have -= copy; |
||
6579 | next += copy; |
||
6580 | if (len) { break inf_leave; } |
||
6581 | } |
||
6582 | else if (state.head) { |
||
6583 | state.head.name = null; |
||
6584 | } |
||
6585 | state.length = 0; |
||
6586 | state.mode = COMMENT; |
||
6587 | /* falls through */ |
||
6588 | case COMMENT: |
||
6589 | if (state.flags & 0x1000) { |
||
6590 | if (have === 0) { break inf_leave; } |
||
6591 | copy = 0; |
||
6592 | do { |
||
6593 | len = input[next + copy++]; |
||
6594 | /* use constant limit because in js we should not preallocate memory */ |
||
6595 | if (state.head && len && |
||
6596 | (state.length < 65536 /*state.head.comm_max*/)) { |
||
6597 | state.head.comment += String.fromCharCode(len); |
||
6598 | } |
||
6599 | } while (len && copy < have); |
||
6600 | if (state.flags & 0x0200) { |
||
6601 | state.check = crc32(state.check, input, copy, next); |
||
6602 | } |
||
6603 | have -= copy; |
||
6604 | next += copy; |
||
6605 | if (len) { break inf_leave; } |
||
6606 | } |
||
6607 | else if (state.head) { |
||
6608 | state.head.comment = null; |
||
6609 | } |
||
6610 | state.mode = HCRC; |
||
6611 | /* falls through */ |
||
6612 | case HCRC: |
||
6613 | if (state.flags & 0x0200) { |
||
6614 | //=== NEEDBITS(16); */ |
||
6615 | while (bits < 16) { |
||
6616 | if (have === 0) { break inf_leave; } |
||
6617 | have--; |
||
6618 | hold += input[next++] << bits; |
||
6619 | bits += 8; |
||
6620 | } |
||
6621 | //===// |
||
6622 | if (hold !== (state.check & 0xffff)) { |
||
6623 | strm.msg = 'header crc mismatch'; |
||
6624 | state.mode = BAD; |
||
6625 | break; |
||
6626 | } |
||
6627 | //=== INITBITS(); |
||
6628 | hold = 0; |
||
6629 | bits = 0; |
||
6630 | //===// |
||
6631 | } |
||
6632 | if (state.head) { |
||
6633 | state.head.hcrc = ((state.flags >> 9) & 1); |
||
6634 | state.head.done = true; |
||
6635 | } |
||
6636 | strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; |
||
6637 | state.mode = TYPE; |
||
6638 | break; |
||
6639 | case DICTID: |
||
6640 | //=== NEEDBITS(32); */ |
||
6641 | while (bits < 32) { |
||
6642 | if (have === 0) { break inf_leave; } |
||
6643 | have--; |
||
6644 | hold += input[next++] << bits; |
||
6645 | bits += 8; |
||
6646 | } |
||
6647 | //===// |
||
6648 | strm.adler = state.check = ZSWAP32(hold); |
||
6649 | //=== INITBITS(); |
||
6650 | hold = 0; |
||
6651 | bits = 0; |
||
6652 | //===// |
||
6653 | state.mode = DICT; |
||
6654 | /* falls through */ |
||
6655 | case DICT: |
||
6656 | if (state.havedict === 0) { |
||
6657 | //--- RESTORE() --- |
||
6658 | strm.next_out = put; |
||
6659 | strm.avail_out = left; |
||
6660 | strm.next_in = next; |
||
6661 | strm.avail_in = have; |
||
6662 | state.hold = hold; |
||
6663 | state.bits = bits; |
||
6664 | //--- |
||
6665 | return Z_NEED_DICT; |
||
6666 | } |
||
6667 | strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; |
||
6668 | state.mode = TYPE; |
||
6669 | /* falls through */ |
||
6670 | case TYPE: |
||
6671 | if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } |
||
6672 | /* falls through */ |
||
6673 | case TYPEDO: |
||
6674 | if (state.last) { |
||
6675 | //--- BYTEBITS() ---// |
||
6676 | hold >>>= bits & 7; |
||
6677 | bits -= bits & 7; |
||
6678 | //---// |
||
6679 | state.mode = CHECK; |
||
6680 | break; |
||
6681 | } |
||
6682 | //=== NEEDBITS(3); */ |
||
6683 | while (bits < 3) { |
||
6684 | if (have === 0) { break inf_leave; } |
||
6685 | have--; |
||
6686 | hold += input[next++] << bits; |
||
6687 | bits += 8; |
||
6688 | } |
||
6689 | //===// |
||
6690 | state.last = (hold & 0x01)/*BITS(1)*/; |
||
6691 | //--- DROPBITS(1) ---// |
||
6692 | hold >>>= 1; |
||
6693 | bits -= 1; |
||
6694 | //---// |
||
6695 | |||
6696 | switch ((hold & 0x03)/*BITS(2)*/) { |
||
6697 | case 0: /* stored block */ |
||
6698 | //Tracev((stderr, "inflate: stored block%s\n", |
||
6699 | // state.last ? " (last)" : "")); |
||
6700 | state.mode = STORED; |
||
6701 | break; |
||
6702 | case 1: /* fixed block */ |
||
6703 | fixedtables(state); |
||
6704 | //Tracev((stderr, "inflate: fixed codes block%s\n", |
||
6705 | // state.last ? " (last)" : "")); |
||
6706 | state.mode = LEN_; /* decode codes */ |
||
6707 | if (flush === Z_TREES) { |
||
6708 | //--- DROPBITS(2) ---// |
||
6709 | hold >>>= 2; |
||
6710 | bits -= 2; |
||
6711 | //---// |
||
6712 | break inf_leave; |
||
6713 | } |
||
6714 | break; |
||
6715 | case 2: /* dynamic block */ |
||
6716 | //Tracev((stderr, "inflate: dynamic codes block%s\n", |
||
6717 | // state.last ? " (last)" : "")); |
||
6718 | state.mode = TABLE; |
||
6719 | break; |
||
6720 | case 3: |
||
6721 | strm.msg = 'invalid block type'; |
||
6722 | state.mode = BAD; |
||
6723 | } |
||
6724 | //--- DROPBITS(2) ---// |
||
6725 | hold >>>= 2; |
||
6726 | bits -= 2; |
||
6727 | //---// |
||
6728 | break; |
||
6729 | case STORED: |
||
6730 | //--- BYTEBITS() ---// /* go to byte boundary */ |
||
6731 | hold >>>= bits & 7; |
||
6732 | bits -= bits & 7; |
||
6733 | //---// |
||
6734 | //=== NEEDBITS(32); */ |
||
6735 | while (bits < 32) { |
||
6736 | if (have === 0) { break inf_leave; } |
||
6737 | have--; |
||
6738 | hold += input[next++] << bits; |
||
6739 | bits += 8; |
||
6740 | } |
||
6741 | //===// |
||
6742 | if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { |
||
6743 | strm.msg = 'invalid stored block lengths'; |
||
6744 | state.mode = BAD; |
||
6745 | break; |
||
6746 | } |
||
6747 | state.length = hold & 0xffff; |
||
6748 | //Tracev((stderr, "inflate: stored length %u\n", |
||
6749 | // state.length)); |
||
6750 | //=== INITBITS(); |
||
6751 | hold = 0; |
||
6752 | bits = 0; |
||
6753 | //===// |
||
6754 | state.mode = COPY_; |
||
6755 | if (flush === Z_TREES) { break inf_leave; } |
||
6756 | /* falls through */ |
||
6757 | case COPY_: |
||
6758 | state.mode = COPY; |
||
6759 | /* falls through */ |
||
6760 | case COPY: |
||
6761 | copy = state.length; |
||
6762 | if (copy) { |
||
6763 | if (copy > have) { copy = have; } |
||
6764 | if (copy > left) { copy = left; } |
||
6765 | if (copy === 0) { break inf_leave; } |
||
6766 | //--- zmemcpy(put, next, copy); --- |
||
6767 | utils.arraySet(output, input, next, copy, put); |
||
6768 | //---// |
||
6769 | have -= copy; |
||
6770 | next += copy; |
||
6771 | left -= copy; |
||
6772 | put += copy; |
||
6773 | state.length -= copy; |
||
6774 | break; |
||
6775 | } |
||
6776 | //Tracev((stderr, "inflate: stored end\n")); |
||
6777 | state.mode = TYPE; |
||
6778 | break; |
||
6779 | case TABLE: |
||
6780 | //=== NEEDBITS(14); */ |
||
6781 | while (bits < 14) { |
||
6782 | if (have === 0) { break inf_leave; } |
||
6783 | have--; |
||
6784 | hold += input[next++] << bits; |
||
6785 | bits += 8; |
||
6786 | } |
||
6787 | //===// |
||
6788 | state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; |
||
6789 | //--- DROPBITS(5) ---// |
||
6790 | hold >>>= 5; |
||
6791 | bits -= 5; |
||
6792 | //---// |
||
6793 | state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; |
||
6794 | //--- DROPBITS(5) ---// |
||
6795 | hold >>>= 5; |
||
6796 | bits -= 5; |
||
6797 | //---// |
||
6798 | state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; |
||
6799 | //--- DROPBITS(4) ---// |
||
6800 | hold >>>= 4; |
||
6801 | bits -= 4; |
||
6802 | //---// |
||
6803 | //#ifndef PKZIP_BUG_WORKAROUND |
||
6804 | if (state.nlen > 286 || state.ndist > 30) { |
||
6805 | strm.msg = 'too many length or distance symbols'; |
||
6806 | state.mode = BAD; |
||
6807 | break; |
||
6808 | } |
||
6809 | //#endif |
||
6810 | //Tracev((stderr, "inflate: table sizes ok\n")); |
||
6811 | state.have = 0; |
||
6812 | state.mode = LENLENS; |
||
6813 | /* falls through */ |
||
6814 | case LENLENS: |
||
6815 | while (state.have < state.ncode) { |
||
6816 | //=== NEEDBITS(3); |
||
6817 | while (bits < 3) { |
||
6818 | if (have === 0) { break inf_leave; } |
||
6819 | have--; |
||
6820 | hold += input[next++] << bits; |
||
6821 | bits += 8; |
||
6822 | } |
||
6823 | //===// |
||
6824 | state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); |
||
6825 | //--- DROPBITS(3) ---// |
||
6826 | hold >>>= 3; |
||
6827 | bits -= 3; |
||
6828 | //---// |
||
6829 | } |
||
6830 | while (state.have < 19) { |
||
6831 | state.lens[order[state.have++]] = 0; |
||
6832 | } |
||
6833 | // We have separate tables & no pointers. 2 commented lines below not needed. |
||
6834 | //state.next = state.codes; |
||
6835 | //state.lencode = state.next; |
||
6836 | // Switch to use dynamic table |
||
6837 | state.lencode = state.lendyn; |
||
6838 | state.lenbits = 7; |
||
6839 | |||
6840 | opts = {bits: state.lenbits}; |
||
6841 | ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); |
||
6842 | state.lenbits = opts.bits; |
||
6843 | |||
6844 | if (ret) { |
||
6845 | strm.msg = 'invalid code lengths set'; |
||
6846 | state.mode = BAD; |
||
6847 | break; |
||
6848 | } |
||
6849 | //Tracev((stderr, "inflate: code lengths ok\n")); |
||
6850 | state.have = 0; |
||
6851 | state.mode = CODELENS; |
||
6852 | /* falls through */ |
||
6853 | case CODELENS: |
||
6854 | while (state.have < state.nlen + state.ndist) { |
||
6855 | View Code Duplication | for (;;) { |
|
6856 | here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ |
||
6857 | here_bits = here >>> 24; |
||
6858 | here_op = (here >>> 16) & 0xff; |
||
6859 | here_val = here & 0xffff; |
||
6860 | |||
6861 | if ((here_bits) <= bits) { break; } |
||
6862 | //--- PULLBYTE() ---// |
||
6863 | if (have === 0) { break inf_leave; } |
||
6864 | have--; |
||
6865 | hold += input[next++] << bits; |
||
6866 | bits += 8; |
||
6867 | //---// |
||
6868 | } |
||
6869 | if (here_val < 16) { |
||
6870 | //--- DROPBITS(here.bits) ---// |
||
6871 | hold >>>= here_bits; |
||
6872 | bits -= here_bits; |
||
6873 | //---// |
||
6874 | state.lens[state.have++] = here_val; |
||
6875 | } |
||
6876 | else { |
||
6877 | if (here_val === 16) { |
||
6878 | //=== NEEDBITS(here.bits + 2); |
||
6879 | n = here_bits + 2; |
||
6880 | while (bits < n) { |
||
6881 | if (have === 0) { break inf_leave; } |
||
6882 | have--; |
||
6883 | hold += input[next++] << bits; |
||
6884 | bits += 8; |
||
6885 | } |
||
6886 | //===// |
||
6887 | //--- DROPBITS(here.bits) ---// |
||
6888 | hold >>>= here_bits; |
||
6889 | bits -= here_bits; |
||
6890 | //---// |
||
6891 | if (state.have === 0) { |
||
6892 | strm.msg = 'invalid bit length repeat'; |
||
6893 | state.mode = BAD; |
||
6894 | break; |
||
6895 | } |
||
6896 | len = state.lens[state.have - 1]; |
||
6897 | copy = 3 + (hold & 0x03);//BITS(2); |
||
6898 | //--- DROPBITS(2) ---// |
||
6899 | hold >>>= 2; |
||
6900 | bits -= 2; |
||
6901 | //---// |
||
6902 | } |
||
6903 | else if (here_val === 17) { |
||
6904 | //=== NEEDBITS(here.bits + 3); |
||
6905 | n = here_bits + 3; |
||
6906 | while (bits < n) { |
||
6907 | if (have === 0) { break inf_leave; } |
||
6908 | have--; |
||
6909 | hold += input[next++] << bits; |
||
6910 | bits += 8; |
||
6911 | } |
||
6912 | //===// |
||
6913 | //--- DROPBITS(here.bits) ---// |
||
6914 | hold >>>= here_bits; |
||
6915 | bits -= here_bits; |
||
6916 | //---// |
||
6917 | len = 0; |
||
6918 | copy = 3 + (hold & 0x07);//BITS(3); |
||
6919 | //--- DROPBITS(3) ---// |
||
6920 | hold >>>= 3; |
||
6921 | bits -= 3; |
||
6922 | //---// |
||
6923 | } |
||
6924 | else { |
||
6925 | //=== NEEDBITS(here.bits + 7); |
||
6926 | n = here_bits + 7; |
||
6927 | while (bits < n) { |
||
6928 | if (have === 0) { break inf_leave; } |
||
6929 | have--; |
||
6930 | hold += input[next++] << bits; |
||
6931 | bits += 8; |
||
6932 | } |
||
6933 | //===// |
||
6934 | //--- DROPBITS(here.bits) ---// |
||
6935 | hold >>>= here_bits; |
||
6936 | bits -= here_bits; |
||
6937 | //---// |
||
6938 | len = 0; |
||
6939 | copy = 11 + (hold & 0x7f);//BITS(7); |
||
6940 | //--- DROPBITS(7) ---// |
||
6941 | hold >>>= 7; |
||
6942 | bits -= 7; |
||
6943 | //---// |
||
6944 | } |
||
6945 | if (state.have + copy > state.nlen + state.ndist) { |
||
6946 | strm.msg = 'invalid bit length repeat'; |
||
6947 | state.mode = BAD; |
||
6948 | break; |
||
6949 | } |
||
6950 | while (copy--) { |
||
6951 | state.lens[state.have++] = len; |
||
6952 | } |
||
6953 | } |
||
6954 | } |
||
6955 | |||
6956 | /* handle error breaks in while */ |
||
6957 | if (state.mode === BAD) { break; } |
||
6958 | |||
6959 | /* check for end-of-block code (better have one) */ |
||
6960 | if (state.lens[256] === 0) { |
||
6961 | strm.msg = 'invalid code -- missing end-of-block'; |
||
6962 | state.mode = BAD; |
||
6963 | break; |
||
6964 | } |
||
6965 | |||
6966 | /* build code tables -- note: do not change the lenbits or distbits |
||
6967 | values here (9 and 6) without reading the comments in inftrees.h |
||
6968 | concerning the ENOUGH constants, which depend on those values */ |
||
6969 | state.lenbits = 9; |
||
6970 | |||
6971 | opts = {bits: state.lenbits}; |
||
6972 | ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); |
||
6973 | // We have separate tables & no pointers. 2 commented lines below not needed. |
||
6974 | // state.next_index = opts.table_index; |
||
6975 | state.lenbits = opts.bits; |
||
6976 | // state.lencode = state.next; |
||
6977 | |||
6978 | if (ret) { |
||
6979 | strm.msg = 'invalid literal/lengths set'; |
||
6980 | state.mode = BAD; |
||
6981 | break; |
||
6982 | } |
||
6983 | |||
6984 | state.distbits = 6; |
||
6985 | //state.distcode.copy(state.codes); |
||
6986 | // Switch to use dynamic table |
||
6987 | state.distcode = state.distdyn; |
||
6988 | opts = {bits: state.distbits}; |
||
6989 | ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); |
||
6990 | // We have separate tables & no pointers. 2 commented lines below not needed. |
||
6991 | // state.next_index = opts.table_index; |
||
6992 | state.distbits = opts.bits; |
||
6993 | // state.distcode = state.next; |
||
6994 | |||
6995 | if (ret) { |
||
6996 | strm.msg = 'invalid distances set'; |
||
6997 | state.mode = BAD; |
||
6998 | break; |
||
6999 | } |
||
7000 | //Tracev((stderr, 'inflate: codes ok\n')); |
||
7001 | state.mode = LEN_; |
||
7002 | if (flush === Z_TREES) { break inf_leave; } |
||
7003 | /* falls through */ |
||
7004 | case LEN_: |
||
7005 | state.mode = LEN; |
||
7006 | /* falls through */ |
||
7007 | case LEN: |
||
7008 | if (have >= 6 && left >= 258) { |
||
7009 | //--- RESTORE() --- |
||
7010 | strm.next_out = put; |
||
7011 | strm.avail_out = left; |
||
7012 | strm.next_in = next; |
||
7013 | strm.avail_in = have; |
||
7014 | state.hold = hold; |
||
7015 | state.bits = bits; |
||
7016 | //--- |
||
7017 | inflate_fast(strm, _out); |
||
7018 | //--- LOAD() --- |
||
7019 | put = strm.next_out; |
||
7020 | output = strm.output; |
||
7021 | left = strm.avail_out; |
||
7022 | next = strm.next_in; |
||
7023 | input = strm.input; |
||
7024 | have = strm.avail_in; |
||
7025 | hold = state.hold; |
||
7026 | bits = state.bits; |
||
7027 | //--- |
||
7028 | |||
7029 | if (state.mode === TYPE) { |
||
7030 | state.back = -1; |
||
7031 | } |
||
7032 | break; |
||
7033 | } |
||
7034 | state.back = 0; |
||
7035 | View Code Duplication | for (;;) { |
|
7036 | here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ |
||
7037 | here_bits = here >>> 24; |
||
7038 | here_op = (here >>> 16) & 0xff; |
||
7039 | here_val = here & 0xffff; |
||
7040 | |||
7041 | if (here_bits <= bits) { break; } |
||
7042 | //--- PULLBYTE() ---// |
||
7043 | if (have === 0) { break inf_leave; } |
||
7044 | have--; |
||
7045 | hold += input[next++] << bits; |
||
7046 | bits += 8; |
||
7047 | //---// |
||
7048 | } |
||
7049 | if (here_op && (here_op & 0xf0) === 0) { |
||
7050 | last_bits = here_bits; |
||
7051 | last_op = here_op; |
||
7052 | last_val = here_val; |
||
7053 | for (;;) { |
||
7054 | here = state.lencode[last_val + |
||
7055 | ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; |
||
7056 | here_bits = here >>> 24; |
||
7057 | here_op = (here >>> 16) & 0xff; |
||
7058 | here_val = here & 0xffff; |
||
7059 | |||
7060 | if ((last_bits + here_bits) <= bits) { break; } |
||
7061 | //--- PULLBYTE() ---// |
||
7062 | if (have === 0) { break inf_leave; } |
||
7063 | have--; |
||
7064 | hold += input[next++] << bits; |
||
7065 | bits += 8; |
||
7066 | //---// |
||
7067 | } |
||
7068 | //--- DROPBITS(last.bits) ---// |
||
7069 | hold >>>= last_bits; |
||
7070 | bits -= last_bits; |
||
7071 | //---// |
||
7072 | state.back += last_bits; |
||
7073 | } |
||
7074 | //--- DROPBITS(here.bits) ---// |
||
7075 | hold >>>= here_bits; |
||
7076 | bits -= here_bits; |
||
7077 | //---// |
||
7078 | state.back += here_bits; |
||
7079 | state.length = here_val; |
||
7080 | if (here_op === 0) { |
||
7081 | //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
||
7082 | // "inflate: literal '%c'\n" : |
||
7083 | // "inflate: literal 0x%02x\n", here.val)); |
||
7084 | state.mode = LIT; |
||
7085 | break; |
||
7086 | } |
||
7087 | if (here_op & 32) { |
||
7088 | //Tracevv((stderr, "inflate: end of block\n")); |
||
7089 | state.back = -1; |
||
7090 | state.mode = TYPE; |
||
7091 | break; |
||
7092 | } |
||
7093 | if (here_op & 64) { |
||
7094 | strm.msg = 'invalid literal/length code'; |
||
7095 | state.mode = BAD; |
||
7096 | break; |
||
7097 | } |
||
7098 | state.extra = here_op & 15; |
||
7099 | state.mode = LENEXT; |
||
7100 | /* falls through */ |
||
7101 | case LENEXT: |
||
7102 | if (state.extra) { |
||
7103 | //=== NEEDBITS(state.extra); |
||
7104 | n = state.extra; |
||
7105 | while (bits < n) { |
||
7106 | if (have === 0) { break inf_leave; } |
||
7107 | have--; |
||
7108 | hold += input[next++] << bits; |
||
7109 | bits += 8; |
||
7110 | } |
||
7111 | //===// |
||
7112 | state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; |
||
7113 | //--- DROPBITS(state.extra) ---// |
||
7114 | hold >>>= state.extra; |
||
7115 | bits -= state.extra; |
||
7116 | //---// |
||
7117 | state.back += state.extra; |
||
7118 | } |
||
7119 | //Tracevv((stderr, "inflate: length %u\n", state.length)); |
||
7120 | state.was = state.length; |
||
7121 | state.mode = DIST; |
||
7122 | /* falls through */ |
||
7123 | case DIST: |
||
7124 | for (;;) { |
||
7125 | here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ |
||
7126 | here_bits = here >>> 24; |
||
7127 | here_op = (here >>> 16) & 0xff; |
||
7128 | here_val = here & 0xffff; |
||
7129 | |||
7130 | if ((here_bits) <= bits) { break; } |
||
7131 | //--- PULLBYTE() ---// |
||
7132 | if (have === 0) { break inf_leave; } |
||
7133 | have--; |
||
7134 | hold += input[next++] << bits; |
||
7135 | bits += 8; |
||
7136 | //---// |
||
7137 | } |
||
7138 | if ((here_op & 0xf0) === 0) { |
||
7139 | last_bits = here_bits; |
||
7140 | last_op = here_op; |
||
7141 | last_val = here_val; |
||
7142 | for (;;) { |
||
7143 | here = state.distcode[last_val + |
||
7144 | ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; |
||
7145 | here_bits = here >>> 24; |
||
7146 | here_op = (here >>> 16) & 0xff; |
||
7147 | here_val = here & 0xffff; |
||
7148 | |||
7149 | if ((last_bits + here_bits) <= bits) { break; } |
||
7150 | //--- PULLBYTE() ---// |
||
7151 | if (have === 0) { break inf_leave; } |
||
7152 | have--; |
||
7153 | hold += input[next++] << bits; |
||
7154 | bits += 8; |
||
7155 | //---// |
||
7156 | } |
||
7157 | //--- DROPBITS(last.bits) ---// |
||
7158 | hold >>>= last_bits; |
||
7159 | bits -= last_bits; |
||
7160 | //---// |
||
7161 | state.back += last_bits; |
||
7162 | } |
||
7163 | //--- DROPBITS(here.bits) ---// |
||
7164 | hold >>>= here_bits; |
||
7165 | bits -= here_bits; |
||
7166 | //---// |
||
7167 | state.back += here_bits; |
||
7168 | if (here_op & 64) { |
||
7169 | strm.msg = 'invalid distance code'; |
||
7170 | state.mode = BAD; |
||
7171 | break; |
||
7172 | } |
||
7173 | state.offset = here_val; |
||
7174 | state.extra = (here_op) & 15; |
||
7175 | state.mode = DISTEXT; |
||
7176 | /* falls through */ |
||
7177 | case DISTEXT: |
||
7178 | if (state.extra) { |
||
7179 | //=== NEEDBITS(state.extra); |
||
7180 | n = state.extra; |
||
7181 | while (bits < n) { |
||
7182 | if (have === 0) { break inf_leave; } |
||
7183 | have--; |
||
7184 | hold += input[next++] << bits; |
||
7185 | bits += 8; |
||
7186 | } |
||
7187 | //===// |
||
7188 | state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; |
||
7189 | //--- DROPBITS(state.extra) ---// |
||
7190 | hold >>>= state.extra; |
||
7191 | bits -= state.extra; |
||
7192 | //---// |
||
7193 | state.back += state.extra; |
||
7194 | } |
||
7195 | //#ifdef INFLATE_STRICT |
||
7196 | if (state.offset > state.dmax) { |
||
7197 | strm.msg = 'invalid distance too far back'; |
||
7198 | state.mode = BAD; |
||
7199 | break; |
||
7200 | } |
||
7201 | //#endif |
||
7202 | //Tracevv((stderr, "inflate: distance %u\n", state.offset)); |
||
7203 | state.mode = MATCH; |
||
7204 | /* falls through */ |
||
7205 | case MATCH: |
||
7206 | if (left === 0) { break inf_leave; } |
||
7207 | copy = _out - left; |
||
7208 | if (state.offset > copy) { /* copy from window */ |
||
7209 | copy = state.offset - copy; |
||
7210 | if (copy > state.whave) { |
||
7211 | if (state.sane) { |
||
7212 | strm.msg = 'invalid distance too far back'; |
||
7213 | state.mode = BAD; |
||
7214 | break; |
||
7215 | } |
||
7216 | // (!) This block is disabled in zlib defailts, |
||
7217 | // don't enable it for binary compatibility |
||
7218 | //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR |
||
7219 | // Trace((stderr, "inflate.c too far\n")); |
||
7220 | // copy -= state.whave; |
||
7221 | // if (copy > state.length) { copy = state.length; } |
||
7222 | // if (copy > left) { copy = left; } |
||
7223 | // left -= copy; |
||
7224 | // state.length -= copy; |
||
7225 | // do { |
||
7226 | // output[put++] = 0; |
||
7227 | // } while (--copy); |
||
7228 | // if (state.length === 0) { state.mode = LEN; } |
||
7229 | // break; |
||
7230 | //#endif |
||
7231 | } |
||
7232 | if (copy > state.wnext) { |
||
7233 | copy -= state.wnext; |
||
7234 | from = state.wsize - copy; |
||
7235 | } |
||
7236 | else { |
||
7237 | from = state.wnext - copy; |
||
7238 | } |
||
7239 | if (copy > state.length) { copy = state.length; } |
||
7240 | from_source = state.window; |
||
7241 | } |
||
7242 | else { /* copy from output */ |
||
7243 | from_source = output; |
||
7244 | from = put - state.offset; |
||
7245 | copy = state.length; |
||
7246 | } |
||
7247 | if (copy > left) { copy = left; } |
||
7248 | left -= copy; |
||
7249 | state.length -= copy; |
||
7250 | do { |
||
7251 | output[put++] = from_source[from++]; |
||
7252 | } while (--copy); |
||
7253 | if (state.length === 0) { state.mode = LEN; } |
||
7254 | break; |
||
7255 | case LIT: |
||
7256 | if (left === 0) { break inf_leave; } |
||
7257 | output[put++] = state.length; |
||
7258 | left--; |
||
7259 | state.mode = LEN; |
||
7260 | break; |
||
7261 | case CHECK: |
||
7262 | if (state.wrap) { |
||
7263 | //=== NEEDBITS(32); |
||
7264 | while (bits < 32) { |
||
7265 | if (have === 0) { break inf_leave; } |
||
7266 | have--; |
||
7267 | // Use '|' insdead of '+' to make sure that result is signed |
||
7268 | hold |= input[next++] << bits; |
||
7269 | bits += 8; |
||
7270 | } |
||
7271 | //===// |
||
7272 | _out -= left; |
||
7273 | strm.total_out += _out; |
||
7274 | state.total += _out; |
||
7275 | if (_out) { |
||
7276 | strm.adler = state.check = |
||
7277 | /*UPDATE(state.check, put - _out, _out);*/ |
||
7278 | (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); |
||
7279 | |||
7280 | } |
||
7281 | _out = left; |
||
7282 | // NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too |
||
7283 | if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { |
||
7284 | strm.msg = 'incorrect data check'; |
||
7285 | state.mode = BAD; |
||
7286 | break; |
||
7287 | } |
||
7288 | //=== INITBITS(); |
||
7289 | hold = 0; |
||
7290 | bits = 0; |
||
7291 | //===// |
||
7292 | //Tracev((stderr, "inflate: check matches trailer\n")); |
||
7293 | } |
||
7294 | state.mode = LENGTH; |
||
7295 | /* falls through */ |
||
7296 | case LENGTH: |
||
7297 | if (state.wrap && state.flags) { |
||
7298 | //=== NEEDBITS(32); |
||
7299 | while (bits < 32) { |
||
7300 | if (have === 0) { break inf_leave; } |
||
7301 | have--; |
||
7302 | hold += input[next++] << bits; |
||
7303 | bits += 8; |
||
7304 | } |
||
7305 | //===// |
||
7306 | if (hold !== (state.total & 0xffffffff)) { |
||
7307 | strm.msg = 'incorrect length check'; |
||
7308 | state.mode = BAD; |
||
7309 | break; |
||
7310 | } |
||
7311 | //=== INITBITS(); |
||
7312 | hold = 0; |
||
7313 | bits = 0; |
||
7314 | //===// |
||
7315 | //Tracev((stderr, "inflate: length matches trailer\n")); |
||
7316 | } |
||
7317 | state.mode = DONE; |
||
7318 | /* falls through */ |
||
7319 | case DONE: |
||
7320 | ret = Z_STREAM_END; |
||
7321 | break inf_leave; |
||
7322 | case BAD: |
||
7323 | ret = Z_DATA_ERROR; |
||
7324 | break inf_leave; |
||
7325 | case MEM: |
||
7326 | return Z_MEM_ERROR; |
||
7327 | case SYNC: |
||
7328 | /* falls through */ |
||
7329 | default: |
||
7330 | return Z_STREAM_ERROR; |
||
7331 | } |
||
7332 | } |
||
7333 | |||
7334 | // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" |
||
7335 | |||
7336 | /* |
||
7337 | Return from inflate(), updating the total counts and the check value. |
||
7338 | If there was no progress during the inflate() call, return a buffer |
||
7339 | error. Call updatewindow() to create and/or update the window state. |
||
7340 | Note: a memory error from inflate() is non-recoverable. |
||
7341 | */ |
||
7342 | |||
7343 | //--- RESTORE() --- |
||
7344 | strm.next_out = put; |
||
7345 | strm.avail_out = left; |
||
7346 | strm.next_in = next; |
||
7347 | strm.avail_in = have; |
||
7348 | state.hold = hold; |
||
7349 | state.bits = bits; |
||
7350 | //--- |
||
7351 | |||
7352 | if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && |
||
7353 | (state.mode < CHECK || flush !== Z_FINISH))) { |
||
7354 | if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { |
||
7355 | state.mode = MEM; |
||
7356 | return Z_MEM_ERROR; |
||
7357 | } |
||
7358 | } |
||
7359 | _in -= strm.avail_in; |
||
7360 | _out -= strm.avail_out; |
||
7361 | strm.total_in += _in; |
||
7362 | strm.total_out += _out; |
||
7363 | state.total += _out; |
||
7364 | if (state.wrap && _out) { |
||
7365 | strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ |
||
7366 | (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); |
||
7367 | } |
||
7368 | strm.data_type = state.bits + (state.last ? 64 : 0) + |
||
7369 | (state.mode === TYPE ? 128 : 0) + |
||
7370 | (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); |
||
7371 | if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { |
||
7372 | ret = Z_BUF_ERROR; |
||
7373 | } |
||
7374 | return ret; |
||
7375 | } |
||
7376 | |||
7377 | function inflateEnd(strm) { |
||
7378 | |||
7379 | if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { |
||
7380 | return Z_STREAM_ERROR; |
||
7381 | } |
||
7382 | |||
7383 | var state = strm.state; |
||
7384 | if (state.window) { |
||
7385 | state.window = null; |
||
7386 | } |
||
7387 | strm.state = null; |
||
7388 | return Z_OK; |
||
7389 | } |
||
7390 | |||
7391 | function inflateGetHeader(strm, head) { |
||
7392 | var state; |
||
7393 | |||
7394 | /* check state */ |
||
7395 | if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
||
7396 | state = strm.state; |
||
7397 | if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } |
||
7398 | |||
7399 | /* save header structure */ |
||
7400 | state.head = head; |
||
7401 | head.done = false; |
||
7402 | return Z_OK; |
||
7403 | } |
||
7404 | |||
7405 | |||
7406 | exports.inflateReset = inflateReset; |
||
7407 | exports.inflateReset2 = inflateReset2; |
||
7408 | exports.inflateResetKeep = inflateResetKeep; |
||
7409 | exports.inflateInit = inflateInit; |
||
7410 | exports.inflateInit2 = inflateInit2; |
||
7411 | exports.inflate = inflate; |
||
7412 | exports.inflateEnd = inflateEnd; |
||
7413 | exports.inflateGetHeader = inflateGetHeader; |
||
7414 | exports.inflateInfo = 'pako inflate (from Nodeca project)'; |
||
7415 | |||
7416 | /* Not implemented |
||
7417 | exports.inflateCopy = inflateCopy; |
||
7418 | exports.inflateGetDictionary = inflateGetDictionary; |
||
7419 | exports.inflateMark = inflateMark; |
||
7420 | exports.inflatePrime = inflatePrime; |
||
7421 | exports.inflateSetDictionary = inflateSetDictionary; |
||
7422 | exports.inflateSync = inflateSync; |
||
7423 | exports.inflateSyncPoint = inflateSyncPoint; |
||
7424 | exports.inflateUndermine = inflateUndermine; |
||
7425 | */ |
||
7426 | },{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(_dereq_,module,exports){ |
||
7427 | 'use strict'; |
||
7428 | |||
7429 | |||
7430 | var utils = _dereq_('../utils/common'); |
||
7431 | |||
7432 | var MAXBITS = 15; |
||
7433 | var ENOUGH_LENS = 852; |
||
7434 | var ENOUGH_DISTS = 592; |
||
7435 | //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); |
||
7436 | |||
7437 | var CODES = 0; |
||
7438 | var LENS = 1; |
||
7439 | var DISTS = 2; |
||
7440 | |||
7441 | var lbase = [ /* Length codes 257..285 base */ |
||
7442 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
||
7443 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 |
||
7444 | ]; |
||
7445 | |||
7446 | var lext = [ /* Length codes 257..285 extra */ |
||
7447 | 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, |
||
7448 | 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 |
||
7449 | ]; |
||
7450 | |||
7451 | var dbase = [ /* Distance codes 0..29 base */ |
||
7452 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
||
7453 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
||
7454 | 8193, 12289, 16385, 24577, 0, 0 |
||
7455 | ]; |
||
7456 | |||
7457 | var dext = [ /* Distance codes 0..29 extra */ |
||
7458 | 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, |
||
7459 | 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, |
||
7460 | 28, 28, 29, 29, 64, 64 |
||
7461 | ]; |
||
7462 | |||
7463 | module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) |
||
7464 | { |
||
7465 | var bits = opts.bits; |
||
7466 | //here = opts.here; /* table entry for duplication */ |
||
7467 | |||
7468 | var len = 0; /* a code's length in bits */ |
||
7469 | var sym = 0; /* index of code symbols */ |
||
7470 | var min = 0, max = 0; /* minimum and maximum code lengths */ |
||
7471 | var root = 0; /* number of index bits for root table */ |
||
7472 | var curr = 0; /* number of index bits for current table */ |
||
7473 | var drop = 0; /* code bits to drop for sub-table */ |
||
7474 | var left = 0; /* number of prefix codes available */ |
||
7475 | var used = 0; /* code entries in table used */ |
||
7476 | var huff = 0; /* Huffman code */ |
||
7477 | var incr; /* for incrementing code, index */ |
||
7478 | var fill; /* index for replicating entries */ |
||
7479 | var low; /* low bits for current root entry */ |
||
7480 | var mask; /* mask for low root bits */ |
||
7481 | var next; /* next available space in table */ |
||
7482 | var base = null; /* base value table to use */ |
||
7483 | var base_index = 0; |
||
7484 | // var shoextra; /* extra bits table to use */ |
||
7485 | var end; /* use base and extra for symbol > end */ |
||
7486 | var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ |
||
7487 | var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ |
||
7488 | var extra = null; |
||
7489 | var extra_index = 0; |
||
7490 | |||
7491 | var here_bits, here_op, here_val; |
||
7492 | |||
7493 | /* |
||
7494 | Process a set of code lengths to create a canonical Huffman code. The |
||
7495 | code lengths are lens[0..codes-1]. Each length corresponds to the |
||
7496 | symbols 0..codes-1. The Huffman code is generated by first sorting the |
||
7497 | symbols by length from short to long, and retaining the symbol order |
||
7498 | for codes with equal lengths. Then the code starts with all zero bits |
||
7499 | for the first code of the shortest length, and the codes are integer |
||
7500 | increments for the same length, and zeros are appended as the length |
||
7501 | increases. For the deflate format, these bits are stored backwards |
||
7502 | from their more natural integer increment ordering, and so when the |
||
7503 | decoding tables are built in the large loop below, the integer codes |
||
7504 | are incremented backwards. |
||
7505 | |||
7506 | This routine assumes, but does not check, that all of the entries in |
||
7507 | lens[] are in the range 0..MAXBITS. The caller must assure this. |
||
7508 | 1..MAXBITS is interpreted as that code length. zero means that that |
||
7509 | symbol does not occur in this code. |
||
7510 | |||
7511 | The codes are sorted by computing a count of codes for each length, |
||
7512 | creating from that a table of starting indices for each length in the |
||
7513 | sorted table, and then entering the symbols in order in the sorted |
||
7514 | table. The sorted table is work[], with that space being provided by |
||
7515 | the caller. |
||
7516 | |||
7517 | The length counts are used for other purposes as well, i.e. finding |
||
7518 | the minimum and maximum length codes, determining if there are any |
||
7519 | codes at all, checking for a valid set of lengths, and looking ahead |
||
7520 | at length counts to determine sub-table sizes when building the |
||
7521 | decoding tables. |
||
7522 | */ |
||
7523 | |||
7524 | /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ |
||
7525 | for (len = 0; len <= MAXBITS; len++) { |
||
7526 | count[len] = 0; |
||
7527 | } |
||
7528 | for (sym = 0; sym < codes; sym++) { |
||
7529 | count[lens[lens_index + sym]]++; |
||
7530 | } |
||
7531 | |||
7532 | /* bound code lengths, force root to be within code lengths */ |
||
7533 | root = bits; |
||
7534 | for (max = MAXBITS; max >= 1; max--) { |
||
7535 | if (count[max] !== 0) { break; } |
||
7536 | } |
||
7537 | if (root > max) { |
||
7538 | root = max; |
||
7539 | } |
||
7540 | if (max === 0) { /* no symbols to code at all */ |
||
7541 | //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ |
||
7542 | //table.bits[opts.table_index] = 1; //here.bits = (var char)1; |
||
7543 | //table.val[opts.table_index++] = 0; //here.val = (var short)0; |
||
7544 | table[table_index++] = (1 << 24) | (64 << 16) | 0; |
||
7545 | |||
7546 | |||
7547 | //table.op[opts.table_index] = 64; |
||
7548 | //table.bits[opts.table_index] = 1; |
||
7549 | //table.val[opts.table_index++] = 0; |
||
7550 | table[table_index++] = (1 << 24) | (64 << 16) | 0; |
||
7551 | |||
7552 | opts.bits = 1; |
||
7553 | return 0; /* no symbols, but wait for decoding to report error */ |
||
7554 | } |
||
7555 | for (min = 1; min < max; min++) { |
||
7556 | if (count[min] !== 0) { break; } |
||
7557 | } |
||
7558 | if (root < min) { |
||
7559 | root = min; |
||
7560 | } |
||
7561 | |||
7562 | /* check for an over-subscribed or incomplete set of lengths */ |
||
7563 | left = 1; |
||
7564 | for (len = 1; len <= MAXBITS; len++) { |
||
7565 | left <<= 1; |
||
7566 | left -= count[len]; |
||
7567 | if (left < 0) { |
||
7568 | return -1; |
||
7569 | } /* over-subscribed */ |
||
7570 | } |
||
7571 | if (left > 0 && (type === CODES || max !== 1)) { |
||
7572 | return -1; /* incomplete set */ |
||
7573 | } |
||
7574 | |||
7575 | /* generate offsets into symbol table for each length for sorting */ |
||
7576 | offs[1] = 0; |
||
7577 | for (len = 1; len < MAXBITS; len++) { |
||
7578 | offs[len + 1] = offs[len] + count[len]; |
||
7579 | } |
||
7580 | |||
7581 | /* sort symbols by length, by symbol order within each length */ |
||
7582 | for (sym = 0; sym < codes; sym++) { |
||
7583 | if (lens[lens_index + sym] !== 0) { |
||
7584 | work[offs[lens[lens_index + sym]]++] = sym; |
||
7585 | } |
||
7586 | } |
||
7587 | |||
7588 | /* |
||
7589 | Create and fill in decoding tables. In this loop, the table being |
||
7590 | filled is at next and has curr index bits. The code being used is huff |
||
7591 | with length len. That code is converted to an index by dropping drop |
||
7592 | bits off of the bottom. For codes where len is less than drop + curr, |
||
7593 | those top drop + curr - len bits are incremented through all values to |
||
7594 | fill the table with replicated entries. |
||
7595 | |||
7596 | root is the number of index bits for the root table. When len exceeds |
||
7597 | root, sub-tables are created pointed to by the root entry with an index |
||
7598 | of the low root bits of huff. This is saved in low to check for when a |
||
7599 | new sub-table should be started. drop is zero when the root table is |
||
7600 | being filled, and drop is root when sub-tables are being filled. |
||
7601 | |||
7602 | When a new sub-table is needed, it is necessary to look ahead in the |
||
7603 | code lengths to determine what size sub-table is needed. The length |
||
7604 | counts are used for this, and so count[] is decremented as codes are |
||
7605 | entered in the tables. |
||
7606 | |||
7607 | used keeps track of how many table entries have been allocated from the |
||
7608 | provided *table space. It is checked for LENS and DIST tables against |
||
7609 | the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in |
||
7610 | the initial root table size constants. See the comments in inftrees.h |
||
7611 | for more information. |
||
7612 | |||
7613 | sym increments through all symbols, and the loop terminates when |
||
7614 | all codes of length max, i.e. all codes, have been processed. This |
||
7615 | routine permits incomplete codes, so another loop after this one fills |
||
7616 | in the rest of the decoding tables with invalid code markers. |
||
7617 | */ |
||
7618 | |||
7619 | /* set up for code type */ |
||
7620 | // poor man optimization - use if-else instead of switch, |
||
7621 | // to avoid deopts in old v8 |
||
7622 | if (type === CODES) { |
||
7623 | base = extra = work; /* dummy value--not used */ |
||
7624 | end = 19; |
||
7625 | } else if (type === LENS) { |
||
7626 | base = lbase; |
||
7627 | base_index -= 257; |
||
7628 | extra = lext; |
||
7629 | extra_index -= 257; |
||
7630 | end = 256; |
||
7631 | } else { /* DISTS */ |
||
7632 | base = dbase; |
||
7633 | extra = dext; |
||
7634 | end = -1; |
||
7635 | } |
||
7636 | |||
7637 | /* initialize opts for loop */ |
||
7638 | huff = 0; /* starting code */ |
||
7639 | sym = 0; /* starting code symbol */ |
||
7640 | len = min; /* starting code length */ |
||
7641 | next = table_index; /* current table to fill in */ |
||
7642 | curr = root; /* current table index bits */ |
||
7643 | drop = 0; /* current bits to drop from code for index */ |
||
7644 | low = -1; /* trigger new sub-table when len > root */ |
||
7645 | used = 1 << root; /* use root table entries */ |
||
7646 | mask = used - 1; /* mask for comparing low */ |
||
7647 | |||
7648 | /* check available table space */ |
||
7649 | if ((type === LENS && used > ENOUGH_LENS) || |
||
7650 | (type === DISTS && used > ENOUGH_DISTS)) { |
||
7651 | return 1; |
||
7652 | } |
||
7653 | |||
7654 | var i=0; |
||
7655 | /* process all codes and make table entries */ |
||
7656 | for (;;) { |
||
7657 | i++; |
||
7658 | /* create table entry */ |
||
7659 | here_bits = len - drop; |
||
7660 | if (work[sym] < end) { |
||
7661 | here_op = 0; |
||
7662 | here_val = work[sym]; |
||
7663 | } |
||
7664 | else if (work[sym] > end) { |
||
7665 | here_op = extra[extra_index + work[sym]]; |
||
7666 | here_val = base[base_index + work[sym]]; |
||
7667 | } |
||
7668 | else { |
||
7669 | here_op = 32 + 64; /* end of block */ |
||
7670 | here_val = 0; |
||
7671 | } |
||
7672 | |||
7673 | /* replicate for those indices with low len bits equal to huff */ |
||
7674 | incr = 1 << (len - drop); |
||
7675 | fill = 1 << curr; |
||
7676 | min = fill; /* save offset to next table */ |
||
7677 | do { |
||
7678 | fill -= incr; |
||
7679 | table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; |
||
7680 | } while (fill !== 0); |
||
7681 | |||
7682 | /* backwards increment the len-bit code huff */ |
||
7683 | incr = 1 << (len - 1); |
||
7684 | while (huff & incr) { |
||
7685 | incr >>= 1; |
||
7686 | } |
||
7687 | if (incr !== 0) { |
||
7688 | huff &= incr - 1; |
||
7689 | huff += incr; |
||
7690 | } else { |
||
7691 | huff = 0; |
||
7692 | } |
||
7693 | |||
7694 | /* go to next symbol, update count, len */ |
||
7695 | sym++; |
||
7696 | if (--count[len] === 0) { |
||
7697 | if (len === max) { break; } |
||
7698 | len = lens[lens_index + work[sym]]; |
||
7699 | } |
||
7700 | |||
7701 | /* create new sub-table if needed */ |
||
7702 | if (len > root && (huff & mask) !== low) { |
||
7703 | /* if first time, transition to sub-tables */ |
||
7704 | if (drop === 0) { |
||
7705 | drop = root; |
||
7706 | } |
||
7707 | |||
7708 | /* increment past last table */ |
||
7709 | next += min; /* here min is 1 << curr */ |
||
7710 | |||
7711 | /* determine length of next table */ |
||
7712 | curr = len - drop; |
||
7713 | left = 1 << curr; |
||
7714 | while (curr + drop < max) { |
||
7715 | left -= count[curr + drop]; |
||
7716 | if (left <= 0) { break; } |
||
7717 | curr++; |
||
7718 | left <<= 1; |
||
7719 | } |
||
7720 | |||
7721 | /* check for enough space */ |
||
7722 | used += 1 << curr; |
||
7723 | if ((type === LENS && used > ENOUGH_LENS) || |
||
7724 | (type === DISTS && used > ENOUGH_DISTS)) { |
||
7725 | return 1; |
||
7726 | } |
||
7727 | |||
7728 | /* point entry in root table to sub-table */ |
||
7729 | low = huff & mask; |
||
7730 | /*table.op[low] = curr; |
||
7731 | table.bits[low] = root; |
||
7732 | table.val[low] = next - opts.table_index;*/ |
||
7733 | table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; |
||
7734 | } |
||
7735 | } |
||
7736 | |||
7737 | /* fill in remaining table entry if code is incomplete (guaranteed to have |
||
7738 | at most one remaining entry, since if the code is incomplete, the |
||
7739 | maximum code length that was allowed to get this far is one bit) */ |
||
7740 | if (huff !== 0) { |
||
7741 | //table.op[next + huff] = 64; /* invalid code marker */ |
||
7742 | //table.bits[next + huff] = len - drop; |
||
7743 | //table.val[next + huff] = 0; |
||
7744 | table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; |
||
7745 | } |
||
7746 | |||
7747 | /* set return parameters */ |
||
7748 | //opts.table_index += used; |
||
7749 | opts.bits = root; |
||
7750 | return 0; |
||
7751 | }; |
||
7752 | |||
7753 | },{"../utils/common":27}],37:[function(_dereq_,module,exports){ |
||
7754 | 'use strict'; |
||
7755 | |||
7756 | module.exports = { |
||
7757 | '2': 'need dictionary', /* Z_NEED_DICT 2 */ |
||
7758 | '1': 'stream end', /* Z_STREAM_END 1 */ |
||
7759 | '0': '', /* Z_OK 0 */ |
||
7760 | '-1': 'file error', /* Z_ERRNO (-1) */ |
||
7761 | '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ |
||
7762 | '-3': 'data error', /* Z_DATA_ERROR (-3) */ |
||
7763 | '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ |
||
7764 | '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ |
||
7765 | '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ |
||
7766 | }; |
||
7767 | },{}],38:[function(_dereq_,module,exports){ |
||
7768 | 'use strict'; |
||
7769 | |||
7770 | |||
7771 | var utils = _dereq_('../utils/common'); |
||
7772 | |||
7773 | /* Public constants ==========================================================*/ |
||
7774 | /* ===========================================================================*/ |
||
7775 | |||
7776 | |||
7777 | //var Z_FILTERED = 1; |
||
7778 | //var Z_HUFFMAN_ONLY = 2; |
||
7779 | //var Z_RLE = 3; |
||
7780 | var Z_FIXED = 4; |
||
7781 | //var Z_DEFAULT_STRATEGY = 0; |
||
7782 | |||
7783 | /* Possible values of the data_type field (though see inflate()) */ |
||
7784 | var Z_BINARY = 0; |
||
7785 | var Z_TEXT = 1; |
||
7786 | //var Z_ASCII = 1; // = Z_TEXT |
||
7787 | var Z_UNKNOWN = 2; |
||
7788 | |||
7789 | /*============================================================================*/ |
||
7790 | |||
7791 | |||
7792 | function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } |
||
7793 | |||
7794 | // From zutil.h |
||
7795 | |||
7796 | var STORED_BLOCK = 0; |
||
7797 | var STATIC_TREES = 1; |
||
7798 | var DYN_TREES = 2; |
||
7799 | /* The three kinds of block type */ |
||
7800 | |||
7801 | var MIN_MATCH = 3; |
||
7802 | var MAX_MATCH = 258; |
||
7803 | /* The minimum and maximum match lengths */ |
||
7804 | |||
7805 | // From deflate.h |
||
7806 | /* =========================================================================== |
||
7807 | * Internal compression state. |
||
7808 | */ |
||
7809 | |||
7810 | var LENGTH_CODES = 29; |
||
7811 | /* number of length codes, not counting the special END_BLOCK code */ |
||
7812 | |||
7813 | var LITERALS = 256; |
||
7814 | /* number of literal bytes 0..255 */ |
||
7815 | |||
7816 | var L_CODES = LITERALS + 1 + LENGTH_CODES; |
||
7817 | /* number of Literal or Length codes, including the END_BLOCK code */ |
||
7818 | |||
7819 | var D_CODES = 30; |
||
7820 | /* number of distance codes */ |
||
7821 | |||
7822 | var BL_CODES = 19; |
||
7823 | /* number of codes used to transfer the bit lengths */ |
||
7824 | |||
7825 | var HEAP_SIZE = 2*L_CODES + 1; |
||
7826 | /* maximum heap size */ |
||
7827 | |||
7828 | var MAX_BITS = 15; |
||
7829 | /* All codes must not exceed MAX_BITS bits */ |
||
7830 | |||
7831 | var Buf_size = 16; |
||
7832 | /* size of bit buffer in bi_buf */ |
||
7833 | |||
7834 | |||
7835 | /* =========================================================================== |
||
7836 | * Constants |
||
7837 | */ |
||
7838 | |||
7839 | var MAX_BL_BITS = 7; |
||
7840 | /* Bit length codes must not exceed MAX_BL_BITS bits */ |
||
7841 | |||
7842 | var END_BLOCK = 256; |
||
7843 | /* end of block literal code */ |
||
7844 | |||
7845 | var REP_3_6 = 16; |
||
7846 | /* repeat previous bit length 3-6 times (2 bits of repeat count) */ |
||
7847 | |||
7848 | var REPZ_3_10 = 17; |
||
7849 | /* repeat a zero length 3-10 times (3 bits of repeat count) */ |
||
7850 | |||
7851 | var REPZ_11_138 = 18; |
||
7852 | /* repeat a zero length 11-138 times (7 bits of repeat count) */ |
||
7853 | |||
7854 | var extra_lbits = /* extra bits for each length code */ |
||
7855 | [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; |
||
7856 | |||
7857 | var extra_dbits = /* extra bits for each distance code */ |
||
7858 | [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; |
||
7859 | |||
7860 | var extra_blbits = /* extra bits for each bit length code */ |
||
7861 | [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; |
||
7862 | |||
7863 | var bl_order = |
||
7864 | [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; |
||
7865 | /* The lengths of the bit length codes are sent in order of decreasing |
||
7866 | * probability, to avoid transmitting the lengths for unused bit length codes. |
||
7867 | */ |
||
7868 | |||
7869 | /* =========================================================================== |
||
7870 | * Local data. These are initialized only once. |
||
7871 | */ |
||
7872 | |||
7873 | // We pre-fill arrays with 0 to avoid uninitialized gaps |
||
7874 | |||
7875 | var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ |
||
7876 | |||
7877 | // !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 |
||
7878 | var static_ltree = new Array((L_CODES+2) * 2); |
||
7879 | zero(static_ltree); |
||
7880 | /* The static literal tree. Since the bit lengths are imposed, there is no |
||
7881 | * need for the L_CODES extra codes used during heap construction. However |
||
7882 | * The codes 286 and 287 are needed to build a canonical tree (see _tr_init |
||
7883 | * below). |
||
7884 | */ |
||
7885 | |||
7886 | var static_dtree = new Array(D_CODES * 2); |
||
7887 | zero(static_dtree); |
||
7888 | /* The static distance tree. (Actually a trivial tree since all codes use |
||
7889 | * 5 bits.) |
||
7890 | */ |
||
7891 | |||
7892 | var _dist_code = new Array(DIST_CODE_LEN); |
||
7893 | zero(_dist_code); |
||
7894 | /* Distance codes. The first 256 values correspond to the distances |
||
7895 | * 3 .. 258, the last 256 values correspond to the top 8 bits of |
||
7896 | * the 15 bit distances. |
||
7897 | */ |
||
7898 | |||
7899 | var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); |
||
7900 | zero(_length_code); |
||
7901 | /* length code for each normalized match length (0 == MIN_MATCH) */ |
||
7902 | |||
7903 | var base_length = new Array(LENGTH_CODES); |
||
7904 | zero(base_length); |
||
7905 | /* First normalized length for each code (0 = MIN_MATCH) */ |
||
7906 | |||
7907 | var base_dist = new Array(D_CODES); |
||
7908 | zero(base_dist); |
||
7909 | /* First normalized distance for each code (0 = distance of 1) */ |
||
7910 | |||
7911 | |||
7912 | var StaticTreeDesc = function (static_tree, extra_bits, extra_base, elems, max_length) { |
||
7913 | |||
7914 | this.static_tree = static_tree; /* static tree or NULL */ |
||
7915 | this.extra_bits = extra_bits; /* extra bits for each code or NULL */ |
||
7916 | this.extra_base = extra_base; /* base index for extra_bits */ |
||
7917 | this.elems = elems; /* max number of elements in the tree */ |
||
7918 | this.max_length = max_length; /* max bit length for the codes */ |
||
7919 | |||
7920 | // show if `static_tree` has data or dummy - needed for monomorphic objects |
||
7921 | this.has_stree = static_tree && static_tree.length; |
||
7922 | }; |
||
7923 | |||
7924 | |||
7925 | var static_l_desc; |
||
7926 | var static_d_desc; |
||
7927 | var static_bl_desc; |
||
7928 | |||
7929 | |||
7930 | var TreeDesc = function(dyn_tree, stat_desc) { |
||
7931 | this.dyn_tree = dyn_tree; /* the dynamic tree */ |
||
7932 | this.max_code = 0; /* largest code with non zero frequency */ |
||
7933 | this.stat_desc = stat_desc; /* the corresponding static tree */ |
||
7934 | }; |
||
7935 | |||
7936 | |||
7937 | |||
7938 | function d_code(dist) { |
||
7939 | return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; |
||
7940 | } |
||
7941 | |||
7942 | |||
7943 | /* =========================================================================== |
||
7944 | * Output a short LSB first on the stream. |
||
7945 | * IN assertion: there is enough room in pendingBuf. |
||
7946 | */ |
||
7947 | function put_short (s, w) { |
||
7948 | // put_byte(s, (uch)((w) & 0xff)); |
||
7949 | // put_byte(s, (uch)((ush)(w) >> 8)); |
||
7950 | s.pending_buf[s.pending++] = (w) & 0xff; |
||
7951 | s.pending_buf[s.pending++] = (w >>> 8) & 0xff; |
||
7952 | } |
||
7953 | |||
7954 | |||
7955 | /* =========================================================================== |
||
7956 | * Send a value on a given number of bits. |
||
7957 | * IN assertion: length <= 16 and value fits in length bits. |
||
7958 | */ |
||
7959 | function send_bits(s, value, length) { |
||
7960 | if (s.bi_valid > (Buf_size - length)) { |
||
7961 | s.bi_buf |= (value << s.bi_valid) & 0xffff; |
||
7962 | put_short(s, s.bi_buf); |
||
7963 | s.bi_buf = value >> (Buf_size - s.bi_valid); |
||
7964 | s.bi_valid += length - Buf_size; |
||
7965 | } else { |
||
7966 | s.bi_buf |= (value << s.bi_valid) & 0xffff; |
||
7967 | s.bi_valid += length; |
||
7968 | } |
||
7969 | } |
||
7970 | |||
7971 | |||
7972 | function send_code(s, c, tree) { |
||
7973 | send_bits(s, tree[c*2]/*.Code*/, tree[c*2 + 1]/*.Len*/); |
||
7974 | } |
||
7975 | |||
7976 | |||
7977 | /* =========================================================================== |
||
7978 | * Reverse the first len bits of a code, using straightforward code (a faster |
||
7979 | * method would use a table) |
||
7980 | * IN assertion: 1 <= len <= 15 |
||
7981 | */ |
||
7982 | function bi_reverse(code, len) { |
||
7983 | var res = 0; |
||
7984 | do { |
||
7985 | res |= code & 1; |
||
7986 | code >>>= 1; |
||
7987 | res <<= 1; |
||
7988 | } while (--len > 0); |
||
7989 | return res >>> 1; |
||
7990 | } |
||
7991 | |||
7992 | |||
7993 | /* =========================================================================== |
||
7994 | * Flush the bit buffer, keeping at most 7 bits in it. |
||
7995 | */ |
||
7996 | function bi_flush(s) { |
||
7997 | if (s.bi_valid === 16) { |
||
7998 | put_short(s, s.bi_buf); |
||
7999 | s.bi_buf = 0; |
||
8000 | s.bi_valid = 0; |
||
8001 | |||
8002 | } else if (s.bi_valid >= 8) { |
||
8003 | s.pending_buf[s.pending++] = s.bi_buf & 0xff; |
||
8004 | s.bi_buf >>= 8; |
||
8005 | s.bi_valid -= 8; |
||
8006 | } |
||
8007 | } |
||
8008 | |||
8009 | |||
8010 | /* =========================================================================== |
||
8011 | * Compute the optimal bit lengths for a tree and update the total bit length |
||
8012 | * for the current block. |
||
8013 | * IN assertion: the fields freq and dad are set, heap[heap_max] and |
||
8014 | * above are the tree nodes sorted by increasing frequency. |
||
8015 | * OUT assertions: the field len is set to the optimal bit length, the |
||
8016 | * array bl_count contains the frequencies for each bit length. |
||
8017 | * The length opt_len is updated; static_len is also updated if stree is |
||
8018 | * not null. |
||
8019 | */ |
||
8020 | function gen_bitlen(s, desc) |
||
8021 | // deflate_state *s; |
||
8022 | // tree_desc *desc; /* the tree descriptor */ |
||
8023 | { |
||
8024 | var tree = desc.dyn_tree; |
||
8025 | var max_code = desc.max_code; |
||
8026 | var stree = desc.stat_desc.static_tree; |
||
8027 | var has_stree = desc.stat_desc.has_stree; |
||
8028 | var extra = desc.stat_desc.extra_bits; |
||
8029 | var base = desc.stat_desc.extra_base; |
||
8030 | var max_length = desc.stat_desc.max_length; |
||
8031 | var h; /* heap index */ |
||
8032 | var n, m; /* iterate over the tree elements */ |
||
8033 | var bits; /* bit length */ |
||
8034 | var xbits; /* extra bits */ |
||
8035 | var f; /* frequency */ |
||
8036 | var overflow = 0; /* number of elements with bit length too large */ |
||
8037 | |||
8038 | for (bits = 0; bits <= MAX_BITS; bits++) { |
||
8039 | s.bl_count[bits] = 0; |
||
8040 | } |
||
8041 | |||
8042 | /* In a first pass, compute the optimal bit lengths (which may |
||
8043 | * overflow in the case of the bit length tree). |
||
8044 | */ |
||
8045 | tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ |
||
8046 | |||
8047 | for (h = s.heap_max+1; h < HEAP_SIZE; h++) { |
||
8048 | n = s.heap[h]; |
||
8049 | bits = tree[tree[n*2 +1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; |
||
8050 | if (bits > max_length) { |
||
8051 | bits = max_length; |
||
8052 | overflow++; |
||
8053 | } |
||
8054 | tree[n*2 + 1]/*.Len*/ = bits; |
||
8055 | /* We overwrite tree[n].Dad which is no longer needed */ |
||
8056 | |||
8057 | if (n > max_code) { continue; } /* not a leaf node */ |
||
8058 | |||
8059 | s.bl_count[bits]++; |
||
8060 | xbits = 0; |
||
8061 | if (n >= base) { |
||
8062 | xbits = extra[n-base]; |
||
8063 | } |
||
8064 | f = tree[n * 2]/*.Freq*/; |
||
8065 | s.opt_len += f * (bits + xbits); |
||
8066 | if (has_stree) { |
||
8067 | s.static_len += f * (stree[n*2 + 1]/*.Len*/ + xbits); |
||
8068 | } |
||
8069 | } |
||
8070 | if (overflow === 0) { return; } |
||
8071 | |||
8072 | // Trace((stderr,"\nbit length overflow\n")); |
||
8073 | /* This happens for example on obj2 and pic of the Calgary corpus */ |
||
8074 | |||
8075 | /* Find the first bit length which could increase: */ |
||
8076 | do { |
||
8077 | bits = max_length-1; |
||
8078 | while (s.bl_count[bits] === 0) { bits--; } |
||
8079 | s.bl_count[bits]--; /* move one leaf down the tree */ |
||
8080 | s.bl_count[bits+1] += 2; /* move one overflow item as its brother */ |
||
8081 | s.bl_count[max_length]--; |
||
8082 | /* The brother of the overflow item also moves one step up, |
||
8083 | * but this does not affect bl_count[max_length] |
||
8084 | */ |
||
8085 | overflow -= 2; |
||
8086 | } while (overflow > 0); |
||
8087 | |||
8088 | /* Now recompute all bit lengths, scanning in increasing frequency. |
||
8089 | * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
||
8090 | * lengths instead of fixing only the wrong ones. This idea is taken |
||
8091 | * from 'ar' written by Haruhiko Okumura.) |
||
8092 | */ |
||
8093 | for (bits = max_length; bits !== 0; bits--) { |
||
8094 | n = s.bl_count[bits]; |
||
8095 | while (n !== 0) { |
||
8096 | m = s.heap[--h]; |
||
8097 | if (m > max_code) { continue; } |
||
8098 | if (tree[m*2 + 1]/*.Len*/ !== bits) { |
||
8099 | // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); |
||
8100 | s.opt_len += (bits - tree[m*2 + 1]/*.Len*/)*tree[m*2]/*.Freq*/; |
||
8101 | tree[m*2 + 1]/*.Len*/ = bits; |
||
8102 | } |
||
8103 | n--; |
||
8104 | } |
||
8105 | } |
||
8106 | } |
||
8107 | |||
8108 | |||
8109 | /* =========================================================================== |
||
8110 | * Generate the codes for a given tree and bit counts (which need not be |
||
8111 | * optimal). |
||
8112 | * IN assertion: the array bl_count contains the bit length statistics for |
||
8113 | * the given tree and the field len is set for all tree elements. |
||
8114 | * OUT assertion: the field code is set for all tree elements of non |
||
8115 | * zero code length. |
||
8116 | */ |
||
8117 | function gen_codes(tree, max_code, bl_count) |
||
8118 | // ct_data *tree; /* the tree to decorate */ |
||
8119 | // int max_code; /* largest code with non zero frequency */ |
||
8120 | // ushf *bl_count; /* number of codes at each bit length */ |
||
8121 | { |
||
8122 | var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ |
||
8123 | var code = 0; /* running code value */ |
||
8124 | var bits; /* bit index */ |
||
8125 | var n; /* code index */ |
||
8126 | |||
8127 | /* The distribution counts are first used to generate the code values |
||
8128 | * without bit reversal. |
||
8129 | */ |
||
8130 | for (bits = 1; bits <= MAX_BITS; bits++) { |
||
8131 | next_code[bits] = code = (code + bl_count[bits-1]) << 1; |
||
8132 | } |
||
8133 | /* Check that the bit counts in bl_count are consistent. The last code |
||
8134 | * must be all ones. |
||
8135 | */ |
||
8136 | //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, |
||
8137 | // "inconsistent bit counts"); |
||
8138 | //Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); |
||
8139 | |||
8140 | for (n = 0; n <= max_code; n++) { |
||
8141 | var len = tree[n*2 + 1]/*.Len*/; |
||
8142 | if (len === 0) { continue; } |
||
8143 | /* Now reverse the bits */ |
||
8144 | tree[n*2]/*.Code*/ = bi_reverse(next_code[len]++, len); |
||
8145 | |||
8146 | //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", |
||
8147 | // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); |
||
8148 | } |
||
8149 | } |
||
8150 | |||
8151 | |||
8152 | /* =========================================================================== |
||
8153 | * Initialize the various 'constant' tables. |
||
8154 | */ |
||
8155 | function tr_static_init() { |
||
8156 | var n; /* iterates over tree elements */ |
||
8157 | var bits; /* bit counter */ |
||
8158 | var length; /* length value */ |
||
8159 | var code; /* code value */ |
||
8160 | var dist; /* distance index */ |
||
8161 | var bl_count = new Array(MAX_BITS+1); |
||
8162 | /* number of codes at each bit length for an optimal tree */ |
||
8163 | |||
8164 | // do check in _tr_init() |
||
8165 | //if (static_init_done) return; |
||
8166 | |||
8167 | /* For some embedded targets, global variables are not initialized: */ |
||
8168 | /*#ifdef NO_INIT_GLOBAL_POINTERS |
||
8169 | static_l_desc.static_tree = static_ltree; |
||
8170 | static_l_desc.extra_bits = extra_lbits; |
||
8171 | static_d_desc.static_tree = static_dtree; |
||
8172 | static_d_desc.extra_bits = extra_dbits; |
||
8173 | static_bl_desc.extra_bits = extra_blbits; |
||
8174 | #endif*/ |
||
8175 | |||
8176 | /* Initialize the mapping length (0..255) -> length code (0..28) */ |
||
8177 | length = 0; |
||
8178 | for (code = 0; code < LENGTH_CODES-1; code++) { |
||
8179 | base_length[code] = length; |
||
8180 | for (n = 0; n < (1<<extra_lbits[code]); n++) { |
||
8181 | _length_code[length++] = code; |
||
8182 | } |
||
8183 | } |
||
8184 | //Assert (length == 256, "tr_static_init: length != 256"); |
||
8185 | /* Note that the length 255 (match length 258) can be represented |
||
8186 | * in two different ways: code 284 + 5 bits or code 285, so we |
||
8187 | * overwrite length_code[255] to use the best encoding: |
||
8188 | */ |
||
8189 | _length_code[length-1] = code; |
||
8190 | |||
8191 | /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ |
||
8192 | dist = 0; |
||
8193 | for (code = 0 ; code < 16; code++) { |
||
8194 | base_dist[code] = dist; |
||
8195 | for (n = 0; n < (1<<extra_dbits[code]); n++) { |
||
8196 | _dist_code[dist++] = code; |
||
8197 | } |
||
8198 | } |
||
8199 | //Assert (dist == 256, "tr_static_init: dist != 256"); |
||
8200 | dist >>= 7; /* from now on, all distances are divided by 128 */ |
||
8201 | for ( ; code < D_CODES; code++) { |
||
8202 | base_dist[code] = dist << 7; |
||
8203 | for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { |
||
8204 | _dist_code[256 + dist++] = code; |
||
8205 | } |
||
8206 | } |
||
8207 | //Assert (dist == 256, "tr_static_init: 256+dist != 512"); |
||
8208 | |||
8209 | /* Construct the codes of the static literal tree */ |
||
8210 | for (bits = 0; bits <= MAX_BITS; bits++) { |
||
8211 | bl_count[bits] = 0; |
||
8212 | } |
||
8213 | |||
8214 | n = 0; |
||
8215 | while (n <= 143) { |
||
8216 | static_ltree[n*2 + 1]/*.Len*/ = 8; |
||
8217 | n++; |
||
8218 | bl_count[8]++; |
||
8219 | } |
||
8220 | while (n <= 255) { |
||
8221 | static_ltree[n*2 + 1]/*.Len*/ = 9; |
||
8222 | n++; |
||
8223 | bl_count[9]++; |
||
8224 | } |
||
8225 | while (n <= 279) { |
||
8226 | static_ltree[n*2 + 1]/*.Len*/ = 7; |
||
8227 | n++; |
||
8228 | bl_count[7]++; |
||
8229 | } |
||
8230 | while (n <= 287) { |
||
8231 | static_ltree[n*2 + 1]/*.Len*/ = 8; |
||
8232 | n++; |
||
8233 | bl_count[8]++; |
||
8234 | } |
||
8235 | /* Codes 286 and 287 do not exist, but we must include them in the |
||
8236 | * tree construction to get a canonical Huffman tree (longest code |
||
8237 | * all ones) |
||
8238 | */ |
||
8239 | gen_codes(static_ltree, L_CODES+1, bl_count); |
||
8240 | |||
8241 | /* The static distance tree is trivial: */ |
||
8242 | for (n = 0; n < D_CODES; n++) { |
||
8243 | static_dtree[n*2 + 1]/*.Len*/ = 5; |
||
8244 | static_dtree[n*2]/*.Code*/ = bi_reverse(n, 5); |
||
8245 | } |
||
8246 | |||
8247 | // Now data ready and we can init static trees |
||
8248 | static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); |
||
8249 | static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); |
||
8250 | static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); |
||
8251 | |||
8252 | //static_init_done = true; |
||
8253 | } |
||
8254 | |||
8255 | |||
8256 | /* =========================================================================== |
||
8257 | * Initialize a new block. |
||
8258 | */ |
||
8259 | function init_block(s) { |
||
8260 | var n; /* iterates over tree elements */ |
||
8261 | |||
8262 | /* Initialize the trees. */ |
||
8263 | for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n*2]/*.Freq*/ = 0; } |
||
8264 | for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n*2]/*.Freq*/ = 0; } |
||
8265 | for (n = 0; n < BL_CODES; n++) { s.bl_tree[n*2]/*.Freq*/ = 0; } |
||
8266 | |||
8267 | s.dyn_ltree[END_BLOCK*2]/*.Freq*/ = 1; |
||
8268 | s.opt_len = s.static_len = 0; |
||
8269 | s.last_lit = s.matches = 0; |
||
8270 | } |
||
8271 | |||
8272 | |||
8273 | /* =========================================================================== |
||
8274 | * Flush the bit buffer and align the output on a byte boundary |
||
8275 | */ |
||
8276 | function bi_windup(s) |
||
8277 | { |
||
8278 | if (s.bi_valid > 8) { |
||
8279 | put_short(s, s.bi_buf); |
||
8280 | } else if (s.bi_valid > 0) { |
||
8281 | //put_byte(s, (Byte)s->bi_buf); |
||
8282 | s.pending_buf[s.pending++] = s.bi_buf; |
||
8283 | } |
||
8284 | s.bi_buf = 0; |
||
8285 | s.bi_valid = 0; |
||
8286 | } |
||
8287 | |||
8288 | /* =========================================================================== |
||
8289 | * Copy a stored block, storing first the length and its |
||
8290 | * one's complement if requested. |
||
8291 | */ |
||
8292 | function copy_block(s, buf, len, header) |
||
8293 | //DeflateState *s; |
||
8294 | //charf *buf; /* the input data */ |
||
8295 | //unsigned len; /* its length */ |
||
8296 | //int header; /* true if block header must be written */ |
||
8297 | { |
||
8298 | bi_windup(s); /* align on byte boundary */ |
||
8299 | |||
8300 | if (header) { |
||
8301 | put_short(s, len); |
||
8302 | put_short(s, ~len); |
||
8303 | } |
||
8304 | // while (len--) { |
||
8305 | // put_byte(s, *buf++); |
||
8306 | // } |
||
8307 | utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); |
||
8308 | s.pending += len; |
||
8309 | } |
||
8310 | |||
8311 | /* =========================================================================== |
||
8312 | * Compares to subtrees, using the tree depth as tie breaker when |
||
8313 | * the subtrees have equal frequency. This minimizes the worst case length. |
||
8314 | */ |
||
8315 | function smaller(tree, n, m, depth) { |
||
8316 | var _n2 = n*2; |
||
8317 | var _m2 = m*2; |
||
8318 | return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || |
||
8319 | (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); |
||
8320 | } |
||
8321 | |||
8322 | /* =========================================================================== |
||
8323 | * Restore the heap property by moving down the tree starting at node k, |
||
8324 | * exchanging a node with the smallest of its two sons if necessary, stopping |
||
8325 | * when the heap property is re-established (each father smaller than its |
||
8326 | * two sons). |
||
8327 | */ |
||
8328 | function pqdownheap(s, tree, k) |
||
8329 | // deflate_state *s; |
||
8330 | // ct_data *tree; /* the tree to restore */ |
||
8331 | // int k; /* node to move down */ |
||
8332 | { |
||
8333 | var v = s.heap[k]; |
||
8334 | var j = k << 1; /* left son of k */ |
||
8335 | while (j <= s.heap_len) { |
||
8336 | /* Set j to the smallest of the two sons: */ |
||
8337 | if (j < s.heap_len && |
||
8338 | smaller(tree, s.heap[j+1], s.heap[j], s.depth)) { |
||
8339 | j++; |
||
8340 | } |
||
8341 | /* Exit if v is smaller than both sons */ |
||
8342 | if (smaller(tree, v, s.heap[j], s.depth)) { break; } |
||
8343 | |||
8344 | /* Exchange v with the smallest son */ |
||
8345 | s.heap[k] = s.heap[j]; |
||
8346 | k = j; |
||
8347 | |||
8348 | /* And continue down the tree, setting j to the left son of k */ |
||
8349 | j <<= 1; |
||
8350 | } |
||
8351 | s.heap[k] = v; |
||
8352 | } |
||
8353 | |||
8354 | |||
8355 | // inlined manually |
||
8356 | // var SMALLEST = 1; |
||
8357 | |||
8358 | /* =========================================================================== |
||
8359 | * Send the block data compressed using the given Huffman trees |
||
8360 | */ |
||
8361 | function compress_block(s, ltree, dtree) |
||
8362 | // deflate_state *s; |
||
8363 | // const ct_data *ltree; /* literal tree */ |
||
8364 | // const ct_data *dtree; /* distance tree */ |
||
8365 | { |
||
8366 | var dist; /* distance of matched string */ |
||
8367 | var lc; /* match length or unmatched char (if dist == 0) */ |
||
8368 | var lx = 0; /* running index in l_buf */ |
||
8369 | var code; /* the code to send */ |
||
8370 | var extra; /* number of extra bits to send */ |
||
8371 | |||
8372 | if (s.last_lit !== 0) { |
||
8373 | do { |
||
8374 | dist = (s.pending_buf[s.d_buf + lx*2] << 8) | (s.pending_buf[s.d_buf + lx*2 + 1]); |
||
8375 | lc = s.pending_buf[s.l_buf + lx]; |
||
8376 | lx++; |
||
8377 | |||
8378 | if (dist === 0) { |
||
8379 | send_code(s, lc, ltree); /* send a literal byte */ |
||
8380 | //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
||
8381 | } else { |
||
8382 | /* Here, lc is the match length - MIN_MATCH */ |
||
8383 | code = _length_code[lc]; |
||
8384 | send_code(s, code+LITERALS+1, ltree); /* send the length code */ |
||
8385 | extra = extra_lbits[code]; |
||
8386 | if (extra !== 0) { |
||
8387 | lc -= base_length[code]; |
||
8388 | send_bits(s, lc, extra); /* send the extra length bits */ |
||
8389 | } |
||
8390 | dist--; /* dist is now the match distance - 1 */ |
||
8391 | code = d_code(dist); |
||
8392 | //Assert (code < D_CODES, "bad d_code"); |
||
8393 | |||
8394 | send_code(s, code, dtree); /* send the distance code */ |
||
8395 | extra = extra_dbits[code]; |
||
8396 | if (extra !== 0) { |
||
8397 | dist -= base_dist[code]; |
||
8398 | send_bits(s, dist, extra); /* send the extra distance bits */ |
||
8399 | } |
||
8400 | } /* literal or match pair ? */ |
||
8401 | |||
8402 | /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ |
||
8403 | //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, |
||
8404 | // "pendingBuf overflow"); |
||
8405 | |||
8406 | } while (lx < s.last_lit); |
||
8407 | } |
||
8408 | |||
8409 | send_code(s, END_BLOCK, ltree); |
||
8410 | } |
||
8411 | |||
8412 | |||
8413 | /* =========================================================================== |
||
8414 | * Construct one Huffman tree and assigns the code bit strings and lengths. |
||
8415 | * Update the total bit length for the current block. |
||
8416 | * IN assertion: the field freq is set for all tree elements. |
||
8417 | * OUT assertions: the fields len and code are set to the optimal bit length |
||
8418 | * and corresponding code. The length opt_len is updated; static_len is |
||
8419 | * also updated if stree is not null. The field max_code is set. |
||
8420 | */ |
||
8421 | function build_tree(s, desc) |
||
8422 | // deflate_state *s; |
||
8423 | // tree_desc *desc; /* the tree descriptor */ |
||
8424 | { |
||
8425 | var tree = desc.dyn_tree; |
||
8426 | var stree = desc.stat_desc.static_tree; |
||
8427 | var has_stree = desc.stat_desc.has_stree; |
||
8428 | var elems = desc.stat_desc.elems; |
||
8429 | var n, m; /* iterate over heap elements */ |
||
8430 | var max_code = -1; /* largest code with non zero frequency */ |
||
8431 | var node; /* new node being created */ |
||
8432 | |||
8433 | /* Construct the initial heap, with least frequent element in |
||
8434 | * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
||
8435 | * heap[0] is not used. |
||
8436 | */ |
||
8437 | s.heap_len = 0; |
||
8438 | s.heap_max = HEAP_SIZE; |
||
8439 | |||
8440 | for (n = 0; n < elems; n++) { |
||
8441 | if (tree[n * 2]/*.Freq*/ !== 0) { |
||
8442 | s.heap[++s.heap_len] = max_code = n; |
||
8443 | s.depth[n] = 0; |
||
8444 | |||
8445 | } else { |
||
8446 | tree[n*2 + 1]/*.Len*/ = 0; |
||
8447 | } |
||
8448 | } |
||
8449 | |||
8450 | /* The pkzip format requires that at least one distance code exists, |
||
8451 | * and that at least one bit should be sent even if there is only one |
||
8452 | * possible code. So to avoid special checks later on we force at least |
||
8453 | * two codes of non zero frequency. |
||
8454 | */ |
||
8455 | while (s.heap_len < 2) { |
||
8456 | node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); |
||
8457 | tree[node * 2]/*.Freq*/ = 1; |
||
8458 | s.depth[node] = 0; |
||
8459 | s.opt_len--; |
||
8460 | |||
8461 | if (has_stree) { |
||
8462 | s.static_len -= stree[node*2 + 1]/*.Len*/; |
||
8463 | } |
||
8464 | /* node is 0 or 1 so it does not have extra bits */ |
||
8465 | } |
||
8466 | desc.max_code = max_code; |
||
8467 | |||
8468 | /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
||
8469 | * establish sub-heaps of increasing lengths: |
||
8470 | */ |
||
8471 | for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } |
||
8472 | |||
8473 | /* Construct the Huffman tree by repeatedly combining the least two |
||
8474 | * frequent nodes. |
||
8475 | */ |
||
8476 | node = elems; /* next internal node of the tree */ |
||
8477 | do { |
||
8478 | //pqremove(s, tree, n); /* n = node of least frequency */ |
||
8479 | /*** pqremove ***/ |
||
8480 | n = s.heap[1/*SMALLEST*/]; |
||
8481 | s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; |
||
8482 | pqdownheap(s, tree, 1/*SMALLEST*/); |
||
8483 | /***/ |
||
8484 | |||
8485 | m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ |
||
8486 | |||
8487 | s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ |
||
8488 | s.heap[--s.heap_max] = m; |
||
8489 | |||
8490 | /* Create a new node father of n and m */ |
||
8491 | tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; |
||
8492 | s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; |
||
8493 | tree[n*2 + 1]/*.Dad*/ = tree[m*2 + 1]/*.Dad*/ = node; |
||
8494 | |||
8495 | /* and insert the new node in the heap */ |
||
8496 | s.heap[1/*SMALLEST*/] = node++; |
||
8497 | pqdownheap(s, tree, 1/*SMALLEST*/); |
||
8498 | |||
8499 | } while (s.heap_len >= 2); |
||
8500 | |||
8501 | s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; |
||
8502 | |||
8503 | /* At this point, the fields freq and dad are set. We can now |
||
8504 | * generate the bit lengths. |
||
8505 | */ |
||
8506 | gen_bitlen(s, desc); |
||
8507 | |||
8508 | /* The field len is now set, we can generate the bit codes */ |
||
8509 | gen_codes(tree, max_code, s.bl_count); |
||
8510 | } |
||
8511 | |||
8512 | |||
8513 | /* =========================================================================== |
||
8514 | * Scan a literal or distance tree to determine the frequencies of the codes |
||
8515 | * in the bit length tree. |
||
8516 | */ |
||
8517 | function scan_tree(s, tree, max_code) |
||
8518 | // deflate_state *s; |
||
8519 | // ct_data *tree; /* the tree to be scanned */ |
||
8520 | // int max_code; /* and its largest code of non zero frequency */ |
||
8521 | { |
||
8522 | var n; /* iterates over all tree elements */ |
||
8523 | var prevlen = -1; /* last emitted length */ |
||
8524 | var curlen; /* length of current code */ |
||
8525 | |||
8526 | var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ |
||
8527 | |||
8528 | var count = 0; /* repeat count of the current code */ |
||
8529 | var max_count = 7; /* max repeat count */ |
||
8530 | var min_count = 4; /* min repeat count */ |
||
8531 | |||
8532 | if (nextlen === 0) { |
||
8533 | max_count = 138; |
||
8534 | min_count = 3; |
||
8535 | } |
||
8536 | tree[(max_code+1)*2 + 1]/*.Len*/ = 0xffff; /* guard */ |
||
8537 | |||
8538 | for (n = 0; n <= max_code; n++) { |
||
8539 | curlen = nextlen; |
||
8540 | nextlen = tree[(n+1)*2 + 1]/*.Len*/; |
||
8541 | |||
8542 | if (++count < max_count && curlen === nextlen) { |
||
8543 | continue; |
||
8544 | |||
8545 | } else if (count < min_count) { |
||
8546 | s.bl_tree[curlen * 2]/*.Freq*/ += count; |
||
8547 | |||
8548 | } else if (curlen !== 0) { |
||
8549 | |||
8550 | if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } |
||
8551 | s.bl_tree[REP_3_6*2]/*.Freq*/++; |
||
8552 | |||
8553 | } else if (count <= 10) { |
||
8554 | s.bl_tree[REPZ_3_10*2]/*.Freq*/++; |
||
8555 | |||
8556 | } else { |
||
8557 | s.bl_tree[REPZ_11_138*2]/*.Freq*/++; |
||
8558 | } |
||
8559 | |||
8560 | count = 0; |
||
8561 | prevlen = curlen; |
||
8562 | |||
8563 | if (nextlen === 0) { |
||
8564 | max_count = 138; |
||
8565 | min_count = 3; |
||
8566 | |||
8567 | } else if (curlen === nextlen) { |
||
8568 | max_count = 6; |
||
8569 | min_count = 3; |
||
8570 | |||
8571 | } else { |
||
8572 | max_count = 7; |
||
8573 | min_count = 4; |
||
8574 | } |
||
8575 | } |
||
8576 | } |
||
8577 | |||
8578 | |||
8579 | /* =========================================================================== |
||
8580 | * Send a literal or distance tree in compressed form, using the codes in |
||
8581 | * bl_tree. |
||
8582 | */ |
||
8583 | function send_tree(s, tree, max_code) |
||
8584 | // deflate_state *s; |
||
8585 | // ct_data *tree; /* the tree to be scanned */ |
||
8586 | // int max_code; /* and its largest code of non zero frequency */ |
||
8587 | { |
||
8588 | var n; /* iterates over all tree elements */ |
||
8589 | var prevlen = -1; /* last emitted length */ |
||
8590 | var curlen; /* length of current code */ |
||
8591 | |||
8592 | var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ |
||
8593 | |||
8594 | var count = 0; /* repeat count of the current code */ |
||
8595 | var max_count = 7; /* max repeat count */ |
||
8596 | var min_count = 4; /* min repeat count */ |
||
8597 | |||
8598 | /* tree[max_code+1].Len = -1; */ /* guard already set */ |
||
8599 | if (nextlen === 0) { |
||
8600 | max_count = 138; |
||
8601 | min_count = 3; |
||
8602 | } |
||
8603 | |||
8604 | for (n = 0; n <= max_code; n++) { |
||
8605 | curlen = nextlen; |
||
8606 | nextlen = tree[(n+1)*2 + 1]/*.Len*/; |
||
8607 | |||
8608 | if (++count < max_count && curlen === nextlen) { |
||
8609 | continue; |
||
8610 | |||
8611 | } else if (count < min_count) { |
||
8612 | do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); |
||
8613 | |||
8614 | } else if (curlen !== 0) { |
||
8615 | if (curlen !== prevlen) { |
||
8616 | send_code(s, curlen, s.bl_tree); |
||
8617 | count--; |
||
8618 | } |
||
8619 | //Assert(count >= 3 && count <= 6, " 3_6?"); |
||
8620 | send_code(s, REP_3_6, s.bl_tree); |
||
8621 | send_bits(s, count-3, 2); |
||
8622 | |||
8623 | } else if (count <= 10) { |
||
8624 | send_code(s, REPZ_3_10, s.bl_tree); |
||
8625 | send_bits(s, count-3, 3); |
||
8626 | |||
8627 | } else { |
||
8628 | send_code(s, REPZ_11_138, s.bl_tree); |
||
8629 | send_bits(s, count-11, 7); |
||
8630 | } |
||
8631 | |||
8632 | count = 0; |
||
8633 | prevlen = curlen; |
||
8634 | if (nextlen === 0) { |
||
8635 | max_count = 138; |
||
8636 | min_count = 3; |
||
8637 | |||
8638 | } else if (curlen === nextlen) { |
||
8639 | max_count = 6; |
||
8640 | min_count = 3; |
||
8641 | |||
8642 | } else { |
||
8643 | max_count = 7; |
||
8644 | min_count = 4; |
||
8645 | } |
||
8646 | } |
||
8647 | } |
||
8648 | |||
8649 | |||
8650 | /* =========================================================================== |
||
8651 | * Construct the Huffman tree for the bit lengths and return the index in |
||
8652 | * bl_order of the last bit length code to send. |
||
8653 | */ |
||
8654 | function build_bl_tree(s) { |
||
8655 | var max_blindex; /* index of last bit length code of non zero freq */ |
||
8656 | |||
8657 | /* Determine the bit length frequencies for literal and distance trees */ |
||
8658 | scan_tree(s, s.dyn_ltree, s.l_desc.max_code); |
||
8659 | scan_tree(s, s.dyn_dtree, s.d_desc.max_code); |
||
8660 | |||
8661 | /* Build the bit length tree: */ |
||
8662 | build_tree(s, s.bl_desc); |
||
8663 | /* opt_len now includes the length of the tree representations, except |
||
8664 | * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
||
8665 | */ |
||
8666 | |||
8667 | /* Determine the number of bit length codes to send. The pkzip format |
||
8668 | * requires that at least 4 bit length codes be sent. (appnote.txt says |
||
8669 | * 3 but the actual value used is 4.) |
||
8670 | */ |
||
8671 | for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { |
||
8672 | if (s.bl_tree[bl_order[max_blindex]*2 + 1]/*.Len*/ !== 0) { |
||
8673 | break; |
||
8674 | } |
||
8675 | } |
||
8676 | /* Update opt_len to include the bit length tree and counts */ |
||
8677 | s.opt_len += 3*(max_blindex+1) + 5+5+4; |
||
8678 | //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", |
||
8679 | // s->opt_len, s->static_len)); |
||
8680 | |||
8681 | return max_blindex; |
||
8682 | } |
||
8683 | |||
8684 | |||
8685 | /* =========================================================================== |
||
8686 | * Send the header for a block using dynamic Huffman trees: the counts, the |
||
8687 | * lengths of the bit length codes, the literal tree and the distance tree. |
||
8688 | * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
||
8689 | */ |
||
8690 | function send_all_trees(s, lcodes, dcodes, blcodes) |
||
8691 | // deflate_state *s; |
||
8692 | // int lcodes, dcodes, blcodes; /* number of codes for each tree */ |
||
8693 | { |
||
8694 | var rank; /* index in bl_order */ |
||
8695 | |||
8696 | //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); |
||
8697 | //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, |
||
8698 | // "too many codes"); |
||
8699 | //Tracev((stderr, "\nbl counts: ")); |
||
8700 | send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ |
||
8701 | send_bits(s, dcodes-1, 5); |
||
8702 | send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ |
||
8703 | for (rank = 0; rank < blcodes; rank++) { |
||
8704 | //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
||
8705 | send_bits(s, s.bl_tree[bl_order[rank]*2 + 1]/*.Len*/, 3); |
||
8706 | } |
||
8707 | //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); |
||
8708 | |||
8709 | send_tree(s, s.dyn_ltree, lcodes-1); /* literal tree */ |
||
8710 | //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); |
||
8711 | |||
8712 | send_tree(s, s.dyn_dtree, dcodes-1); /* distance tree */ |
||
8713 | //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); |
||
8714 | } |
||
8715 | |||
8716 | |||
8717 | /* =========================================================================== |
||
8718 | * Check if the data type is TEXT or BINARY, using the following algorithm: |
||
8719 | * - TEXT if the two conditions below are satisfied: |
||
8720 | * a) There are no non-portable control characters belonging to the |
||
8721 | * "black list" (0..6, 14..25, 28..31). |
||
8722 | * b) There is at least one printable character belonging to the |
||
8723 | * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). |
||
8724 | * - BINARY otherwise. |
||
8725 | * - The following partially-portable control characters form a |
||
8726 | * "gray list" that is ignored in this detection algorithm: |
||
8727 | * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). |
||
8728 | * IN assertion: the fields Freq of dyn_ltree are set. |
||
8729 | */ |
||
8730 | function detect_data_type(s) { |
||
8731 | /* black_mask is the bit mask of black-listed bytes |
||
8732 | * set bits 0..6, 14..25, and 28..31 |
||
8733 | * 0xf3ffc07f = binary 11110011111111111100000001111111 |
||
8734 | */ |
||
8735 | var black_mask = 0xf3ffc07f; |
||
8736 | var n; |
||
8737 | |||
8738 | /* Check for non-textual ("black-listed") bytes. */ |
||
8739 | for (n = 0; n <= 31; n++, black_mask >>>= 1) { |
||
8740 | if ((black_mask & 1) && (s.dyn_ltree[n*2]/*.Freq*/ !== 0)) { |
||
8741 | return Z_BINARY; |
||
8742 | } |
||
8743 | } |
||
8744 | |||
8745 | /* Check for textual ("white-listed") bytes. */ |
||
8746 | if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || |
||
8747 | s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { |
||
8748 | return Z_TEXT; |
||
8749 | } |
||
8750 | for (n = 32; n < LITERALS; n++) { |
||
8751 | if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { |
||
8752 | return Z_TEXT; |
||
8753 | } |
||
8754 | } |
||
8755 | |||
8756 | /* There are no "black-listed" or "white-listed" bytes: |
||
8757 | * this stream either is empty or has tolerated ("gray-listed") bytes only. |
||
8758 | */ |
||
8759 | return Z_BINARY; |
||
8760 | } |
||
8761 | |||
8762 | |||
8763 | var static_init_done = false; |
||
8764 | |||
8765 | /* =========================================================================== |
||
8766 | * Initialize the tree data structures for a new zlib stream. |
||
8767 | */ |
||
8768 | function _tr_init(s) |
||
8769 | { |
||
8770 | |||
8771 | if (!static_init_done) { |
||
8772 | tr_static_init(); |
||
8773 | static_init_done = true; |
||
8774 | } |
||
8775 | |||
8776 | s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); |
||
8777 | s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); |
||
8778 | s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); |
||
8779 | |||
8780 | s.bi_buf = 0; |
||
8781 | s.bi_valid = 0; |
||
8782 | |||
8783 | /* Initialize the first block of the first file: */ |
||
8784 | init_block(s); |
||
8785 | } |
||
8786 | |||
8787 | |||
8788 | /* =========================================================================== |
||
8789 | * Send a stored block |
||
8790 | */ |
||
8791 | function _tr_stored_block(s, buf, stored_len, last) |
||
8792 | //DeflateState *s; |
||
8793 | //charf *buf; /* input block */ |
||
8794 | //ulg stored_len; /* length of input block */ |
||
8795 | //int last; /* one if this is the last block for a file */ |
||
8796 | { |
||
8797 | send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ |
||
8798 | copy_block(s, buf, stored_len, true); /* with header */ |
||
8799 | } |
||
8800 | |||
8801 | |||
8802 | /* =========================================================================== |
||
8803 | * Send one empty static block to give enough lookahead for inflate. |
||
8804 | * This takes 10 bits, of which 7 may remain in the bit buffer. |
||
8805 | */ |
||
8806 | function _tr_align(s) { |
||
8807 | send_bits(s, STATIC_TREES<<1, 3); |
||
8808 | send_code(s, END_BLOCK, static_ltree); |
||
8809 | bi_flush(s); |
||
8810 | } |
||
8811 | |||
8812 | |||
8813 | /* =========================================================================== |
||
8814 | * Determine the best encoding for the current block: dynamic trees, static |
||
8815 | * trees or store, and output the encoded block to the zip file. |
||
8816 | */ |
||
8817 | function _tr_flush_block(s, buf, stored_len, last) |
||
8818 | //DeflateState *s; |
||
8819 | //charf *buf; /* input block, or NULL if too old */ |
||
8820 | //ulg stored_len; /* length of input block */ |
||
8821 | //int last; /* one if this is the last block for a file */ |
||
8822 | { |
||
8823 | var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
||
8824 | var max_blindex = 0; /* index of last bit length code of non zero freq */ |
||
8825 | |||
8826 | /* Build the Huffman trees unless a stored block is forced */ |
||
8827 | if (s.level > 0) { |
||
8828 | |||
8829 | /* Check if the file is binary or text */ |
||
8830 | if (s.strm.data_type === Z_UNKNOWN) { |
||
8831 | s.strm.data_type = detect_data_type(s); |
||
8832 | } |
||
8833 | |||
8834 | /* Construct the literal and distance trees */ |
||
8835 | build_tree(s, s.l_desc); |
||
8836 | // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, |
||
8837 | // s->static_len)); |
||
8838 | |||
8839 | build_tree(s, s.d_desc); |
||
8840 | // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, |
||
8841 | // s->static_len)); |
||
8842 | /* At this point, opt_len and static_len are the total bit lengths of |
||
8843 | * the compressed block data, excluding the tree representations. |
||
8844 | */ |
||
8845 | |||
8846 | /* Build the bit length tree for the above two trees, and get the index |
||
8847 | * in bl_order of the last bit length code to send. |
||
8848 | */ |
||
8849 | max_blindex = build_bl_tree(s); |
||
8850 | |||
8851 | /* Determine the best encoding. Compute the block lengths in bytes. */ |
||
8852 | opt_lenb = (s.opt_len+3+7) >>> 3; |
||
8853 | static_lenb = (s.static_len+3+7) >>> 3; |
||
8854 | |||
8855 | // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
||
8856 | // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
||
8857 | // s->last_lit)); |
||
8858 | |||
8859 | if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } |
||
8860 | |||
8861 | } else { |
||
8862 | // Assert(buf != (char*)0, "lost buf"); |
||
8863 | opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ |
||
8864 | } |
||
8865 | |||
8866 | if ((stored_len+4 <= opt_lenb) && (buf !== -1)) { |
||
8867 | /* 4: two words for the lengths */ |
||
8868 | |||
8869 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
||
8870 | * Otherwise we can't have processed more than WSIZE input bytes since |
||
8871 | * the last block flush, because compression would have been |
||
8872 | * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
||
8873 | * transform a block into a stored block. |
||
8874 | */ |
||
8875 | _tr_stored_block(s, buf, stored_len, last); |
||
8876 | |||
8877 | } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { |
||
8878 | |||
8879 | send_bits(s, (STATIC_TREES<<1) + (last ? 1 : 0), 3); |
||
8880 | compress_block(s, static_ltree, static_dtree); |
||
8881 | |||
8882 | } else { |
||
8883 | send_bits(s, (DYN_TREES<<1) + (last ? 1 : 0), 3); |
||
8884 | send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1, max_blindex+1); |
||
8885 | compress_block(s, s.dyn_ltree, s.dyn_dtree); |
||
8886 | } |
||
8887 | // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); |
||
8888 | /* The above check is made mod 2^32, for files larger than 512 MB |
||
8889 | * and uLong implemented on 32 bits. |
||
8890 | */ |
||
8891 | init_block(s); |
||
8892 | |||
8893 | if (last) { |
||
8894 | bi_windup(s); |
||
8895 | } |
||
8896 | // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, |
||
8897 | // s->compressed_len-7*last)); |
||
8898 | } |
||
8899 | |||
8900 | /* =========================================================================== |
||
8901 | * Save the match info and tally the frequency counts. Return true if |
||
8902 | * the current block must be flushed. |
||
8903 | */ |
||
8904 | function _tr_tally(s, dist, lc) |
||
8905 | // deflate_state *s; |
||
8906 | // unsigned dist; /* distance of matched string */ |
||
8907 | // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
||
8908 | { |
||
8909 | //var out_length, in_length, dcode; |
||
8910 | |||
8911 | s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; |
||
8912 | s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; |
||
8913 | |||
8914 | s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; |
||
8915 | s.last_lit++; |
||
8916 | |||
8917 | if (dist === 0) { |
||
8918 | /* lc is the unmatched char */ |
||
8919 | s.dyn_ltree[lc*2]/*.Freq*/++; |
||
8920 | } else { |
||
8921 | s.matches++; |
||
8922 | /* Here, lc is the match length - MIN_MATCH */ |
||
8923 | dist--; /* dist = match distance - 1 */ |
||
8924 | //Assert((ush)dist < (ush)MAX_DIST(s) && |
||
8925 | // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && |
||
8926 | // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); |
||
8927 | |||
8928 | s.dyn_ltree[(_length_code[lc]+LITERALS+1) * 2]/*.Freq*/++; |
||
8929 | s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; |
||
8930 | } |
||
8931 | |||
8932 | // (!) This block is disabled in zlib defailts, |
||
8933 | // don't enable it for binary compatibility |
||
8934 | |||
8935 | //#ifdef TRUNCATE_BLOCK |
||
8936 | // /* Try to guess if it is profitable to stop the current block here */ |
||
8937 | // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { |
||
8938 | // /* Compute an upper bound for the compressed length */ |
||
8939 | // out_length = s.last_lit*8; |
||
8940 | // in_length = s.strstart - s.block_start; |
||
8941 | // |
||
8942 | // for (dcode = 0; dcode < D_CODES; dcode++) { |
||
8943 | // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); |
||
8944 | // } |
||
8945 | // out_length >>>= 3; |
||
8946 | // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", |
||
8947 | // // s->last_lit, in_length, out_length, |
||
8948 | // // 100L - out_length*100L/in_length)); |
||
8949 | // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { |
||
8950 | // return true; |
||
8951 | // } |
||
8952 | // } |
||
8953 | //#endif |
||
8954 | |||
8955 | return (s.last_lit === s.lit_bufsize-1); |
||
8956 | /* We avoid equality with lit_bufsize because of wraparound at 64K |
||
8957 | * on 16 bit machines and because stored blocks are restricted to |
||
8958 | * 64K-1 bytes. |
||
8959 | */ |
||
8960 | } |
||
8961 | |||
8962 | exports._tr_init = _tr_init; |
||
8963 | exports._tr_stored_block = _tr_stored_block; |
||
8964 | exports._tr_flush_block = _tr_flush_block; |
||
8965 | exports._tr_tally = _tr_tally; |
||
8966 | exports._tr_align = _tr_align; |
||
8967 | },{"../utils/common":27}],39:[function(_dereq_,module,exports){ |
||
8968 | 'use strict'; |
||
8969 | |||
8970 | |||
8971 | function ZStream() { |
||
8972 | /* next input byte */ |
||
8973 | this.input = null; // JS specific, because we have no pointers |
||
8974 | this.next_in = 0; |
||
8975 | /* number of bytes available at input */ |
||
8976 | this.avail_in = 0; |
||
8977 | /* total number of input bytes read so far */ |
||
8978 | this.total_in = 0; |
||
8979 | /* next output byte should be put there */ |
||
8980 | this.output = null; // JS specific, because we have no pointers |
||
8981 | this.next_out = 0; |
||
8982 | /* remaining free space at output */ |
||
8983 | this.avail_out = 0; |
||
8984 | /* total number of bytes output so far */ |
||
8985 | this.total_out = 0; |
||
8986 | /* last error message, NULL if no error */ |
||
8987 | this.msg = ''/*Z_NULL*/; |
||
8988 | /* not visible by applications */ |
||
8989 | this.state = null; |
||
8990 | /* best guess about the data type: binary or text */ |
||
8991 | this.data_type = 2/*Z_UNKNOWN*/; |
||
8992 | /* adler32 value of the uncompressed data */ |
||
8993 | this.adler = 0; |
||
8994 | } |
||
8995 | |||
8996 | module.exports = ZStream; |
||
8997 | },{}]},{},[9]) |
||
8998 | (9) |
||
8999 | })); |
||
9000 |