|
// compiled png.js https://github.com/arian/pngjs |
|
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PNGReader = f()}})(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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.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(require,module,exports){ |
|
"use strict"; |
|
|
|
var PNG = function(){ |
|
|
|
// initialize all members to keep the same hidden class |
|
this.width = 0; |
|
this.height = 0; |
|
this.bitDepth = 0; |
|
this.colorType = 0; |
|
this.compressionMethod = 0; |
|
this.filterMethod = 0; |
|
this.interlaceMethod = 0; |
|
|
|
this.colors = 0; |
|
this.alpha = false; |
|
this.pixelBits = 0; |
|
|
|
this.palette = null; |
|
this.pixels = null; |
|
|
|
}; |
|
|
|
PNG.prototype.getWidth = function(){ |
|
return this.width; |
|
}; |
|
|
|
PNG.prototype.setWidth = function(width){ |
|
this.width = width; |
|
}; |
|
|
|
PNG.prototype.getHeight = function(){ |
|
return this.height; |
|
}; |
|
|
|
PNG.prototype.setHeight = function(height){ |
|
this.height = height; |
|
}; |
|
|
|
PNG.prototype.getBitDepth = function(){ |
|
return this.bitDepth; |
|
}; |
|
|
|
PNG.prototype.setBitDepth = function(bitDepth){ |
|
if ([2, 4, 8, 16].indexOf(bitDepth) === -1){ |
|
throw new Error("invalid bith depth " + bitDepth); |
|
} |
|
this.bitDepth = bitDepth; |
|
}; |
|
|
|
PNG.prototype.getColorType = function(){ |
|
return this.colorType; |
|
}; |
|
|
|
PNG.prototype.setColorType = function(colorType){ |
|
|
|
// Color Allowed Interpretation |
|
// Type Bit Depths |
|
// |
|
// 0 1,2,4,8,16 Each pixel is a grayscale sample. |
|
// |
|
// 2 8,16 Each pixel is an R,G,B triple. |
|
// |
|
// 3 1,2,4,8 Each pixel is a palette index; |
|
// a PLTE chunk must appear. |
|
// |
|
// 4 8,16 Each pixel is a grayscale sample, |
|
// followed by an alpha sample. |
|
// |
|
// 6 8,16 Each pixel is an R,G,B triple, |
|
// followed by an alpha sample. |
|
|
|
var colors = 0, alpha = false; |
|
|
|
switch (colorType){ |
|
case 0: colors = 1; break; |
|
case 2: colors = 3; break; |
|
case 3: colors = 1; break; |
|
case 4: colors = 2; alpha = true; break; |
|
case 6: colors = 4; alpha = true; break; |
|
default: throw new Error("invalid color type"); |
|
} |
|
|
|
this.colors = colors; |
|
this.alpha = alpha; |
|
this.colorType = colorType; |
|
}; |
|
|
|
PNG.prototype.getCompressionMethod = function(){ |
|
return this.compressionMethod; |
|
}; |
|
|
|
PNG.prototype.setCompressionMethod = function(compressionMethod){ |
|
if (compressionMethod !== 0){ |
|
throw new Error("invalid compression method " + compressionMethod); |
|
} |
|
this.compressionMethod = compressionMethod; |
|
}; |
|
|
|
PNG.prototype.getFilterMethod = function(){ |
|
return this.filterMethod; |
|
}; |
|
|
|
PNG.prototype.setFilterMethod = function(filterMethod){ |
|
if (filterMethod !== 0){ |
|
throw new Error("invalid filter method " + filterMethod); |
|
} |
|
this.filterMethod = filterMethod; |
|
}; |
|
|
|
PNG.prototype.getInterlaceMethod = function(){ |
|
return this.interlaceMethod; |
|
}; |
|
|
|
PNG.prototype.setInterlaceMethod = function(interlaceMethod){ |
|
if (interlaceMethod !== 0 && interlaceMethod !== 1){ |
|
throw new Error("invalid interlace method " + interlaceMethod); |
|
} |
|
this.interlaceMethod = interlaceMethod; |
|
}; |
|
|
|
PNG.prototype.setPalette = function(palette){ |
|
if (palette.length % 3 !== 0){ |
|
throw new Error("incorrect PLTE chunk length"); |
|
} |
|
if (palette.length > (Math.pow(2, this.bitDepth) * 3)){ |
|
throw new Error("palette has more colors than 2^bitdepth"); |
|
} |
|
this.palette = palette; |
|
}; |
|
|
|
PNG.prototype.getPalette = function(){ |
|
return this.palette; |
|
}; |
|
|
|
/** |
|
* get the pixel color on a certain location in a normalized way |
|
* result is an array: [red, green, blue, alpha] |
|
*/ |
|
PNG.prototype.getPixel = function(x, y){ |
|
if (!this.pixels) throw new Error("pixel data is empty"); |
|
if (x >= this.width || y >= this.height){ |
|
throw new Error("x,y position out of bound"); |
|
} |
|
var i = this.colors * this.bitDepth / 8 * (y * this.width + x); |
|
var pixels = this.pixels; |
|
|
|
switch (this.colorType){ |
|
case 0: return [pixels[i], pixels[i], pixels[i], 255]; |
|
case 2: return [pixels[i], pixels[i + 1], pixels[i + 2], 255]; |
|
case 3: return [ |
|
this.palette[pixels[i] * 3 + 0], |
|
this.palette[pixels[i] * 3 + 1], |
|
this.palette[pixels[i] * 3 + 2], |
|
255]; |
|
case 4: return [pixels[i], pixels[i], pixels[i], pixels[i + 1]]; |
|
case 6: return [pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3]]; |
|
} |
|
}; |
|
|
|
module.exports = PNG; |
|
|
|
},{}],2:[function(require,module,exports){ |
|
(function (Buffer){ |
|
/*global Uint8Array:true ArrayBuffer:true */ |
|
"use strict"; |
|
|
|
var zlib = require('zlib'); |
|
var PNG = require('./PNG'); |
|
|
|
var inflate = function(data, callback){ |
|
return zlib.inflate(new Buffer(data), callback); |
|
}; |
|
|
|
var slice = Array.prototype.slice; |
|
var toString = Object.prototype.toString; |
|
|
|
function equalBytes(a, b){ |
|
if (a.length != b.length) return false; |
|
for (var l = a.length; l--;) if (a[l] != b[l]) return false; |
|
return true; |
|
} |
|
|
|
function readUInt32(buffer, offset){ |
|
return (buffer[offset] << 24) + |
|
(buffer[offset + 1] << 16) + |
|
(buffer[offset + 2] << 8) + |
|
(buffer[offset + 3] << 0); |
|
} |
|
|
|
function readUInt16(buffer, offset){ |
|
return (buffer[offset + 1] << 8) + (buffer[offset] << 0); |
|
} |
|
|
|
function readUInt8(buffer, offset){ |
|
return buffer[offset] << 0; |
|
} |
|
|
|
function bufferToString(buffer){ |
|
var str = ''; |
|
for (var i = 0; i < buffer.length; i++){ |
|
str += String.fromCharCode(buffer[i]); |
|
} |
|
return str; |
|
} |
|
|
|
var PNGReader = function(bytes){ |
|
|
|
if (typeof bytes == 'string'){ |
|
var bts = bytes; |
|
bytes = new Array(bts.length); |
|
for (var i = 0, l = bts.length; i < l; i++){ |
|
bytes[i] = bts[i].charCodeAt(0); |
|
} |
|
} else { |
|
var type = toString.call(bytes).slice(8, -1); |
|
if (type == 'ArrayBuffer') bytes = new Uint8Array(bytes); |
|
} |
|
|
|
// current pointer |
|
this.i = 0; |
|
// bytes buffer |
|
this.bytes = bytes; |
|
// Output object |
|
this.png = new PNG(); |
|
|
|
this.dataChunks = []; |
|
|
|
}; |
|
|
|
PNGReader.prototype.readBytes = function(length){ |
|
var end = this.i + length; |
|
if (end > this.bytes.length){ |
|
throw new Error('Unexpectedly reached end of file'); |
|
} |
|
var bytes = slice.call(this.bytes, this.i, end); |
|
this.i = end; |
|
return bytes; |
|
}; |
|
|
|
/** |
|
* http://www.w3.org/TR/2003/REC-PNG-20031110/#5PNG-file-signature |
|
*/ |
|
PNGReader.prototype.decodeHeader = function(){ |
|
|
|
if (this.i !== 0){ |
|
throw new Error('file pointer should be at 0 to read the header'); |
|
} |
|
|
|
var header = this.readBytes(8); |
|
|
|
if (!equalBytes(header, [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])){ |
|
throw new Error('invalid PNGReader file (bad signature)'); |
|
} |
|
|
|
this.header = header; |
|
|
|
}; |
|
|
|
/** |
|
* http://www.w3.org/TR/2003/REC-PNG-20031110/#5Chunk-layout |
|
* |
|
* length = 4 bytes |
|
* type = 4 bytes (IHDR, PLTE, IDAT, IEND or others) |
|
* chunk = length bytes |
|
* crc = 4 bytes |
|
*/ |
|
PNGReader.prototype.decodeChunk = function(){ |
|
|
|
var length = readUInt32(this.readBytes(4), 0); |
|
|
|
if (length < 0){ |
|
throw new Error('Bad chunk length ' + (0xFFFFFFFF & length)); |
|
} |
|
|
|
var type = bufferToString(this.readBytes(4)); |
|
var chunk = this.readBytes(length); |
|
var crc = this.readBytes(4); |
|
|
|
switch (type){ |
|
case 'IHDR': this.decodeIHDR(chunk); break; |
|
case 'PLTE': this.decodePLTE(chunk); break; |
|
case 'IDAT': this.decodeIDAT(chunk); break; |
|
case 'IEND': this.decodeIEND(chunk); break; |
|
} |
|
|
|
return type; |
|
|
|
}; |
|
|
|
/** |
|
* http://www.w3.org/TR/2003/REC-PNG-20031110/#11IHDR |
|
* http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.IHDR |
|
* |
|
* Width 4 bytes |
|
* Height 4 bytes |
|
* Bit depth 1 byte |
|
* Colour type 1 byte |
|
* Compression method 1 byte |
|
* Filter method 1 byte |
|
* Interlace method 1 byte |
|
*/ |
|
PNGReader.prototype.decodeIHDR = function(chunk){ |
|
var png = this.png; |
|
|
|
png.setWidth( readUInt32(chunk, 0)); |
|
png.setHeight( readUInt32(chunk, 4)); |
|
png.setBitDepth( readUInt8(chunk, 8)); |
|
png.setColorType( readUInt8(chunk, 9)); |
|
png.setCompressionMethod( readUInt8(chunk, 10)); |
|
png.setFilterMethod( readUInt8(chunk, 11)); |
|
png.setInterlaceMethod( readUInt8(chunk, 12)); |
|
|
|
}; |
|
|
|
/** |
|
* |
|
* http://www.w3.org/TR/PNG/#11PLTE |
|
*/ |
|
PNGReader.prototype.decodePLTE = function(chunk){ |
|
this.png.setPalette(chunk); |
|
}; |
|
|
|
/** |
|
* http://www.w3.org/TR/2003/REC-PNG-20031110/#11IDAT |
|
*/ |
|
PNGReader.prototype.decodeIDAT = function(chunk){ |
|
// multiple IDAT chunks will concatenated |
|
this.dataChunks.push(chunk); |
|
}; |
|
|
|
/** |
|
* http://www.w3.org/TR/2003/REC-PNG-20031110/#11IEND |
|
*/ |
|
PNGReader.prototype.decodeIEND = function(){ |
|
}; |
|
|
|
/** |
|
* Uncompress IDAT chunks |
|
*/ |
|
PNGReader.prototype.decodePixels = function(callback){ |
|
var png = this.png; |
|
var reader = this; |
|
var length = 0; |
|
var i, j, k, l; |
|
for (l = this.dataChunks.length; l--;) length += this.dataChunks[l].length; |
|
var data = new Buffer(length); |
|
for (i = 0, k = 0, l = this.dataChunks.length; i < l; i++){ |
|
var chunk = this.dataChunks[i]; |
|
for (j = 0; j < chunk.length; j++) data[k++] = chunk[j]; |
|
} |
|
inflate(data, function(err, data){ |
|
if (err) return callback(err); |
|
|
|
try { |
|
if (png.getInterlaceMethod() === 0){ |
|
reader.interlaceNone(data); |
|
} else { |
|
reader.interlaceAdam7(data); |
|
} |
|
} catch (e){ |
|
return callback(e); |
|
} |
|
|
|
callback(); |
|
}); |
|
}; |
|
|
|
// Different interlace methods |
|
|
|
PNGReader.prototype.interlaceNone = function(data){ |
|
|
|
var png = this.png; |
|
|
|
// bytes per pixel |
|
var bpp = Math.max(1, png.colors * png.bitDepth / 8); |
|
|
|
// color bytes per row |
|
var cpr = bpp * png.width; |
|
|
|
var pixels = new Buffer(bpp * png.width * png.height); |
|
var scanline; |
|
var offset = 0; |
|
|
|
for (var i = 0; i < data.length; i += cpr + 1){ |
|
|
|
scanline = slice.call(data, i + 1, i + cpr + 1); |
|
|
|
switch (readUInt8(data, i)){ |
|
case 0: this.unFilterNone( scanline, pixels, bpp, offset, cpr); break; |
|
case 1: this.unFilterSub( scanline, pixels, bpp, offset, cpr); break; |
|
case 2: this.unFilterUp( scanline, pixels, bpp, offset, cpr); break; |
|
case 3: this.unFilterAverage(scanline, pixels, bpp, offset, cpr); break; |
|
case 4: this.unFilterPaeth( scanline, pixels, bpp, offset, cpr); break; |
|
default: throw new Error("unkown filtered scanline"); |
|
} |
|
|
|
offset += cpr; |
|
|
|
} |
|
|
|
png.pixels = pixels; |
|
|
|
}; |
|
|
|
PNGReader.prototype.interlaceAdam7 = function(data){ |
|
throw new Error("Adam7 interlacing is not implemented yet"); |
|
}; |
|
|
|
// Unfiltering |
|
|
|
/** |
|
* No filtering, direct copy |
|
*/ |
|
PNGReader.prototype.unFilterNone = function(scanline, pixels, bpp, of, length){ |
|
for (var i = 0, to = length; i < to; i++){ |
|
pixels[of + i] = scanline[i]; |
|
} |
|
}; |
|
|
|
/** |
|
* The Sub() filter transmits the difference between each byte and the value |
|
* of the corresponding byte of the prior pixel. |
|
* Sub(x) = Raw(x) + Raw(x - bpp) |
|
*/ |
|
PNGReader.prototype.unFilterSub = function(scanline, pixels, bpp, of, length){ |
|
var i = 0; |
|
for (; i < bpp; i++) pixels[of + i] = scanline[i]; |
|
for (; i < length; i++){ |
|
// Raw(x) + Raw(x - bpp) |
|
pixels[of + i] = (scanline[i] + pixels[of + i - bpp]) & 0xFF; |
|
} |
|
}; |
|
|
|
/** |
|
* The Up() filter is just like the Sub() filter except that the pixel |
|
* immediately above the current pixel, rather than just to its left, is used |
|
* as the predictor. |
|
* Up(x) = Raw(x) + Prior(x) |
|
*/ |
|
PNGReader.prototype.unFilterUp = function(scanline, pixels, bpp, of, length){ |
|
var i = 0, byte, prev; |
|
// Prior(x) is 0 for all x on the first scanline |
|
if ((of - length) < 0) for (; i < length; i++){ |
|
pixels[of + i] = scanline[i]; |
|
} else for (; i < length; i++){ |
|
// Raw(x) |
|
byte = scanline[i]; |
|
// Prior(x) |
|
prev = pixels[of + i - length]; |
|
pixels[of + i] = (byte + prev) & 0xFF; |
|
} |
|
}; |
|
|
|
/** |
|
* The Average() filter uses the average of the two neighboring pixels (left |
|
* and above) to predict the value of a pixel. |
|
* Average(x) = Raw(x) + floor((Raw(x-bpp)+Prior(x))/2) |
|
*/ |
|
PNGReader.prototype.unFilterAverage = function(scanline, pixels, bpp, of, length){ |
|
var i = 0, byte, prev, prior; |
|
if ((of - length) < 0){ |
|
// Prior(x) == 0 && Raw(x - bpp) == 0 |
|
for (; i < bpp; i++){ |
|
pixels[of + i] = scanline[i]; |
|
} |
|
// Prior(x) == 0 && Raw(x - bpp) != 0 (right shift, prevent doubles) |
|
for (; i < length; i++){ |
|
pixels[of + i] = (scanline[i] + (pixels[of + i - bpp] >> 1)) & 0xFF; |
|
} |
|
} else { |
|
// Prior(x) != 0 && Raw(x - bpp) == 0 |
|
for (; i < bpp; i++){ |
|
pixels[of + i] = (scanline[i] + (pixels[of - length + i] >> 1)) & 0xFF; |
|
} |
|
// Prior(x) != 0 && Raw(x - bpp) != 0 |
|
for (; i < length; i++){ |
|
byte = scanline[i]; |
|
prev = pixels[of + i - bpp]; |
|
prior = pixels[of + i - length]; |
|
pixels[of + i] = (byte + (prev + prior >> 1)) & 0xFF; |
|
} |
|
} |
|
}; |
|
|
|
/** |
|
* The Paeth() filter computes a simple linear function of the three |
|
* neighboring pixels (left, above, upper left), then chooses as predictor |
|
* the neighboring pixel closest to the computed value. This technique is due |
|
* to Alan W. Paeth. |
|
* Paeth(x) = Raw(x) + |
|
* PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp)) |
|
* function PaethPredictor (a, b, c) |
|
* begin |
|
* ; a = left, b = above, c = upper left |
|
* p := a + b - c ; initial estimate |
|
* pa := abs(p - a) ; distances to a, b, c |
|
* pb := abs(p - b) |
|
* pc := abs(p - c) |
|
* ; return nearest of a,b,c, |
|
* ; breaking ties in order a,b,c. |
|
* if pa <= pb AND pa <= pc then return a |
|
* else if pb <= pc then return b |
|
* else return c |
|
* end |
|
*/ |
|
PNGReader.prototype.unFilterPaeth = function(scanline, pixels, bpp, of, length){ |
|
var i = 0, raw, a, b, c, p, pa, pb, pc, pr; |
|
if ((of - length) < 0){ |
|
// Prior(x) == 0 && Raw(x - bpp) == 0 |
|
for (; i < bpp; i++){ |
|
pixels[of + i] = scanline[i]; |
|
} |
|
// Prior(x) == 0 && Raw(x - bpp) != 0 |
|
// paethPredictor(x, 0, 0) is always x |
|
for (; i < length; i++){ |
|
pixels[of + i] = (scanline[i] + pixels[of + i - bpp]) & 0xFF; |
|
} |
|
} else { |
|
// Prior(x) != 0 && Raw(x - bpp) == 0 |
|
// paethPredictor(x, 0, 0) is always x |
|
for (; i < bpp; i++){ |
|
pixels[of + i] = (scanline[i] + pixels[of + i - length]) & 0xFF; |
|
} |
|
// Prior(x) != 0 && Raw(x - bpp) != 0 |
|
for (; i < length; i++){ |
|
raw = scanline[i]; |
|
a = pixels[of + i - bpp]; |
|
b = pixels[of + i - length]; |
|
c = pixels[of + i - length - bpp]; |
|
p = a + b - c; |
|
pa = Math.abs(p - a); |
|
pb = Math.abs(p - b); |
|
pc = Math.abs(p - c); |
|
if (pa <= pb && pa <= pc) pr = a; |
|
else if (pb <= pc) pr = b; |
|
else pr = c; |
|
pixels[of + i] = (raw + pr) & 0xFF; |
|
} |
|
} |
|
}; |
|
|
|
/** |
|
* Parse the PNG file |
|
* |
|
* reader.parse(options, callback) |
|
* OR |
|
* reader.parse(callback) |
|
* |
|
* OPTIONS: |
|
* option | type | default |
|
* ---------------------------- |
|
* data boolean true should it read the pixel data |
|
*/ |
|
PNGReader.prototype.parse = function(options, callback){ |
|
|
|
if (typeof options == 'function') callback = options; |
|
if (typeof options != 'object') options = {}; |
|
|
|
try { |
|
|
|
this.decodeHeader(); |
|
|
|
while (this.i < this.bytes.length){ |
|
var type = this.decodeChunk(); |
|
// stop after IHDR chunk, or after IEND |
|
if (type == 'IHDR' && options.data === false || type == 'IEND') break; |
|
} |
|
|
|
var png = this.png; |
|
|
|
this.decodePixels(function(err){ |
|
callback(err, png); |
|
}); |
|
|
|
} catch (e){ |
|
callback(e); |
|
} |
|
|
|
}; |
|
|
|
module.exports = PNGReader; |
|
|
|
}).call(this,require("buffer").Buffer) |
|
},{"./PNG":1,"buffer":8,"zlib":7}],3:[function(require,module,exports){ |
|
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 |
|
// |
|
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! |
|
// |
|
// Originally from narwhal.js (http://narwhaljs.org) |
|
// Copyright (c) 2009 Thomas Robinson <280north.com> |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|
// of this software and associated documentation files (the 'Software'), to |
|
// deal in the Software without restriction, including without limitation the |
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
// sell copies of the Software, and to permit persons to whom the Software is |
|
// furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included in |
|
// all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
// when used in node, this will actually load the util module we depend on |
|
// versus loading the builtin util module as happens otherwise |
|
// this is a bug in node module loading as far as I am concerned |
|
var util = require('util/'); |
|
|
|
var pSlice = Array.prototype.slice; |
|
var hasOwn = Object.prototype.hasOwnProperty; |
|
|
|
// 1. The assert module provides functions that throw |
|
// AssertionError's when particular conditions are not met. The |
|
// assert module must conform to the following interface. |
|
|
|
var assert = module.exports = ok; |
|
|
|
// 2. The AssertionError is defined in assert. |
|
// new assert.AssertionError({ message: message, |
|
// actual: actual, |
|
// expected: expected }) |
|
|
|
assert.AssertionError = function AssertionError(options) { |
|
this.name = 'AssertionError'; |
|
this.actual = options.actual; |
|
this.expected = options.expected; |
|
this.operator = options.operator; |
|
if (options.message) { |
|
this.message = options.message; |
|
this.generatedMessage = false; |
|
} else { |
|
this.message = getMessage(this); |
|
this.generatedMessage = true; |
|
} |
|
var stackStartFunction = options.stackStartFunction || fail; |
|
|
|
if (Error.captureStackTrace) { |
|
Error.captureStackTrace(this, stackStartFunction); |
|
} |
|
else { |
|
// non v8 browsers so we can have a stacktrace |
|
var err = new Error(); |
|
if (err.stack) { |
|
var out = err.stack; |
|
|
|
// try to strip useless frames |
|
var fn_name = stackStartFunction.name; |
|
var idx = out.indexOf('\n' + fn_name); |
|
if (idx >= 0) { |
|
// once we have located the function frame |
|
// we need to strip out everything before it (and its line) |
|
var next_line = out.indexOf('\n', idx + 1); |
|
out = out.substring(next_line + 1); |
|
} |
|
|
|
this.stack = out; |
|
} |
|
} |
|
}; |
|
|
|
// assert.AssertionError instanceof Error |
|
util.inherits(assert.AssertionError, Error); |
|
|
|
function replacer(key, value) { |
|
if (util.isUndefined(value)) { |
|
return '' + value; |
|
} |
|
if (util.isNumber(value) && !isFinite(value)) { |
|
return value.toString(); |
|
} |
|
if (util.isFunction(value) || util.isRegExp(value)) { |
|
return value.toString(); |
|
} |
|
return value; |
|
} |
|
|
|
function truncate(s, n) { |
|
if (util.isString(s)) { |
|
return s.length < n ? s : s.slice(0, n); |
|
} else { |
|
return s; |
|
} |
|
} |
|
|
|
function getMessage(self) { |
|
return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + |
|
self.operator + ' ' + |
|
truncate(JSON.stringify(self.expected, replacer), 128); |
|
} |
|
|
|
// At present only the three keys mentioned above are used and |
|
// understood by the spec. Implementations or sub modules can pass |
|
// other keys to the AssertionError's constructor - they will be |
|
// ignored. |
|
|
|
// 3. All of the following functions must throw an AssertionError |
|
// when a corresponding condition is not met, with a message that |
|
// may be undefined if not provided. All assertion methods provide |
|
// both the actual and expected values to the assertion error for |
|
// display purposes. |
|
|
|
function fail(actual, expected, message, operator, stackStartFunction) { |
|
throw new assert.AssertionError({ |
|
message: message, |
|
actual: actual, |
|
expected: expected, |
|
operator: operator, |
|
stackStartFunction: stackStartFunction |
|
}); |
|
} |
|
|
|
// EXTENSION! allows for well behaved errors defined elsewhere. |
|
assert.fail = fail; |
|
|
|
// 4. Pure assertion tests whether a value is truthy, as determined |
|
// by !!guard. |
|
// assert.ok(guard, message_opt); |
|
// This statement is equivalent to assert.equal(true, !!guard, |
|
// message_opt);. To test strictly for the value true, use |
|
// assert.strictEqual(true, guard, message_opt);. |
|
|
|
function ok(value, message) { |
|
if (!value) fail(value, true, message, '==', assert.ok); |
|
} |
|
assert.ok = ok; |
|
|
|
// 5. The equality assertion tests shallow, coercive equality with |
|
// ==. |
|
// assert.equal(actual, expected, message_opt); |
|
|
|
assert.equal = function equal(actual, expected, message) { |
|
if (actual != expected) fail(actual, expected, message, '==', assert.equal); |
|
}; |
|
|
|
// 6. The non-equality assertion tests for whether two objects are not equal |
|
// with != assert.notEqual(actual, expected, message_opt); |
|
|
|
assert.notEqual = function notEqual(actual, expected, message) { |
|
if (actual == expected) { |
|
fail(actual, expected, message, '!=', assert.notEqual); |
|
} |
|
}; |
|
|
|
// 7. The equivalence assertion tests a deep equality relation. |
|
// assert.deepEqual(actual, expected, message_opt); |
|
|
|
assert.deepEqual = function deepEqual(actual, expected, message) { |
|
if (!_deepEqual(actual, expected)) { |
|
fail(actual, expected, message, 'deepEqual', assert.deepEqual); |
|
} |
|
}; |
|
|
|
function _deepEqual(actual, expected) { |
|
// 7.1. All identical values are equivalent, as determined by ===. |
|
if (actual === expected) { |
|
return true; |
|
|
|
} else if (util.isBuffer(actual) && util.isBuffer(expected)) { |
|
if (actual.length != expected.length) return false; |
|
|
|
for (var i = 0; i < actual.length; i++) { |
|
if (actual[i] !== expected[i]) return false; |
|
} |
|
|
|
return true; |
|
|
|
// 7.2. If the expected value is a Date object, the actual value is |
|
// equivalent if it is also a Date object that refers to the same time. |
|
} else if (util.isDate(actual) && util.isDate(expected)) { |
|
return actual.getTime() === expected.getTime(); |
|
|
|
// 7.3 If the expected value is a RegExp object, the actual value is |
|
// equivalent if it is also a RegExp object with the same source and |
|
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). |
|
} else if (util.isRegExp(actual) && util.isRegExp(expected)) { |
|
return actual.source === expected.source && |
|
actual.global === expected.global && |
|
actual.multiline === expected.multiline && |
|
actual.lastIndex === expected.lastIndex && |
|
actual.ignoreCase === expected.ignoreCase; |
|
|
|
// 7.4. Other pairs that do not both pass typeof value == 'object', |
|
// equivalence is determined by ==. |
|
} else if (!util.isObject(actual) && !util.isObject(expected)) { |
|
return actual == expected; |
|
|
|
// 7.5 For all other Object pairs, including Array objects, equivalence is |
|
// determined by having the same number of owned properties (as verified |
|
// with Object.prototype.hasOwnProperty.call), the same set of keys |
|
// (although not necessarily the same order), equivalent values for every |
|
// corresponding key, and an identical 'prototype' property. Note: this |
|
// accounts for both named and indexed properties on Arrays. |
|
} else { |
|
return objEquiv(actual, expected); |
|
} |
|
} |
|
|
|
function isArguments(object) { |
|
return Object.prototype.toString.call(object) == '[object Arguments]'; |
|
} |
|
|
|
function objEquiv(a, b) { |
|
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) |
|
return false; |
|
// an identical 'prototype' property. |
|
if (a.prototype !== b.prototype) return false; |
|
// if one is a primitive, the other must be same |
|
if (util.isPrimitive(a) || util.isPrimitive(b)) { |
|
return a === b; |
|
} |
|
var aIsArgs = isArguments(a), |
|
bIsArgs = isArguments(b); |
|
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) |
|
return false; |
|
if (aIsArgs) { |
|
a = pSlice.call(a); |
|
b = pSlice.call(b); |
|
return _deepEqual(a, b); |
|
} |
|
var ka = objectKeys(a), |
|
kb = objectKeys(b), |
|
key, i; |
|
// having the same number of owned properties (keys incorporates |
|
// hasOwnProperty) |
|
if (ka.length != kb.length) |
|
return false; |
|
//the same set of keys (although not necessarily the same order), |
|
ka.sort(); |
|
kb.sort(); |
|
//~~~cheap key test |
|
for (i = ka.length - 1; i >= 0; i--) { |
|
if (ka[i] != kb[i]) |
|
return false; |
|
} |
|
//equivalent values for every corresponding key, and |
|
//~~~possibly expensive deep test |
|
for (i = ka.length - 1; i >= 0; i--) { |
|
key = ka[i]; |
|
if (!_deepEqual(a[key], b[key])) return false; |
|
} |
|
return true; |
|
} |
|
|
|
// 8. The non-equivalence assertion tests for any deep inequality. |
|
// assert.notDeepEqual(actual, expected, message_opt); |
|
|
|
assert.notDeepEqual = function notDeepEqual(actual, expected, message) { |
|
if (_deepEqual(actual, expected)) { |
|
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); |
|
} |
|
}; |
|
|
|
// 9. The strict equality assertion tests strict equality, as determined by ===. |
|
// assert.strictEqual(actual, expected, message_opt); |
|
|
|
assert.strictEqual = function strictEqual(actual, expected, message) { |
|
if (actual !== expected) { |
|
fail(actual, expected, message, '===', assert.strictEqual); |
|
} |
|
}; |
|
|
|
// 10. The strict non-equality assertion tests for strict inequality, as |
|
// determined by !==. assert.notStrictEqual(actual, expected, message_opt); |
|
|
|
assert.notStrictEqual = function notStrictEqual(actual, expected, message) { |
|
if (actual === expected) { |
|
fail(actual, expected, message, '!==', assert.notStrictEqual); |
|
} |
|
}; |
|
|
|
function expectedException(actual, expected) { |
|
if (!actual || !expected) { |
|
return false; |
|
} |
|
|
|
if (Object.prototype.toString.call(expected) == '[object RegExp]') { |
|
return expected.test(actual); |
|
} else if (actual instanceof expected) { |
|
return true; |
|
} else if (expected.call({}, actual) === true) { |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
function _throws(shouldThrow, block, expected, message) { |
|
var actual; |
|
|
|
if (util.isString(expected)) { |
|
message = expected; |
|
expected = null; |
|
} |
|
|
|
try { |
|
block(); |
|
} catch (e) { |
|
actual = e; |
|
} |
|
|
|
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + |
|
(message ? ' ' + message : '.'); |
|
|
|
if (shouldThrow && !actual) { |
|
fail(actual, expected, 'Missing expected exception' + message); |
|
} |
|
|
|
if (!shouldThrow && expectedException(actual, expected)) { |
|
fail(actual, expected, 'Got unwanted exception' + message); |
|
} |
|
|
|
if ((shouldThrow && actual && expected && |
|
!expectedException(actual, expected)) || (!shouldThrow && actual)) { |
|
throw actual; |
|
} |
|
} |
|
|
|
// 11. Expected to throw an error: |
|
// assert.throws(block, Error_opt, message_opt); |
|
|
|
assert.throws = function(block, /*optional*/error, /*optional*/message) { |
|
_throws.apply(this, [true].concat(pSlice.call(arguments))); |
|
}; |
|
|
|
// EXTENSION! This is annoying to write outside this module. |
|
assert.doesNotThrow = function(block, /*optional*/message) { |
|
_throws.apply(this, [false].concat(pSlice.call(arguments))); |
|
}; |
|
|
|
assert.ifError = function(err) { if (err) {throw err;}}; |
|
|
|
var objectKeys = Object.keys || function (obj) { |
|
var keys = []; |
|
for (var key in obj) { |
|
if (hasOwn.call(obj, key)) keys.push(key); |
|
} |
|
return keys; |
|
}; |
|
|
|
},{"util/":37}],4:[function(require,module,exports){ |
|
;(function (exports) { |
|
'use strict' |
|
|
|
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' |
|
|
|
var Arr = (typeof Uint8Array !== 'undefined') |
|
? Uint8Array |
|
: Array |
|
|
|
var PLUS = '+'.charCodeAt(0) |
|
var SLASH = '/'.charCodeAt(0) |
|
var NUMBER = '0'.charCodeAt(0) |
|
var LOWER = 'a'.charCodeAt(0) |
|
var UPPER = 'A'.charCodeAt(0) |
|
var PLUS_URL_SAFE = '-'.charCodeAt(0) |
|
var SLASH_URL_SAFE = '_'.charCodeAt(0) |
|
|
|
function decode (elt) { |
|
var code = elt.charCodeAt(0) |
|
if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+' |
|
if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/' |
|
if (code < NUMBER) return -1 // no match |
|
if (code < NUMBER + 10) return code - NUMBER + 26 + 26 |
|
if (code < UPPER + 26) return code - UPPER |
|
if (code < LOWER + 26) return code - LOWER + 26 |
|
} |
|
|
|
function b64ToByteArray (b64) { |
|
var i, j, l, tmp, placeHolders, arr |
|
|
|
if (b64.length % 4 > 0) { |
|
throw new Error('Invalid string. Length must be a multiple of 4') |
|
} |
|
|
|
// the number of equal signs (place holders) |
|
// if there are two placeholders, than the two characters before it |
|
// represent one byte |
|
// if there is only one, then the three characters before it represent 2 bytes |
|
// this is just a cheap hack to not do indexOf twice |
|
var len = b64.length |
|
placeHolders = b64.charAt(len - 2) === '=' ? 2 : b64.charAt(len - 1) === '=' ? 1 : 0 |
|
|
|
// base64 is 4/3 + up to two characters of the original data |
|
arr = new Arr(b64.length * 3 / 4 - placeHolders) |
|
|
|
// if there are placeholders, only get up to the last complete 4 chars |
|
l = placeHolders > 0 ? b64.length - 4 : b64.length |
|
|
|
var L = 0 |
|
|
|
function push (v) { |
|
arr[L++] = v |
|
} |
|
|
|
for (i = 0, j = 0; i < l; i += 4, j += 3) { |
|
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) |
|
push((tmp & 0xFF0000) >> 16) |
|
push((tmp & 0xFF00) >> 8) |
|
push(tmp & 0xFF) |
|
} |
|
|
|
if (placeHolders === 2) { |
|
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) |
|
push(tmp & 0xFF) |
|
} else if (placeHolders === 1) { |
|
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) |
|
push((tmp >> 8) & 0xFF) |
|
push(tmp & 0xFF) |
|
} |
|
|
|
return arr |
|
} |
|
|
|
function uint8ToBase64 (uint8) { |
|
var i |
|
var extraBytes = uint8.length % 3 // if we have 1 byte left, pad 2 bytes |
|
var output = '' |
|
var temp, length |
|
|
|
function encode (num) { |
|
return lookup.charAt(num) |
|
} |
|
|
|
function tripletToBase64 (num) { |
|
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) |
|
} |
|
|
|
// go through the array every three bytes, we'll deal with trailing stuff later |
|
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { |
|
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) |
|
output += tripletToBase64(temp) |
|
} |
|
|
|
// pad the end with zeros, but make sure to not forget the extra bytes |
|
switch (extraBytes) { |
|
case 1: |
|
temp = uint8[uint8.length - 1] |
|
output += encode(temp >> 2) |
|
output += encode((temp << 4) & 0x3F) |
|
output += '==' |
|
break |
|
case 2: |
|
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) |
|
output += encode(temp >> 10) |
|
output += encode((temp >> 4) & 0x3F) |
|
output += encode((temp << 2) & 0x3F) |
|
output += '=' |
|
break |
|
default: |
|
break |
|
} |
|
|
|
return output |
|
} |
|
|
|
exports.toByteArray = b64ToByteArray |
|
exports.fromByteArray = uint8ToBase64 |
|
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) |
|
|
|
},{}],5:[function(require,module,exports){ |
|
|
|
},{}],6:[function(require,module,exports){ |
|
(function (process,Buffer){ |
|
var msg = require('pako/lib/zlib/messages'); |
|
var zstream = require('pako/lib/zlib/zstream'); |
|
var zlib_deflate = require('pako/lib/zlib/deflate.js'); |
|
var zlib_inflate = require('pako/lib/zlib/inflate.js'); |
|
var constants = require('pako/lib/zlib/constants'); |
|
|
|
for (var key in constants) { |
|
exports[key] = constants[key]; |
|
} |
|
|
|
// zlib modes |
|
exports.NONE = 0; |
|
exports.DEFLATE = 1; |
|
exports.INFLATE = 2; |
|
exports.GZIP = 3; |
|
exports.GUNZIP = 4; |
|
exports.DEFLATERAW = 5; |
|
exports.INFLATERAW = 6; |
|
exports.UNZIP = 7; |
|
|
|
/** |
|
* Emulate Node's zlib C++ layer for use by the JS layer in index.js |
|
*/ |
|
function Zlib(mode) { |
|
if (mode < exports.DEFLATE || mode > exports.UNZIP) |
|
throw new TypeError("Bad argument"); |
|
|
|
this.mode = mode; |
|
this.init_done = false; |
|
this.write_in_progress = false; |
|
this.pending_close = false; |
|
this.windowBits = 0; |
|
this.level = 0; |
|
this.memLevel = 0; |
|
this.strategy = 0; |
|
this.dictionary = null; |
|
} |
|
|
|
Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { |
|
this.windowBits = windowBits; |
|
this.level = level; |
|
this.memLevel = memLevel; |
|
this.strategy = strategy; |
|
// dictionary not supported. |
|
|
|
if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) |
|
this.windowBits += 16; |
|
|
|
if (this.mode === exports.UNZIP) |
|
this.windowBits += 32; |
|
|
|
if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) |
|
this.windowBits = -this.windowBits; |
|
|
|
this.strm = new zstream(); |
|
|
|
switch (this.mode) { |
|
case exports.DEFLATE: |
|
case exports.GZIP: |
|
case exports.DEFLATERAW: |
|
var status = zlib_deflate.deflateInit2( |
|
this.strm, |
|
this.level, |
|
exports.Z_DEFLATED, |
|
this.windowBits, |
|
this.memLevel, |
|
this.strategy |
|
); |
|
break; |
|
case exports.INFLATE: |
|
case exports.GUNZIP: |
|
case exports.INFLATERAW: |
|
case exports.UNZIP: |
|
var status = zlib_inflate.inflateInit2( |
|
this.strm, |
|
this.windowBits |
|
); |
|
break; |
|
default: |
|
throw new Error("Unknown mode " + this.mode); |
|
} |
|
|
|
if (status !== exports.Z_OK) { |
|
this._error(status); |
|
return; |
|
} |
|
|
|
this.write_in_progress = false; |
|
this.init_done = true; |
|
}; |
|
|
|
Zlib.prototype.params = function() { |
|
throw new Error("deflateParams Not supported"); |
|
}; |
|
|
|
Zlib.prototype._writeCheck = function() { |
|
if (!this.init_done) |
|
throw new Error("write before init"); |
|
|
|
if (this.mode === exports.NONE) |
|
throw new Error("already finalized"); |
|
|
|
if (this.write_in_progress) |
|
throw new Error("write already in progress"); |
|
|
|
if (this.pending_close) |
|
throw new Error("close is pending"); |
|
}; |
|
|
|
Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { |
|
this._writeCheck(); |
|
this.write_in_progress = true; |
|
|
|
var self = this; |
|
process.nextTick(function() { |
|
self.write_in_progress = false; |
|
var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); |
|
self.callback(res[0], res[1]); |
|
|
|
if (self.pending_close) |
|
self.close(); |
|
}); |
|
|
|
return this; |
|
}; |
|
|
|
// set method for Node buffers, used by pako |
|
function bufferSet(data, offset) { |
|
for (var i = 0; i < data.length; i++) { |
|
this[offset + i] = data[i]; |
|
} |
|
} |
|
|
|
Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { |
|
this._writeCheck(); |
|
return this._write(flush, input, in_off, in_len, out, out_off, out_len); |
|
}; |
|
|
|
Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { |
|
this.write_in_progress = true; |
|
|
|
if (flush !== exports.Z_NO_FLUSH && |
|
flush !== exports.Z_PARTIAL_FLUSH && |
|
flush !== exports.Z_SYNC_FLUSH && |
|
flush !== exports.Z_FULL_FLUSH && |
|
flush !== exports.Z_FINISH && |
|
flush !== exports.Z_BLOCK) { |
|
throw new Error("Invalid flush value"); |
|
} |
|
|
|
if (input == null) { |
|
input = new Buffer(0); |
|
in_len = 0; |
|
in_off = 0; |
|
} |
|
|
|
if (out._set) |
|
out.set = out._set; |
|
else |
|
out.set = bufferSet; |
|
|
|
var strm = this.strm; |
|
strm.avail_in = in_len; |
|
strm.input = input; |
|
strm.next_in = in_off; |
|
strm.avail_out = out_len; |
|
strm.output = out; |
|
strm.next_out = out_off; |
|
|
|
switch (this.mode) { |
|
case exports.DEFLATE: |
|
case exports.GZIP: |
|
case exports.DEFLATERAW: |
|
var status = zlib_deflate.deflate(strm, flush); |
|
break; |
|
case exports.UNZIP: |
|
case exports.INFLATE: |
|
case exports.GUNZIP: |
|
case exports.INFLATERAW: |
|
var status = zlib_inflate.inflate(strm, flush); |
|
break; |
|
default: |
|
throw new Error("Unknown mode " + this.mode); |
|
} |
|
|
|
if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { |
|
this._error(status); |
|
} |
|
|
|
this.write_in_progress = false; |
|
return [strm.avail_in, strm.avail_out]; |
|
}; |
|
|
|
Zlib.prototype.close = function() { |
|
if (this.write_in_progress) { |
|
this.pending_close = true; |
|
return; |
|
} |
|
|
|
this.pending_close = false; |
|
|
|
if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { |
|
zlib_deflate.deflateEnd(this.strm); |
|
} else { |
|
zlib_inflate.inflateEnd(this.strm); |
|
} |
|
|
|
this.mode = exports.NONE; |
|
}; |
|
|
|
Zlib.prototype.reset = function() { |
|
switch (this.mode) { |
|
case exports.DEFLATE: |
|
case exports.DEFLATERAW: |
|
var status = zlib_deflate.deflateReset(this.strm); |
|
break; |
|
case exports.INFLATE: |
|
case exports.INFLATERAW: |
|
var status = zlib_inflate.inflateReset(this.strm); |
|
break; |
|
} |
|
|
|
if (status !== exports.Z_OK) { |
|
this._error(status); |
|
} |
|
}; |
|
|
|
Zlib.prototype._error = function(status) { |
|
this.onerror(msg[status] + ': ' + this.strm.msg, status); |
|
|
|
this.write_in_progress = false; |
|
if (this.pending_close) |
|
this.close(); |
|
}; |
|
|
|
exports.Zlib = Zlib; |
|
|
|
}).call(this,require('_process'),require("buffer").Buffer) |
|
},{"_process":28,"buffer":8,"pako/lib/zlib/constants":18,"pako/lib/zlib/deflate.js":20,"pako/lib/zlib/inflate.js":22,"pako/lib/zlib/messages":24,"pako/lib/zlib/zstream":26}],7:[function(require,module,exports){ |
|
(function (process,Buffer){ |
|
// Copyright Joyent, Inc. and other Node contributors. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the |
|
// "Software"), to deal in the Software without restriction, including |
|
// without limitation the rights to use, copy, modify, merge, publish, |
|
// distribute, sublicense, and/or sell copies of the Software, and to permit |
|
// persons to whom the Software is furnished to do so, subject to the |
|
// following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
var Transform = require('_stream_transform'); |
|
|
|
var binding = require('./binding'); |
|
var util = require('util'); |
|
var assert = require('assert').ok; |
|
|
|
// zlib doesn't provide these, so kludge them in following the same |
|
// const naming scheme zlib uses. |
|
binding.Z_MIN_WINDOWBITS = 8; |
|
binding.Z_MAX_WINDOWBITS = 15; |
|
binding.Z_DEFAULT_WINDOWBITS = 15; |
|
|
|
// fewer than 64 bytes per chunk is stupid. |
|
// technically it could work with as few as 8, but even 64 bytes |
|
// is absurdly low. Usually a MB or more is best. |
|
binding.Z_MIN_CHUNK = 64; |
|
binding.Z_MAX_CHUNK = Infinity; |
|
binding.Z_DEFAULT_CHUNK = (16 * 1024); |
|
|
|
binding.Z_MIN_MEMLEVEL = 1; |
|
binding.Z_MAX_MEMLEVEL = 9; |
|
binding.Z_DEFAULT_MEMLEVEL = 8; |
|
|
|
binding.Z_MIN_LEVEL = -1; |
|
binding.Z_MAX_LEVEL = 9; |
|
binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION; |
|
|
|
// expose all the zlib constants |
|
Object.keys(binding).forEach(function(k) { |
|
if (k.match(/^Z/)) exports[k] = binding[k]; |
|
}); |
|
|
|
// translation table for return codes. |
|
exports.codes = { |
|
Z_OK: binding.Z_OK, |
|
Z_STREAM_END: binding.Z_STREAM_END, |
|
Z_NEED_DICT: binding.Z_NEED_DICT, |
|
Z_ERRNO: binding.Z_ERRNO, |
|
Z_STREAM_ERROR: binding.Z_STREAM_ERROR, |
|
Z_DATA_ERROR: binding.Z_DATA_ERROR, |
|
Z_MEM_ERROR: binding.Z_MEM_ERROR, |
|
Z_BUF_ERROR: binding.Z_BUF_ERROR, |
|
Z_VERSION_ERROR: binding.Z_VERSION_ERROR |
|
}; |
|
|
|
Object.keys(exports.codes).forEach(function(k) { |
|
exports.codes[exports.codes[k]] = k; |
|
}); |
|
|
|
exports.Deflate = Deflate; |
|
exports.Inflate = Inflate; |
|
exports.Gzip = Gzip; |
|
exports.Gunzip = Gunzip; |
|
exports.DeflateRaw = DeflateRaw; |
|
exports.InflateRaw = InflateRaw; |
|
exports.Unzip = Unzip; |
|
|
|
exports.createDeflate = function(o) { |
|
return new Deflate(o); |
|
}; |
|
|
|
exports.createInflate = function(o) { |
|
return new Inflate(o); |
|
}; |
|
|
|
exports.createDeflateRaw = function(o) { |
|
return new DeflateRaw(o); |
|
}; |
|
|
|
exports.createInflateRaw = function(o) { |
|
return new InflateRaw(o); |
|
}; |
|
|
|
exports.createGzip = function(o) { |
|
return new Gzip(o); |
|
}; |
|
|
|
exports.createGunzip = function(o) { |
|
return new Gunzip(o); |
|
}; |
|
|
|
exports.createUnzip = function(o) { |
|
return new Unzip(o); |
|
}; |
|
|
|
|
|
// Convenience methods. |
|
// compress/decompress a string or buffer in one step. |
|
exports.deflate = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new Deflate(opts), buffer, callback); |
|
}; |
|
|
|
exports.deflateSync = function(buffer, opts) { |
|
return zlibBufferSync(new Deflate(opts), buffer); |
|
}; |
|
|
|
exports.gzip = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new Gzip(opts), buffer, callback); |
|
}; |
|
|
|
exports.gzipSync = function(buffer, opts) { |
|
return zlibBufferSync(new Gzip(opts), buffer); |
|
}; |
|
|
|
exports.deflateRaw = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new DeflateRaw(opts), buffer, callback); |
|
}; |
|
|
|
exports.deflateRawSync = function(buffer, opts) { |
|
return zlibBufferSync(new DeflateRaw(opts), buffer); |
|
}; |
|
|
|
exports.unzip = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new Unzip(opts), buffer, callback); |
|
}; |
|
|
|
exports.unzipSync = function(buffer, opts) { |
|
return zlibBufferSync(new Unzip(opts), buffer); |
|
}; |
|
|
|
exports.inflate = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new Inflate(opts), buffer, callback); |
|
}; |
|
|
|
exports.inflateSync = function(buffer, opts) { |
|
return zlibBufferSync(new Inflate(opts), buffer); |
|
}; |
|
|
|
exports.gunzip = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new Gunzip(opts), buffer, callback); |
|
}; |
|
|
|
exports.gunzipSync = function(buffer, opts) { |
|
return zlibBufferSync(new Gunzip(opts), buffer); |
|
}; |
|
|
|
exports.inflateRaw = function(buffer, opts, callback) { |
|
if (typeof opts === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
return zlibBuffer(new InflateRaw(opts), buffer, callback); |
|
}; |
|
|
|
exports.inflateRawSync = function(buffer, opts) { |
|
return zlibBufferSync(new InflateRaw(opts), buffer); |
|
}; |
|
|
|
function zlibBuffer(engine, buffer, callback) { |
|
var buffers = []; |
|
var nread = 0; |
|
|
|
engine.on('error', onError); |
|
engine.on('end', onEnd); |
|
|
|
engine.end(buffer); |
|
flow(); |
|
|
|
function flow() { |
|
var chunk; |
|
while (null !== (chunk = engine.read())) { |
|
buffers.push(chunk); |
|
nread += chunk.length; |
|
} |
|
engine.once('readable', flow); |
|
} |
|
|
|
function onError(err) { |
|
engine.removeListener('end', onEnd); |
|
engine.removeListener('readable', flow); |
|
callback(err); |
|
} |
|
|
|
function onEnd() { |
|
var buf = Buffer.concat(buffers, nread); |
|
buffers = []; |
|
callback(null, buf); |
|
engine.close(); |
|
} |
|
} |
|
|
|
function zlibBufferSync(engine, buffer) { |
|
if (typeof buffer === 'string') |
|
buffer = new Buffer(buffer); |
|
if (!Buffer.isBuffer(buffer)) |
|
throw new TypeError('Not a string or buffer'); |
|
|
|
var flushFlag = binding.Z_FINISH; |
|
|
|
return engine._processChunk(buffer, flushFlag); |
|
} |
|
|
|
// generic zlib |
|
// minimal 2-byte header |
|
function Deflate(opts) { |
|
if (!(this instanceof Deflate)) return new Deflate(opts); |
|
Zlib.call(this, opts, binding.DEFLATE); |
|
} |
|
|
|
function Inflate(opts) { |
|
if (!(this instanceof Inflate)) return new Inflate(opts); |
|
Zlib.call(this, opts, binding.INFLATE); |
|
} |
|
|
|
|
|
|
|
// gzip - bigger header, same deflate compression |
|
function Gzip(opts) { |
|
if (!(this instanceof Gzip)) return new Gzip(opts); |
|
Zlib.call(this, opts, binding.GZIP); |
|
} |
|
|
|
function Gunzip(opts) { |
|
if (!(this instanceof Gunzip)) return new Gunzip(opts); |
|
Zlib.call(this, opts, binding.GUNZIP); |
|
} |
|
|
|
|
|
|
|
// raw - no header |
|
function DeflateRaw(opts) { |
|
if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts); |
|
Zlib.call(this, opts, binding.DEFLATERAW); |
|
} |
|
|
|
function InflateRaw(opts) { |
|
if (!(this instanceof InflateRaw)) return new InflateRaw(opts); |
|
Zlib.call(this, opts, binding.INFLATERAW); |
|
} |
|
|
|
|
|
// auto-detect header. |
|
function Unzip(opts) { |
|
if (!(this instanceof Unzip)) return new Unzip(opts); |
|
Zlib.call(this, opts, binding.UNZIP); |
|
} |
|
|
|
|
|
// the Zlib class they all inherit from |
|
// This thing manages the queue of requests, and returns |
|
// true or false if there is anything in the queue when |
|
// you call the .write() method. |
|
|
|
function Zlib(opts, mode) { |
|
this._opts = opts = opts || {}; |
|
this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; |
|
|
|
Transform.call(this, opts); |
|
|
|
if (opts.flush) { |
|
if (opts.flush !== binding.Z_NO_FLUSH && |
|
opts.flush !== binding.Z_PARTIAL_FLUSH && |
|
opts.flush !== binding.Z_SYNC_FLUSH && |
|
opts.flush !== binding.Z_FULL_FLUSH && |
|
opts.flush !== binding.Z_FINISH && |
|
opts.flush !== binding.Z_BLOCK) { |
|
throw new Error('Invalid flush flag: ' + opts.flush); |
|
} |
|
} |
|
this._flushFlag = opts.flush || binding.Z_NO_FLUSH; |
|
|
|
if (opts.chunkSize) { |
|
if (opts.chunkSize < exports.Z_MIN_CHUNK || |
|
opts.chunkSize > exports.Z_MAX_CHUNK) { |
|
throw new Error('Invalid chunk size: ' + opts.chunkSize); |
|
} |
|
} |
|
|
|
if (opts.windowBits) { |
|
if (opts.windowBits < exports.Z_MIN_WINDOWBITS || |
|
opts.windowBits > exports.Z_MAX_WINDOWBITS) { |
|
throw new Error('Invalid windowBits: ' + opts.windowBits); |
|
} |
|
} |
|
|
|
if (opts.level) { |
|
if (opts.level < exports.Z_MIN_LEVEL || |
|
opts.level > exports.Z_MAX_LEVEL) { |
|
throw new Error('Invalid compression level: ' + opts.level); |
|
} |
|
} |
|
|
|
if (opts.memLevel) { |
|
if (opts.memLevel < exports.Z_MIN_MEMLEVEL || |
|
opts.memLevel > exports.Z_MAX_MEMLEVEL) { |
|
throw new Error('Invalid memLevel: ' + opts.memLevel); |
|
} |
|
} |
|
|
|
if (opts.strategy) { |
|
if (opts.strategy != exports.Z_FILTERED && |
|
opts.strategy != exports.Z_HUFFMAN_ONLY && |
|
opts.strategy != exports.Z_RLE && |
|
opts.strategy != exports.Z_FIXED && |
|
opts.strategy != exports.Z_DEFAULT_STRATEGY) { |
|
throw new Error('Invalid strategy: ' + opts.strategy); |
|
} |
|
} |
|
|
|
if (opts.dictionary) { |
|
if (!Buffer.isBuffer(opts.dictionary)) { |
|
throw new Error('Invalid dictionary: it should be a Buffer instance'); |
|
} |
|
} |
|
|
|
this._binding = new binding.Zlib(mode); |
|
|
|
var self = this; |
|
this._hadError = false; |
|
this._binding.onerror = function(message, errno) { |
|
// there is no way to cleanly recover. |
|
// continuing only obscures problems. |
|
self._binding = null; |
|
self._hadError = true; |
|
|
|
var error = new Error(message); |
|
error.errno = errno; |
|
error.code = exports.codes[errno]; |
|
self.emit('error', error); |
|
}; |
|
|
|
var level = exports.Z_DEFAULT_COMPRESSION; |
|
if (typeof opts.level === 'number') level = opts.level; |
|
|
|
var strategy = exports.Z_DEFAULT_STRATEGY; |
|
if (typeof opts.strategy === 'number') strategy = opts.strategy; |
|
|
|
this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, |
|
level, |
|
opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, |
|
strategy, |
|
opts.dictionary); |
|
|
|
this._buffer = new Buffer(this._chunkSize); |
|
this._offset = 0; |
|
this._closed = false; |
|
this._level = level; |
|
this._strategy = strategy; |
|
|
|
this.once('end', this.close); |
|
} |
|
|
|
util.inherits(Zlib, Transform); |
|
|
|
Zlib.prototype.params = function(level, strategy, callback) { |
|
if (level < exports.Z_MIN_LEVEL || |
|
level > exports.Z_MAX_LEVEL) { |
|
throw new RangeError('Invalid compression level: ' + level); |
|
} |
|
if (strategy != exports.Z_FILTERED && |
|
strategy != exports.Z_HUFFMAN_ONLY && |
|
strategy != exports.Z_RLE && |
|
strategy != exports.Z_FIXED && |
|
strategy != exports.Z_DEFAULT_STRATEGY) { |
|
throw new TypeError('Invalid strategy: ' + strategy); |
|
} |
|
|
|
if (this._level !== level || this._strategy !== strategy) { |
|
var self = this; |
|
this.flush(binding.Z_SYNC_FLUSH, function() { |
|
self._binding.params(level, strategy); |
|
if (!self._hadError) { |
|
self._level = level; |
|
self._strategy = strategy; |
|
if (callback) callback(); |
|
} |
|
}); |
|
} else { |
|
process.nextTick(callback); |
|
} |
|
}; |
|
|
|
Zlib.prototype.reset = function() { |
|
return this._binding.reset(); |
|
}; |
|
|
|
// This is the _flush function called by the transform class, |
|
// internally, when the last chunk has been written. |
|
Zlib.prototype._flush = function(callback) { |
|
this._transform(new Buffer(0), '', callback); |
|
}; |
|
|
|
Zlib.prototype.flush = function(kind, callback) { |
|
var ws = this._writableState; |
|
|
|
if (typeof kind === 'function' || (kind === void 0 && !callback)) { |
|
callback = kind; |
|
kind = binding.Z_FULL_FLUSH; |
|
} |
|
|
|
if (ws.ended) { |
|
if (callback) |
|
process.nextTick(callback); |
|
} else if (ws.ending) { |
|
if (callback) |
|
this.once('end', callback); |
|
} else if (ws.needDrain) { |
|
var self = this; |
|
this.once('drain', function() { |
|
self.flush(callback); |
|
}); |
|
} else { |
|
this._flushFlag = kind; |
|
this.write(new Buffer(0), '', callback); |
|
} |
|
}; |
|
|
|
Zlib.prototype.close = function(callback) { |
|
if (callback) |
|
process.nextTick(callback); |
|
|
|
if (this._closed) |
|
return; |
|
|
|
this._closed = true; |
|
|
|
this._binding.close(); |
|
|
|
var self = this; |
|
process.nextTick(function() { |
|
self.emit('close'); |
|
}); |
|
}; |
|
|
|
Zlib.prototype._transform = function(chunk, encoding, cb) { |
|
var flushFlag; |
|
var ws = this._writableState; |
|
var ending = ws.ending || ws.ended; |
|
var last = ending && (!chunk || ws.length === chunk.length); |
|
|
|
if (!chunk === null && !Buffer.isBuffer(chunk)) |
|
return cb(new Error('invalid input')); |
|
|
|
// If it's the last chunk, or a final flush, we use the Z_FINISH flush flag. |
|
// If it's explicitly flushing at some other time, then we use |
|
// Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression |
|
// goodness. |
|
if (last) |
|
flushFlag = binding.Z_FINISH; |
|
else { |
|
flushFlag = this._flushFlag; |
|
// once we've flushed the last of the queue, stop flushing and |
|
// go back to the normal behavior. |
|
if (chunk.length >= ws.length) { |
|
this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH; |
|
} |
|
} |
|
|
|
var self = this; |
|
this._processChunk(chunk, flushFlag, cb); |
|
}; |
|
|
|
Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { |
|
var availInBefore = chunk && chunk.length; |
|
var availOutBefore = this._chunkSize - this._offset; |
|
var inOff = 0; |
|
|
|
var self = this; |
|
|
|
var async = typeof cb === 'function'; |
|
|
|
if (!async) { |
|
var buffers = []; |
|
var nread = 0; |
|
|
|
var error; |
|
this.on('error', function(er) { |
|
error = er; |
|
}); |
|
|
|
do { |
|
var res = this._binding.writeSync(flushFlag, |
|
chunk, // in |
|
inOff, // in_off |
|
availInBefore, // in_len |
|
this._buffer, // out |
|
this._offset, //out_off |
|
availOutBefore); // out_len |
|
} while (!this._hadError && callback(res[0], res[1])); |
|
|
|
if (this._hadError) { |
|
throw error; |
|
} |
|
|
|
var buf = Buffer.concat(buffers, nread); |
|
this.close(); |
|
|
|
return buf; |
|
} |
|
|
|
var req = this._binding.write(flushFlag, |
|
chunk, // in |
|
inOff, // in_off |
|
availInBefore, // in_len |
|
this._buffer, // out |
|
this._offset, //out_off |
|
availOutBefore); // out_len |
|
|
|
req.buffer = chunk; |
|
req.callback = callback; |
|
|
|
function callback(availInAfter, availOutAfter) { |
|
if (self._hadError) |
|
return; |
|
|
|
var have = availOutBefore - availOutAfter; |
|
assert(have >= 0, 'have should not go down'); |
|
|
|
if (have > 0) { |
|
var out = self._buffer.slice(self._offset, self._offset + have); |
|
self._offset += have; |
|
// serve some output to the consumer. |
|
if (async) { |
|
self.push(out); |
|
} else { |
|
buffers.push(out); |
|
nread += out.length; |
|
} |
|
} |
|
|
|
// exhausted the output buffer, or used all the input create a new one. |
|
if (availOutAfter === 0 || self._offset >= self._chunkSize) { |
|
availOutBefore = self._chunkSize; |
|
self._offset = 0; |
|
self._buffer = new Buffer(self._chunkSize); |
|
} |
|
|
|
if (availOutAfter === 0) { |
|
// Not actually done. Need to reprocess. |
|
// Also, update the availInBefore to the availInAfter value, |
|
// so that if we have to hit it a third (fourth, etc.) time, |
|
// it'll have the correct byte counts. |
|
inOff += (availInBefore - availInAfter); |
|
availInBefore = availInAfter; |
|
|
|
if (!async) |
|
return true; |
|
|
|
var newReq = self._binding.write(flushFlag, |
|
chunk, |
|
inOff, |
|
availInBefore, |
|
self._buffer, |
|
self._offset, |
|
self._chunkSize); |
|
newReq.callback = callback; // this same function |
|
newReq.buffer = chunk; |
|
return; |
|
} |
|
|
|
if (!async) |
|
return false; |
|
|
|
// finished with the chunk. |
|
cb(); |
|
} |
|
}; |
|
|
|
util.inherits(Deflate, Zlib); |
|
util.inherits(Inflate, Zlib); |
|
util.inherits(Gzip, Zlib); |
|
util.inherits(Gunzip, Zlib); |
|
util.inherits(DeflateRaw, Zlib); |
|
util.inherits(InflateRaw, Zlib); |
|
util.inherits(Unzip, Zlib); |
|
|
|
}).call(this,require('_process'),require("buffer").Buffer) |
|
},{"./binding":6,"_process":28,"_stream_transform":33,"assert":3,"buffer":8,"util":37}],8:[function(require,module,exports){ |
|
(function (global){ |
|
/*! |
|
* The buffer module from node.js, for the browser. |
|
* |
|
* @author Feross Aboukhadijeh <[email protected]> <http://feross.org> |
|
* @license MIT |
|
*/ |
|
/* eslint-disable no-proto */ |
|
|
|
'use strict' |
|
|
|
var base64 = require('base64-js') |
|
var ieee754 = require('ieee754') |
|
var isArray = require('isarray') |
|
|
|
exports.Buffer = Buffer |
|
exports.SlowBuffer = SlowBuffer |
|
exports.INSPECT_MAX_BYTES = 50 |
|
Buffer.poolSize = 8192 // not used by this implementation |
|
|
|
var rootParent = {} |
|
|
|
/** |
|
* If `Buffer.TYPED_ARRAY_SUPPORT`: |
|
* === true Use Uint8Array implementation (fastest) |
|
* === false Use Object implementation (most compatible, even IE6) |
|
* |
|
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, |
|
* Opera 11.6+, iOS 4.2+. |
|
* |
|
* Due to various browser bugs, sometimes the Object implementation will be used even |
|
* when the browser supports typed arrays. |
|
* |
|
* Note: |
|
* |
|
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, |
|
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. |
|
* |
|
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. |
|
* |
|
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of |
|
* incorrect length in some situations. |
|
|
|
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they |
|
* get the Object implementation, which is slower but behaves correctly. |
|
*/ |
|
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined |
|
? global.TYPED_ARRAY_SUPPORT |
|
: typedArraySupport() |
|
|
|
function typedArraySupport () { |
|
try { |
|
var arr = new Uint8Array(1) |
|
arr.foo = function () { return 42 } |
|
return arr.foo() === 42 && // typed array instances can be augmented |
|
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` |
|
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` |
|
} catch (e) { |
|
return false |
|
} |
|
} |
|
|
|
function kMaxLength () { |
|
return Buffer.TYPED_ARRAY_SUPPORT |
|
? 0x7fffffff |
|
: 0x3fffffff |
|
} |
|
|
|
/** |
|
* Class: Buffer |
|
* ============= |
|
* |
|
* The Buffer constructor returns instances of `Uint8Array` that are augmented |
|
* with function properties for all the node `Buffer` API functions. We use |
|
* `Uint8Array` so that square bracket notation works as expected -- it returns |
|
* a single octet. |
|
* |
|
* By augmenting the instances, we can avoid modifying the `Uint8Array` |
|
* prototype. |
|
*/ |
|
function Buffer (arg) { |
|
if (!(this instanceof Buffer)) { |
|
// Avoid going through an ArgumentsAdaptorTrampoline in the common case. |
|
if (arguments.length > 1) return new Buffer(arg, arguments[1]) |
|
return new Buffer(arg) |
|
} |
|
|
|
if (!Buffer.TYPED_ARRAY_SUPPORT) { |
|
this.length = 0 |
|
this.parent = undefined |
|
} |
|
|
|
// Common case. |
|
if (typeof arg === 'number') { |
|
return fromNumber(this, arg) |
|
} |
|
|
|
// Slightly less common case. |
|
if (typeof arg === 'string') { |
|
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') |
|
} |
|
|
|
// Unusual. |
|
return fromObject(this, arg) |
|
} |
|
|
|
function fromNumber (that, length) { |
|
that = allocate(that, length < 0 ? 0 : checked(length) | 0) |
|
if (!Buffer.TYPED_ARRAY_SUPPORT) { |
|
for (var i = 0; i < length; i++) { |
|
that[i] = 0 |
|
} |
|
} |
|
return that |
|
} |
|
|
|
function fromString (that, string, encoding) { |
|
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' |
|
|
|
// Assumption: byteLength() return value is always < kMaxLength. |
|
var length = byteLength(string, encoding) | 0 |
|
that = allocate(that, length) |
|
|
|
that.write(string, encoding) |
|
return that |
|
} |
|
|
|
function fromObject (that, object) { |
|
if (Buffer.isBuffer(object)) return fromBuffer(that, object) |
|
|
|
if (isArray(object)) return fromArray(that, object) |
|
|
|
if (object == null) { |
|
throw new TypeError('must start with number, buffer, array or string') |
|
} |
|
|
|
if (typeof ArrayBuffer !== 'undefined') { |
|
if (object.buffer instanceof ArrayBuffer) { |
|
return fromTypedArray(that, object) |
|
} |
|
if (object instanceof ArrayBuffer) { |
|
return fromArrayBuffer(that, object) |
|
} |
|
} |
|
|
|
if (object.length) return fromArrayLike(that, object) |
|
|
|
return fromJsonObject(that, object) |
|
} |
|
|
|
function fromBuffer (that, buffer) { |
|
var length = checked(buffer.length) | 0 |
|
that = allocate(that, length) |
|
buffer.copy(that, 0, 0, length) |
|
return that |
|
} |
|
|
|
function fromArray (that, array) { |
|
var length = checked(array.length) | 0 |
|
that = allocate(that, length) |
|
for (var i = 0; i < length; i += 1) { |
|
that[i] = array[i] & 255 |
|
} |
|
return that |
|
} |
|
|
|
// Duplicate of fromArray() to keep fromArray() monomorphic. |
|
function fromTypedArray (that, array) { |
|
var length = checked(array.length) | 0 |
|
that = allocate(that, length) |
|
// Truncating the elements is probably not what people expect from typed |
|
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior |
|
// of the old Buffer constructor. |
|
for (var i = 0; i < length; i += 1) { |
|
that[i] = array[i] & 255 |
|
} |
|
return that |
|
} |
|
|
|
function fromArrayBuffer (that, array) { |
|
array.byteLength // this throws if `array` is not a valid ArrayBuffer |
|
|
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
// Return an augmented `Uint8Array` instance, for best performance |
|
that = new Uint8Array(array) |
|
that.__proto__ = Buffer.prototype |
|
} else { |
|
// Fallback: Return an object instance of the Buffer class |
|
that = fromTypedArray(that, new Uint8Array(array)) |
|
} |
|
return that |
|
} |
|
|
|
function fromArrayLike (that, array) { |
|
var length = checked(array.length) | 0 |
|
that = allocate(that, length) |
|
for (var i = 0; i < length; i += 1) { |
|
that[i] = array[i] & 255 |
|
} |
|
return that |
|
} |
|
|
|
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. |
|
// Returns a zero-length buffer for inputs that don't conform to the spec. |
|
function fromJsonObject (that, object) { |
|
var array |
|
var length = 0 |
|
|
|
if (object.type === 'Buffer' && isArray(object.data)) { |
|
array = object.data |
|
length = checked(array.length) | 0 |
|
} |
|
that = allocate(that, length) |
|
|
|
for (var i = 0; i < length; i += 1) { |
|
that[i] = array[i] & 255 |
|
} |
|
return that |
|
} |
|
|
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
Buffer.prototype.__proto__ = Uint8Array.prototype |
|
Buffer.__proto__ = Uint8Array |
|
} else { |
|
// pre-set for values that may exist in the future |
|
Buffer.prototype.length = undefined |
|
Buffer.prototype.parent = undefined |
|
} |
|
|
|
function allocate (that, length) { |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
// Return an augmented `Uint8Array` instance, for best performance |
|
that = new Uint8Array(length) |
|
that.__proto__ = Buffer.prototype |
|
} else { |
|
// Fallback: Return an object instance of the Buffer class |
|
that.length = length |
|
} |
|
|
|
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 |
|
if (fromPool) that.parent = rootParent |
|
|
|
return that |
|
} |
|
|
|
function checked (length) { |
|
// Note: cannot use `length < kMaxLength` here because that fails when |
|
// length is NaN (which is otherwise coerced to zero.) |
|
if (length >= kMaxLength()) { |
|
throw new RangeError('Attempt to allocate Buffer larger than maximum ' + |
|
'size: 0x' + kMaxLength().toString(16) + ' bytes') |
|
} |
|
return length | 0 |
|
} |
|
|
|
function SlowBuffer (subject, encoding) { |
|
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) |
|
|
|
var buf = new Buffer(subject, encoding) |
|
delete buf.parent |
|
return buf |
|
} |
|
|
|
Buffer.isBuffer = function isBuffer (b) { |
|
return !!(b != null && b._isBuffer) |
|
} |
|
|
|
Buffer.compare = function compare (a, b) { |
|
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { |
|
throw new TypeError('Arguments must be Buffers') |
|
} |
|
|
|
if (a === b) return 0 |
|
|
|
var x = a.length |
|
var y = b.length |
|
|
|
var i = 0 |
|
var len = Math.min(x, y) |
|
while (i < len) { |
|
if (a[i] !== b[i]) break |
|
|
|
++i |
|
} |
|
|
|
if (i !== len) { |
|
x = a[i] |
|
y = b[i] |
|
} |
|
|
|
if (x < y) return -1 |
|
if (y < x) return 1 |
|
return 0 |
|
} |
|
|
|
Buffer.isEncoding = function isEncoding (encoding) { |
|
switch (String(encoding).toLowerCase()) { |
|
case 'hex': |
|
case 'utf8': |
|
case 'utf-8': |
|
case 'ascii': |
|
case 'binary': |
|
case 'base64': |
|
case 'raw': |
|
case 'ucs2': |
|
case 'ucs-2': |
|
case 'utf16le': |
|
case 'utf-16le': |
|
return true |
|
default: |
|
return false |
|
} |
|
} |
|
|
|
Buffer.concat = function concat (list, length) { |
|
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') |
|
|
|
if (list.length === 0) { |
|
return new Buffer(0) |
|
} |
|
|
|
var i |
|
if (length === undefined) { |
|
length = 0 |
|
for (i = 0; i < list.length; i++) { |
|
length += list[i].length |
|
} |
|
} |
|
|
|
var buf = new Buffer(length) |
|
var pos = 0 |
|
for (i = 0; i < list.length; i++) { |
|
var item = list[i] |
|
item.copy(buf, pos) |
|
pos += item.length |
|
} |
|
return buf |
|
} |
|
|
|
function byteLength (string, encoding) { |
|
if (typeof string !== 'string') string = '' + string |
|
|
|
var len = string.length |
|
if (len === 0) return 0 |
|
|
|
// Use a for loop to avoid recursion |
|
var loweredCase = false |
|
for (;;) { |
|
switch (encoding) { |
|
case 'ascii': |
|
case 'binary': |
|
// Deprecated |
|
case 'raw': |
|
case 'raws': |
|
return len |
|
case 'utf8': |
|
case 'utf-8': |
|
return utf8ToBytes(string).length |
|
case 'ucs2': |
|
case 'ucs-2': |
|
case 'utf16le': |
|
case 'utf-16le': |
|
return len * 2 |
|
case 'hex': |
|
return len >>> 1 |
|
case 'base64': |
|
return base64ToBytes(string).length |
|
default: |
|
if (loweredCase) return utf8ToBytes(string).length // assume utf8 |
|
encoding = ('' + encoding).toLowerCase() |
|
loweredCase = true |
|
} |
|
} |
|
} |
|
Buffer.byteLength = byteLength |
|
|
|
function slowToString (encoding, start, end) { |
|
var loweredCase = false |
|
|
|
start = start | 0 |
|
end = end === undefined || end === Infinity ? this.length : end | 0 |
|
|
|
if (!encoding) encoding = 'utf8' |
|
if (start < 0) start = 0 |
|
if (end > this.length) end = this.length |
|
if (end <= start) return '' |
|
|
|
while (true) { |
|
switch (encoding) { |
|
case 'hex': |
|
return hexSlice(this, start, end) |
|
|
|
case 'utf8': |
|
case 'utf-8': |
|
return utf8Slice(this, start, end) |
|
|
|
case 'ascii': |
|
return asciiSlice(this, start, end) |
|
|
|
case 'binary': |
|
return binarySlice(this, start, end) |
|
|
|
case 'base64': |
|
return base64Slice(this, start, end) |
|
|
|
case 'ucs2': |
|
case 'ucs-2': |
|
case 'utf16le': |
|
case 'utf-16le': |
|
return utf16leSlice(this, start, end) |
|
|
|
default: |
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
|
encoding = (encoding + '').toLowerCase() |
|
loweredCase = true |
|
} |
|
} |
|
} |
|
|
|
// Even though this property is private, it shouldn't be removed because it is |
|
// used by `is-buffer` to detect buffer instances in Safari 5-7. |
|
Buffer.prototype._isBuffer = true |
|
|
|
Buffer.prototype.toString = function toString () { |
|
var length = this.length | 0 |
|
if (length === 0) return '' |
|
if (arguments.length === 0) return utf8Slice(this, 0, length) |
|
return slowToString.apply(this, arguments) |
|
} |
|
|
|
Buffer.prototype.equals = function equals (b) { |
|
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
|
if (this === b) return true |
|
return Buffer.compare(this, b) === 0 |
|
} |
|
|
|
Buffer.prototype.inspect = function inspect () { |
|
var str = '' |
|
var max = exports.INSPECT_MAX_BYTES |
|
if (this.length > 0) { |
|
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') |
|
if (this.length > max) str += ' ... ' |
|
} |
|
return '<Buffer ' + str + '>' |
|
} |
|
|
|
Buffer.prototype.compare = function compare (b) { |
|
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') |
|
if (this === b) return 0 |
|
return Buffer.compare(this, b) |
|
} |
|
|
|
Buffer.prototype.indexOf = function indexOf (val, byteOffset) { |
|
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff |
|
else if (byteOffset < -0x80000000) byteOffset = -0x80000000 |
|
byteOffset >>= 0 |
|
|
|
if (this.length === 0) return -1 |
|
if (byteOffset >= this.length) return -1 |
|
|
|
// Negative offsets start from the end of the buffer |
|
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) |
|
|
|
if (typeof val === 'string') { |
|
if (val.length === 0) return -1 // special case: looking for empty string always fails |
|
return String.prototype.indexOf.call(this, val, byteOffset) |
|
} |
|
if (Buffer.isBuffer(val)) { |
|
return arrayIndexOf(this, val, byteOffset) |
|
} |
|
if (typeof val === 'number') { |
|
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { |
|
return Uint8Array.prototype.indexOf.call(this, val, byteOffset) |
|
} |
|
return arrayIndexOf(this, [ val ], byteOffset) |
|
} |
|
|
|
function arrayIndexOf (arr, val, byteOffset) { |
|
var foundIndex = -1 |
|
for (var i = 0; byteOffset + i < arr.length; i++) { |
|
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { |
|
if (foundIndex === -1) foundIndex = i |
|
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex |
|
} else { |
|
foundIndex = -1 |
|
} |
|
} |
|
return -1 |
|
} |
|
|
|
throw new TypeError('val must be string, number or Buffer') |
|
} |
|
|
|
function hexWrite (buf, string, offset, length) { |
|
offset = Number(offset) || 0 |
|
var remaining = buf.length - offset |
|
if (!length) { |
|
length = remaining |
|
} else { |
|
length = Number(length) |
|
if (length > remaining) { |
|
length = remaining |
|
} |
|
} |
|
|
|
// must be an even number of digits |
|
var strLen = string.length |
|
if (strLen % 2 !== 0) throw new Error('Invalid hex string') |
|
|
|
if (length > strLen / 2) { |
|
length = strLen / 2 |
|
} |
|
for (var i = 0; i < length; i++) { |
|
var parsed = parseInt(string.substr(i * 2, 2), 16) |
|
if (isNaN(parsed)) throw new Error('Invalid hex string') |
|
buf[offset + i] = parsed |
|
} |
|
return i |
|
} |
|
|
|
function utf8Write (buf, string, offset, length) { |
|
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) |
|
} |
|
|
|
function asciiWrite (buf, string, offset, length) { |
|
return blitBuffer(asciiToBytes(string), buf, offset, length) |
|
} |
|
|
|
function binaryWrite (buf, string, offset, length) { |
|
return asciiWrite(buf, string, offset, length) |
|
} |
|
|
|
function base64Write (buf, string, offset, length) { |
|
return blitBuffer(base64ToBytes(string), buf, offset, length) |
|
} |
|
|
|
function ucs2Write (buf, string, offset, length) { |
|
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) |
|
} |
|
|
|
Buffer.prototype.write = function write (string, offset, length, encoding) { |
|
// Buffer#write(string) |
|
if (offset === undefined) { |
|
encoding = 'utf8' |
|
length = this.length |
|
offset = 0 |
|
// Buffer#write(string, encoding) |
|
} else if (length === undefined && typeof offset === 'string') { |
|
encoding = offset |
|
length = this.length |
|
offset = 0 |
|
// Buffer#write(string, offset[, length][, encoding]) |
|
} else if (isFinite(offset)) { |
|
offset = offset | 0 |
|
if (isFinite(length)) { |
|
length = length | 0 |
|
if (encoding === undefined) encoding = 'utf8' |
|
} else { |
|
encoding = length |
|
length = undefined |
|
} |
|
// legacy write(string, encoding, offset, length) - remove in v0.13 |
|
} else { |
|
var swap = encoding |
|
encoding = offset |
|
offset = length | 0 |
|
length = swap |
|
} |
|
|
|
var remaining = this.length - offset |
|
if (length === undefined || length > remaining) length = remaining |
|
|
|
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { |
|
throw new RangeError('attempt to write outside buffer bounds') |
|
} |
|
|
|
if (!encoding) encoding = 'utf8' |
|
|
|
var loweredCase = false |
|
for (;;) { |
|
switch (encoding) { |
|
case 'hex': |
|
return hexWrite(this, string, offset, length) |
|
|
|
case 'utf8': |
|
case 'utf-8': |
|
return utf8Write(this, string, offset, length) |
|
|
|
case 'ascii': |
|
return asciiWrite(this, string, offset, length) |
|
|
|
case 'binary': |
|
return binaryWrite(this, string, offset, length) |
|
|
|
case 'base64': |
|
// Warning: maxLength not taken into account in base64Write |
|
return base64Write(this, string, offset, length) |
|
|
|
case 'ucs2': |
|
case 'ucs-2': |
|
case 'utf16le': |
|
case 'utf-16le': |
|
return ucs2Write(this, string, offset, length) |
|
|
|
default: |
|
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) |
|
encoding = ('' + encoding).toLowerCase() |
|
loweredCase = true |
|
} |
|
} |
|
} |
|
|
|
Buffer.prototype.toJSON = function toJSON () { |
|
return { |
|
type: 'Buffer', |
|
data: Array.prototype.slice.call(this._arr || this, 0) |
|
} |
|
} |
|
|
|
function base64Slice (buf, start, end) { |
|
if (start === 0 && end === buf.length) { |
|
return base64.fromByteArray(buf) |
|
} else { |
|
return base64.fromByteArray(buf.slice(start, end)) |
|
} |
|
} |
|
|
|
function utf8Slice (buf, start, end) { |
|
end = Math.min(buf.length, end) |
|
var res = [] |
|
|
|
var i = start |
|
while (i < end) { |
|
var firstByte = buf[i] |
|
var codePoint = null |
|
var bytesPerSequence = (firstByte > 0xEF) ? 4 |
|
: (firstByte > 0xDF) ? 3 |
|
: (firstByte > 0xBF) ? 2 |
|
: 1 |
|
|
|
if (i + bytesPerSequence <= end) { |
|
var secondByte, thirdByte, fourthByte, tempCodePoint |
|
|
|
switch (bytesPerSequence) { |
|
case 1: |
|
if (firstByte < 0x80) { |
|
codePoint = firstByte |
|
} |
|
break |
|
case 2: |
|
secondByte = buf[i + 1] |
|
if ((secondByte & 0xC0) === 0x80) { |
|
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) |
|
if (tempCodePoint > 0x7F) { |
|
codePoint = tempCodePoint |
|
} |
|
} |
|
break |
|
case 3: |
|
secondByte = buf[i + 1] |
|
thirdByte = buf[i + 2] |
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { |
|
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) |
|
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { |
|
codePoint = tempCodePoint |
|
} |
|
} |
|
break |
|
case 4: |
|
secondByte = buf[i + 1] |
|
thirdByte = buf[i + 2] |
|
fourthByte = buf[i + 3] |
|
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { |
|
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) |
|
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { |
|
codePoint = tempCodePoint |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (codePoint === null) { |
|
// we did not generate a valid codePoint so insert a |
|
// replacement char (U+FFFD) and advance only 1 byte |
|
codePoint = 0xFFFD |
|
bytesPerSequence = 1 |
|
} else if (codePoint > 0xFFFF) { |
|
// encode to utf16 (surrogate pair dance) |
|
codePoint -= 0x10000 |
|
res.push(codePoint >>> 10 & 0x3FF | 0xD800) |
|
codePoint = 0xDC00 | codePoint & 0x3FF |
|
} |
|
|
|
res.push(codePoint) |
|
i += bytesPerSequence |
|
} |
|
|
|
return decodeCodePointsArray(res) |
|
} |
|
|
|
// Based on http://stackoverflow.com/a/22747272/680742, the browser with |
|
// the lowest limit is Chrome, with 0x10000 args. |
|
// We go 1 magnitude less, for safety |
|
var MAX_ARGUMENTS_LENGTH = 0x1000 |
|
|
|
function decodeCodePointsArray (codePoints) { |
|
var len = codePoints.length |
|
if (len <= MAX_ARGUMENTS_LENGTH) { |
|
return String.fromCharCode.apply(String, codePoints) // avoid extra slice() |
|
} |
|
|
|
// Decode in chunks to avoid "call stack size exceeded". |
|
var res = '' |
|
var i = 0 |
|
while (i < len) { |
|
res += String.fromCharCode.apply( |
|
String, |
|
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) |
|
) |
|
} |
|
return res |
|
} |
|
|
|
function asciiSlice (buf, start, end) { |
|
var ret = '' |
|
end = Math.min(buf.length, end) |
|
|
|
for (var i = start; i < end; i++) { |
|
ret += String.fromCharCode(buf[i] & 0x7F) |
|
} |
|
return ret |
|
} |
|
|
|
function binarySlice (buf, start, end) { |
|
var ret = '' |
|
end = Math.min(buf.length, end) |
|
|
|
for (var i = start; i < end; i++) { |
|
ret += String.fromCharCode(buf[i]) |
|
} |
|
return ret |
|
} |
|
|
|
function hexSlice (buf, start, end) { |
|
var len = buf.length |
|
|
|
if (!start || start < 0) start = 0 |
|
if (!end || end < 0 || end > len) end = len |
|
|
|
var out = '' |
|
for (var i = start; i < end; i++) { |
|
out += toHex(buf[i]) |
|
} |
|
return out |
|
} |
|
|
|
function utf16leSlice (buf, start, end) { |
|
var bytes = buf.slice(start, end) |
|
var res = '' |
|
for (var i = 0; i < bytes.length; i += 2) { |
|
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) |
|
} |
|
return res |
|
} |
|
|
|
Buffer.prototype.slice = function slice (start, end) { |
|
var len = this.length |
|
start = ~~start |
|
end = end === undefined ? len : ~~end |
|
|
|
if (start < 0) { |
|
start += len |
|
if (start < 0) start = 0 |
|
} else if (start > len) { |
|
start = len |
|
} |
|
|
|
if (end < 0) { |
|
end += len |
|
if (end < 0) end = 0 |
|
} else if (end > len) { |
|
end = len |
|
} |
|
|
|
if (end < start) end = start |
|
|
|
var newBuf |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
newBuf = this.subarray(start, end) |
|
newBuf.__proto__ = Buffer.prototype |
|
} else { |
|
var sliceLen = end - start |
|
newBuf = new Buffer(sliceLen, undefined) |
|
for (var i = 0; i < sliceLen; i++) { |
|
newBuf[i] = this[i + start] |
|
} |
|
} |
|
|
|
if (newBuf.length) newBuf.parent = this.parent || this |
|
|
|
return newBuf |
|
} |
|
|
|
/* |
|
* Need to make sure that buffer isn't trying to write out of bounds. |
|
*/ |
|
function checkOffset (offset, ext, length) { |
|
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') |
|
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') |
|
} |
|
|
|
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) checkOffset(offset, byteLength, this.length) |
|
|
|
var val = this[offset] |
|
var mul = 1 |
|
var i = 0 |
|
while (++i < byteLength && (mul *= 0x100)) { |
|
val += this[offset + i] * mul |
|
} |
|
|
|
return val |
|
} |
|
|
|
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) { |
|
checkOffset(offset, byteLength, this.length) |
|
} |
|
|
|
var val = this[offset + --byteLength] |
|
var mul = 1 |
|
while (byteLength > 0 && (mul *= 0x100)) { |
|
val += this[offset + --byteLength] * mul |
|
} |
|
|
|
return val |
|
} |
|
|
|
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 1, this.length) |
|
return this[offset] |
|
} |
|
|
|
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 2, this.length) |
|
return this[offset] | (this[offset + 1] << 8) |
|
} |
|
|
|
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 2, this.length) |
|
return (this[offset] << 8) | this[offset + 1] |
|
} |
|
|
|
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
|
|
return ((this[offset]) | |
|
(this[offset + 1] << 8) | |
|
(this[offset + 2] << 16)) + |
|
(this[offset + 3] * 0x1000000) |
|
} |
|
|
|
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
|
|
return (this[offset] * 0x1000000) + |
|
((this[offset + 1] << 16) | |
|
(this[offset + 2] << 8) | |
|
this[offset + 3]) |
|
} |
|
|
|
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) checkOffset(offset, byteLength, this.length) |
|
|
|
var val = this[offset] |
|
var mul = 1 |
|
var i = 0 |
|
while (++i < byteLength && (mul *= 0x100)) { |
|
val += this[offset + i] * mul |
|
} |
|
mul *= 0x80 |
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
|
|
|
return val |
|
} |
|
|
|
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) checkOffset(offset, byteLength, this.length) |
|
|
|
var i = byteLength |
|
var mul = 1 |
|
var val = this[offset + --i] |
|
while (i > 0 && (mul *= 0x100)) { |
|
val += this[offset + --i] * mul |
|
} |
|
mul *= 0x80 |
|
|
|
if (val >= mul) val -= Math.pow(2, 8 * byteLength) |
|
|
|
return val |
|
} |
|
|
|
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 1, this.length) |
|
if (!(this[offset] & 0x80)) return (this[offset]) |
|
return ((0xff - this[offset] + 1) * -1) |
|
} |
|
|
|
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 2, this.length) |
|
var val = this[offset] | (this[offset + 1] << 8) |
|
return (val & 0x8000) ? val | 0xFFFF0000 : val |
|
} |
|
|
|
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 2, this.length) |
|
var val = this[offset + 1] | (this[offset] << 8) |
|
return (val & 0x8000) ? val | 0xFFFF0000 : val |
|
} |
|
|
|
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
|
|
return (this[offset]) | |
|
(this[offset + 1] << 8) | |
|
(this[offset + 2] << 16) | |
|
(this[offset + 3] << 24) |
|
} |
|
|
|
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
|
|
return (this[offset] << 24) | |
|
(this[offset + 1] << 16) | |
|
(this[offset + 2] << 8) | |
|
(this[offset + 3]) |
|
} |
|
|
|
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
return ieee754.read(this, offset, true, 23, 4) |
|
} |
|
|
|
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 4, this.length) |
|
return ieee754.read(this, offset, false, 23, 4) |
|
} |
|
|
|
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 8, this.length) |
|
return ieee754.read(this, offset, true, 52, 8) |
|
} |
|
|
|
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { |
|
if (!noAssert) checkOffset(offset, 8, this.length) |
|
return ieee754.read(this, offset, false, 52, 8) |
|
} |
|
|
|
function checkInt (buf, value, offset, ext, max, min) { |
|
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') |
|
if (value > max || value < min) throw new RangeError('value is out of bounds') |
|
if (offset + ext > buf.length) throw new RangeError('index out of range') |
|
} |
|
|
|
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
|
|
|
var mul = 1 |
|
var i = 0 |
|
this[offset] = value & 0xFF |
|
while (++i < byteLength && (mul *= 0x100)) { |
|
this[offset + i] = (value / mul) & 0xFF |
|
} |
|
|
|
return offset + byteLength |
|
} |
|
|
|
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
byteLength = byteLength | 0 |
|
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) |
|
|
|
var i = byteLength - 1 |
|
var mul = 1 |
|
this[offset + i] = value & 0xFF |
|
while (--i >= 0 && (mul *= 0x100)) { |
|
this[offset + i] = (value / mul) & 0xFF |
|
} |
|
|
|
return offset + byteLength |
|
} |
|
|
|
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) |
|
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
|
this[offset] = (value & 0xff) |
|
return offset + 1 |
|
} |
|
|
|
function objectWriteUInt16 (buf, value, offset, littleEndian) { |
|
if (value < 0) value = 0xffff + value + 1 |
|
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { |
|
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> |
|
(littleEndian ? i : 1 - i) * 8 |
|
} |
|
} |
|
|
|
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value & 0xff) |
|
this[offset + 1] = (value >>> 8) |
|
} else { |
|
objectWriteUInt16(this, value, offset, true) |
|
} |
|
return offset + 2 |
|
} |
|
|
|
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value >>> 8) |
|
this[offset + 1] = (value & 0xff) |
|
} else { |
|
objectWriteUInt16(this, value, offset, false) |
|
} |
|
return offset + 2 |
|
} |
|
|
|
function objectWriteUInt32 (buf, value, offset, littleEndian) { |
|
if (value < 0) value = 0xffffffff + value + 1 |
|
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { |
|
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff |
|
} |
|
} |
|
|
|
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset + 3] = (value >>> 24) |
|
this[offset + 2] = (value >>> 16) |
|
this[offset + 1] = (value >>> 8) |
|
this[offset] = (value & 0xff) |
|
} else { |
|
objectWriteUInt32(this, value, offset, true) |
|
} |
|
return offset + 4 |
|
} |
|
|
|
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value >>> 24) |
|
this[offset + 1] = (value >>> 16) |
|
this[offset + 2] = (value >>> 8) |
|
this[offset + 3] = (value & 0xff) |
|
} else { |
|
objectWriteUInt32(this, value, offset, false) |
|
} |
|
return offset + 4 |
|
} |
|
|
|
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) { |
|
var limit = Math.pow(2, 8 * byteLength - 1) |
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit) |
|
} |
|
|
|
var i = 0 |
|
var mul = 1 |
|
var sub = value < 0 ? 1 : 0 |
|
this[offset] = value & 0xFF |
|
while (++i < byteLength && (mul *= 0x100)) { |
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
|
} |
|
|
|
return offset + byteLength |
|
} |
|
|
|
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) { |
|
var limit = Math.pow(2, 8 * byteLength - 1) |
|
|
|
checkInt(this, value, offset, byteLength, limit - 1, -limit) |
|
} |
|
|
|
var i = byteLength - 1 |
|
var mul = 1 |
|
var sub = value < 0 ? 1 : 0 |
|
this[offset + i] = value & 0xFF |
|
while (--i >= 0 && (mul *= 0x100)) { |
|
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF |
|
} |
|
|
|
return offset + byteLength |
|
} |
|
|
|
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) |
|
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) |
|
if (value < 0) value = 0xff + value + 1 |
|
this[offset] = (value & 0xff) |
|
return offset + 1 |
|
} |
|
|
|
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value & 0xff) |
|
this[offset + 1] = (value >>> 8) |
|
} else { |
|
objectWriteUInt16(this, value, offset, true) |
|
} |
|
return offset + 2 |
|
} |
|
|
|
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value >>> 8) |
|
this[offset + 1] = (value & 0xff) |
|
} else { |
|
objectWriteUInt16(this, value, offset, false) |
|
} |
|
return offset + 2 |
|
} |
|
|
|
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value & 0xff) |
|
this[offset + 1] = (value >>> 8) |
|
this[offset + 2] = (value >>> 16) |
|
this[offset + 3] = (value >>> 24) |
|
} else { |
|
objectWriteUInt32(this, value, offset, true) |
|
} |
|
return offset + 4 |
|
} |
|
|
|
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { |
|
value = +value |
|
offset = offset | 0 |
|
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) |
|
if (value < 0) value = 0xffffffff + value + 1 |
|
if (Buffer.TYPED_ARRAY_SUPPORT) { |
|
this[offset] = (value >>> 24) |
|
this[offset + 1] = (value >>> 16) |
|
this[offset + 2] = (value >>> 8) |
|
this[offset + 3] = (value & 0xff) |
|
} else { |
|
objectWriteUInt32(this, value, offset, false) |
|
} |
|
return offset + 4 |
|
} |
|
|
|
function checkIEEE754 (buf, value, offset, ext, max, min) { |
|
if (value > max || value < min) throw new RangeError('value is out of bounds') |
|
if (offset + ext > buf.length) throw new RangeError('index out of range') |
|
if (offset < 0) throw new RangeError('index out of range') |
|
} |
|
|
|
function writeFloat (buf, value, offset, littleEndian, noAssert) { |
|
if (!noAssert) { |
|
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) |
|
} |
|
ieee754.write(buf, value, offset, littleEndian, 23, 4) |
|
return offset + 4 |
|
} |
|
|
|
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { |
|
return writeFloat(this, value, offset, true, noAssert) |
|
} |
|
|
|
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { |
|
return writeFloat(this, value, offset, false, noAssert) |
|
} |
|
|
|
function writeDouble (buf, value, offset, littleEndian, noAssert) { |
|
if (!noAssert) { |
|
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) |
|
} |
|
ieee754.write(buf, value, offset, littleEndian, 52, 8) |
|
return offset + 8 |
|
} |
|
|
|
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { |
|
return writeDouble(this, value, offset, true, noAssert) |
|
} |
|
|
|
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { |
|
return writeDouble(this, value, offset, false, noAssert) |
|
} |
|
|
|
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) |
|
Buffer.prototype.copy = function copy (target, targetStart, start, end) { |
|
if (!start) start = 0 |
|
if (!end && end !== 0) end = this.length |
|
if (targetStart >= target.length) targetStart = target.length |
|
if (!targetStart) targetStart = 0 |
|
if (end > 0 && end < start) end = start |
|
|
|
// Copy 0 bytes; we're done |
|
if (end === start) return 0 |
|
if (target.length === 0 || this.length === 0) return 0 |
|
|
|
// Fatal error conditions |
|
if (targetStart < 0) { |
|
throw new RangeError('targetStart out of bounds') |
|
} |
|
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') |
|
if (end < 0) throw new RangeError('sourceEnd out of bounds') |
|
|
|
// Are we oob? |
|
if (end > this.length) end = this.length |
|
if (target.length - targetStart < end - start) { |
|
end = target.length - targetStart + start |
|
} |
|
|
|
var len = end - start |
|
var i |
|
|
|
if (this === target && start < targetStart && targetStart < end) { |
|
// descending copy from end |
|
for (i = len - 1; i >= 0; i--) { |
|
target[i + targetStart] = this[i + start] |
|
} |
|
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { |
|
// ascending copy from start |
|
for (i = 0; i < len; i++) { |
|
target[i + targetStart] = this[i + start] |
|
} |
|
} else { |
|
Uint8Array.prototype.set.call( |
|
target, |
|
this.subarray(start, start + len), |
|
targetStart |
|
) |
|
} |
|
|
|
return len |
|
} |
|
|
|
// fill(value, start=0, end=buffer.length) |
|
Buffer.prototype.fill = function fill (value, start, end) { |
|
if (!value) value = 0 |
|
if (!start) start = 0 |
|
if (!end) end = this.length |
|
|
|
if (end < start) throw new RangeError('end < start') |
|
|
|
// Fill 0 bytes; we're done |
|
if (end === start) return |
|
if (this.length === 0) return |
|
|
|
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') |
|
if (end < 0 || end > this.length) throw new RangeError('end out of bounds') |
|
|
|
var i |
|
if (typeof value === 'number') { |
|
for (i = start; i < end; i++) { |
|
this[i] = value |
|
} |
|
} else { |
|
var bytes = utf8ToBytes(value.toString()) |
|
var len = bytes.length |
|
for (i = start; i < end; i++) { |
|
this[i] = bytes[i % len] |
|
} |
|
} |
|
|
|
return this |
|
} |
|
|
|
// HELPER FUNCTIONS |
|
// ================ |
|
|
|
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g |
|
|
|
function base64clean (str) { |
|
// Node strips out invalid characters like \n and \t from the string, base64-js does not |
|
str = stringtrim(str).replace(INVALID_BASE64_RE, '') |
|
// Node converts strings with length < 2 to '' |
|
if (str.length < 2) return '' |
|
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not |
|
while (str.length % 4 !== 0) { |
|
str = str + '=' |
|
} |
|
return str |
|
} |
|
|
|
function stringtrim (str) { |
|
if (str.trim) return str.trim() |
|
return str.replace(/^\s+|\s+$/g, '') |
|
} |
|
|
|
function toHex (n) { |
|
if (n < 16) return '0' + n.toString(16) |
|
return n.toString(16) |
|
} |
|
|
|
function utf8ToBytes (string, units) { |
|
units = units || Infinity |
|
var codePoint |
|
var length = string.length |
|
var leadSurrogate = null |
|
var bytes = [] |
|
|
|
for (var i = 0; i < length; i++) { |
|
codePoint = string.charCodeAt(i) |
|
|
|
// is surrogate component |
|
if (codePoint > 0xD7FF && codePoint < 0xE000) { |
|
// last char was a lead |
|
if (!leadSurrogate) { |
|
// no lead yet |
|
if (codePoint > 0xDBFF) { |
|
// unexpected trail |
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
|
continue |
|
} else if (i + 1 === length) { |
|
// unpaired lead |
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
|
continue |
|
} |
|
|
|
// valid lead |
|
leadSurrogate = codePoint |
|
|
|
continue |
|
} |
|
|
|
// 2 leads in a row |
|
if (codePoint < 0xDC00) { |
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
|
leadSurrogate = codePoint |
|
continue |
|
} |
|
|
|
// valid surrogate pair |
|
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 |
|
} else if (leadSurrogate) { |
|
// valid bmp char, but last char was a lead |
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
|
} |
|
|
|
leadSurrogate = null |
|
|
|
// encode utf8 |
|
if (codePoint < 0x80) { |
|
if ((units -= 1) < 0) break |
|
bytes.push(codePoint) |
|
} else if (codePoint < 0x800) { |
|
if ((units -= 2) < 0) break |
|
bytes.push( |
|
codePoint >> 0x6 | 0xC0, |
|
codePoint & 0x3F | 0x80 |
|
) |
|
} else if (codePoint < 0x10000) { |
|
if ((units -= 3) < 0) break |
|
bytes.push( |
|
codePoint >> 0xC | 0xE0, |
|
codePoint >> 0x6 & 0x3F | 0x80, |
|
codePoint & 0x3F | 0x80 |
|
) |
|
} else if (codePoint < 0x110000) { |
|
if ((units -= 4) < 0) break |
|
bytes.push( |
|
codePoint >> 0x12 | 0xF0, |
|
codePoint >> 0xC & 0x3F | 0x80, |
|
codePoint >> 0x6 & 0x3F | 0x80, |
|
codePoint & 0x3F | 0x80 |
|
) |
|
} else { |
|
throw new Error('Invalid code point') |
|
} |
|
} |
|
|
|
return bytes |
|
} |
|
|
|
function asciiToBytes (str) { |
|
var byteArray = [] |
|
for (var i = 0; i < str.length; i++) { |
|
// Node's code seems to be doing this and not & 0x7F.. |
|
byteArray.push(str.charCodeAt(i) & 0xFF) |
|
} |
|
return byteArray |
|
} |
|
|
|
function utf16leToBytes (str, units) { |
|
var c, hi, lo |
|
var byteArray = [] |
|
for (var i = 0; i < str.length; i++) { |
|
if ((units -= 2) < 0) break |
|
|
|
c = str.charCodeAt(i) |
|
hi = c >> 8 |
|
lo = c % 256 |
|
byteArray.push(lo) |
|
byteArray.push(hi) |
|
} |
|
|
|
return byteArray |
|
} |
|
|
|
function base64ToBytes (str) { |
|
return base64.toByteArray(base64clean(str)) |
|
} |
|
|
|
function blitBuffer (src, dst, offset, length) { |
|
for (var i = 0; i < length; i++) { |
|
if ((i + offset >= dst.length) || (i >= src.length)) break |
|
dst[i + offset] = src[i] |
|
} |
|
return i |
|
} |
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
|
},{"base64-js":4,"ieee754":12,"isarray":9}],9:[function(require,module,exports){ |
|
var toString = {}.toString; |
|
|
|
module.exports = Array.isArray || function (arr) { |
|
return toString.call(arr) == '[object Array]'; |
|
}; |
|
|
|
},{}],10:[function(require,module,exports){ |
|
(function (Buffer){ |
|
// Copyright Joyent, Inc. and other Node contributors. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the |
|
// "Software"), to deal in the Software without restriction, including |
|
// without limitation the rights to use, copy, modify, merge, publish, |
|
// distribute, sublicense, and/or sell copies of the Software, and to permit |
|
// persons to whom the Software is furnished to do so, subject to the |
|
// following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
// NOTE: These type checking functions intentionally don't use `instanceof` |
|
// because it is fragile and can be easily faked with `Object.create()`. |
|
|
|
function isArray(arg) { |
|
if (Array.isArray) { |
|
return Array.isArray(arg); |
|
} |
|
return objectToString(arg) === '[object Array]'; |
|
} |
|
exports.isArray = isArray; |
|
|
|
function isBoolean(arg) { |
|
return typeof arg === 'boolean'; |
|
} |
|
exports.isBoolean = isBoolean; |
|
|
|
function isNull(arg) { |
|
return arg === null; |
|
} |
|
exports.isNull = isNull; |
|
|
|
function isNullOrUndefined(arg) { |
|
return arg == null; |
|
} |
|
exports.isNullOrUndefined = isNullOrUndefined; |
|
|
|
function isNumber(arg) { |
|
return typeof arg === 'number'; |
|
} |
|
exports.isNumber = isNumber; |
|
|
|
function isString(arg) { |
|
return typeof arg === 'string'; |
|
} |
|
exports.isString = isString; |
|
|
|
function isSymbol(arg) { |
|
return typeof arg === 'symbol'; |
|
} |
|
exports.isSymbol = isSymbol; |
|
|
|
function isUndefined(arg) { |
|
return arg === void 0; |
|
} |
|
exports.isUndefined = isUndefined; |
|
|
|
function isRegExp(re) { |
|
return objectToString(re) === '[object RegExp]'; |
|
} |
|
exports.isRegExp = isRegExp; |
|
|
|
function isObject(arg) { |
|
return typeof arg === 'object' && arg !== null; |
|
} |
|
exports.isObject = isObject; |
|
|
|
function isDate(d) { |
|
return objectToString(d) === '[object Date]'; |
|
} |
|
exports.isDate = isDate; |
|
|
|
function isError(e) { |
|
return (objectToString(e) === '[object Error]' || e instanceof Error); |
|
} |
|
exports.isError = isError; |
|
|
|
function isFunction(arg) { |
|
return typeof arg === 'function'; |
|
} |
|
exports.isFunction = isFunction; |
|
|
|
function isPrimitive(arg) { |
|
return arg === null || |
|
typeof arg === 'boolean' || |
|
typeof arg === 'number' || |
|
typeof arg === 'string' || |
|
typeof arg === 'symbol' || // ES6 symbol |
|
typeof arg === 'undefined'; |
|
} |
|
exports.isPrimitive = isPrimitive; |
|
|
|
exports.isBuffer = Buffer.isBuffer; |
|
|
|
function objectToString(o) { |
|
return Object.prototype.toString.call(o); |
|
} |
|
|
|
}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) |
|
},{"../../is-buffer/index.js":14}],11:[function(require,module,exports){ |
|
// Copyright Joyent, Inc. and other Node contributors. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the |
|
// "Software"), to deal in the Software without restriction, including |
|
// without limitation the rights to use, copy, modify, merge, publish, |
|
// distribute, sublicense, and/or sell copies of the Software, and to permit |
|
// persons to whom the Software is furnished to do so, subject to the |
|
// following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
function EventEmitter() { |
|
this._events = this._events || {}; |
|
this._maxListeners = this._maxListeners || undefined; |
|
} |
|
module.exports = EventEmitter; |
|
|
|
// Backwards-compat with node 0.10.x |
|
EventEmitter.EventEmitter = EventEmitter; |
|
|
|
EventEmitter.prototype._events = undefined; |
|
EventEmitter.prototype._maxListeners = undefined; |
|
|
|
// By default EventEmitters will print a warning if more than 10 listeners are |
|
// added to it. This is a useful default which helps finding memory leaks. |
|
EventEmitter.defaultMaxListeners = 10; |
|
|
|
// Obviously not all Emitters should be limited to 10. This function allows |
|
// that to be increased. Set to zero for unlimited. |
|
EventEmitter.prototype.setMaxListeners = function(n) { |
|
if (!isNumber(n) || n < 0 || isNaN(n)) |
|
throw TypeError('n must be a positive number'); |
|
this._maxListeners = n; |
|
return this; |
|
}; |
|
|
|
EventEmitter.prototype.emit = function(type) { |
|
var er, handler, len, args, i, listeners; |
|
|
|
if (!this._events) |
|
this._events = {}; |
|
|
|
// If there is no 'error' event listener then throw. |
|
if (type === 'error') { |
|
if (!this._events.error || |
|
(isObject(this._events.error) && !this._events.error.length)) { |
|
er = arguments[1]; |
|
if (er instanceof Error) { |
|
throw er; // Unhandled 'error' event |
|
} |
|
throw TypeError('Uncaught, unspecified "error" event.'); |
|
} |
|
} |
|
|
|
handler = this._events[type]; |
|
|
|
if (isUndefined(handler)) |
|
return false; |
|
|
|
if (isFunction(handler)) { |
|
switch (arguments.length) { |
|
// fast cases |
|
case 1: |
|
handler.call(this); |
|
break; |
|
case 2: |
|
handler.call(this, arguments[1]); |
|
break; |
|
case 3: |
|
handler.call(this, arguments[1], arguments[2]); |
|
break; |
|
// slower |
|
default: |
|
args = Array.prototype.slice.call(arguments, 1); |
|
handler.apply(this, args); |
|
} |
|
} else if (isObject(handler)) { |
|
args = Array.prototype.slice.call(arguments, 1); |
|
listeners = handler.slice(); |
|
len = listeners.length; |
|
for (i = 0; i < len; i++) |
|
listeners[i].apply(this, args); |
|
} |
|
|
|
return true; |
|
}; |
|
|
|
EventEmitter.prototype.addListener = function(type, listener) { |
|
var m; |
|
|
|
if (!isFunction(listener)) |
|
throw TypeError('listener must be a function'); |
|
|
|
if (!this._events) |
|
this._events = {}; |
|
|
|
// To avoid recursion in the case that type === "newListener"! Before |
|
// adding it to the listeners, first emit "newListener". |
|
if (this._events.newListener) |
|
this.emit('newListener', type, |
|
isFunction(listener.listener) ? |
|
listener.listener : listener); |
|
|
|
if (!this._events[type]) |
|
// Optimize the case of one listener. Don't need the extra array object. |
|
this._events[type] = listener; |
|
else if (isObject(this._events[type])) |
|
// If we've already got an array, just append. |
|
this._events[type].push(listener); |
|
else |
|
// Adding the second element, need to change to array. |
|
this._events[type] = [this._events[type], listener]; |
|
|
|
// Check for listener leak |
|
if (isObject(this._events[type]) && !this._events[type].warned) { |
|
if (!isUndefined(this._maxListeners)) { |
|
m = this._maxListeners; |
|
} else { |
|
m = EventEmitter.defaultMaxListeners; |
|
} |
|
|
|
if (m && m > 0 && this._events[type].length > m) { |
|
this._events[type].warned = true; |
|
console.error('(node) warning: possible EventEmitter memory ' + |
|
'leak detected. %d listeners added. ' + |
|
'Use emitter.setMaxListeners() to increase limit.', |
|
this._events[type].length); |
|
if (typeof console.trace === 'function') { |
|
// not supported in IE 10 |
|
console.trace(); |
|
} |
|
} |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener; |
|
|
|
EventEmitter.prototype.once = function(type, listener) { |
|
if (!isFunction(listener)) |
|
throw TypeError('listener must be a function'); |
|
|
|
var fired = false; |
|
|
|
function g() { |
|
this.removeListener(type, g); |
|
|
|
if (!fired) { |
|
fired = true; |
|
listener.apply(this, arguments); |
|
} |
|
} |
|
|
|
g.listener = listener; |
|
this.on(type, g); |
|
|
|
return this; |
|
}; |
|
|
|
// emits a 'removeListener' event iff the listener was removed |
|
EventEmitter.prototype.removeListener = function(type, listener) { |
|
var list, position, length, i; |
|
|
|
if (!isFunction(listener)) |
|
throw TypeError('listener must be a function'); |
|
|
|
if (!this._events || !this._events[type]) |
|
return this; |
|
|
|
list = this._events[type]; |
|
length = list.length; |
|
position = -1; |
|
|
|
if (list === listener || |
|
(isFunction(list.listener) && list.listener === listener)) { |
|
delete this._events[type]; |
|
if (this._events.removeListener) |
|
this.emit('removeListener', type, listener); |
|
|
|
} else if (isObject(list)) { |
|
for (i = length; i-- > 0;) { |
|
if (list[i] === listener || |
|
(list[i].listener && list[i].listener === listener)) { |
|
position = i; |
|
break; |
|
} |
|
} |
|
|
|
if (position < 0) |
|
return this; |
|
|
|
if (list.length === 1) { |
|
list.length = 0; |
|
delete this._events[type]; |
|
} else { |
|
list.splice(position, 1); |
|
} |
|
|
|
if (this._events.removeListener) |
|
this.emit('removeListener', type, listener); |
|
} |
|
|
|
return this; |
|
}; |
|
|
|
EventEmitter.prototype.removeAllListeners = function(type) { |
|
var key, listeners; |
|
|
|
if (!this._events) |
|
return this; |
|
|
|
// not listening for removeListener, no need to emit |
|
if (!this._events.removeListener) { |
|
if (arguments.length === 0) |
|
this._events = {}; |
|
else if (this._events[type]) |
|
delete this._events[type]; |
|
return this; |
|
} |
|
|
|
// emit removeListener for all listeners on all events |
|
if (arguments.length === 0) { |
|
for (key in this._events) { |
|
if (key === 'removeListener') continue; |
|
this.removeAllListeners(key); |
|
} |
|
this.removeAllListeners('removeListener'); |
|
this._events = {}; |
|
return this; |
|
} |
|
|
|
listeners = this._events[type]; |
|
|
|
if (isFunction(listeners)) { |
|
this.removeListener(type, listeners); |
|
} else if (listeners) { |
|
// LIFO order |
|
while (listeners.length) |
|
this.removeListener(type, listeners[listeners.length - 1]); |
|
} |
|
delete this._events[type]; |
|
|
|
return this; |
|
}; |
|
|
|
EventEmitter.prototype.listeners = function(type) { |
|
var ret; |
|
if (!this._events || !this._events[type]) |
|
ret = []; |
|
else if (isFunction(this._events[type])) |
|
ret = [this._events[type]]; |
|
else |
|
ret = this._events[type].slice(); |
|
return ret; |
|
}; |
|
|
|
EventEmitter.prototype.listenerCount = function(type) { |
|
if (this._events) { |
|
var evlistener = this._events[type]; |
|
|
|
if (isFunction(evlistener)) |
|
return 1; |
|
else if (evlistener) |
|
return evlistener.length; |
|
} |
|
return 0; |
|
}; |
|
|
|
EventEmitter.listenerCount = function(emitter, type) { |
|
return emitter.listenerCount(type); |
|
}; |
|
|
|
function isFunction(arg) { |
|
return typeof arg === 'function'; |
|
} |
|
|
|
function isNumber(arg) { |
|
return typeof arg === 'number'; |
|
} |
|
|
|
function isObject(arg) { |
|
return typeof arg === 'object' && arg !== null; |
|
} |
|
|
|
function isUndefined(arg) { |
|
return arg === void 0; |
|
} |
|
|
|
},{}],12:[function(require,module,exports){ |
|
exports.read = function (buffer, offset, isLE, mLen, nBytes) { |
|
var e, m |
|
var eLen = nBytes * 8 - mLen - 1 |
|
var eMax = (1 << eLen) - 1 |
|
var eBias = eMax >> 1 |
|
var nBits = -7 |
|
var i = isLE ? (nBytes - 1) : 0 |
|
var d = isLE ? -1 : 1 |
|
var s = buffer[offset + i] |
|
|
|
i += d |
|
|
|
e = s & ((1 << (-nBits)) - 1) |
|
s >>= (-nBits) |
|
nBits += eLen |
|
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
|
|
|
m = e & ((1 << (-nBits)) - 1) |
|
e >>= (-nBits) |
|
nBits += mLen |
|
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} |
|
|
|
if (e === 0) { |
|
e = 1 - eBias |
|
} else if (e === eMax) { |
|
return m ? NaN : ((s ? -1 : 1) * Infinity) |
|
} else { |
|
m = m + Math.pow(2, mLen) |
|
e = e - eBias |
|
} |
|
return (s ? -1 : 1) * m * Math.pow(2, e - mLen) |
|
} |
|
|
|
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { |
|
var e, m, c |
|
var eLen = nBytes * 8 - mLen - 1 |
|
var eMax = (1 << eLen) - 1 |
|
var eBias = eMax >> 1 |
|
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) |
|
var i = isLE ? 0 : (nBytes - 1) |
|
var d = isLE ? 1 : -1 |
|
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 |
|
|
|
value = Math.abs(value) |
|
|
|
if (isNaN(value) || value === Infinity) { |
|
m = isNaN(value) ? 1 : 0 |
|
e = eMax |
|
} else { |
|
e = Math.floor(Math.log(value) / Math.LN2) |
|
if (value * (c = Math.pow(2, -e)) < 1) { |
|
e-- |
|
c *= 2 |
|
} |
|
if (e + eBias >= 1) { |
|
value += rt / c |
|
} else { |
|
value += rt * Math.pow(2, 1 - eBias) |
|
} |
|
if (value * c >= 2) { |
|
e++ |
|
c /= 2 |
|
} |
|
|
|
if (e + eBias >= eMax) { |
|
m = 0 |
|
e = eMax |
|
} else if (e + eBias >= 1) { |
|
m = (value * c - 1) * Math.pow(2, mLen) |
|
e = e + eBias |
|
} else { |
|
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) |
|
e = 0 |
|
} |
|
} |
|
|
|
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} |
|
|
|
e = (e << mLen) | m |
|
eLen += mLen |
|
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} |
|
|
|
buffer[offset + i - d] |= s * 128 |
|
} |
|
|
|
},{}],13:[function(require,module,exports){ |
|
if (typeof Object.create === 'function') { |
|
// implementation from standard node.js 'util' module |
|
module.exports = function inherits(ctor, superCtor) { |
|
ctor.super_ = superCtor |
|
ctor.prototype = Object.create(superCtor.prototype, { |
|
constructor: { |
|
value: ctor, |
|
enumerable: false, |
|
writable: true, |
|
configurable: true |
|
} |
|
}); |
|
}; |
|
} else { |
|
// old school shim for old browsers |
|
module.exports = function inherits(ctor, superCtor) { |
|
ctor.super_ = superCtor |
|
var TempCtor = function () {} |
|
TempCtor.prototype = superCtor.prototype |
|
ctor.prototype = new TempCtor() |
|
ctor.prototype.constructor = ctor |
|
} |
|
} |
|
|
|
},{}],14:[function(require,module,exports){ |
|
/** |
|
* Determine if an object is Buffer |
|
* |
|
* Author: Feross Aboukhadijeh <[email protected]> <http://feross.org> |
|
* License: MIT |
|
* |
|
* `npm install is-buffer` |
|
*/ |
|
|
|
module.exports = function (obj) { |
|
return !!(obj != null && |
|
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) |
|
(obj.constructor && |
|
typeof obj.constructor.isBuffer === 'function' && |
|
obj.constructor.isBuffer(obj)) |
|
)) |
|
} |
|
|
|
},{}],15:[function(require,module,exports){ |
|
module.exports = Array.isArray || function (arr) { |
|
return Object.prototype.toString.call(arr) == '[object Array]'; |
|
}; |
|
|
|
},{}],16:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
|
|
var TYPED_OK = (typeof Uint8Array !== 'undefined') && |
|
(typeof Uint16Array !== 'undefined') && |
|
(typeof Int32Array !== 'undefined'); |
|
|
|
|
|
exports.assign = function (obj /*from1, from2, from3, ...*/) { |
|
var sources = Array.prototype.slice.call(arguments, 1); |
|
while (sources.length) { |
|
var source = sources.shift(); |
|
if (!source) { continue; } |
|
|
|
if (typeof source !== 'object') { |
|
throw new TypeError(source + 'must be non-object'); |
|
} |
|
|
|
for (var p in source) { |
|
if (source.hasOwnProperty(p)) { |
|
obj[p] = source[p]; |
|
} |
|
} |
|
} |
|
|
|
return obj; |
|
}; |
|
|
|
|
|
// reduce buffer size, avoiding mem copy |
|
exports.shrinkBuf = function (buf, size) { |
|
if (buf.length === size) { return buf; } |
|
if (buf.subarray) { return buf.subarray(0, size); } |
|
buf.length = size; |
|
return buf; |
|
}; |
|
|
|
|
|
var fnTyped = { |
|
arraySet: function (dest, src, src_offs, len, dest_offs) { |
|
if (src.subarray && dest.subarray) { |
|
dest.set(src.subarray(src_offs, src_offs+len), dest_offs); |
|
return; |
|
} |
|
// Fallback to ordinary array |
|
for (var i=0; i<len; i++) { |
|
dest[dest_offs + i] = src[src_offs + i]; |
|
} |
|
}, |
|
// Join array of chunks to single array. |
|
flattenChunks: function(chunks) { |
|
var i, l, len, pos, chunk, result; |
|
|
|
// calculate data length |
|
len = 0; |
|
for (i=0, l=chunks.length; i<l; i++) { |
|
len += chunks[i].length; |
|
} |
|
|
|
// join chunks |
|
result = new Uint8Array(len); |
|
pos = 0; |
|
for (i=0, l=chunks.length; i<l; i++) { |
|
chunk = chunks[i]; |
|
result.set(chunk, pos); |
|
pos += chunk.length; |
|
} |
|
|
|
return result; |
|
} |
|
}; |
|
|
|
var fnUntyped = { |
|
arraySet: function (dest, src, src_offs, len, dest_offs) { |
|
for (var i=0; i<len; i++) { |
|
dest[dest_offs + i] = src[src_offs + i]; |
|
} |
|
}, |
|
// Join array of chunks to single array. |
|
flattenChunks: function(chunks) { |
|
return [].concat.apply([], chunks); |
|
} |
|
}; |
|
|
|
|
|
// Enable/Disable typed arrays use, for testing |
|
// |
|
exports.setTyped = function (on) { |
|
if (on) { |
|
exports.Buf8 = Uint8Array; |
|
exports.Buf16 = Uint16Array; |
|
exports.Buf32 = Int32Array; |
|
exports.assign(exports, fnTyped); |
|
} else { |
|
exports.Buf8 = Array; |
|
exports.Buf16 = Array; |
|
exports.Buf32 = Array; |
|
exports.assign(exports, fnUntyped); |
|
} |
|
}; |
|
|
|
exports.setTyped(TYPED_OK); |
|
|
|
},{}],17:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
// Note: adler32 takes 12% for level 0 and 2% for level 6. |
|
// It doesn't worth to make additional optimizationa as in original. |
|
// Small size is preferable. |
|
|
|
function adler32(adler, buf, len, pos) { |
|
var s1 = (adler & 0xffff) |0, |
|
s2 = ((adler >>> 16) & 0xffff) |0, |
|
n = 0; |
|
|
|
while (len !== 0) { |
|
// Set limit ~ twice less than 5552, to keep |
|
// s2 in 31-bits, because we force signed ints. |
|
// in other case %= will fail. |
|
n = len > 2000 ? 2000 : len; |
|
len -= n; |
|
|
|
do { |
|
s1 = (s1 + buf[pos++]) |0; |
|
s2 = (s2 + s1) |0; |
|
} while (--n); |
|
|
|
s1 %= 65521; |
|
s2 %= 65521; |
|
} |
|
|
|
return (s1 | (s2 << 16)) |0; |
|
} |
|
|
|
|
|
module.exports = adler32; |
|
|
|
},{}],18:[function(require,module,exports){ |
|
module.exports = { |
|
|
|
/* Allowed flush values; see deflate() and inflate() below for details */ |
|
Z_NO_FLUSH: 0, |
|
Z_PARTIAL_FLUSH: 1, |
|
Z_SYNC_FLUSH: 2, |
|
Z_FULL_FLUSH: 3, |
|
Z_FINISH: 4, |
|
Z_BLOCK: 5, |
|
Z_TREES: 6, |
|
|
|
/* Return codes for the compression/decompression functions. Negative values |
|
* are errors, positive values are used for special but normal events. |
|
*/ |
|
Z_OK: 0, |
|
Z_STREAM_END: 1, |
|
Z_NEED_DICT: 2, |
|
Z_ERRNO: -1, |
|
Z_STREAM_ERROR: -2, |
|
Z_DATA_ERROR: -3, |
|
//Z_MEM_ERROR: -4, |
|
Z_BUF_ERROR: -5, |
|
//Z_VERSION_ERROR: -6, |
|
|
|
/* compression levels */ |
|
Z_NO_COMPRESSION: 0, |
|
Z_BEST_SPEED: 1, |
|
Z_BEST_COMPRESSION: 9, |
|
Z_DEFAULT_COMPRESSION: -1, |
|
|
|
|
|
Z_FILTERED: 1, |
|
Z_HUFFMAN_ONLY: 2, |
|
Z_RLE: 3, |
|
Z_FIXED: 4, |
|
Z_DEFAULT_STRATEGY: 0, |
|
|
|
/* Possible values of the data_type field (though see inflate()) */ |
|
Z_BINARY: 0, |
|
Z_TEXT: 1, |
|
//Z_ASCII: 1, // = Z_TEXT (deprecated) |
|
Z_UNKNOWN: 2, |
|
|
|
/* The deflate compression method */ |
|
Z_DEFLATED: 8 |
|
//Z_NULL: null // Use -1 or null inline, depending on var type |
|
}; |
|
|
|
},{}],19:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
// Note: we can't get significant speed boost here. |
|
// So write code to minimize size - no pregenerated tables |
|
// and array tools dependencies. |
|
|
|
|
|
// Use ordinary array, since untyped makes no boost here |
|
function makeTable() { |
|
var c, table = []; |
|
|
|
for (var n =0; n < 256; n++) { |
|
c = n; |
|
for (var k =0; k < 8; k++) { |
|
c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); |
|
} |
|
table[n] = c; |
|
} |
|
|
|
return table; |
|
} |
|
|
|
// Create table on load. Just 255 signed longs. Not a problem. |
|
var crcTable = makeTable(); |
|
|
|
|
|
function crc32(crc, buf, len, pos) { |
|
var t = crcTable, |
|
end = pos + len; |
|
|
|
crc = crc ^ (-1); |
|
|
|
for (var i = pos; i < end; i++) { |
|
crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; |
|
} |
|
|
|
return (crc ^ (-1)); // >>> 0; |
|
} |
|
|
|
|
|
module.exports = crc32; |
|
|
|
},{}],20:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
var utils = require('../utils/common'); |
|
var trees = require('./trees'); |
|
var adler32 = require('./adler32'); |
|
var crc32 = require('./crc32'); |
|
var msg = require('./messages'); |
|
|
|
/* Public constants ==========================================================*/ |
|
/* ===========================================================================*/ |
|
|
|
|
|
/* Allowed flush values; see deflate() and inflate() below for details */ |
|
var Z_NO_FLUSH = 0; |
|
var Z_PARTIAL_FLUSH = 1; |
|
//var Z_SYNC_FLUSH = 2; |
|
var Z_FULL_FLUSH = 3; |
|
var Z_FINISH = 4; |
|
var Z_BLOCK = 5; |
|
//var Z_TREES = 6; |
|
|
|
|
|
/* Return codes for the compression/decompression functions. Negative values |
|
* are errors, positive values are used for special but normal events. |
|
*/ |
|
var Z_OK = 0; |
|
var Z_STREAM_END = 1; |
|
//var Z_NEED_DICT = 2; |
|
//var Z_ERRNO = -1; |
|
var Z_STREAM_ERROR = -2; |
|
var Z_DATA_ERROR = -3; |
|
//var Z_MEM_ERROR = -4; |
|
var Z_BUF_ERROR = -5; |
|
//var Z_VERSION_ERROR = -6; |
|
|
|
|
|
/* compression levels */ |
|
//var Z_NO_COMPRESSION = 0; |
|
//var Z_BEST_SPEED = 1; |
|
//var Z_BEST_COMPRESSION = 9; |
|
var Z_DEFAULT_COMPRESSION = -1; |
|
|
|
|
|
var Z_FILTERED = 1; |
|
var Z_HUFFMAN_ONLY = 2; |
|
var Z_RLE = 3; |
|
var Z_FIXED = 4; |
|
var Z_DEFAULT_STRATEGY = 0; |
|
|
|
/* Possible values of the data_type field (though see inflate()) */ |
|
//var Z_BINARY = 0; |
|
//var Z_TEXT = 1; |
|
//var Z_ASCII = 1; // = Z_TEXT |
|
var Z_UNKNOWN = 2; |
|
|
|
|
|
/* The deflate compression method */ |
|
var Z_DEFLATED = 8; |
|
|
|
/*============================================================================*/ |
|
|
|
|
|
var MAX_MEM_LEVEL = 9; |
|
/* Maximum value for memLevel in deflateInit2 */ |
|
var MAX_WBITS = 15; |
|
/* 32K LZ77 window */ |
|
var DEF_MEM_LEVEL = 8; |
|
|
|
|
|
var LENGTH_CODES = 29; |
|
/* number of length codes, not counting the special END_BLOCK code */ |
|
var LITERALS = 256; |
|
/* number of literal bytes 0..255 */ |
|
var L_CODES = LITERALS + 1 + LENGTH_CODES; |
|
/* number of Literal or Length codes, including the END_BLOCK code */ |
|
var D_CODES = 30; |
|
/* number of distance codes */ |
|
var BL_CODES = 19; |
|
/* number of codes used to transfer the bit lengths */ |
|
var HEAP_SIZE = 2*L_CODES + 1; |
|
/* maximum heap size */ |
|
var MAX_BITS = 15; |
|
/* All codes must not exceed MAX_BITS bits */ |
|
|
|
var MIN_MATCH = 3; |
|
var MAX_MATCH = 258; |
|
var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); |
|
|
|
var PRESET_DICT = 0x20; |
|
|
|
var INIT_STATE = 42; |
|
var EXTRA_STATE = 69; |
|
var NAME_STATE = 73; |
|
var COMMENT_STATE = 91; |
|
var HCRC_STATE = 103; |
|
var BUSY_STATE = 113; |
|
var FINISH_STATE = 666; |
|
|
|
var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ |
|
var BS_BLOCK_DONE = 2; /* block flush performed */ |
|
var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ |
|
var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ |
|
|
|
var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. |
|
|
|
function err(strm, errorCode) { |
|
strm.msg = msg[errorCode]; |
|
return errorCode; |
|
} |
|
|
|
function rank(f) { |
|
return ((f) << 1) - ((f) > 4 ? 9 : 0); |
|
} |
|
|
|
function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } |
|
|
|
|
|
/* ========================================================================= |
|
* Flush as much pending output as possible. All deflate() output goes |
|
* through this function so some applications may wish to modify it |
|
* to avoid allocating a large strm->output buffer and copying into it. |
|
* (See also read_buf()). |
|
*/ |
|
function flush_pending(strm) { |
|
var s = strm.state; |
|
|
|
//_tr_flush_bits(s); |
|
var len = s.pending; |
|
if (len > strm.avail_out) { |
|
len = strm.avail_out; |
|
} |
|
if (len === 0) { return; } |
|
|
|
utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); |
|
strm.next_out += len; |
|
s.pending_out += len; |
|
strm.total_out += len; |
|
strm.avail_out -= len; |
|
s.pending -= len; |
|
if (s.pending === 0) { |
|
s.pending_out = 0; |
|
} |
|
} |
|
|
|
|
|
function flush_block_only (s, last) { |
|
trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); |
|
s.block_start = s.strstart; |
|
flush_pending(s.strm); |
|
} |
|
|
|
|
|
function put_byte(s, b) { |
|
s.pending_buf[s.pending++] = b; |
|
} |
|
|
|
|
|
/* ========================================================================= |
|
* Put a short in the pending buffer. The 16-bit value is put in MSB order. |
|
* IN assertion: the stream state is correct and there is enough room in |
|
* pending_buf. |
|
*/ |
|
function putShortMSB(s, b) { |
|
// put_byte(s, (Byte)(b >> 8)); |
|
// put_byte(s, (Byte)(b & 0xff)); |
|
s.pending_buf[s.pending++] = (b >>> 8) & 0xff; |
|
s.pending_buf[s.pending++] = b & 0xff; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Read a new buffer from the current input stream, update the adler32 |
|
* and total number of bytes read. All deflate() input goes through |
|
* this function so some applications may wish to modify it to avoid |
|
* allocating a large strm->input buffer and copying from it. |
|
* (See also flush_pending()). |
|
*/ |
|
function read_buf(strm, buf, start, size) { |
|
var len = strm.avail_in; |
|
|
|
if (len > size) { len = size; } |
|
if (len === 0) { return 0; } |
|
|
|
strm.avail_in -= len; |
|
|
|
utils.arraySet(buf, strm.input, strm.next_in, len, start); |
|
if (strm.state.wrap === 1) { |
|
strm.adler = adler32(strm.adler, buf, len, start); |
|
} |
|
|
|
else if (strm.state.wrap === 2) { |
|
strm.adler = crc32(strm.adler, buf, len, start); |
|
} |
|
|
|
strm.next_in += len; |
|
strm.total_in += len; |
|
|
|
return len; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Set match_start to the longest match starting at the given string and |
|
* return its length. Matches shorter or equal to prev_length are discarded, |
|
* in which case the result is equal to prev_length and match_start is |
|
* garbage. |
|
* IN assertions: cur_match is the head of the hash chain for the current |
|
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 |
|
* OUT assertion: the match length is not greater than s->lookahead. |
|
*/ |
|
function longest_match(s, cur_match) { |
|
var chain_length = s.max_chain_length; /* max hash chain length */ |
|
var scan = s.strstart; /* current string */ |
|
var match; /* matched string */ |
|
var len; /* length of current match */ |
|
var best_len = s.prev_length; /* best match length so far */ |
|
var nice_match = s.nice_match; /* stop if match long enough */ |
|
var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? |
|
s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; |
|
|
|
var _win = s.window; // shortcut |
|
|
|
var wmask = s.w_mask; |
|
var prev = s.prev; |
|
|
|
/* Stop when cur_match becomes <= limit. To simplify the code, |
|
* we prevent matches with the string of window index 0. |
|
*/ |
|
|
|
var strend = s.strstart + MAX_MATCH; |
|
var scan_end1 = _win[scan + best_len - 1]; |
|
var scan_end = _win[scan + best_len]; |
|
|
|
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. |
|
* It is easy to get rid of this optimization if necessary. |
|
*/ |
|
// Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); |
|
|
|
/* Do not waste too much time if we already have a good match: */ |
|
if (s.prev_length >= s.good_match) { |
|
chain_length >>= 2; |
|
} |
|
/* Do not look for matches beyond the end of the input. This is necessary |
|
* to make deflate deterministic. |
|
*/ |
|
if (nice_match > s.lookahead) { nice_match = s.lookahead; } |
|
|
|
// Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); |
|
|
|
do { |
|
// Assert(cur_match < s->strstart, "no future"); |
|
match = cur_match; |
|
|
|
/* Skip to next match if the match length cannot increase |
|
* or if the match length is less than 2. Note that the checks below |
|
* for insufficient lookahead only occur occasionally for performance |
|
* reasons. Therefore uninitialized memory will be accessed, and |
|
* conditional jumps will be made that depend on those values. |
|
* However the length of the match is limited to the lookahead, so |
|
* the output of deflate is not affected by the uninitialized values. |
|
*/ |
|
|
|
if (_win[match + best_len] !== scan_end || |
|
_win[match + best_len - 1] !== scan_end1 || |
|
_win[match] !== _win[scan] || |
|
_win[++match] !== _win[scan + 1]) { |
|
continue; |
|
} |
|
|
|
/* The check at best_len-1 can be removed because it will be made |
|
* again later. (This heuristic is not always a win.) |
|
* It is not necessary to compare scan[2] and match[2] since they |
|
* are always equal when the other bytes match, given that |
|
* the hash keys are equal and that HASH_BITS >= 8. |
|
*/ |
|
scan += 2; |
|
match++; |
|
// Assert(*scan == *match, "match[2]?"); |
|
|
|
/* We check for insufficient lookahead only every 8th comparison; |
|
* the 256th check will be made at strstart+258. |
|
*/ |
|
do { |
|
/*jshint noempty:false*/ |
|
} while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
|
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
|
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
|
_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && |
|
scan < strend); |
|
|
|
// Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); |
|
|
|
len = MAX_MATCH - (strend - scan); |
|
scan = strend - MAX_MATCH; |
|
|
|
if (len > best_len) { |
|
s.match_start = cur_match; |
|
best_len = len; |
|
if (len >= nice_match) { |
|
break; |
|
} |
|
scan_end1 = _win[scan + best_len - 1]; |
|
scan_end = _win[scan + best_len]; |
|
} |
|
} while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); |
|
|
|
if (best_len <= s.lookahead) { |
|
return best_len; |
|
} |
|
return s.lookahead; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Fill the window when the lookahead becomes insufficient. |
|
* Updates strstart and lookahead. |
|
* |
|
* IN assertion: lookahead < MIN_LOOKAHEAD |
|
* OUT assertions: strstart <= window_size-MIN_LOOKAHEAD |
|
* At least one byte has been read, or avail_in == 0; reads are |
|
* performed for at least two bytes (required for the zip translate_eol |
|
* option -- not supported here). |
|
*/ |
|
function fill_window(s) { |
|
var _w_size = s.w_size; |
|
var p, n, m, more, str; |
|
|
|
//Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); |
|
|
|
do { |
|
more = s.window_size - s.lookahead - s.strstart; |
|
|
|
// JS ints have 32 bit, block below not needed |
|
/* Deal with !@#$% 64K limit: */ |
|
//if (sizeof(int) <= 2) { |
|
// if (more == 0 && s->strstart == 0 && s->lookahead == 0) { |
|
// more = wsize; |
|
// |
|
// } else if (more == (unsigned)(-1)) { |
|
// /* Very unlikely, but possible on 16 bit machine if |
|
// * strstart == 0 && lookahead == 1 (input done a byte at time) |
|
// */ |
|
// more--; |
|
// } |
|
//} |
|
|
|
|
|
/* If the window is almost full and there is insufficient lookahead, |
|
* move the upper half to the lower one to make room in the upper half. |
|
*/ |
|
if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { |
|
|
|
utils.arraySet(s.window, s.window, _w_size, _w_size, 0); |
|
s.match_start -= _w_size; |
|
s.strstart -= _w_size; |
|
/* we now have strstart >= MAX_DIST */ |
|
s.block_start -= _w_size; |
|
|
|
/* Slide the hash table (could be avoided with 32 bit values |
|
at the expense of memory usage). We slide even when level == 0 |
|
to keep the hash table consistent if we switch back to level > 0 |
|
later. (Using level 0 permanently is not an optimal usage of |
|
zlib, so we don't care about this pathological case.) |
|
*/ |
|
|
|
n = s.hash_size; |
|
p = n; |
|
do { |
|
m = s.head[--p]; |
|
s.head[p] = (m >= _w_size ? m - _w_size : 0); |
|
} while (--n); |
|
|
|
n = _w_size; |
|
p = n; |
|
do { |
|
m = s.prev[--p]; |
|
s.prev[p] = (m >= _w_size ? m - _w_size : 0); |
|
/* If n is not on any hash chain, prev[n] is garbage but |
|
* its value will never be used. |
|
*/ |
|
} while (--n); |
|
|
|
more += _w_size; |
|
} |
|
if (s.strm.avail_in === 0) { |
|
break; |
|
} |
|
|
|
/* If there was no sliding: |
|
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && |
|
* more == window_size - lookahead - strstart |
|
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) |
|
* => more >= window_size - 2*WSIZE + 2 |
|
* In the BIG_MEM or MMAP case (not yet supported), |
|
* window_size == input_size + MIN_LOOKAHEAD && |
|
* strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. |
|
* Otherwise, window_size == 2*WSIZE so more >= 2. |
|
* If there was sliding, more >= WSIZE. So in all cases, more >= 2. |
|
*/ |
|
//Assert(more >= 2, "more < 2"); |
|
n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); |
|
s.lookahead += n; |
|
|
|
/* Initialize the hash value now that we have some input: */ |
|
if (s.lookahead + s.insert >= MIN_MATCH) { |
|
str = s.strstart - s.insert; |
|
s.ins_h = s.window[str]; |
|
|
|
/* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; |
|
//#if MIN_MATCH != 3 |
|
// Call update_hash() MIN_MATCH-3 more times |
|
//#endif |
|
while (s.insert) { |
|
/* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; |
|
|
|
s.prev[str & s.w_mask] = s.head[s.ins_h]; |
|
s.head[s.ins_h] = str; |
|
str++; |
|
s.insert--; |
|
if (s.lookahead + s.insert < MIN_MATCH) { |
|
break; |
|
} |
|
} |
|
} |
|
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, |
|
* but this is not important since only literal bytes will be emitted. |
|
*/ |
|
|
|
} while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); |
|
|
|
/* If the WIN_INIT bytes after the end of the current data have never been |
|
* written, then zero those bytes in order to avoid memory check reports of |
|
* the use of uninitialized (or uninitialised as Julian writes) bytes by |
|
* the longest match routines. Update the high water mark for the next |
|
* time through here. WIN_INIT is set to MAX_MATCH since the longest match |
|
* routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. |
|
*/ |
|
// if (s.high_water < s.window_size) { |
|
// var curr = s.strstart + s.lookahead; |
|
// var init = 0; |
|
// |
|
// if (s.high_water < curr) { |
|
// /* Previous high water mark below current data -- zero WIN_INIT |
|
// * bytes or up to end of window, whichever is less. |
|
// */ |
|
// init = s.window_size - curr; |
|
// if (init > WIN_INIT) |
|
// init = WIN_INIT; |
|
// zmemzero(s->window + curr, (unsigned)init); |
|
// s->high_water = curr + init; |
|
// } |
|
// else if (s->high_water < (ulg)curr + WIN_INIT) { |
|
// /* High water mark at or above current data, but below current data |
|
// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up |
|
// * to end of window, whichever is less. |
|
// */ |
|
// init = (ulg)curr + WIN_INIT - s->high_water; |
|
// if (init > s->window_size - s->high_water) |
|
// init = s->window_size - s->high_water; |
|
// zmemzero(s->window + s->high_water, (unsigned)init); |
|
// s->high_water += init; |
|
// } |
|
// } |
|
// |
|
// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, |
|
// "not enough room for search"); |
|
} |
|
|
|
/* =========================================================================== |
|
* Copy without compression as much as possible from the input stream, return |
|
* the current block state. |
|
* This function does not insert new strings in the dictionary since |
|
* uncompressible data is probably not useful. This function is used |
|
* only for the level=0 compression option. |
|
* NOTE: this function should be optimized to avoid extra copying from |
|
* window to pending_buf. |
|
*/ |
|
function deflate_stored(s, flush) { |
|
/* Stored blocks are limited to 0xffff bytes, pending_buf is limited |
|
* to pending_buf_size, and each stored block has a 5 byte header: |
|
*/ |
|
var max_block_size = 0xffff; |
|
|
|
if (max_block_size > s.pending_buf_size - 5) { |
|
max_block_size = s.pending_buf_size - 5; |
|
} |
|
|
|
/* Copy as much as possible from input to output: */ |
|
for (;;) { |
|
/* Fill the window as much as possible: */ |
|
if (s.lookahead <= 1) { |
|
|
|
//Assert(s->strstart < s->w_size+MAX_DIST(s) || |
|
// s->block_start >= (long)s->w_size, "slide too late"); |
|
// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || |
|
// s.block_start >= s.w_size)) { |
|
// throw new Error("slide too late"); |
|
// } |
|
|
|
fill_window(s); |
|
if (s.lookahead === 0 && flush === Z_NO_FLUSH) { |
|
return BS_NEED_MORE; |
|
} |
|
|
|
if (s.lookahead === 0) { |
|
break; |
|
} |
|
/* flush the current block */ |
|
} |
|
//Assert(s->block_start >= 0L, "block gone"); |
|
// if (s.block_start < 0) throw new Error("block gone"); |
|
|
|
s.strstart += s.lookahead; |
|
s.lookahead = 0; |
|
|
|
/* Emit a stored block if pending_buf will be full: */ |
|
var max_start = s.block_start + max_block_size; |
|
|
|
if (s.strstart === 0 || s.strstart >= max_start) { |
|
/* strstart == 0 is possible when wraparound on 16-bit machine */ |
|
s.lookahead = s.strstart - max_start; |
|
s.strstart = max_start; |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
|
|
|
|
} |
|
/* Flush if we may have to slide, otherwise block_start may become |
|
* negative and the data will be gone: |
|
*/ |
|
if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
} |
|
|
|
s.insert = 0; |
|
|
|
if (flush === Z_FINISH) { |
|
/*** FLUSH_BLOCK(s, 1); ***/ |
|
flush_block_only(s, true); |
|
if (s.strm.avail_out === 0) { |
|
return BS_FINISH_STARTED; |
|
} |
|
/***/ |
|
return BS_FINISH_DONE; |
|
} |
|
|
|
if (s.strstart > s.block_start) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
|
|
return BS_NEED_MORE; |
|
} |
|
|
|
/* =========================================================================== |
|
* Compress as much as possible from the input stream, return the current |
|
* block state. |
|
* This function does not perform lazy evaluation of matches and inserts |
|
* new strings in the dictionary only for unmatched strings or for short |
|
* matches. It is used only for the fast compression options. |
|
*/ |
|
function deflate_fast(s, flush) { |
|
var hash_head; /* head of the hash chain */ |
|
var bflush; /* set if current block must be flushed */ |
|
|
|
for (;;) { |
|
/* Make sure that we always have enough lookahead, except |
|
* at the end of the input file. We need MAX_MATCH bytes |
|
* for the next match, plus MIN_MATCH bytes to insert the |
|
* string following the next match. |
|
*/ |
|
if (s.lookahead < MIN_LOOKAHEAD) { |
|
fill_window(s); |
|
if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { |
|
return BS_NEED_MORE; |
|
} |
|
if (s.lookahead === 0) { |
|
break; /* flush the current block */ |
|
} |
|
} |
|
|
|
/* Insert the string window[strstart .. strstart+2] in the |
|
* dictionary, and set hash_head to the head of the hash chain: |
|
*/ |
|
hash_head = 0/*NIL*/; |
|
if (s.lookahead >= MIN_MATCH) { |
|
/*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
|
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
|
s.head[s.ins_h] = s.strstart; |
|
/***/ |
|
} |
|
|
|
/* Find the longest match, discarding those <= prev_length. |
|
* At this point we have always match_length < MIN_MATCH |
|
*/ |
|
if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { |
|
/* To simplify the code, we prevent matches with the string |
|
* of window index 0 (in particular we have to avoid a match |
|
* of the string with itself at the start of the input file). |
|
*/ |
|
s.match_length = longest_match(s, hash_head); |
|
/* longest_match() sets match_start */ |
|
} |
|
if (s.match_length >= MIN_MATCH) { |
|
// check_match(s, s.strstart, s.match_start, s.match_length); // for debug only |
|
|
|
/*** _tr_tally_dist(s, s.strstart - s.match_start, |
|
s.match_length - MIN_MATCH, bflush); ***/ |
|
bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); |
|
|
|
s.lookahead -= s.match_length; |
|
|
|
/* Insert new strings in the hash table only if the match length |
|
* is not too large. This saves time but degrades compression. |
|
*/ |
|
if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { |
|
s.match_length--; /* string at strstart already in table */ |
|
do { |
|
s.strstart++; |
|
/*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
|
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
|
s.head[s.ins_h] = s.strstart; |
|
/***/ |
|
/* strstart never exceeds WSIZE-MAX_MATCH, so there are |
|
* always MIN_MATCH bytes ahead. |
|
*/ |
|
} while (--s.match_length !== 0); |
|
s.strstart++; |
|
} else |
|
{ |
|
s.strstart += s.match_length; |
|
s.match_length = 0; |
|
s.ins_h = s.window[s.strstart]; |
|
/* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; |
|
|
|
//#if MIN_MATCH != 3 |
|
// Call UPDATE_HASH() MIN_MATCH-3 more times |
|
//#endif |
|
/* If lookahead < MIN_MATCH, ins_h is garbage, but it does not |
|
* matter since it will be recomputed at next deflate call. |
|
*/ |
|
} |
|
} else { |
|
/* No match, output a literal byte */ |
|
//Tracevv((stderr,"%c", s.window[s.strstart])); |
|
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
|
bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
|
|
|
s.lookahead--; |
|
s.strstart++; |
|
} |
|
if (bflush) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
} |
|
s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1); |
|
if (flush === Z_FINISH) { |
|
/*** FLUSH_BLOCK(s, 1); ***/ |
|
flush_block_only(s, true); |
|
if (s.strm.avail_out === 0) { |
|
return BS_FINISH_STARTED; |
|
} |
|
/***/ |
|
return BS_FINISH_DONE; |
|
} |
|
if (s.last_lit) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
return BS_BLOCK_DONE; |
|
} |
|
|
|
/* =========================================================================== |
|
* Same as above, but achieves better compression. We use a lazy |
|
* evaluation for matches: a match is finally adopted only if there is |
|
* no better match at the next window position. |
|
*/ |
|
function deflate_slow(s, flush) { |
|
var hash_head; /* head of hash chain */ |
|
var bflush; /* set if current block must be flushed */ |
|
|
|
var max_insert; |
|
|
|
/* Process the input block. */ |
|
for (;;) { |
|
/* Make sure that we always have enough lookahead, except |
|
* at the end of the input file. We need MAX_MATCH bytes |
|
* for the next match, plus MIN_MATCH bytes to insert the |
|
* string following the next match. |
|
*/ |
|
if (s.lookahead < MIN_LOOKAHEAD) { |
|
fill_window(s); |
|
if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { |
|
return BS_NEED_MORE; |
|
} |
|
if (s.lookahead === 0) { break; } /* flush the current block */ |
|
} |
|
|
|
/* Insert the string window[strstart .. strstart+2] in the |
|
* dictionary, and set hash_head to the head of the hash chain: |
|
*/ |
|
hash_head = 0/*NIL*/; |
|
if (s.lookahead >= MIN_MATCH) { |
|
/*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
|
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
|
s.head[s.ins_h] = s.strstart; |
|
/***/ |
|
} |
|
|
|
/* Find the longest match, discarding those <= prev_length. |
|
*/ |
|
s.prev_length = s.match_length; |
|
s.prev_match = s.match_start; |
|
s.match_length = MIN_MATCH-1; |
|
|
|
if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && |
|
s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { |
|
/* To simplify the code, we prevent matches with the string |
|
* of window index 0 (in particular we have to avoid a match |
|
* of the string with itself at the start of the input file). |
|
*/ |
|
s.match_length = longest_match(s, hash_head); |
|
/* longest_match() sets match_start */ |
|
|
|
if (s.match_length <= 5 && |
|
(s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { |
|
|
|
/* If prev_match is also MIN_MATCH, match_start is garbage |
|
* but we will ignore the current match anyway. |
|
*/ |
|
s.match_length = MIN_MATCH-1; |
|
} |
|
} |
|
/* If there was a match at the previous step and the current |
|
* match is not better, output the previous match: |
|
*/ |
|
if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { |
|
max_insert = s.strstart + s.lookahead - MIN_MATCH; |
|
/* Do not insert strings in hash table beyond this. */ |
|
|
|
//check_match(s, s.strstart-1, s.prev_match, s.prev_length); |
|
|
|
/***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, |
|
s.prev_length - MIN_MATCH, bflush);***/ |
|
bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH); |
|
/* Insert in hash table all strings up to the end of the match. |
|
* strstart-1 and strstart are already inserted. If there is not |
|
* enough lookahead, the last two strings are not inserted in |
|
* the hash table. |
|
*/ |
|
s.lookahead -= s.prev_length-1; |
|
s.prev_length -= 2; |
|
do { |
|
if (++s.strstart <= max_insert) { |
|
/*** INSERT_STRING(s, s.strstart, hash_head); ***/ |
|
s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; |
|
hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; |
|
s.head[s.ins_h] = s.strstart; |
|
/***/ |
|
} |
|
} while (--s.prev_length !== 0); |
|
s.match_available = 0; |
|
s.match_length = MIN_MATCH-1; |
|
s.strstart++; |
|
|
|
if (bflush) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
|
|
} else if (s.match_available) { |
|
/* If there was no match at the previous position, output a |
|
* single literal. If there was a match but the current match |
|
* is longer, truncate the previous match to a single literal. |
|
*/ |
|
//Tracevv((stderr,"%c", s->window[s->strstart-1])); |
|
/*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ |
|
bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); |
|
|
|
if (bflush) { |
|
/*** FLUSH_BLOCK_ONLY(s, 0) ***/ |
|
flush_block_only(s, false); |
|
/***/ |
|
} |
|
s.strstart++; |
|
s.lookahead--; |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
} else { |
|
/* There is no previous match to compare with, wait for |
|
* the next step to decide. |
|
*/ |
|
s.match_available = 1; |
|
s.strstart++; |
|
s.lookahead--; |
|
} |
|
} |
|
//Assert (flush != Z_NO_FLUSH, "no flush?"); |
|
if (s.match_available) { |
|
//Tracevv((stderr,"%c", s->window[s->strstart-1])); |
|
/*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ |
|
bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); |
|
|
|
s.match_available = 0; |
|
} |
|
s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1; |
|
if (flush === Z_FINISH) { |
|
/*** FLUSH_BLOCK(s, 1); ***/ |
|
flush_block_only(s, true); |
|
if (s.strm.avail_out === 0) { |
|
return BS_FINISH_STARTED; |
|
} |
|
/***/ |
|
return BS_FINISH_DONE; |
|
} |
|
if (s.last_lit) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
|
|
return BS_BLOCK_DONE; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* For Z_RLE, simply look for runs of bytes, generate matches only of distance |
|
* one. Do not maintain a hash table. (It will be regenerated if this run of |
|
* deflate switches away from Z_RLE.) |
|
*/ |
|
function deflate_rle(s, flush) { |
|
var bflush; /* set if current block must be flushed */ |
|
var prev; /* byte at distance one to match */ |
|
var scan, strend; /* scan goes up to strend for length of run */ |
|
|
|
var _win = s.window; |
|
|
|
for (;;) { |
|
/* Make sure that we always have enough lookahead, except |
|
* at the end of the input file. We need MAX_MATCH bytes |
|
* for the longest run, plus one for the unrolled loop. |
|
*/ |
|
if (s.lookahead <= MAX_MATCH) { |
|
fill_window(s); |
|
if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { |
|
return BS_NEED_MORE; |
|
} |
|
if (s.lookahead === 0) { break; } /* flush the current block */ |
|
} |
|
|
|
/* See how many times the previous byte repeats */ |
|
s.match_length = 0; |
|
if (s.lookahead >= MIN_MATCH && s.strstart > 0) { |
|
scan = s.strstart - 1; |
|
prev = _win[scan]; |
|
if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { |
|
strend = s.strstart + MAX_MATCH; |
|
do { |
|
/*jshint noempty:false*/ |
|
} while (prev === _win[++scan] && prev === _win[++scan] && |
|
prev === _win[++scan] && prev === _win[++scan] && |
|
prev === _win[++scan] && prev === _win[++scan] && |
|
prev === _win[++scan] && prev === _win[++scan] && |
|
scan < strend); |
|
s.match_length = MAX_MATCH - (strend - scan); |
|
if (s.match_length > s.lookahead) { |
|
s.match_length = s.lookahead; |
|
} |
|
} |
|
//Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); |
|
} |
|
|
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */ |
|
if (s.match_length >= MIN_MATCH) { |
|
//check_match(s, s.strstart, s.strstart - 1, s.match_length); |
|
|
|
/*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ |
|
bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); |
|
|
|
s.lookahead -= s.match_length; |
|
s.strstart += s.match_length; |
|
s.match_length = 0; |
|
} else { |
|
/* No match, output a literal byte */ |
|
//Tracevv((stderr,"%c", s->window[s->strstart])); |
|
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
|
bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
|
|
|
s.lookahead--; |
|
s.strstart++; |
|
} |
|
if (bflush) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
} |
|
s.insert = 0; |
|
if (flush === Z_FINISH) { |
|
/*** FLUSH_BLOCK(s, 1); ***/ |
|
flush_block_only(s, true); |
|
if (s.strm.avail_out === 0) { |
|
return BS_FINISH_STARTED; |
|
} |
|
/***/ |
|
return BS_FINISH_DONE; |
|
} |
|
if (s.last_lit) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
return BS_BLOCK_DONE; |
|
} |
|
|
|
/* =========================================================================== |
|
* For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. |
|
* (It will be regenerated if this run of deflate switches away from Huffman.) |
|
*/ |
|
function deflate_huff(s, flush) { |
|
var bflush; /* set if current block must be flushed */ |
|
|
|
for (;;) { |
|
/* Make sure that we have a literal to write. */ |
|
if (s.lookahead === 0) { |
|
fill_window(s); |
|
if (s.lookahead === 0) { |
|
if (flush === Z_NO_FLUSH) { |
|
return BS_NEED_MORE; |
|
} |
|
break; /* flush the current block */ |
|
} |
|
} |
|
|
|
/* Output a literal byte */ |
|
s.match_length = 0; |
|
//Tracevv((stderr,"%c", s->window[s->strstart])); |
|
/*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ |
|
bflush = trees._tr_tally(s, 0, s.window[s.strstart]); |
|
s.lookahead--; |
|
s.strstart++; |
|
if (bflush) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
} |
|
s.insert = 0; |
|
if (flush === Z_FINISH) { |
|
/*** FLUSH_BLOCK(s, 1); ***/ |
|
flush_block_only(s, true); |
|
if (s.strm.avail_out === 0) { |
|
return BS_FINISH_STARTED; |
|
} |
|
/***/ |
|
return BS_FINISH_DONE; |
|
} |
|
if (s.last_lit) { |
|
/*** FLUSH_BLOCK(s, 0); ***/ |
|
flush_block_only(s, false); |
|
if (s.strm.avail_out === 0) { |
|
return BS_NEED_MORE; |
|
} |
|
/***/ |
|
} |
|
return BS_BLOCK_DONE; |
|
} |
|
|
|
/* Values for max_lazy_match, good_match and max_chain_length, depending on |
|
* the desired pack level (0..9). The values given below have been tuned to |
|
* exclude worst case performance for pathological files. Better values may be |
|
* found for specific files. |
|
*/ |
|
var Config = function (good_length, max_lazy, nice_length, max_chain, func) { |
|
this.good_length = good_length; |
|
this.max_lazy = max_lazy; |
|
this.nice_length = nice_length; |
|
this.max_chain = max_chain; |
|
this.func = func; |
|
}; |
|
|
|
var configuration_table; |
|
|
|
configuration_table = [ |
|
/* good lazy nice chain */ |
|
new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ |
|
new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ |
|
new Config(4, 5, 16, 8, deflate_fast), /* 2 */ |
|
new Config(4, 6, 32, 32, deflate_fast), /* 3 */ |
|
|
|
new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ |
|
new Config(8, 16, 32, 32, deflate_slow), /* 5 */ |
|
new Config(8, 16, 128, 128, deflate_slow), /* 6 */ |
|
new Config(8, 32, 128, 256, deflate_slow), /* 7 */ |
|
new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ |
|
new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ |
|
]; |
|
|
|
|
|
/* =========================================================================== |
|
* Initialize the "longest match" routines for a new zlib stream |
|
*/ |
|
function lm_init(s) { |
|
s.window_size = 2 * s.w_size; |
|
|
|
/*** CLEAR_HASH(s); ***/ |
|
zero(s.head); // Fill with NIL (= 0); |
|
|
|
/* Set the default configuration parameters: |
|
*/ |
|
s.max_lazy_match = configuration_table[s.level].max_lazy; |
|
s.good_match = configuration_table[s.level].good_length; |
|
s.nice_match = configuration_table[s.level].nice_length; |
|
s.max_chain_length = configuration_table[s.level].max_chain; |
|
|
|
s.strstart = 0; |
|
s.block_start = 0; |
|
s.lookahead = 0; |
|
s.insert = 0; |
|
s.match_length = s.prev_length = MIN_MATCH - 1; |
|
s.match_available = 0; |
|
s.ins_h = 0; |
|
} |
|
|
|
|
|
function DeflateState() { |
|
this.strm = null; /* pointer back to this zlib stream */ |
|
this.status = 0; /* as the name implies */ |
|
this.pending_buf = null; /* output still pending */ |
|
this.pending_buf_size = 0; /* size of pending_buf */ |
|
this.pending_out = 0; /* next pending byte to output to the stream */ |
|
this.pending = 0; /* nb of bytes in the pending buffer */ |
|
this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ |
|
this.gzhead = null; /* gzip header information to write */ |
|
this.gzindex = 0; /* where in extra, name, or comment */ |
|
this.method = Z_DEFLATED; /* can only be DEFLATED */ |
|
this.last_flush = -1; /* value of flush param for previous deflate call */ |
|
|
|
this.w_size = 0; /* LZ77 window size (32K by default) */ |
|
this.w_bits = 0; /* log2(w_size) (8..16) */ |
|
this.w_mask = 0; /* w_size - 1 */ |
|
|
|
this.window = null; |
|
/* Sliding window. Input bytes are read into the second half of the window, |
|
* and move to the first half later to keep a dictionary of at least wSize |
|
* bytes. With this organization, matches are limited to a distance of |
|
* wSize-MAX_MATCH bytes, but this ensures that IO is always |
|
* performed with a length multiple of the block size. |
|
*/ |
|
|
|
this.window_size = 0; |
|
/* Actual size of window: 2*wSize, except when the user input buffer |
|
* is directly used as sliding window. |
|
*/ |
|
|
|
this.prev = null; |
|
/* Link to older string with same hash index. To limit the size of this |
|
* array to 64K, this link is maintained only for the last 32K strings. |
|
* An index in this array is thus a window index modulo 32K. |
|
*/ |
|
|
|
this.head = null; /* Heads of the hash chains or NIL. */ |
|
|
|
this.ins_h = 0; /* hash index of string to be inserted */ |
|
this.hash_size = 0; /* number of elements in hash table */ |
|
this.hash_bits = 0; /* log2(hash_size) */ |
|
this.hash_mask = 0; /* hash_size-1 */ |
|
|
|
this.hash_shift = 0; |
|
/* Number of bits by which ins_h must be shifted at each input |
|
* step. It must be such that after MIN_MATCH steps, the oldest |
|
* byte no longer takes part in the hash key, that is: |
|
* hash_shift * MIN_MATCH >= hash_bits |
|
*/ |
|
|
|
this.block_start = 0; |
|
/* Window position at the beginning of the current output block. Gets |
|
* negative when the window is moved backwards. |
|
*/ |
|
|
|
this.match_length = 0; /* length of best match */ |
|
this.prev_match = 0; /* previous match */ |
|
this.match_available = 0; /* set if previous match exists */ |
|
this.strstart = 0; /* start of string to insert */ |
|
this.match_start = 0; /* start of matching string */ |
|
this.lookahead = 0; /* number of valid bytes ahead in window */ |
|
|
|
this.prev_length = 0; |
|
/* Length of the best match at previous step. Matches not greater than this |
|
* are discarded. This is used in the lazy match evaluation. |
|
*/ |
|
|
|
this.max_chain_length = 0; |
|
/* To speed up deflation, hash chains are never searched beyond this |
|
* length. A higher limit improves compression ratio but degrades the |
|
* speed. |
|
*/ |
|
|
|
this.max_lazy_match = 0; |
|
/* Attempt to find a better match only when the current match is strictly |
|
* smaller than this value. This mechanism is used only for compression |
|
* levels >= 4. |
|
*/ |
|
// That's alias to max_lazy_match, don't use directly |
|
//this.max_insert_length = 0; |
|
/* Insert new strings in the hash table only if the match length is not |
|
* greater than this length. This saves time but degrades compression. |
|
* max_insert_length is used only for compression levels <= 3. |
|
*/ |
|
|
|
this.level = 0; /* compression level (1..9) */ |
|
this.strategy = 0; /* favor or force Huffman coding*/ |
|
|
|
this.good_match = 0; |
|
/* Use a faster search when the previous match is longer than this */ |
|
|
|
this.nice_match = 0; /* Stop searching when current match exceeds this */ |
|
|
|
/* used by trees.c: */ |
|
|
|
/* Didn't use ct_data typedef below to suppress compiler warning */ |
|
|
|
// struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ |
|
// struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ |
|
// struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ |
|
|
|
// Use flat array of DOUBLE size, with interleaved fata, |
|
// because JS does not support effective |
|
this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); |
|
this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); |
|
this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); |
|
zero(this.dyn_ltree); |
|
zero(this.dyn_dtree); |
|
zero(this.bl_tree); |
|
|
|
this.l_desc = null; /* desc. for literal tree */ |
|
this.d_desc = null; /* desc. for distance tree */ |
|
this.bl_desc = null; /* desc. for bit length tree */ |
|
|
|
//ush bl_count[MAX_BITS+1]; |
|
this.bl_count = new utils.Buf16(MAX_BITS+1); |
|
/* number of codes at each bit length for an optimal tree */ |
|
|
|
//int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ |
|
this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ |
|
zero(this.heap); |
|
|
|
this.heap_len = 0; /* number of elements in the heap */ |
|
this.heap_max = 0; /* element of largest frequency */ |
|
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. |
|
* The same heap array is used to build all trees. |
|
*/ |
|
|
|
this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; |
|
zero(this.depth); |
|
/* Depth of each subtree used as tie breaker for trees of equal frequency |
|
*/ |
|
|
|
this.l_buf = 0; /* buffer index for literals or lengths */ |
|
|
|
this.lit_bufsize = 0; |
|
/* Size of match buffer for literals/lengths. There are 4 reasons for |
|
* limiting lit_bufsize to 64K: |
|
* - frequencies can be kept in 16 bit counters |
|
* - if compression is not successful for the first block, all input |
|
* data is still in the window so we can still emit a stored block even |
|
* when input comes from standard input. (This can also be done for |
|
* all blocks if lit_bufsize is not greater than 32K.) |
|
* - if compression is not successful for a file smaller than 64K, we can |
|
* even emit a stored file instead of a stored block (saving 5 bytes). |
|
* This is applicable only for zip (not gzip or zlib). |
|
* - creating new Huffman trees less frequently may not provide fast |
|
* adaptation to changes in the input data statistics. (Take for |
|
* example a binary file with poorly compressible code followed by |
|
* a highly compressible string table.) Smaller buffer sizes give |
|
* fast adaptation but have of course the overhead of transmitting |
|
* trees more frequently. |
|
* - I can't count above 4 |
|
*/ |
|
|
|
this.last_lit = 0; /* running index in l_buf */ |
|
|
|
this.d_buf = 0; |
|
/* Buffer index for distances. To simplify the code, d_buf and l_buf have |
|
* the same number of elements. To use different lengths, an extra flag |
|
* array would be necessary. |
|
*/ |
|
|
|
this.opt_len = 0; /* bit length of current block with optimal trees */ |
|
this.static_len = 0; /* bit length of current block with static trees */ |
|
this.matches = 0; /* number of string matches in current block */ |
|
this.insert = 0; /* bytes at end of window left to insert */ |
|
|
|
|
|
this.bi_buf = 0; |
|
/* Output buffer. bits are inserted starting at the bottom (least |
|
* significant bits). |
|
*/ |
|
this.bi_valid = 0; |
|
/* Number of valid bits in bi_buf. All bits above the last valid bit |
|
* are always zero. |
|
*/ |
|
|
|
// Used for window memory init. We safely ignore it for JS. That makes |
|
// sense only for pointers and memory check tools. |
|
//this.high_water = 0; |
|
/* High water mark offset in window for initialized bytes -- bytes above |
|
* this are set to zero in order to avoid memory check warnings when |
|
* longest match routines access bytes past the input. This is then |
|
* updated to the new high water mark. |
|
*/ |
|
} |
|
|
|
|
|
function deflateResetKeep(strm) { |
|
var s; |
|
|
|
if (!strm || !strm.state) { |
|
return err(strm, Z_STREAM_ERROR); |
|
} |
|
|
|
strm.total_in = strm.total_out = 0; |
|
strm.data_type = Z_UNKNOWN; |
|
|
|
s = strm.state; |
|
s.pending = 0; |
|
s.pending_out = 0; |
|
|
|
if (s.wrap < 0) { |
|
s.wrap = -s.wrap; |
|
/* was made negative by deflate(..., Z_FINISH); */ |
|
} |
|
s.status = (s.wrap ? INIT_STATE : BUSY_STATE); |
|
strm.adler = (s.wrap === 2) ? |
|
0 // crc32(0, Z_NULL, 0) |
|
: |
|
1; // adler32(0, Z_NULL, 0) |
|
s.last_flush = Z_NO_FLUSH; |
|
trees._tr_init(s); |
|
return Z_OK; |
|
} |
|
|
|
|
|
function deflateReset(strm) { |
|
var ret = deflateResetKeep(strm); |
|
if (ret === Z_OK) { |
|
lm_init(strm.state); |
|
} |
|
return ret; |
|
} |
|
|
|
|
|
function deflateSetHeader(strm, head) { |
|
if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
|
if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } |
|
strm.state.gzhead = head; |
|
return Z_OK; |
|
} |
|
|
|
|
|
function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { |
|
if (!strm) { // === Z_NULL |
|
return Z_STREAM_ERROR; |
|
} |
|
var wrap = 1; |
|
|
|
if (level === Z_DEFAULT_COMPRESSION) { |
|
level = 6; |
|
} |
|
|
|
if (windowBits < 0) { /* suppress zlib wrapper */ |
|
wrap = 0; |
|
windowBits = -windowBits; |
|
} |
|
|
|
else if (windowBits > 15) { |
|
wrap = 2; /* write gzip wrapper instead */ |
|
windowBits -= 16; |
|
} |
|
|
|
|
|
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || |
|
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || |
|
strategy < 0 || strategy > Z_FIXED) { |
|
return err(strm, Z_STREAM_ERROR); |
|
} |
|
|
|
|
|
if (windowBits === 8) { |
|
windowBits = 9; |
|
} |
|
/* until 256-byte window bug fixed */ |
|
|
|
var s = new DeflateState(); |
|
|
|
strm.state = s; |
|
s.strm = strm; |
|
|
|
s.wrap = wrap; |
|
s.gzhead = null; |
|
s.w_bits = windowBits; |
|
s.w_size = 1 << s.w_bits; |
|
s.w_mask = s.w_size - 1; |
|
|
|
s.hash_bits = memLevel + 7; |
|
s.hash_size = 1 << s.hash_bits; |
|
s.hash_mask = s.hash_size - 1; |
|
s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); |
|
|
|
s.window = new utils.Buf8(s.w_size * 2); |
|
s.head = new utils.Buf16(s.hash_size); |
|
s.prev = new utils.Buf16(s.w_size); |
|
|
|
// Don't need mem init magic for JS. |
|
//s.high_water = 0; /* nothing written to s->window yet */ |
|
|
|
s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ |
|
|
|
s.pending_buf_size = s.lit_bufsize * 4; |
|
s.pending_buf = new utils.Buf8(s.pending_buf_size); |
|
|
|
s.d_buf = s.lit_bufsize >> 1; |
|
s.l_buf = (1 + 2) * s.lit_bufsize; |
|
|
|
s.level = level; |
|
s.strategy = strategy; |
|
s.method = method; |
|
|
|
return deflateReset(strm); |
|
} |
|
|
|
function deflateInit(strm, level) { |
|
return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); |
|
} |
|
|
|
|
|
function deflate(strm, flush) { |
|
var old_flush, s; |
|
var beg, val; // for gzip header write only |
|
|
|
if (!strm || !strm.state || |
|
flush > Z_BLOCK || flush < 0) { |
|
return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; |
|
} |
|
|
|
s = strm.state; |
|
|
|
if (!strm.output || |
|
(!strm.input && strm.avail_in !== 0) || |
|
(s.status === FINISH_STATE && flush !== Z_FINISH)) { |
|
return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); |
|
} |
|
|
|
s.strm = strm; /* just in case */ |
|
old_flush = s.last_flush; |
|
s.last_flush = flush; |
|
|
|
/* Write the header */ |
|
if (s.status === INIT_STATE) { |
|
|
|
if (s.wrap === 2) { // GZIP header |
|
strm.adler = 0; //crc32(0L, Z_NULL, 0); |
|
put_byte(s, 31); |
|
put_byte(s, 139); |
|
put_byte(s, 8); |
|
if (!s.gzhead) { // s->gzhead == Z_NULL |
|
put_byte(s, 0); |
|
put_byte(s, 0); |
|
put_byte(s, 0); |
|
put_byte(s, 0); |
|
put_byte(s, 0); |
|
put_byte(s, s.level === 9 ? 2 : |
|
(s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? |
|
4 : 0)); |
|
put_byte(s, OS_CODE); |
|
s.status = BUSY_STATE; |
|
} |
|
else { |
|
put_byte(s, (s.gzhead.text ? 1 : 0) + |
|
(s.gzhead.hcrc ? 2 : 0) + |
|
(!s.gzhead.extra ? 0 : 4) + |
|
(!s.gzhead.name ? 0 : 8) + |
|
(!s.gzhead.comment ? 0 : 16) |
|
); |
|
put_byte(s, s.gzhead.time & 0xff); |
|
put_byte(s, (s.gzhead.time >> 8) & 0xff); |
|
put_byte(s, (s.gzhead.time >> 16) & 0xff); |
|
put_byte(s, (s.gzhead.time >> 24) & 0xff); |
|
put_byte(s, s.level === 9 ? 2 : |
|
(s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? |
|
4 : 0)); |
|
put_byte(s, s.gzhead.os & 0xff); |
|
if (s.gzhead.extra && s.gzhead.extra.length) { |
|
put_byte(s, s.gzhead.extra.length & 0xff); |
|
put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); |
|
} |
|
if (s.gzhead.hcrc) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); |
|
} |
|
s.gzindex = 0; |
|
s.status = EXTRA_STATE; |
|
} |
|
} |
|
else // DEFLATE header |
|
{ |
|
var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; |
|
var level_flags = -1; |
|
|
|
if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { |
|
level_flags = 0; |
|
} else if (s.level < 6) { |
|
level_flags = 1; |
|
} else if (s.level === 6) { |
|
level_flags = 2; |
|
} else { |
|
level_flags = 3; |
|
} |
|
header |= (level_flags << 6); |
|
if (s.strstart !== 0) { header |= PRESET_DICT; } |
|
header += 31 - (header % 31); |
|
|
|
s.status = BUSY_STATE; |
|
putShortMSB(s, header); |
|
|
|
/* Save the adler32 of the preset dictionary: */ |
|
if (s.strstart !== 0) { |
|
putShortMSB(s, strm.adler >>> 16); |
|
putShortMSB(s, strm.adler & 0xffff); |
|
} |
|
strm.adler = 1; // adler32(0L, Z_NULL, 0); |
|
} |
|
} |
|
|
|
//#ifdef GZIP |
|
if (s.status === EXTRA_STATE) { |
|
if (s.gzhead.extra/* != Z_NULL*/) { |
|
beg = s.pending; /* start of bytes to update crc */ |
|
|
|
while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { |
|
if (s.pending === s.pending_buf_size) { |
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
flush_pending(strm); |
|
beg = s.pending; |
|
if (s.pending === s.pending_buf_size) { |
|
break; |
|
} |
|
} |
|
put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); |
|
s.gzindex++; |
|
} |
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
if (s.gzindex === s.gzhead.extra.length) { |
|
s.gzindex = 0; |
|
s.status = NAME_STATE; |
|
} |
|
} |
|
else { |
|
s.status = NAME_STATE; |
|
} |
|
} |
|
if (s.status === NAME_STATE) { |
|
if (s.gzhead.name/* != Z_NULL*/) { |
|
beg = s.pending; /* start of bytes to update crc */ |
|
//int val; |
|
|
|
do { |
|
if (s.pending === s.pending_buf_size) { |
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
flush_pending(strm); |
|
beg = s.pending; |
|
if (s.pending === s.pending_buf_size) { |
|
val = 1; |
|
break; |
|
} |
|
} |
|
// JS specific: little magic to add zero terminator to end of string |
|
if (s.gzindex < s.gzhead.name.length) { |
|
val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; |
|
} else { |
|
val = 0; |
|
} |
|
put_byte(s, val); |
|
} while (val !== 0); |
|
|
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
if (val === 0) { |
|
s.gzindex = 0; |
|
s.status = COMMENT_STATE; |
|
} |
|
} |
|
else { |
|
s.status = COMMENT_STATE; |
|
} |
|
} |
|
if (s.status === COMMENT_STATE) { |
|
if (s.gzhead.comment/* != Z_NULL*/) { |
|
beg = s.pending; /* start of bytes to update crc */ |
|
//int val; |
|
|
|
do { |
|
if (s.pending === s.pending_buf_size) { |
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
flush_pending(strm); |
|
beg = s.pending; |
|
if (s.pending === s.pending_buf_size) { |
|
val = 1; |
|
break; |
|
} |
|
} |
|
// JS specific: little magic to add zero terminator to end of string |
|
if (s.gzindex < s.gzhead.comment.length) { |
|
val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; |
|
} else { |
|
val = 0; |
|
} |
|
put_byte(s, val); |
|
} while (val !== 0); |
|
|
|
if (s.gzhead.hcrc && s.pending > beg) { |
|
strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); |
|
} |
|
if (val === 0) { |
|
s.status = HCRC_STATE; |
|
} |
|
} |
|
else { |
|
s.status = HCRC_STATE; |
|
} |
|
} |
|
if (s.status === HCRC_STATE) { |
|
if (s.gzhead.hcrc) { |
|
if (s.pending + 2 > s.pending_buf_size) { |
|
flush_pending(strm); |
|
} |
|
if (s.pending + 2 <= s.pending_buf_size) { |
|
put_byte(s, strm.adler & 0xff); |
|
put_byte(s, (strm.adler >> 8) & 0xff); |
|
strm.adler = 0; //crc32(0L, Z_NULL, 0); |
|
s.status = BUSY_STATE; |
|
} |
|
} |
|
else { |
|
s.status = BUSY_STATE; |
|
} |
|
} |
|
//#endif |
|
|
|
/* Flush as much pending output as possible */ |
|
if (s.pending !== 0) { |
|
flush_pending(strm); |
|
if (strm.avail_out === 0) { |
|
/* Since avail_out is 0, deflate will be called again with |
|
* more output space, but possibly with both pending and |
|
* avail_in equal to zero. There won't be anything to do, |
|
* but this is not an error situation so make sure we |
|
* return OK instead of BUF_ERROR at next call of deflate: |
|
*/ |
|
s.last_flush = -1; |
|
return Z_OK; |
|
} |
|
|
|
/* Make sure there is something to do and avoid duplicate consecutive |
|
* flushes. For repeated and useless calls with Z_FINISH, we keep |
|
* returning Z_STREAM_END instead of Z_BUF_ERROR. |
|
*/ |
|
} else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && |
|
flush !== Z_FINISH) { |
|
return err(strm, Z_BUF_ERROR); |
|
} |
|
|
|
/* User must not provide more input after the first FINISH: */ |
|
if (s.status === FINISH_STATE && strm.avail_in !== 0) { |
|
return err(strm, Z_BUF_ERROR); |
|
} |
|
|
|
/* Start a new block or continue the current one. |
|
*/ |
|
if (strm.avail_in !== 0 || s.lookahead !== 0 || |
|
(flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { |
|
var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : |
|
(s.strategy === Z_RLE ? deflate_rle(s, flush) : |
|
configuration_table[s.level].func(s, flush)); |
|
|
|
if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { |
|
s.status = FINISH_STATE; |
|
} |
|
if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { |
|
if (strm.avail_out === 0) { |
|
s.last_flush = -1; |
|
/* avoid BUF_ERROR next call, see above */ |
|
} |
|
return Z_OK; |
|
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call |
|
* of deflate should use the same flush parameter to make sure |
|
* that the flush is complete. So we don't have to output an |
|
* empty block here, this will be done at next call. This also |
|
* ensures that for a very small output buffer, we emit at most |
|
* one empty block. |
|
*/ |
|
} |
|
if (bstate === BS_BLOCK_DONE) { |
|
if (flush === Z_PARTIAL_FLUSH) { |
|
trees._tr_align(s); |
|
} |
|
else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ |
|
|
|
trees._tr_stored_block(s, 0, 0, false); |
|
/* For a full flush, this empty block will be recognized |
|
* as a special marker by inflate_sync(). |
|
*/ |
|
if (flush === Z_FULL_FLUSH) { |
|
/*** CLEAR_HASH(s); ***/ /* forget history */ |
|
zero(s.head); // Fill with NIL (= 0); |
|
|
|
if (s.lookahead === 0) { |
|
s.strstart = 0; |
|
s.block_start = 0; |
|
s.insert = 0; |
|
} |
|
} |
|
} |
|
flush_pending(strm); |
|
if (strm.avail_out === 0) { |
|
s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ |
|
return Z_OK; |
|
} |
|
} |
|
} |
|
//Assert(strm->avail_out > 0, "bug2"); |
|
//if (strm.avail_out <= 0) { throw new Error("bug2");} |
|
|
|
if (flush !== Z_FINISH) { return Z_OK; } |
|
if (s.wrap <= 0) { return Z_STREAM_END; } |
|
|
|
/* Write the trailer */ |
|
if (s.wrap === 2) { |
|
put_byte(s, strm.adler & 0xff); |
|
put_byte(s, (strm.adler >> 8) & 0xff); |
|
put_byte(s, (strm.adler >> 16) & 0xff); |
|
put_byte(s, (strm.adler >> 24) & 0xff); |
|
put_byte(s, strm.total_in & 0xff); |
|
put_byte(s, (strm.total_in >> 8) & 0xff); |
|
put_byte(s, (strm.total_in >> 16) & 0xff); |
|
put_byte(s, (strm.total_in >> 24) & 0xff); |
|
} |
|
else |
|
{ |
|
putShortMSB(s, strm.adler >>> 16); |
|
putShortMSB(s, strm.adler & 0xffff); |
|
} |
|
|
|
flush_pending(strm); |
|
/* If avail_out is zero, the application will call deflate again |
|
* to flush the rest. |
|
*/ |
|
if (s.wrap > 0) { s.wrap = -s.wrap; } |
|
/* write the trailer only once! */ |
|
return s.pending !== 0 ? Z_OK : Z_STREAM_END; |
|
} |
|
|
|
function deflateEnd(strm) { |
|
var status; |
|
|
|
if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { |
|
return Z_STREAM_ERROR; |
|
} |
|
|
|
status = strm.state.status; |
|
if (status !== INIT_STATE && |
|
status !== EXTRA_STATE && |
|
status !== NAME_STATE && |
|
status !== COMMENT_STATE && |
|
status !== HCRC_STATE && |
|
status !== BUSY_STATE && |
|
status !== FINISH_STATE |
|
) { |
|
return err(strm, Z_STREAM_ERROR); |
|
} |
|
|
|
strm.state = null; |
|
|
|
return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; |
|
} |
|
|
|
/* ========================================================================= |
|
* Copy the source state to the destination state |
|
*/ |
|
//function deflateCopy(dest, source) { |
|
// |
|
//} |
|
|
|
exports.deflateInit = deflateInit; |
|
exports.deflateInit2 = deflateInit2; |
|
exports.deflateReset = deflateReset; |
|
exports.deflateResetKeep = deflateResetKeep; |
|
exports.deflateSetHeader = deflateSetHeader; |
|
exports.deflate = deflate; |
|
exports.deflateEnd = deflateEnd; |
|
exports.deflateInfo = 'pako deflate (from Nodeca project)'; |
|
|
|
/* Not implemented |
|
exports.deflateBound = deflateBound; |
|
exports.deflateCopy = deflateCopy; |
|
exports.deflateSetDictionary = deflateSetDictionary; |
|
exports.deflateParams = deflateParams; |
|
exports.deflatePending = deflatePending; |
|
exports.deflatePrime = deflatePrime; |
|
exports.deflateTune = deflateTune; |
|
*/ |
|
|
|
},{"../utils/common":16,"./adler32":17,"./crc32":19,"./messages":24,"./trees":25}],21:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
// See state defs from inflate.js |
|
var BAD = 30; /* got a data error -- remain here until reset */ |
|
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ |
|
|
|
/* |
|
Decode literal, length, and distance codes and write out the resulting |
|
literal and match bytes until either not enough input or output is |
|
available, an end-of-block is encountered, or a data error is encountered. |
|
When large enough input and output buffers are supplied to inflate(), for |
|
example, a 16K input buffer and a 64K output buffer, more than 95% of the |
|
inflate execution time is spent in this routine. |
|
|
|
Entry assumptions: |
|
|
|
state.mode === LEN |
|
strm.avail_in >= 6 |
|
strm.avail_out >= 258 |
|
start >= strm.avail_out |
|
state.bits < 8 |
|
|
|
On return, state.mode is one of: |
|
|
|
LEN -- ran out of enough output space or enough available input |
|
TYPE -- reached end of block code, inflate() to interpret next block |
|
BAD -- error in block data |
|
|
|
Notes: |
|
|
|
- The maximum input bits used by a length/distance pair is 15 bits for the |
|
length code, 5 bits for the length extra, 15 bits for the distance code, |
|
and 13 bits for the distance extra. This totals 48 bits, or six bytes. |
|
Therefore if strm.avail_in >= 6, then there is enough input to avoid |
|
checking for available input while decoding. |
|
|
|
- The maximum bytes that a single length/distance pair can output is 258 |
|
bytes, which is the maximum length that can be coded. inflate_fast() |
|
requires strm.avail_out >= 258 for each loop to avoid checking for |
|
output space. |
|
*/ |
|
module.exports = function inflate_fast(strm, start) { |
|
var state; |
|
var _in; /* local strm.input */ |
|
var last; /* have enough input while in < last */ |
|
var _out; /* local strm.output */ |
|
var beg; /* inflate()'s initial strm.output */ |
|
var end; /* while out < end, enough space available */ |
|
//#ifdef INFLATE_STRICT |
|
var dmax; /* maximum distance from zlib header */ |
|
//#endif |
|
var wsize; /* window size or zero if not using window */ |
|
var whave; /* valid bytes in the window */ |
|
var wnext; /* window write index */ |
|
// Use `s_window` instead `window`, avoid conflict with instrumentation tools |
|
var s_window; /* allocated sliding window, if wsize != 0 */ |
|
var hold; /* local strm.hold */ |
|
var bits; /* local strm.bits */ |
|
var lcode; /* local strm.lencode */ |
|
var dcode; /* local strm.distcode */ |
|
var lmask; /* mask for first level of length codes */ |
|
var dmask; /* mask for first level of distance codes */ |
|
var here; /* retrieved table entry */ |
|
var op; /* code bits, operation, extra bits, or */ |
|
/* window position, window bytes to copy */ |
|
var len; /* match length, unused bytes */ |
|
var dist; /* match distance */ |
|
var from; /* where to copy match from */ |
|
var from_source; |
|
|
|
|
|
var input, output; // JS specific, because we have no pointers |
|
|
|
/* copy state to local variables */ |
|
state = strm.state; |
|
//here = state.here; |
|
_in = strm.next_in; |
|
input = strm.input; |
|
last = _in + (strm.avail_in - 5); |
|
_out = strm.next_out; |
|
output = strm.output; |
|
beg = _out - (start - strm.avail_out); |
|
end = _out + (strm.avail_out - 257); |
|
//#ifdef INFLATE_STRICT |
|
dmax = state.dmax; |
|
//#endif |
|
wsize = state.wsize; |
|
whave = state.whave; |
|
wnext = state.wnext; |
|
s_window = state.window; |
|
hold = state.hold; |
|
bits = state.bits; |
|
lcode = state.lencode; |
|
dcode = state.distcode; |
|
lmask = (1 << state.lenbits) - 1; |
|
dmask = (1 << state.distbits) - 1; |
|
|
|
|
|
/* decode literals and length/distances until end-of-block or not enough |
|
input data or output space */ |
|
|
|
top: |
|
do { |
|
if (bits < 15) { |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
} |
|
|
|
here = lcode[hold & lmask]; |
|
|
|
dolen: |
|
for (;;) { // Goto emulation |
|
op = here >>> 24/*here.bits*/; |
|
hold >>>= op; |
|
bits -= op; |
|
op = (here >>> 16) & 0xff/*here.op*/; |
|
if (op === 0) { /* literal */ |
|
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
|
// "inflate: literal '%c'\n" : |
|
// "inflate: literal 0x%02x\n", here.val)); |
|
output[_out++] = here & 0xffff/*here.val*/; |
|
} |
|
else if (op & 16) { /* length base */ |
|
len = here & 0xffff/*here.val*/; |
|
op &= 15; /* number of extra bits */ |
|
if (op) { |
|
if (bits < op) { |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
} |
|
len += hold & ((1 << op) - 1); |
|
hold >>>= op; |
|
bits -= op; |
|
} |
|
//Tracevv((stderr, "inflate: length %u\n", len)); |
|
if (bits < 15) { |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
} |
|
here = dcode[hold & dmask]; |
|
|
|
dodist: |
|
for (;;) { // goto emulation |
|
op = here >>> 24/*here.bits*/; |
|
hold >>>= op; |
|
bits -= op; |
|
op = (here >>> 16) & 0xff/*here.op*/; |
|
|
|
if (op & 16) { /* distance base */ |
|
dist = here & 0xffff/*here.val*/; |
|
op &= 15; /* number of extra bits */ |
|
if (bits < op) { |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
if (bits < op) { |
|
hold += input[_in++] << bits; |
|
bits += 8; |
|
} |
|
} |
|
dist += hold & ((1 << op) - 1); |
|
//#ifdef INFLATE_STRICT |
|
if (dist > dmax) { |
|
strm.msg = 'invalid distance too far back'; |
|
state.mode = BAD; |
|
break top; |
|
} |
|
//#endif |
|
hold >>>= op; |
|
bits -= op; |
|
//Tracevv((stderr, "inflate: distance %u\n", dist)); |
|
op = _out - beg; /* max distance in output */ |
|
if (dist > op) { /* see if copy from window */ |
|
op = dist - op; /* distance back in window */ |
|
if (op > whave) { |
|
if (state.sane) { |
|
strm.msg = 'invalid distance too far back'; |
|
state.mode = BAD; |
|
break top; |
|
} |
|
|
|
// (!) This block is disabled in zlib defailts, |
|
// don't enable it for binary compatibility |
|
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR |
|
// if (len <= op - whave) { |
|
// do { |
|
// output[_out++] = 0; |
|
// } while (--len); |
|
// continue top; |
|
// } |
|
// len -= op - whave; |
|
// do { |
|
// output[_out++] = 0; |
|
// } while (--op > whave); |
|
// if (op === 0) { |
|
// from = _out - dist; |
|
// do { |
|
// output[_out++] = output[from++]; |
|
// } while (--len); |
|
// continue top; |
|
// } |
|
//#endif |
|
} |
|
from = 0; // window index |
|
from_source = s_window; |
|
if (wnext === 0) { /* very common case */ |
|
from += wsize - op; |
|
if (op < len) { /* some from window */ |
|
len -= op; |
|
do { |
|
output[_out++] = s_window[from++]; |
|
} while (--op); |
|
from = _out - dist; /* rest from output */ |
|
from_source = output; |
|
} |
|
} |
|
else if (wnext < op) { /* wrap around window */ |
|
from += wsize + wnext - op; |
|
op -= wnext; |
|
if (op < len) { /* some from end of window */ |
|
len -= op; |
|
do { |
|
output[_out++] = s_window[from++]; |
|
} while (--op); |
|
from = 0; |
|
if (wnext < len) { /* some from start of window */ |
|
op = wnext; |
|
len -= op; |
|
do { |
|
output[_out++] = s_window[from++]; |
|
} while (--op); |
|
from = _out - dist; /* rest from output */ |
|
from_source = output; |
|
} |
|
} |
|
} |
|
else { /* contiguous in window */ |
|
from += wnext - op; |
|
if (op < len) { /* some from window */ |
|
len -= op; |
|
do { |
|
output[_out++] = s_window[from++]; |
|
} while (--op); |
|
from = _out - dist; /* rest from output */ |
|
from_source = output; |
|
} |
|
} |
|
while (len > 2) { |
|
output[_out++] = from_source[from++]; |
|
output[_out++] = from_source[from++]; |
|
output[_out++] = from_source[from++]; |
|
len -= 3; |
|
} |
|
if (len) { |
|
output[_out++] = from_source[from++]; |
|
if (len > 1) { |
|
output[_out++] = from_source[from++]; |
|
} |
|
} |
|
} |
|
else { |
|
from = _out - dist; /* copy direct from output */ |
|
do { /* minimum length is three */ |
|
output[_out++] = output[from++]; |
|
output[_out++] = output[from++]; |
|
output[_out++] = output[from++]; |
|
len -= 3; |
|
} while (len > 2); |
|
if (len) { |
|
output[_out++] = output[from++]; |
|
if (len > 1) { |
|
output[_out++] = output[from++]; |
|
} |
|
} |
|
} |
|
} |
|
else if ((op & 64) === 0) { /* 2nd level distance code */ |
|
here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; |
|
continue dodist; |
|
} |
|
else { |
|
strm.msg = 'invalid distance code'; |
|
state.mode = BAD; |
|
break top; |
|
} |
|
|
|
break; // need to emulate goto via "continue" |
|
} |
|
} |
|
else if ((op & 64) === 0) { /* 2nd level length code */ |
|
here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; |
|
continue dolen; |
|
} |
|
else if (op & 32) { /* end-of-block */ |
|
//Tracevv((stderr, "inflate: end of block\n")); |
|
state.mode = TYPE; |
|
break top; |
|
} |
|
else { |
|
strm.msg = 'invalid literal/length code'; |
|
state.mode = BAD; |
|
break top; |
|
} |
|
|
|
break; // need to emulate goto via "continue" |
|
} |
|
} while (_in < last && _out < end); |
|
|
|
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */ |
|
len = bits >> 3; |
|
_in -= len; |
|
bits -= len << 3; |
|
hold &= (1 << bits) - 1; |
|
|
|
/* update state and return */ |
|
strm.next_in = _in; |
|
strm.next_out = _out; |
|
strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); |
|
strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); |
|
state.hold = hold; |
|
state.bits = bits; |
|
return; |
|
}; |
|
|
|
},{}],22:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
|
|
var utils = require('../utils/common'); |
|
var adler32 = require('./adler32'); |
|
var crc32 = require('./crc32'); |
|
var inflate_fast = require('./inffast'); |
|
var inflate_table = require('./inftrees'); |
|
|
|
var CODES = 0; |
|
var LENS = 1; |
|
var DISTS = 2; |
|
|
|
/* Public constants ==========================================================*/ |
|
/* ===========================================================================*/ |
|
|
|
|
|
/* Allowed flush values; see deflate() and inflate() below for details */ |
|
//var Z_NO_FLUSH = 0; |
|
//var Z_PARTIAL_FLUSH = 1; |
|
//var Z_SYNC_FLUSH = 2; |
|
//var Z_FULL_FLUSH = 3; |
|
var Z_FINISH = 4; |
|
var Z_BLOCK = 5; |
|
var Z_TREES = 6; |
|
|
|
|
|
/* Return codes for the compression/decompression functions. Negative values |
|
* are errors, positive values are used for special but normal events. |
|
*/ |
|
var Z_OK = 0; |
|
var Z_STREAM_END = 1; |
|
var Z_NEED_DICT = 2; |
|
//var Z_ERRNO = -1; |
|
var Z_STREAM_ERROR = -2; |
|
var Z_DATA_ERROR = -3; |
|
var Z_MEM_ERROR = -4; |
|
var Z_BUF_ERROR = -5; |
|
//var Z_VERSION_ERROR = -6; |
|
|
|
/* The deflate compression method */ |
|
var Z_DEFLATED = 8; |
|
|
|
|
|
/* STATES ====================================================================*/ |
|
/* ===========================================================================*/ |
|
|
|
|
|
var HEAD = 1; /* i: waiting for magic header */ |
|
var FLAGS = 2; /* i: waiting for method and flags (gzip) */ |
|
var TIME = 3; /* i: waiting for modification time (gzip) */ |
|
var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ |
|
var EXLEN = 5; /* i: waiting for extra length (gzip) */ |
|
var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ |
|
var NAME = 7; /* i: waiting for end of file name (gzip) */ |
|
var COMMENT = 8; /* i: waiting for end of comment (gzip) */ |
|
var HCRC = 9; /* i: waiting for header crc (gzip) */ |
|
var DICTID = 10; /* i: waiting for dictionary check value */ |
|
var DICT = 11; /* waiting for inflateSetDictionary() call */ |
|
var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ |
|
var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ |
|
var STORED = 14; /* i: waiting for stored size (length and complement) */ |
|
var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ |
|
var COPY = 16; /* i/o: waiting for input or output to copy stored block */ |
|
var TABLE = 17; /* i: waiting for dynamic block table lengths */ |
|
var LENLENS = 18; /* i: waiting for code length code lengths */ |
|
var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ |
|
var LEN_ = 20; /* i: same as LEN below, but only first time in */ |
|
var LEN = 21; /* i: waiting for length/lit/eob code */ |
|
var LENEXT = 22; /* i: waiting for length extra bits */ |
|
var DIST = 23; /* i: waiting for distance code */ |
|
var DISTEXT = 24; /* i: waiting for distance extra bits */ |
|
var MATCH = 25; /* o: waiting for output space to copy string */ |
|
var LIT = 26; /* o: waiting for output space to write literal */ |
|
var CHECK = 27; /* i: waiting for 32-bit check value */ |
|
var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ |
|
var DONE = 29; /* finished check, done -- remain here until reset */ |
|
var BAD = 30; /* got a data error -- remain here until reset */ |
|
var MEM = 31; /* got an inflate() memory error -- remain here until reset */ |
|
var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ |
|
|
|
/* ===========================================================================*/ |
|
|
|
|
|
|
|
var ENOUGH_LENS = 852; |
|
var ENOUGH_DISTS = 592; |
|
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); |
|
|
|
var MAX_WBITS = 15; |
|
/* 32K LZ77 window */ |
|
var DEF_WBITS = MAX_WBITS; |
|
|
|
|
|
function ZSWAP32(q) { |
|
return (((q >>> 24) & 0xff) + |
|
((q >>> 8) & 0xff00) + |
|
((q & 0xff00) << 8) + |
|
((q & 0xff) << 24)); |
|
} |
|
|
|
|
|
function InflateState() { |
|
this.mode = 0; /* current inflate mode */ |
|
this.last = false; /* true if processing last block */ |
|
this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ |
|
this.havedict = false; /* true if dictionary provided */ |
|
this.flags = 0; /* gzip header method and flags (0 if zlib) */ |
|
this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ |
|
this.check = 0; /* protected copy of check value */ |
|
this.total = 0; /* protected copy of output count */ |
|
// TODO: may be {} |
|
this.head = null; /* where to save gzip header information */ |
|
|
|
/* sliding window */ |
|
this.wbits = 0; /* log base 2 of requested window size */ |
|
this.wsize = 0; /* window size or zero if not using window */ |
|
this.whave = 0; /* valid bytes in the window */ |
|
this.wnext = 0; /* window write index */ |
|
this.window = null; /* allocated sliding window, if needed */ |
|
|
|
/* bit accumulator */ |
|
this.hold = 0; /* input bit accumulator */ |
|
this.bits = 0; /* number of bits in "in" */ |
|
|
|
/* for string and stored block copying */ |
|
this.length = 0; /* literal or length of data to copy */ |
|
this.offset = 0; /* distance back to copy string from */ |
|
|
|
/* for table and code decoding */ |
|
this.extra = 0; /* extra bits needed */ |
|
|
|
/* fixed and dynamic code tables */ |
|
this.lencode = null; /* starting table for length/literal codes */ |
|
this.distcode = null; /* starting table for distance codes */ |
|
this.lenbits = 0; /* index bits for lencode */ |
|
this.distbits = 0; /* index bits for distcode */ |
|
|
|
/* dynamic table building */ |
|
this.ncode = 0; /* number of code length code lengths */ |
|
this.nlen = 0; /* number of length code lengths */ |
|
this.ndist = 0; /* number of distance code lengths */ |
|
this.have = 0; /* number of code lengths in lens[] */ |
|
this.next = null; /* next available space in codes[] */ |
|
|
|
this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ |
|
this.work = new utils.Buf16(288); /* work area for code table building */ |
|
|
|
/* |
|
because we don't have pointers in js, we use lencode and distcode directly |
|
as buffers so we don't need codes |
|
*/ |
|
//this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ |
|
this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ |
|
this.distdyn = null; /* dynamic table for distance codes (JS specific) */ |
|
this.sane = 0; /* if false, allow invalid distance too far */ |
|
this.back = 0; /* bits back of last unprocessed length/lit */ |
|
this.was = 0; /* initial length of match */ |
|
} |
|
|
|
function inflateResetKeep(strm) { |
|
var state; |
|
|
|
if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
|
state = strm.state; |
|
strm.total_in = strm.total_out = state.total = 0; |
|
strm.msg = ''; /*Z_NULL*/ |
|
if (state.wrap) { /* to support ill-conceived Java test suite */ |
|
strm.adler = state.wrap & 1; |
|
} |
|
state.mode = HEAD; |
|
state.last = 0; |
|
state.havedict = 0; |
|
state.dmax = 32768; |
|
state.head = null/*Z_NULL*/; |
|
state.hold = 0; |
|
state.bits = 0; |
|
//state.lencode = state.distcode = state.next = state.codes; |
|
state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); |
|
state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); |
|
|
|
state.sane = 1; |
|
state.back = -1; |
|
//Tracev((stderr, "inflate: reset\n")); |
|
return Z_OK; |
|
} |
|
|
|
function inflateReset(strm) { |
|
var state; |
|
|
|
if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
|
state = strm.state; |
|
state.wsize = 0; |
|
state.whave = 0; |
|
state.wnext = 0; |
|
return inflateResetKeep(strm); |
|
|
|
} |
|
|
|
function inflateReset2(strm, windowBits) { |
|
var wrap; |
|
var state; |
|
|
|
/* get the state */ |
|
if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
|
state = strm.state; |
|
|
|
/* extract wrap request from windowBits parameter */ |
|
if (windowBits < 0) { |
|
wrap = 0; |
|
windowBits = -windowBits; |
|
} |
|
else { |
|
wrap = (windowBits >> 4) + 1; |
|
if (windowBits < 48) { |
|
windowBits &= 15; |
|
} |
|
} |
|
|
|
/* set number of window bits, free window if different */ |
|
if (windowBits && (windowBits < 8 || windowBits > 15)) { |
|
return Z_STREAM_ERROR; |
|
} |
|
if (state.window !== null && state.wbits !== windowBits) { |
|
state.window = null; |
|
} |
|
|
|
/* update state and reset the rest of it */ |
|
state.wrap = wrap; |
|
state.wbits = windowBits; |
|
return inflateReset(strm); |
|
} |
|
|
|
function inflateInit2(strm, windowBits) { |
|
var ret; |
|
var state; |
|
|
|
if (!strm) { return Z_STREAM_ERROR; } |
|
//strm.msg = Z_NULL; /* in case we return an error */ |
|
|
|
state = new InflateState(); |
|
|
|
//if (state === Z_NULL) return Z_MEM_ERROR; |
|
//Tracev((stderr, "inflate: allocated\n")); |
|
strm.state = state; |
|
state.window = null/*Z_NULL*/; |
|
ret = inflateReset2(strm, windowBits); |
|
if (ret !== Z_OK) { |
|
strm.state = null/*Z_NULL*/; |
|
} |
|
return ret; |
|
} |
|
|
|
function inflateInit(strm) { |
|
return inflateInit2(strm, DEF_WBITS); |
|
} |
|
|
|
|
|
/* |
|
Return state with length and distance decoding tables and index sizes set to |
|
fixed code decoding. Normally this returns fixed tables from inffixed.h. |
|
If BUILDFIXED is defined, then instead this routine builds the tables the |
|
first time it's called, and returns those tables the first time and |
|
thereafter. This reduces the size of the code by about 2K bytes, in |
|
exchange for a little execution time. However, BUILDFIXED should not be |
|
used for threaded applications, since the rewriting of the tables and virgin |
|
may not be thread-safe. |
|
*/ |
|
var virgin = true; |
|
|
|
var lenfix, distfix; // We have no pointers in JS, so keep tables separate |
|
|
|
function fixedtables(state) { |
|
/* build fixed huffman tables if first call (may not be thread safe) */ |
|
if (virgin) { |
|
var sym; |
|
|
|
lenfix = new utils.Buf32(512); |
|
distfix = new utils.Buf32(32); |
|
|
|
/* literal/length table */ |
|
sym = 0; |
|
while (sym < 144) { state.lens[sym++] = 8; } |
|
while (sym < 256) { state.lens[sym++] = 9; } |
|
while (sym < 280) { state.lens[sym++] = 7; } |
|
while (sym < 288) { state.lens[sym++] = 8; } |
|
|
|
inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); |
|
|
|
/* distance table */ |
|
sym = 0; |
|
while (sym < 32) { state.lens[sym++] = 5; } |
|
|
|
inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); |
|
|
|
/* do this just once */ |
|
virgin = false; |
|
} |
|
|
|
state.lencode = lenfix; |
|
state.lenbits = 9; |
|
state.distcode = distfix; |
|
state.distbits = 5; |
|
} |
|
|
|
|
|
/* |
|
Update the window with the last wsize (normally 32K) bytes written before |
|
returning. If window does not exist yet, create it. This is only called |
|
when a window is already in use, or when output has been written during this |
|
inflate call, but the end of the deflate stream has not been reached yet. |
|
It is also called to create a window for dictionary data when a dictionary |
|
is loaded. |
|
|
|
Providing output buffers larger than 32K to inflate() should provide a speed |
|
advantage, since only the last 32K of output is copied to the sliding window |
|
upon return from inflate(), and since all distances after the first 32K of |
|
output will fall in the output data, making match copies simpler and faster. |
|
The advantage may be dependent on the size of the processor's data caches. |
|
*/ |
|
function updatewindow(strm, src, end, copy) { |
|
var dist; |
|
var state = strm.state; |
|
|
|
/* if it hasn't been done already, allocate space for the window */ |
|
if (state.window === null) { |
|
state.wsize = 1 << state.wbits; |
|
state.wnext = 0; |
|
state.whave = 0; |
|
|
|
state.window = new utils.Buf8(state.wsize); |
|
} |
|
|
|
/* copy state->wsize or less output bytes into the circular window */ |
|
if (copy >= state.wsize) { |
|
utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); |
|
state.wnext = 0; |
|
state.whave = state.wsize; |
|
} |
|
else { |
|
dist = state.wsize - state.wnext; |
|
if (dist > copy) { |
|
dist = copy; |
|
} |
|
//zmemcpy(state->window + state->wnext, end - copy, dist); |
|
utils.arraySet(state.window,src, end - copy, dist, state.wnext); |
|
copy -= dist; |
|
if (copy) { |
|
//zmemcpy(state->window, end - copy, copy); |
|
utils.arraySet(state.window,src, end - copy, copy, 0); |
|
state.wnext = copy; |
|
state.whave = state.wsize; |
|
} |
|
else { |
|
state.wnext += dist; |
|
if (state.wnext === state.wsize) { state.wnext = 0; } |
|
if (state.whave < state.wsize) { state.whave += dist; } |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
function inflate(strm, flush) { |
|
var state; |
|
var input, output; // input/output buffers |
|
var next; /* next input INDEX */ |
|
var put; /* next output INDEX */ |
|
var have, left; /* available input and output */ |
|
var hold; /* bit buffer */ |
|
var bits; /* bits in bit buffer */ |
|
var _in, _out; /* save starting available input and output */ |
|
var copy; /* number of stored or match bytes to copy */ |
|
var from; /* where to copy match bytes from */ |
|
var from_source; |
|
var here = 0; /* current decoding table entry */ |
|
var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) |
|
//var last; /* parent table entry */ |
|
var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) |
|
var len; /* length to copy for repeats, bits to drop */ |
|
var ret; /* return code */ |
|
var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ |
|
var opts; |
|
|
|
var n; // temporary var for NEED_BITS |
|
|
|
var order = /* permutation of code lengths */ |
|
[16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; |
|
|
|
|
|
if (!strm || !strm.state || !strm.output || |
|
(!strm.input && strm.avail_in !== 0)) { |
|
return Z_STREAM_ERROR; |
|
} |
|
|
|
state = strm.state; |
|
if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ |
|
|
|
|
|
//--- LOAD() --- |
|
put = strm.next_out; |
|
output = strm.output; |
|
left = strm.avail_out; |
|
next = strm.next_in; |
|
input = strm.input; |
|
have = strm.avail_in; |
|
hold = state.hold; |
|
bits = state.bits; |
|
//--- |
|
|
|
_in = have; |
|
_out = left; |
|
ret = Z_OK; |
|
|
|
inf_leave: // goto emulation |
|
for (;;) { |
|
switch (state.mode) { |
|
case HEAD: |
|
if (state.wrap === 0) { |
|
state.mode = TYPEDO; |
|
break; |
|
} |
|
//=== NEEDBITS(16); |
|
while (bits < 16) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ |
|
state.check = 0/*crc32(0L, Z_NULL, 0)*/; |
|
//=== CRC2(state.check, hold); |
|
hbuf[0] = hold & 0xff; |
|
hbuf[1] = (hold >>> 8) & 0xff; |
|
state.check = crc32(state.check, hbuf, 2, 0); |
|
//===// |
|
|
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = FLAGS; |
|
break; |
|
} |
|
state.flags = 0; /* expect zlib header */ |
|
if (state.head) { |
|
state.head.done = false; |
|
} |
|
if (!(state.wrap & 1) || /* check if zlib header allowed */ |
|
(((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { |
|
strm.msg = 'incorrect header check'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { |
|
strm.msg = 'unknown compression method'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//--- DROPBITS(4) ---// |
|
hold >>>= 4; |
|
bits -= 4; |
|
//---// |
|
len = (hold & 0x0f)/*BITS(4)*/ + 8; |
|
if (state.wbits === 0) { |
|
state.wbits = len; |
|
} |
|
else if (len > state.wbits) { |
|
strm.msg = 'invalid window size'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
state.dmax = 1 << len; |
|
//Tracev((stderr, "inflate: zlib header ok\n")); |
|
strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; |
|
state.mode = hold & 0x200 ? DICTID : TYPE; |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
break; |
|
case FLAGS: |
|
//=== NEEDBITS(16); */ |
|
while (bits < 16) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.flags = hold; |
|
if ((state.flags & 0xff) !== Z_DEFLATED) { |
|
strm.msg = 'unknown compression method'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
if (state.flags & 0xe000) { |
|
strm.msg = 'unknown header flags set'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
if (state.head) { |
|
state.head.text = ((hold >> 8) & 1); |
|
} |
|
if (state.flags & 0x0200) { |
|
//=== CRC2(state.check, hold); |
|
hbuf[0] = hold & 0xff; |
|
hbuf[1] = (hold >>> 8) & 0xff; |
|
state.check = crc32(state.check, hbuf, 2, 0); |
|
//===// |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = TIME; |
|
/* falls through */ |
|
case TIME: |
|
//=== NEEDBITS(32); */ |
|
while (bits < 32) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if (state.head) { |
|
state.head.time = hold; |
|
} |
|
if (state.flags & 0x0200) { |
|
//=== CRC4(state.check, hold) |
|
hbuf[0] = hold & 0xff; |
|
hbuf[1] = (hold >>> 8) & 0xff; |
|
hbuf[2] = (hold >>> 16) & 0xff; |
|
hbuf[3] = (hold >>> 24) & 0xff; |
|
state.check = crc32(state.check, hbuf, 4, 0); |
|
//=== |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = OS; |
|
/* falls through */ |
|
case OS: |
|
//=== NEEDBITS(16); */ |
|
while (bits < 16) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if (state.head) { |
|
state.head.xflags = (hold & 0xff); |
|
state.head.os = (hold >> 8); |
|
} |
|
if (state.flags & 0x0200) { |
|
//=== CRC2(state.check, hold); |
|
hbuf[0] = hold & 0xff; |
|
hbuf[1] = (hold >>> 8) & 0xff; |
|
state.check = crc32(state.check, hbuf, 2, 0); |
|
//===// |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = EXLEN; |
|
/* falls through */ |
|
case EXLEN: |
|
if (state.flags & 0x0400) { |
|
//=== NEEDBITS(16); */ |
|
while (bits < 16) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.length = hold; |
|
if (state.head) { |
|
state.head.extra_len = hold; |
|
} |
|
if (state.flags & 0x0200) { |
|
//=== CRC2(state.check, hold); |
|
hbuf[0] = hold & 0xff; |
|
hbuf[1] = (hold >>> 8) & 0xff; |
|
state.check = crc32(state.check, hbuf, 2, 0); |
|
//===// |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
} |
|
else if (state.head) { |
|
state.head.extra = null/*Z_NULL*/; |
|
} |
|
state.mode = EXTRA; |
|
/* falls through */ |
|
case EXTRA: |
|
if (state.flags & 0x0400) { |
|
copy = state.length; |
|
if (copy > have) { copy = have; } |
|
if (copy) { |
|
if (state.head) { |
|
len = state.head.extra_len - state.length; |
|
if (!state.head.extra) { |
|
// Use untyped array for more conveniend processing later |
|
state.head.extra = new Array(state.head.extra_len); |
|
} |
|
utils.arraySet( |
|
state.head.extra, |
|
input, |
|
next, |
|
// extra field is limited to 65536 bytes |
|
// - no need for additional size check |
|
copy, |
|
/*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ |
|
len |
|
); |
|
//zmemcpy(state.head.extra + len, next, |
|
// len + copy > state.head.extra_max ? |
|
// state.head.extra_max - len : copy); |
|
} |
|
if (state.flags & 0x0200) { |
|
state.check = crc32(state.check, input, copy, next); |
|
} |
|
have -= copy; |
|
next += copy; |
|
state.length -= copy; |
|
} |
|
if (state.length) { break inf_leave; } |
|
} |
|
state.length = 0; |
|
state.mode = NAME; |
|
/* falls through */ |
|
case NAME: |
|
if (state.flags & 0x0800) { |
|
if (have === 0) { break inf_leave; } |
|
copy = 0; |
|
do { |
|
// TODO: 2 or 1 bytes? |
|
len = input[next + copy++]; |
|
/* use constant limit because in js we should not preallocate memory */ |
|
if (state.head && len && |
|
(state.length < 65536 /*state.head.name_max*/)) { |
|
state.head.name += String.fromCharCode(len); |
|
} |
|
} while (len && copy < have); |
|
|
|
if (state.flags & 0x0200) { |
|
state.check = crc32(state.check, input, copy, next); |
|
} |
|
have -= copy; |
|
next += copy; |
|
if (len) { break inf_leave; } |
|
} |
|
else if (state.head) { |
|
state.head.name = null; |
|
} |
|
state.length = 0; |
|
state.mode = COMMENT; |
|
/* falls through */ |
|
case COMMENT: |
|
if (state.flags & 0x1000) { |
|
if (have === 0) { break inf_leave; } |
|
copy = 0; |
|
do { |
|
len = input[next + copy++]; |
|
/* use constant limit because in js we should not preallocate memory */ |
|
if (state.head && len && |
|
(state.length < 65536 /*state.head.comm_max*/)) { |
|
state.head.comment += String.fromCharCode(len); |
|
} |
|
} while (len && copy < have); |
|
if (state.flags & 0x0200) { |
|
state.check = crc32(state.check, input, copy, next); |
|
} |
|
have -= copy; |
|
next += copy; |
|
if (len) { break inf_leave; } |
|
} |
|
else if (state.head) { |
|
state.head.comment = null; |
|
} |
|
state.mode = HCRC; |
|
/* falls through */ |
|
case HCRC: |
|
if (state.flags & 0x0200) { |
|
//=== NEEDBITS(16); */ |
|
while (bits < 16) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if (hold !== (state.check & 0xffff)) { |
|
strm.msg = 'header crc mismatch'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
} |
|
if (state.head) { |
|
state.head.hcrc = ((state.flags >> 9) & 1); |
|
state.head.done = true; |
|
} |
|
strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; |
|
state.mode = TYPE; |
|
break; |
|
case DICTID: |
|
//=== NEEDBITS(32); */ |
|
while (bits < 32) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
strm.adler = state.check = ZSWAP32(hold); |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = DICT; |
|
/* falls through */ |
|
case DICT: |
|
if (state.havedict === 0) { |
|
//--- RESTORE() --- |
|
strm.next_out = put; |
|
strm.avail_out = left; |
|
strm.next_in = next; |
|
strm.avail_in = have; |
|
state.hold = hold; |
|
state.bits = bits; |
|
//--- |
|
return Z_NEED_DICT; |
|
} |
|
strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; |
|
state.mode = TYPE; |
|
/* falls through */ |
|
case TYPE: |
|
if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } |
|
/* falls through */ |
|
case TYPEDO: |
|
if (state.last) { |
|
//--- BYTEBITS() ---// |
|
hold >>>= bits & 7; |
|
bits -= bits & 7; |
|
//---// |
|
state.mode = CHECK; |
|
break; |
|
} |
|
//=== NEEDBITS(3); */ |
|
while (bits < 3) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.last = (hold & 0x01)/*BITS(1)*/; |
|
//--- DROPBITS(1) ---// |
|
hold >>>= 1; |
|
bits -= 1; |
|
//---// |
|
|
|
switch ((hold & 0x03)/*BITS(2)*/) { |
|
case 0: /* stored block */ |
|
//Tracev((stderr, "inflate: stored block%s\n", |
|
// state.last ? " (last)" : "")); |
|
state.mode = STORED; |
|
break; |
|
case 1: /* fixed block */ |
|
fixedtables(state); |
|
//Tracev((stderr, "inflate: fixed codes block%s\n", |
|
// state.last ? " (last)" : "")); |
|
state.mode = LEN_; /* decode codes */ |
|
if (flush === Z_TREES) { |
|
//--- DROPBITS(2) ---// |
|
hold >>>= 2; |
|
bits -= 2; |
|
//---// |
|
break inf_leave; |
|
} |
|
break; |
|
case 2: /* dynamic block */ |
|
//Tracev((stderr, "inflate: dynamic codes block%s\n", |
|
// state.last ? " (last)" : "")); |
|
state.mode = TABLE; |
|
break; |
|
case 3: |
|
strm.msg = 'invalid block type'; |
|
state.mode = BAD; |
|
} |
|
//--- DROPBITS(2) ---// |
|
hold >>>= 2; |
|
bits -= 2; |
|
//---// |
|
break; |
|
case STORED: |
|
//--- BYTEBITS() ---// /* go to byte boundary */ |
|
hold >>>= bits & 7; |
|
bits -= bits & 7; |
|
//---// |
|
//=== NEEDBITS(32); */ |
|
while (bits < 32) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { |
|
strm.msg = 'invalid stored block lengths'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
state.length = hold & 0xffff; |
|
//Tracev((stderr, "inflate: stored length %u\n", |
|
// state.length)); |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
state.mode = COPY_; |
|
if (flush === Z_TREES) { break inf_leave; } |
|
/* falls through */ |
|
case COPY_: |
|
state.mode = COPY; |
|
/* falls through */ |
|
case COPY: |
|
copy = state.length; |
|
if (copy) { |
|
if (copy > have) { copy = have; } |
|
if (copy > left) { copy = left; } |
|
if (copy === 0) { break inf_leave; } |
|
//--- zmemcpy(put, next, copy); --- |
|
utils.arraySet(output, input, next, copy, put); |
|
//---// |
|
have -= copy; |
|
next += copy; |
|
left -= copy; |
|
put += copy; |
|
state.length -= copy; |
|
break; |
|
} |
|
//Tracev((stderr, "inflate: stored end\n")); |
|
state.mode = TYPE; |
|
break; |
|
case TABLE: |
|
//=== NEEDBITS(14); */ |
|
while (bits < 14) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; |
|
//--- DROPBITS(5) ---// |
|
hold >>>= 5; |
|
bits -= 5; |
|
//---// |
|
state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; |
|
//--- DROPBITS(5) ---// |
|
hold >>>= 5; |
|
bits -= 5; |
|
//---// |
|
state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; |
|
//--- DROPBITS(4) ---// |
|
hold >>>= 4; |
|
bits -= 4; |
|
//---// |
|
//#ifndef PKZIP_BUG_WORKAROUND |
|
if (state.nlen > 286 || state.ndist > 30) { |
|
strm.msg = 'too many length or distance symbols'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//#endif |
|
//Tracev((stderr, "inflate: table sizes ok\n")); |
|
state.have = 0; |
|
state.mode = LENLENS; |
|
/* falls through */ |
|
case LENLENS: |
|
while (state.have < state.ncode) { |
|
//=== NEEDBITS(3); |
|
while (bits < 3) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); |
|
//--- DROPBITS(3) ---// |
|
hold >>>= 3; |
|
bits -= 3; |
|
//---// |
|
} |
|
while (state.have < 19) { |
|
state.lens[order[state.have++]] = 0; |
|
} |
|
// We have separate tables & no pointers. 2 commented lines below not needed. |
|
//state.next = state.codes; |
|
//state.lencode = state.next; |
|
// Switch to use dynamic table |
|
state.lencode = state.lendyn; |
|
state.lenbits = 7; |
|
|
|
opts = {bits: state.lenbits}; |
|
ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); |
|
state.lenbits = opts.bits; |
|
|
|
if (ret) { |
|
strm.msg = 'invalid code lengths set'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//Tracev((stderr, "inflate: code lengths ok\n")); |
|
state.have = 0; |
|
state.mode = CODELENS; |
|
/* falls through */ |
|
case CODELENS: |
|
while (state.have < state.nlen + state.ndist) { |
|
for (;;) { |
|
here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ |
|
here_bits = here >>> 24; |
|
here_op = (here >>> 16) & 0xff; |
|
here_val = here & 0xffff; |
|
|
|
if ((here_bits) <= bits) { break; } |
|
//--- PULLBYTE() ---// |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
//---// |
|
} |
|
if (here_val < 16) { |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
state.lens[state.have++] = here_val; |
|
} |
|
else { |
|
if (here_val === 16) { |
|
//=== NEEDBITS(here.bits + 2); |
|
n = here_bits + 2; |
|
while (bits < n) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
if (state.have === 0) { |
|
strm.msg = 'invalid bit length repeat'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
len = state.lens[state.have - 1]; |
|
copy = 3 + (hold & 0x03);//BITS(2); |
|
//--- DROPBITS(2) ---// |
|
hold >>>= 2; |
|
bits -= 2; |
|
//---// |
|
} |
|
else if (here_val === 17) { |
|
//=== NEEDBITS(here.bits + 3); |
|
n = here_bits + 3; |
|
while (bits < n) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
len = 0; |
|
copy = 3 + (hold & 0x07);//BITS(3); |
|
//--- DROPBITS(3) ---// |
|
hold >>>= 3; |
|
bits -= 3; |
|
//---// |
|
} |
|
else { |
|
//=== NEEDBITS(here.bits + 7); |
|
n = here_bits + 7; |
|
while (bits < n) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
len = 0; |
|
copy = 11 + (hold & 0x7f);//BITS(7); |
|
//--- DROPBITS(7) ---// |
|
hold >>>= 7; |
|
bits -= 7; |
|
//---// |
|
} |
|
if (state.have + copy > state.nlen + state.ndist) { |
|
strm.msg = 'invalid bit length repeat'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
while (copy--) { |
|
state.lens[state.have++] = len; |
|
} |
|
} |
|
} |
|
|
|
/* handle error breaks in while */ |
|
if (state.mode === BAD) { break; } |
|
|
|
/* check for end-of-block code (better have one) */ |
|
if (state.lens[256] === 0) { |
|
strm.msg = 'invalid code -- missing end-of-block'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
|
|
/* build code tables -- note: do not change the lenbits or distbits |
|
values here (9 and 6) without reading the comments in inftrees.h |
|
concerning the ENOUGH constants, which depend on those values */ |
|
state.lenbits = 9; |
|
|
|
opts = {bits: state.lenbits}; |
|
ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); |
|
// We have separate tables & no pointers. 2 commented lines below not needed. |
|
// state.next_index = opts.table_index; |
|
state.lenbits = opts.bits; |
|
// state.lencode = state.next; |
|
|
|
if (ret) { |
|
strm.msg = 'invalid literal/lengths set'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
|
|
state.distbits = 6; |
|
//state.distcode.copy(state.codes); |
|
// Switch to use dynamic table |
|
state.distcode = state.distdyn; |
|
opts = {bits: state.distbits}; |
|
ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); |
|
// We have separate tables & no pointers. 2 commented lines below not needed. |
|
// state.next_index = opts.table_index; |
|
state.distbits = opts.bits; |
|
// state.distcode = state.next; |
|
|
|
if (ret) { |
|
strm.msg = 'invalid distances set'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//Tracev((stderr, 'inflate: codes ok\n')); |
|
state.mode = LEN_; |
|
if (flush === Z_TREES) { break inf_leave; } |
|
/* falls through */ |
|
case LEN_: |
|
state.mode = LEN; |
|
/* falls through */ |
|
case LEN: |
|
if (have >= 6 && left >= 258) { |
|
//--- RESTORE() --- |
|
strm.next_out = put; |
|
strm.avail_out = left; |
|
strm.next_in = next; |
|
strm.avail_in = have; |
|
state.hold = hold; |
|
state.bits = bits; |
|
//--- |
|
inflate_fast(strm, _out); |
|
//--- LOAD() --- |
|
put = strm.next_out; |
|
output = strm.output; |
|
left = strm.avail_out; |
|
next = strm.next_in; |
|
input = strm.input; |
|
have = strm.avail_in; |
|
hold = state.hold; |
|
bits = state.bits; |
|
//--- |
|
|
|
if (state.mode === TYPE) { |
|
state.back = -1; |
|
} |
|
break; |
|
} |
|
state.back = 0; |
|
for (;;) { |
|
here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ |
|
here_bits = here >>> 24; |
|
here_op = (here >>> 16) & 0xff; |
|
here_val = here & 0xffff; |
|
|
|
if (here_bits <= bits) { break; } |
|
//--- PULLBYTE() ---// |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
//---// |
|
} |
|
if (here_op && (here_op & 0xf0) === 0) { |
|
last_bits = here_bits; |
|
last_op = here_op; |
|
last_val = here_val; |
|
for (;;) { |
|
here = state.lencode[last_val + |
|
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; |
|
here_bits = here >>> 24; |
|
here_op = (here >>> 16) & 0xff; |
|
here_val = here & 0xffff; |
|
|
|
if ((last_bits + here_bits) <= bits) { break; } |
|
//--- PULLBYTE() ---// |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
//---// |
|
} |
|
//--- DROPBITS(last.bits) ---// |
|
hold >>>= last_bits; |
|
bits -= last_bits; |
|
//---// |
|
state.back += last_bits; |
|
} |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
state.back += here_bits; |
|
state.length = here_val; |
|
if (here_op === 0) { |
|
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
|
// "inflate: literal '%c'\n" : |
|
// "inflate: literal 0x%02x\n", here.val)); |
|
state.mode = LIT; |
|
break; |
|
} |
|
if (here_op & 32) { |
|
//Tracevv((stderr, "inflate: end of block\n")); |
|
state.back = -1; |
|
state.mode = TYPE; |
|
break; |
|
} |
|
if (here_op & 64) { |
|
strm.msg = 'invalid literal/length code'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
state.extra = here_op & 15; |
|
state.mode = LENEXT; |
|
/* falls through */ |
|
case LENEXT: |
|
if (state.extra) { |
|
//=== NEEDBITS(state.extra); |
|
n = state.extra; |
|
while (bits < n) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; |
|
//--- DROPBITS(state.extra) ---// |
|
hold >>>= state.extra; |
|
bits -= state.extra; |
|
//---// |
|
state.back += state.extra; |
|
} |
|
//Tracevv((stderr, "inflate: length %u\n", state.length)); |
|
state.was = state.length; |
|
state.mode = DIST; |
|
/* falls through */ |
|
case DIST: |
|
for (;;) { |
|
here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ |
|
here_bits = here >>> 24; |
|
here_op = (here >>> 16) & 0xff; |
|
here_val = here & 0xffff; |
|
|
|
if ((here_bits) <= bits) { break; } |
|
//--- PULLBYTE() ---// |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
//---// |
|
} |
|
if ((here_op & 0xf0) === 0) { |
|
last_bits = here_bits; |
|
last_op = here_op; |
|
last_val = here_val; |
|
for (;;) { |
|
here = state.distcode[last_val + |
|
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; |
|
here_bits = here >>> 24; |
|
here_op = (here >>> 16) & 0xff; |
|
here_val = here & 0xffff; |
|
|
|
if ((last_bits + here_bits) <= bits) { break; } |
|
//--- PULLBYTE() ---// |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
//---// |
|
} |
|
//--- DROPBITS(last.bits) ---// |
|
hold >>>= last_bits; |
|
bits -= last_bits; |
|
//---// |
|
state.back += last_bits; |
|
} |
|
//--- DROPBITS(here.bits) ---// |
|
hold >>>= here_bits; |
|
bits -= here_bits; |
|
//---// |
|
state.back += here_bits; |
|
if (here_op & 64) { |
|
strm.msg = 'invalid distance code'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
state.offset = here_val; |
|
state.extra = (here_op) & 15; |
|
state.mode = DISTEXT; |
|
/* falls through */ |
|
case DISTEXT: |
|
if (state.extra) { |
|
//=== NEEDBITS(state.extra); |
|
n = state.extra; |
|
while (bits < n) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; |
|
//--- DROPBITS(state.extra) ---// |
|
hold >>>= state.extra; |
|
bits -= state.extra; |
|
//---// |
|
state.back += state.extra; |
|
} |
|
//#ifdef INFLATE_STRICT |
|
if (state.offset > state.dmax) { |
|
strm.msg = 'invalid distance too far back'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//#endif |
|
//Tracevv((stderr, "inflate: distance %u\n", state.offset)); |
|
state.mode = MATCH; |
|
/* falls through */ |
|
case MATCH: |
|
if (left === 0) { break inf_leave; } |
|
copy = _out - left; |
|
if (state.offset > copy) { /* copy from window */ |
|
copy = state.offset - copy; |
|
if (copy > state.whave) { |
|
if (state.sane) { |
|
strm.msg = 'invalid distance too far back'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
// (!) This block is disabled in zlib defailts, |
|
// don't enable it for binary compatibility |
|
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR |
|
// Trace((stderr, "inflate.c too far\n")); |
|
// copy -= state.whave; |
|
// if (copy > state.length) { copy = state.length; } |
|
// if (copy > left) { copy = left; } |
|
// left -= copy; |
|
// state.length -= copy; |
|
// do { |
|
// output[put++] = 0; |
|
// } while (--copy); |
|
// if (state.length === 0) { state.mode = LEN; } |
|
// break; |
|
//#endif |
|
} |
|
if (copy > state.wnext) { |
|
copy -= state.wnext; |
|
from = state.wsize - copy; |
|
} |
|
else { |
|
from = state.wnext - copy; |
|
} |
|
if (copy > state.length) { copy = state.length; } |
|
from_source = state.window; |
|
} |
|
else { /* copy from output */ |
|
from_source = output; |
|
from = put - state.offset; |
|
copy = state.length; |
|
} |
|
if (copy > left) { copy = left; } |
|
left -= copy; |
|
state.length -= copy; |
|
do { |
|
output[put++] = from_source[from++]; |
|
} while (--copy); |
|
if (state.length === 0) { state.mode = LEN; } |
|
break; |
|
case LIT: |
|
if (left === 0) { break inf_leave; } |
|
output[put++] = state.length; |
|
left--; |
|
state.mode = LEN; |
|
break; |
|
case CHECK: |
|
if (state.wrap) { |
|
//=== NEEDBITS(32); |
|
while (bits < 32) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
// Use '|' insdead of '+' to make sure that result is signed |
|
hold |= input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
_out -= left; |
|
strm.total_out += _out; |
|
state.total += _out; |
|
if (_out) { |
|
strm.adler = state.check = |
|
/*UPDATE(state.check, put - _out, _out);*/ |
|
(state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); |
|
|
|
} |
|
_out = left; |
|
// NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too |
|
if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { |
|
strm.msg = 'incorrect data check'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
//Tracev((stderr, "inflate: check matches trailer\n")); |
|
} |
|
state.mode = LENGTH; |
|
/* falls through */ |
|
case LENGTH: |
|
if (state.wrap && state.flags) { |
|
//=== NEEDBITS(32); |
|
while (bits < 32) { |
|
if (have === 0) { break inf_leave; } |
|
have--; |
|
hold += input[next++] << bits; |
|
bits += 8; |
|
} |
|
//===// |
|
if (hold !== (state.total & 0xffffffff)) { |
|
strm.msg = 'incorrect length check'; |
|
state.mode = BAD; |
|
break; |
|
} |
|
//=== INITBITS(); |
|
hold = 0; |
|
bits = 0; |
|
//===// |
|
//Tracev((stderr, "inflate: length matches trailer\n")); |
|
} |
|
state.mode = DONE; |
|
/* falls through */ |
|
case DONE: |
|
ret = Z_STREAM_END; |
|
break inf_leave; |
|
case BAD: |
|
ret = Z_DATA_ERROR; |
|
break inf_leave; |
|
case MEM: |
|
return Z_MEM_ERROR; |
|
case SYNC: |
|
/* falls through */ |
|
default: |
|
return Z_STREAM_ERROR; |
|
} |
|
} |
|
|
|
// inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" |
|
|
|
/* |
|
Return from inflate(), updating the total counts and the check value. |
|
If there was no progress during the inflate() call, return a buffer |
|
error. Call updatewindow() to create and/or update the window state. |
|
Note: a memory error from inflate() is non-recoverable. |
|
*/ |
|
|
|
//--- RESTORE() --- |
|
strm.next_out = put; |
|
strm.avail_out = left; |
|
strm.next_in = next; |
|
strm.avail_in = have; |
|
state.hold = hold; |
|
state.bits = bits; |
|
//--- |
|
|
|
if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && |
|
(state.mode < CHECK || flush !== Z_FINISH))) { |
|
if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { |
|
state.mode = MEM; |
|
return Z_MEM_ERROR; |
|
} |
|
} |
|
_in -= strm.avail_in; |
|
_out -= strm.avail_out; |
|
strm.total_in += _in; |
|
strm.total_out += _out; |
|
state.total += _out; |
|
if (state.wrap && _out) { |
|
strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ |
|
(state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); |
|
} |
|
strm.data_type = state.bits + (state.last ? 64 : 0) + |
|
(state.mode === TYPE ? 128 : 0) + |
|
(state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); |
|
if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { |
|
ret = Z_BUF_ERROR; |
|
} |
|
return ret; |
|
} |
|
|
|
function inflateEnd(strm) { |
|
|
|
if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { |
|
return Z_STREAM_ERROR; |
|
} |
|
|
|
var state = strm.state; |
|
if (state.window) { |
|
state.window = null; |
|
} |
|
strm.state = null; |
|
return Z_OK; |
|
} |
|
|
|
function inflateGetHeader(strm, head) { |
|
var state; |
|
|
|
/* check state */ |
|
if (!strm || !strm.state) { return Z_STREAM_ERROR; } |
|
state = strm.state; |
|
if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } |
|
|
|
/* save header structure */ |
|
state.head = head; |
|
head.done = false; |
|
return Z_OK; |
|
} |
|
|
|
|
|
exports.inflateReset = inflateReset; |
|
exports.inflateReset2 = inflateReset2; |
|
exports.inflateResetKeep = inflateResetKeep; |
|
exports.inflateInit = inflateInit; |
|
exports.inflateInit2 = inflateInit2; |
|
exports.inflate = inflate; |
|
exports.inflateEnd = inflateEnd; |
|
exports.inflateGetHeader = inflateGetHeader; |
|
exports.inflateInfo = 'pako inflate (from Nodeca project)'; |
|
|
|
/* Not implemented |
|
exports.inflateCopy = inflateCopy; |
|
exports.inflateGetDictionary = inflateGetDictionary; |
|
exports.inflateMark = inflateMark; |
|
exports.inflatePrime = inflatePrime; |
|
exports.inflateSetDictionary = inflateSetDictionary; |
|
exports.inflateSync = inflateSync; |
|
exports.inflateSyncPoint = inflateSyncPoint; |
|
exports.inflateUndermine = inflateUndermine; |
|
*/ |
|
|
|
},{"../utils/common":16,"./adler32":17,"./crc32":19,"./inffast":21,"./inftrees":23}],23:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
|
|
var utils = require('../utils/common'); |
|
|
|
var MAXBITS = 15; |
|
var ENOUGH_LENS = 852; |
|
var ENOUGH_DISTS = 592; |
|
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); |
|
|
|
var CODES = 0; |
|
var LENS = 1; |
|
var DISTS = 2; |
|
|
|
var lbase = [ /* Length codes 257..285 base */ |
|
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
|
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 |
|
]; |
|
|
|
var lext = [ /* Length codes 257..285 extra */ |
|
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, |
|
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 |
|
]; |
|
|
|
var dbase = [ /* Distance codes 0..29 base */ |
|
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
|
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
|
8193, 12289, 16385, 24577, 0, 0 |
|
]; |
|
|
|
var dext = [ /* Distance codes 0..29 extra */ |
|
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, |
|
23, 23, 24, 24, 25, 25, 26, 26, 27, 27, |
|
28, 28, 29, 29, 64, 64 |
|
]; |
|
|
|
module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) |
|
{ |
|
var bits = opts.bits; |
|
//here = opts.here; /* table entry for duplication */ |
|
|
|
var len = 0; /* a code's length in bits */ |
|
var sym = 0; /* index of code symbols */ |
|
var min = 0, max = 0; /* minimum and maximum code lengths */ |
|
var root = 0; /* number of index bits for root table */ |
|
var curr = 0; /* number of index bits for current table */ |
|
var drop = 0; /* code bits to drop for sub-table */ |
|
var left = 0; /* number of prefix codes available */ |
|
var used = 0; /* code entries in table used */ |
|
var huff = 0; /* Huffman code */ |
|
var incr; /* for incrementing code, index */ |
|
var fill; /* index for replicating entries */ |
|
var low; /* low bits for current root entry */ |
|
var mask; /* mask for low root bits */ |
|
var next; /* next available space in table */ |
|
var base = null; /* base value table to use */ |
|
var base_index = 0; |
|
// var shoextra; /* extra bits table to use */ |
|
var end; /* use base and extra for symbol > end */ |
|
var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ |
|
var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ |
|
var extra = null; |
|
var extra_index = 0; |
|
|
|
var here_bits, here_op, here_val; |
|
|
|
/* |
|
Process a set of code lengths to create a canonical Huffman code. The |
|
code lengths are lens[0..codes-1]. Each length corresponds to the |
|
symbols 0..codes-1. The Huffman code is generated by first sorting the |
|
symbols by length from short to long, and retaining the symbol order |
|
for codes with equal lengths. Then the code starts with all zero bits |
|
for the first code of the shortest length, and the codes are integer |
|
increments for the same length, and zeros are appended as the length |
|
increases. For the deflate format, these bits are stored backwards |
|
from their more natural integer increment ordering, and so when the |
|
decoding tables are built in the large loop below, the integer codes |
|
are incremented backwards. |
|
|
|
This routine assumes, but does not check, that all of the entries in |
|
lens[] are in the range 0..MAXBITS. The caller must assure this. |
|
1..MAXBITS is interpreted as that code length. zero means that that |
|
symbol does not occur in this code. |
|
|
|
The codes are sorted by computing a count of codes for each length, |
|
creating from that a table of starting indices for each length in the |
|
sorted table, and then entering the symbols in order in the sorted |
|
table. The sorted table is work[], with that space being provided by |
|
the caller. |
|
|
|
The length counts are used for other purposes as well, i.e. finding |
|
the minimum and maximum length codes, determining if there are any |
|
codes at all, checking for a valid set of lengths, and looking ahead |
|
at length counts to determine sub-table sizes when building the |
|
decoding tables. |
|
*/ |
|
|
|
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ |
|
for (len = 0; len <= MAXBITS; len++) { |
|
count[len] = 0; |
|
} |
|
for (sym = 0; sym < codes; sym++) { |
|
count[lens[lens_index + sym]]++; |
|
} |
|
|
|
/* bound code lengths, force root to be within code lengths */ |
|
root = bits; |
|
for (max = MAXBITS; max >= 1; max--) { |
|
if (count[max] !== 0) { break; } |
|
} |
|
if (root > max) { |
|
root = max; |
|
} |
|
if (max === 0) { /* no symbols to code at all */ |
|
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ |
|
//table.bits[opts.table_index] = 1; //here.bits = (var char)1; |
|
//table.val[opts.table_index++] = 0; //here.val = (var short)0; |
|
table[table_index++] = (1 << 24) | (64 << 16) | 0; |
|
|
|
|
|
//table.op[opts.table_index] = 64; |
|
//table.bits[opts.table_index] = 1; |
|
//table.val[opts.table_index++] = 0; |
|
table[table_index++] = (1 << 24) | (64 << 16) | 0; |
|
|
|
opts.bits = 1; |
|
return 0; /* no symbols, but wait for decoding to report error */ |
|
} |
|
for (min = 1; min < max; min++) { |
|
if (count[min] !== 0) { break; } |
|
} |
|
if (root < min) { |
|
root = min; |
|
} |
|
|
|
/* check for an over-subscribed or incomplete set of lengths */ |
|
left = 1; |
|
for (len = 1; len <= MAXBITS; len++) { |
|
left <<= 1; |
|
left -= count[len]; |
|
if (left < 0) { |
|
return -1; |
|
} /* over-subscribed */ |
|
} |
|
if (left > 0 && (type === CODES || max !== 1)) { |
|
return -1; /* incomplete set */ |
|
} |
|
|
|
/* generate offsets into symbol table for each length for sorting */ |
|
offs[1] = 0; |
|
for (len = 1; len < MAXBITS; len++) { |
|
offs[len + 1] = offs[len] + count[len]; |
|
} |
|
|
|
/* sort symbols by length, by symbol order within each length */ |
|
for (sym = 0; sym < codes; sym++) { |
|
if (lens[lens_index + sym] !== 0) { |
|
work[offs[lens[lens_index + sym]]++] = sym; |
|
} |
|
} |
|
|
|
/* |
|
Create and fill in decoding tables. In this loop, the table being |
|
filled is at next and has curr index bits. The code being used is huff |
|
with length len. That code is converted to an index by dropping drop |
|
bits off of the bottom. For codes where len is less than drop + curr, |
|
those top drop + curr - len bits are incremented through all values to |
|
fill the table with replicated entries. |
|
|
|
root is the number of index bits for the root table. When len exceeds |
|
root, sub-tables are created pointed to by the root entry with an index |
|
of the low root bits of huff. This is saved in low to check for when a |
|
new sub-table should be started. drop is zero when the root table is |
|
being filled, and drop is root when sub-tables are being filled. |
|
|
|
When a new sub-table is needed, it is necessary to look ahead in the |
|
code lengths to determine what size sub-table is needed. The length |
|
counts are used for this, and so count[] is decremented as codes are |
|
entered in the tables. |
|
|
|
used keeps track of how many table entries have been allocated from the |
|
provided *table space. It is checked for LENS and DIST tables against |
|
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in |
|
the initial root table size constants. See the comments in inftrees.h |
|
for more information. |
|
|
|
sym increments through all symbols, and the loop terminates when |
|
all codes of length max, i.e. all codes, have been processed. This |
|
routine permits incomplete codes, so another loop after this one fills |
|
in the rest of the decoding tables with invalid code markers. |
|
*/ |
|
|
|
/* set up for code type */ |
|
// poor man optimization - use if-else instead of switch, |
|
// to avoid deopts in old v8 |
|
if (type === CODES) { |
|
base = extra = work; /* dummy value--not used */ |
|
end = 19; |
|
|
|
} else if (type === LENS) { |
|
base = lbase; |
|
base_index -= 257; |
|
extra = lext; |
|
extra_index -= 257; |
|
end = 256; |
|
|
|
} else { /* DISTS */ |
|
base = dbase; |
|
extra = dext; |
|
end = -1; |
|
} |
|
|
|
/* initialize opts for loop */ |
|
huff = 0; /* starting code */ |
|
sym = 0; /* starting code symbol */ |
|
len = min; /* starting code length */ |
|
next = table_index; /* current table to fill in */ |
|
curr = root; /* current table index bits */ |
|
drop = 0; /* current bits to drop from code for index */ |
|
low = -1; /* trigger new sub-table when len > root */ |
|
used = 1 << root; /* use root table entries */ |
|
mask = used - 1; /* mask for comparing low */ |
|
|
|
/* check available table space */ |
|
if ((type === LENS && used > ENOUGH_LENS) || |
|
(type === DISTS && used > ENOUGH_DISTS)) { |
|
return 1; |
|
} |
|
|
|
var i=0; |
|
/* process all codes and make table entries */ |
|
for (;;) { |
|
i++; |
|
/* create table entry */ |
|
here_bits = len - drop; |
|
if (work[sym] < end) { |
|
here_op = 0; |
|
here_val = work[sym]; |
|
} |
|
else if (work[sym] > end) { |
|
here_op = extra[extra_index + work[sym]]; |
|
here_val = base[base_index + work[sym]]; |
|
} |
|
else { |
|
here_op = 32 + 64; /* end of block */ |
|
here_val = 0; |
|
} |
|
|
|
/* replicate for those indices with low len bits equal to huff */ |
|
incr = 1 << (len - drop); |
|
fill = 1 << curr; |
|
min = fill; /* save offset to next table */ |
|
do { |
|
fill -= incr; |
|
table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; |
|
} while (fill !== 0); |
|
|
|
/* backwards increment the len-bit code huff */ |
|
incr = 1 << (len - 1); |
|
while (huff & incr) { |
|
incr >>= 1; |
|
} |
|
if (incr !== 0) { |
|
huff &= incr - 1; |
|
huff += incr; |
|
} else { |
|
huff = 0; |
|
} |
|
|
|
/* go to next symbol, update count, len */ |
|
sym++; |
|
if (--count[len] === 0) { |
|
if (len === max) { break; } |
|
len = lens[lens_index + work[sym]]; |
|
} |
|
|
|
/* create new sub-table if needed */ |
|
if (len > root && (huff & mask) !== low) { |
|
/* if first time, transition to sub-tables */ |
|
if (drop === 0) { |
|
drop = root; |
|
} |
|
|
|
/* increment past last table */ |
|
next += min; /* here min is 1 << curr */ |
|
|
|
/* determine length of next table */ |
|
curr = len - drop; |
|
left = 1 << curr; |
|
while (curr + drop < max) { |
|
left -= count[curr + drop]; |
|
if (left <= 0) { break; } |
|
curr++; |
|
left <<= 1; |
|
} |
|
|
|
/* check for enough space */ |
|
used += 1 << curr; |
|
if ((type === LENS && used > ENOUGH_LENS) || |
|
(type === DISTS && used > ENOUGH_DISTS)) { |
|
return 1; |
|
} |
|
|
|
/* point entry in root table to sub-table */ |
|
low = huff & mask; |
|
/*table.op[low] = curr; |
|
table.bits[low] = root; |
|
table.val[low] = next - opts.table_index;*/ |
|
table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; |
|
} |
|
} |
|
|
|
/* fill in remaining table entry if code is incomplete (guaranteed to have |
|
at most one remaining entry, since if the code is incomplete, the |
|
maximum code length that was allowed to get this far is one bit) */ |
|
if (huff !== 0) { |
|
//table.op[next + huff] = 64; /* invalid code marker */ |
|
//table.bits[next + huff] = len - drop; |
|
//table.val[next + huff] = 0; |
|
table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; |
|
} |
|
|
|
/* set return parameters */ |
|
//opts.table_index += used; |
|
opts.bits = root; |
|
return 0; |
|
}; |
|
|
|
},{"../utils/common":16}],24:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
module.exports = { |
|
'2': 'need dictionary', /* Z_NEED_DICT 2 */ |
|
'1': 'stream end', /* Z_STREAM_END 1 */ |
|
'0': '', /* Z_OK 0 */ |
|
'-1': 'file error', /* Z_ERRNO (-1) */ |
|
'-2': 'stream error', /* Z_STREAM_ERROR (-2) */ |
|
'-3': 'data error', /* Z_DATA_ERROR (-3) */ |
|
'-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ |
|
'-5': 'buffer error', /* Z_BUF_ERROR (-5) */ |
|
'-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ |
|
}; |
|
|
|
},{}],25:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
|
|
var utils = require('../utils/common'); |
|
|
|
/* Public constants ==========================================================*/ |
|
/* ===========================================================================*/ |
|
|
|
|
|
//var Z_FILTERED = 1; |
|
//var Z_HUFFMAN_ONLY = 2; |
|
//var Z_RLE = 3; |
|
var Z_FIXED = 4; |
|
//var Z_DEFAULT_STRATEGY = 0; |
|
|
|
/* Possible values of the data_type field (though see inflate()) */ |
|
var Z_BINARY = 0; |
|
var Z_TEXT = 1; |
|
//var Z_ASCII = 1; // = Z_TEXT |
|
var Z_UNKNOWN = 2; |
|
|
|
/*============================================================================*/ |
|
|
|
|
|
function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } |
|
|
|
// From zutil.h |
|
|
|
var STORED_BLOCK = 0; |
|
var STATIC_TREES = 1; |
|
var DYN_TREES = 2; |
|
/* The three kinds of block type */ |
|
|
|
var MIN_MATCH = 3; |
|
var MAX_MATCH = 258; |
|
/* The minimum and maximum match lengths */ |
|
|
|
// From deflate.h |
|
/* =========================================================================== |
|
* Internal compression state. |
|
*/ |
|
|
|
var LENGTH_CODES = 29; |
|
/* number of length codes, not counting the special END_BLOCK code */ |
|
|
|
var LITERALS = 256; |
|
/* number of literal bytes 0..255 */ |
|
|
|
var L_CODES = LITERALS + 1 + LENGTH_CODES; |
|
/* number of Literal or Length codes, including the END_BLOCK code */ |
|
|
|
var D_CODES = 30; |
|
/* number of distance codes */ |
|
|
|
var BL_CODES = 19; |
|
/* number of codes used to transfer the bit lengths */ |
|
|
|
var HEAP_SIZE = 2*L_CODES + 1; |
|
/* maximum heap size */ |
|
|
|
var MAX_BITS = 15; |
|
/* All codes must not exceed MAX_BITS bits */ |
|
|
|
var Buf_size = 16; |
|
/* size of bit buffer in bi_buf */ |
|
|
|
|
|
/* =========================================================================== |
|
* Constants |
|
*/ |
|
|
|
var MAX_BL_BITS = 7; |
|
/* Bit length codes must not exceed MAX_BL_BITS bits */ |
|
|
|
var END_BLOCK = 256; |
|
/* end of block literal code */ |
|
|
|
var REP_3_6 = 16; |
|
/* repeat previous bit length 3-6 times (2 bits of repeat count) */ |
|
|
|
var REPZ_3_10 = 17; |
|
/* repeat a zero length 3-10 times (3 bits of repeat count) */ |
|
|
|
var REPZ_11_138 = 18; |
|
/* repeat a zero length 11-138 times (7 bits of repeat count) */ |
|
|
|
var extra_lbits = /* extra bits for each length code */ |
|
[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]; |
|
|
|
var extra_dbits = /* extra bits for each distance code */ |
|
[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]; |
|
|
|
var extra_blbits = /* extra bits for each bit length code */ |
|
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; |
|
|
|
var bl_order = |
|
[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; |
|
/* The lengths of the bit length codes are sent in order of decreasing |
|
* probability, to avoid transmitting the lengths for unused bit length codes. |
|
*/ |
|
|
|
/* =========================================================================== |
|
* Local data. These are initialized only once. |
|
*/ |
|
|
|
// We pre-fill arrays with 0 to avoid uninitialized gaps |
|
|
|
var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ |
|
|
|
// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 |
|
var static_ltree = new Array((L_CODES+2) * 2); |
|
zero(static_ltree); |
|
/* The static literal tree. Since the bit lengths are imposed, there is no |
|
* need for the L_CODES extra codes used during heap construction. However |
|
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init |
|
* below). |
|
*/ |
|
|
|
var static_dtree = new Array(D_CODES * 2); |
|
zero(static_dtree); |
|
/* The static distance tree. (Actually a trivial tree since all codes use |
|
* 5 bits.) |
|
*/ |
|
|
|
var _dist_code = new Array(DIST_CODE_LEN); |
|
zero(_dist_code); |
|
/* Distance codes. The first 256 values correspond to the distances |
|
* 3 .. 258, the last 256 values correspond to the top 8 bits of |
|
* the 15 bit distances. |
|
*/ |
|
|
|
var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); |
|
zero(_length_code); |
|
/* length code for each normalized match length (0 == MIN_MATCH) */ |
|
|
|
var base_length = new Array(LENGTH_CODES); |
|
zero(base_length); |
|
/* First normalized length for each code (0 = MIN_MATCH) */ |
|
|
|
var base_dist = new Array(D_CODES); |
|
zero(base_dist); |
|
/* First normalized distance for each code (0 = distance of 1) */ |
|
|
|
|
|
var StaticTreeDesc = function (static_tree, extra_bits, extra_base, elems, max_length) { |
|
|
|
this.static_tree = static_tree; /* static tree or NULL */ |
|
this.extra_bits = extra_bits; /* extra bits for each code or NULL */ |
|
this.extra_base = extra_base; /* base index for extra_bits */ |
|
this.elems = elems; /* max number of elements in the tree */ |
|
this.max_length = max_length; /* max bit length for the codes */ |
|
|
|
// show if `static_tree` has data or dummy - needed for monomorphic objects |
|
this.has_stree = static_tree && static_tree.length; |
|
}; |
|
|
|
|
|
var static_l_desc; |
|
var static_d_desc; |
|
var static_bl_desc; |
|
|
|
|
|
var TreeDesc = function(dyn_tree, stat_desc) { |
|
this.dyn_tree = dyn_tree; /* the dynamic tree */ |
|
this.max_code = 0; /* largest code with non zero frequency */ |
|
this.stat_desc = stat_desc; /* the corresponding static tree */ |
|
}; |
|
|
|
|
|
|
|
function d_code(dist) { |
|
return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Output a short LSB first on the stream. |
|
* IN assertion: there is enough room in pendingBuf. |
|
*/ |
|
function put_short (s, w) { |
|
// put_byte(s, (uch)((w) & 0xff)); |
|
// put_byte(s, (uch)((ush)(w) >> 8)); |
|
s.pending_buf[s.pending++] = (w) & 0xff; |
|
s.pending_buf[s.pending++] = (w >>> 8) & 0xff; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Send a value on a given number of bits. |
|
* IN assertion: length <= 16 and value fits in length bits. |
|
*/ |
|
function send_bits(s, value, length) { |
|
if (s.bi_valid > (Buf_size - length)) { |
|
s.bi_buf |= (value << s.bi_valid) & 0xffff; |
|
put_short(s, s.bi_buf); |
|
s.bi_buf = value >> (Buf_size - s.bi_valid); |
|
s.bi_valid += length - Buf_size; |
|
} else { |
|
s.bi_buf |= (value << s.bi_valid) & 0xffff; |
|
s.bi_valid += length; |
|
} |
|
} |
|
|
|
|
|
function send_code(s, c, tree) { |
|
send_bits(s, tree[c*2]/*.Code*/, tree[c*2 + 1]/*.Len*/); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Reverse the first len bits of a code, using straightforward code (a faster |
|
* method would use a table) |
|
* IN assertion: 1 <= len <= 15 |
|
*/ |
|
function bi_reverse(code, len) { |
|
var res = 0; |
|
do { |
|
res |= code & 1; |
|
code >>>= 1; |
|
res <<= 1; |
|
} while (--len > 0); |
|
return res >>> 1; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Flush the bit buffer, keeping at most 7 bits in it. |
|
*/ |
|
function bi_flush(s) { |
|
if (s.bi_valid === 16) { |
|
put_short(s, s.bi_buf); |
|
s.bi_buf = 0; |
|
s.bi_valid = 0; |
|
|
|
} else if (s.bi_valid >= 8) { |
|
s.pending_buf[s.pending++] = s.bi_buf & 0xff; |
|
s.bi_buf >>= 8; |
|
s.bi_valid -= 8; |
|
} |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Compute the optimal bit lengths for a tree and update the total bit length |
|
* for the current block. |
|
* IN assertion: the fields freq and dad are set, heap[heap_max] and |
|
* above are the tree nodes sorted by increasing frequency. |
|
* OUT assertions: the field len is set to the optimal bit length, the |
|
* array bl_count contains the frequencies for each bit length. |
|
* The length opt_len is updated; static_len is also updated if stree is |
|
* not null. |
|
*/ |
|
function gen_bitlen(s, desc) |
|
// deflate_state *s; |
|
// tree_desc *desc; /* the tree descriptor */ |
|
{ |
|
var tree = desc.dyn_tree; |
|
var max_code = desc.max_code; |
|
var stree = desc.stat_desc.static_tree; |
|
var has_stree = desc.stat_desc.has_stree; |
|
var extra = desc.stat_desc.extra_bits; |
|
var base = desc.stat_desc.extra_base; |
|
var max_length = desc.stat_desc.max_length; |
|
var h; /* heap index */ |
|
var n, m; /* iterate over the tree elements */ |
|
var bits; /* bit length */ |
|
var xbits; /* extra bits */ |
|
var f; /* frequency */ |
|
var overflow = 0; /* number of elements with bit length too large */ |
|
|
|
for (bits = 0; bits <= MAX_BITS; bits++) { |
|
s.bl_count[bits] = 0; |
|
} |
|
|
|
/* In a first pass, compute the optimal bit lengths (which may |
|
* overflow in the case of the bit length tree). |
|
*/ |
|
tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ |
|
|
|
for (h = s.heap_max+1; h < HEAP_SIZE; h++) { |
|
n = s.heap[h]; |
|
bits = tree[tree[n*2 +1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; |
|
if (bits > max_length) { |
|
bits = max_length; |
|
overflow++; |
|
} |
|
tree[n*2 + 1]/*.Len*/ = bits; |
|
/* We overwrite tree[n].Dad which is no longer needed */ |
|
|
|
if (n > max_code) { continue; } /* not a leaf node */ |
|
|
|
s.bl_count[bits]++; |
|
xbits = 0; |
|
if (n >= base) { |
|
xbits = extra[n-base]; |
|
} |
|
f = tree[n * 2]/*.Freq*/; |
|
s.opt_len += f * (bits + xbits); |
|
if (has_stree) { |
|
s.static_len += f * (stree[n*2 + 1]/*.Len*/ + xbits); |
|
} |
|
} |
|
if (overflow === 0) { return; } |
|
|
|
// Trace((stderr,"\nbit length overflow\n")); |
|
/* This happens for example on obj2 and pic of the Calgary corpus */ |
|
|
|
/* Find the first bit length which could increase: */ |
|
do { |
|
bits = max_length-1; |
|
while (s.bl_count[bits] === 0) { bits--; } |
|
s.bl_count[bits]--; /* move one leaf down the tree */ |
|
s.bl_count[bits+1] += 2; /* move one overflow item as its brother */ |
|
s.bl_count[max_length]--; |
|
/* The brother of the overflow item also moves one step up, |
|
* but this does not affect bl_count[max_length] |
|
*/ |
|
overflow -= 2; |
|
} while (overflow > 0); |
|
|
|
/* Now recompute all bit lengths, scanning in increasing frequency. |
|
* h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
|
* lengths instead of fixing only the wrong ones. This idea is taken |
|
* from 'ar' written by Haruhiko Okumura.) |
|
*/ |
|
for (bits = max_length; bits !== 0; bits--) { |
|
n = s.bl_count[bits]; |
|
while (n !== 0) { |
|
m = s.heap[--h]; |
|
if (m > max_code) { continue; } |
|
if (tree[m*2 + 1]/*.Len*/ !== bits) { |
|
// Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); |
|
s.opt_len += (bits - tree[m*2 + 1]/*.Len*/)*tree[m*2]/*.Freq*/; |
|
tree[m*2 + 1]/*.Len*/ = bits; |
|
} |
|
n--; |
|
} |
|
} |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Generate the codes for a given tree and bit counts (which need not be |
|
* optimal). |
|
* IN assertion: the array bl_count contains the bit length statistics for |
|
* the given tree and the field len is set for all tree elements. |
|
* OUT assertion: the field code is set for all tree elements of non |
|
* zero code length. |
|
*/ |
|
function gen_codes(tree, max_code, bl_count) |
|
// ct_data *tree; /* the tree to decorate */ |
|
// int max_code; /* largest code with non zero frequency */ |
|
// ushf *bl_count; /* number of codes at each bit length */ |
|
{ |
|
var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ |
|
var code = 0; /* running code value */ |
|
var bits; /* bit index */ |
|
var n; /* code index */ |
|
|
|
/* The distribution counts are first used to generate the code values |
|
* without bit reversal. |
|
*/ |
|
for (bits = 1; bits <= MAX_BITS; bits++) { |
|
next_code[bits] = code = (code + bl_count[bits-1]) << 1; |
|
} |
|
/* Check that the bit counts in bl_count are consistent. The last code |
|
* must be all ones. |
|
*/ |
|
//Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, |
|
// "inconsistent bit counts"); |
|
//Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); |
|
|
|
for (n = 0; n <= max_code; n++) { |
|
var len = tree[n*2 + 1]/*.Len*/; |
|
if (len === 0) { continue; } |
|
/* Now reverse the bits */ |
|
tree[n*2]/*.Code*/ = bi_reverse(next_code[len]++, len); |
|
|
|
//Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", |
|
// n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); |
|
} |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Initialize the various 'constant' tables. |
|
*/ |
|
function tr_static_init() { |
|
var n; /* iterates over tree elements */ |
|
var bits; /* bit counter */ |
|
var length; /* length value */ |
|
var code; /* code value */ |
|
var dist; /* distance index */ |
|
var bl_count = new Array(MAX_BITS+1); |
|
/* number of codes at each bit length for an optimal tree */ |
|
|
|
// do check in _tr_init() |
|
//if (static_init_done) return; |
|
|
|
/* For some embedded targets, global variables are not initialized: */ |
|
/*#ifdef NO_INIT_GLOBAL_POINTERS |
|
static_l_desc.static_tree = static_ltree; |
|
static_l_desc.extra_bits = extra_lbits; |
|
static_d_desc.static_tree = static_dtree; |
|
static_d_desc.extra_bits = extra_dbits; |
|
static_bl_desc.extra_bits = extra_blbits; |
|
#endif*/ |
|
|
|
/* Initialize the mapping length (0..255) -> length code (0..28) */ |
|
length = 0; |
|
for (code = 0; code < LENGTH_CODES-1; code++) { |
|
base_length[code] = length; |
|
for (n = 0; n < (1<<extra_lbits[code]); n++) { |
|
_length_code[length++] = code; |
|
} |
|
} |
|
//Assert (length == 256, "tr_static_init: length != 256"); |
|
/* Note that the length 255 (match length 258) can be represented |
|
* in two different ways: code 284 + 5 bits or code 285, so we |
|
* overwrite length_code[255] to use the best encoding: |
|
*/ |
|
_length_code[length-1] = code; |
|
|
|
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */ |
|
dist = 0; |
|
for (code = 0 ; code < 16; code++) { |
|
base_dist[code] = dist; |
|
for (n = 0; n < (1<<extra_dbits[code]); n++) { |
|
_dist_code[dist++] = code; |
|
} |
|
} |
|
//Assert (dist == 256, "tr_static_init: dist != 256"); |
|
dist >>= 7; /* from now on, all distances are divided by 128 */ |
|
for (; code < D_CODES; code++) { |
|
base_dist[code] = dist << 7; |
|
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { |
|
_dist_code[256 + dist++] = code; |
|
} |
|
} |
|
//Assert (dist == 256, "tr_static_init: 256+dist != 512"); |
|
|
|
/* Construct the codes of the static literal tree */ |
|
for (bits = 0; bits <= MAX_BITS; bits++) { |
|
bl_count[bits] = 0; |
|
} |
|
|
|
n = 0; |
|
while (n <= 143) { |
|
static_ltree[n*2 + 1]/*.Len*/ = 8; |
|
n++; |
|
bl_count[8]++; |
|
} |
|
while (n <= 255) { |
|
static_ltree[n*2 + 1]/*.Len*/ = 9; |
|
n++; |
|
bl_count[9]++; |
|
} |
|
while (n <= 279) { |
|
static_ltree[n*2 + 1]/*.Len*/ = 7; |
|
n++; |
|
bl_count[7]++; |
|
} |
|
while (n <= 287) { |
|
static_ltree[n*2 + 1]/*.Len*/ = 8; |
|
n++; |
|
bl_count[8]++; |
|
} |
|
/* Codes 286 and 287 do not exist, but we must include them in the |
|
* tree construction to get a canonical Huffman tree (longest code |
|
* all ones) |
|
*/ |
|
gen_codes(static_ltree, L_CODES+1, bl_count); |
|
|
|
/* The static distance tree is trivial: */ |
|
for (n = 0; n < D_CODES; n++) { |
|
static_dtree[n*2 + 1]/*.Len*/ = 5; |
|
static_dtree[n*2]/*.Code*/ = bi_reverse(n, 5); |
|
} |
|
|
|
// Now data ready and we can init static trees |
|
static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); |
|
static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); |
|
static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); |
|
|
|
//static_init_done = true; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Initialize a new block. |
|
*/ |
|
function init_block(s) { |
|
var n; /* iterates over tree elements */ |
|
|
|
/* Initialize the trees. */ |
|
for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n*2]/*.Freq*/ = 0; } |
|
for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n*2]/*.Freq*/ = 0; } |
|
for (n = 0; n < BL_CODES; n++) { s.bl_tree[n*2]/*.Freq*/ = 0; } |
|
|
|
s.dyn_ltree[END_BLOCK*2]/*.Freq*/ = 1; |
|
s.opt_len = s.static_len = 0; |
|
s.last_lit = s.matches = 0; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Flush the bit buffer and align the output on a byte boundary |
|
*/ |
|
function bi_windup(s) |
|
{ |
|
if (s.bi_valid > 8) { |
|
put_short(s, s.bi_buf); |
|
} else if (s.bi_valid > 0) { |
|
//put_byte(s, (Byte)s->bi_buf); |
|
s.pending_buf[s.pending++] = s.bi_buf; |
|
} |
|
s.bi_buf = 0; |
|
s.bi_valid = 0; |
|
} |
|
|
|
/* =========================================================================== |
|
* Copy a stored block, storing first the length and its |
|
* one's complement if requested. |
|
*/ |
|
function copy_block(s, buf, len, header) |
|
//DeflateState *s; |
|
//charf *buf; /* the input data */ |
|
//unsigned len; /* its length */ |
|
//int header; /* true if block header must be written */ |
|
{ |
|
bi_windup(s); /* align on byte boundary */ |
|
|
|
if (header) { |
|
put_short(s, len); |
|
put_short(s, ~len); |
|
} |
|
// while (len--) { |
|
// put_byte(s, *buf++); |
|
// } |
|
utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); |
|
s.pending += len; |
|
} |
|
|
|
/* =========================================================================== |
|
* Compares to subtrees, using the tree depth as tie breaker when |
|
* the subtrees have equal frequency. This minimizes the worst case length. |
|
*/ |
|
function smaller(tree, n, m, depth) { |
|
var _n2 = n*2; |
|
var _m2 = m*2; |
|
return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || |
|
(tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); |
|
} |
|
|
|
/* =========================================================================== |
|
* Restore the heap property by moving down the tree starting at node k, |
|
* exchanging a node with the smallest of its two sons if necessary, stopping |
|
* when the heap property is re-established (each father smaller than its |
|
* two sons). |
|
*/ |
|
function pqdownheap(s, tree, k) |
|
// deflate_state *s; |
|
// ct_data *tree; /* the tree to restore */ |
|
// int k; /* node to move down */ |
|
{ |
|
var v = s.heap[k]; |
|
var j = k << 1; /* left son of k */ |
|
while (j <= s.heap_len) { |
|
/* Set j to the smallest of the two sons: */ |
|
if (j < s.heap_len && |
|
smaller(tree, s.heap[j+1], s.heap[j], s.depth)) { |
|
j++; |
|
} |
|
/* Exit if v is smaller than both sons */ |
|
if (smaller(tree, v, s.heap[j], s.depth)) { break; } |
|
|
|
/* Exchange v with the smallest son */ |
|
s.heap[k] = s.heap[j]; |
|
k = j; |
|
|
|
/* And continue down the tree, setting j to the left son of k */ |
|
j <<= 1; |
|
} |
|
s.heap[k] = v; |
|
} |
|
|
|
|
|
// inlined manually |
|
// var SMALLEST = 1; |
|
|
|
/* =========================================================================== |
|
* Send the block data compressed using the given Huffman trees |
|
*/ |
|
function compress_block(s, ltree, dtree) |
|
// deflate_state *s; |
|
// const ct_data *ltree; /* literal tree */ |
|
// const ct_data *dtree; /* distance tree */ |
|
{ |
|
var dist; /* distance of matched string */ |
|
var lc; /* match length or unmatched char (if dist == 0) */ |
|
var lx = 0; /* running index in l_buf */ |
|
var code; /* the code to send */ |
|
var extra; /* number of extra bits to send */ |
|
|
|
if (s.last_lit !== 0) { |
|
do { |
|
dist = (s.pending_buf[s.d_buf + lx*2] << 8) | (s.pending_buf[s.d_buf + lx*2 + 1]); |
|
lc = s.pending_buf[s.l_buf + lx]; |
|
lx++; |
|
|
|
if (dist === 0) { |
|
send_code(s, lc, ltree); /* send a literal byte */ |
|
//Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
|
} else { |
|
/* Here, lc is the match length - MIN_MATCH */ |
|
code = _length_code[lc]; |
|
send_code(s, code+LITERALS+1, ltree); /* send the length code */ |
|
extra = extra_lbits[code]; |
|
if (extra !== 0) { |
|
lc -= base_length[code]; |
|
send_bits(s, lc, extra); /* send the extra length bits */ |
|
} |
|
dist--; /* dist is now the match distance - 1 */ |
|
code = d_code(dist); |
|
//Assert (code < D_CODES, "bad d_code"); |
|
|
|
send_code(s, code, dtree); /* send the distance code */ |
|
extra = extra_dbits[code]; |
|
if (extra !== 0) { |
|
dist -= base_dist[code]; |
|
send_bits(s, dist, extra); /* send the extra distance bits */ |
|
} |
|
} /* literal or match pair ? */ |
|
|
|
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ |
|
//Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, |
|
// "pendingBuf overflow"); |
|
|
|
} while (lx < s.last_lit); |
|
} |
|
|
|
send_code(s, END_BLOCK, ltree); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Construct one Huffman tree and assigns the code bit strings and lengths. |
|
* Update the total bit length for the current block. |
|
* IN assertion: the field freq is set for all tree elements. |
|
* OUT assertions: the fields len and code are set to the optimal bit length |
|
* and corresponding code. The length opt_len is updated; static_len is |
|
* also updated if stree is not null. The field max_code is set. |
|
*/ |
|
function build_tree(s, desc) |
|
// deflate_state *s; |
|
// tree_desc *desc; /* the tree descriptor */ |
|
{ |
|
var tree = desc.dyn_tree; |
|
var stree = desc.stat_desc.static_tree; |
|
var has_stree = desc.stat_desc.has_stree; |
|
var elems = desc.stat_desc.elems; |
|
var n, m; /* iterate over heap elements */ |
|
var max_code = -1; /* largest code with non zero frequency */ |
|
var node; /* new node being created */ |
|
|
|
/* Construct the initial heap, with least frequent element in |
|
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
|
* heap[0] is not used. |
|
*/ |
|
s.heap_len = 0; |
|
s.heap_max = HEAP_SIZE; |
|
|
|
for (n = 0; n < elems; n++) { |
|
if (tree[n * 2]/*.Freq*/ !== 0) { |
|
s.heap[++s.heap_len] = max_code = n; |
|
s.depth[n] = 0; |
|
|
|
} else { |
|
tree[n*2 + 1]/*.Len*/ = 0; |
|
} |
|
} |
|
|
|
/* The pkzip format requires that at least one distance code exists, |
|
* and that at least one bit should be sent even if there is only one |
|
* possible code. So to avoid special checks later on we force at least |
|
* two codes of non zero frequency. |
|
*/ |
|
while (s.heap_len < 2) { |
|
node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); |
|
tree[node * 2]/*.Freq*/ = 1; |
|
s.depth[node] = 0; |
|
s.opt_len--; |
|
|
|
if (has_stree) { |
|
s.static_len -= stree[node*2 + 1]/*.Len*/; |
|
} |
|
/* node is 0 or 1 so it does not have extra bits */ |
|
} |
|
desc.max_code = max_code; |
|
|
|
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
|
* establish sub-heaps of increasing lengths: |
|
*/ |
|
for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } |
|
|
|
/* Construct the Huffman tree by repeatedly combining the least two |
|
* frequent nodes. |
|
*/ |
|
node = elems; /* next internal node of the tree */ |
|
do { |
|
//pqremove(s, tree, n); /* n = node of least frequency */ |
|
/*** pqremove ***/ |
|
n = s.heap[1/*SMALLEST*/]; |
|
s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; |
|
pqdownheap(s, tree, 1/*SMALLEST*/); |
|
/***/ |
|
|
|
m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ |
|
|
|
s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ |
|
s.heap[--s.heap_max] = m; |
|
|
|
/* Create a new node father of n and m */ |
|
tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; |
|
s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; |
|
tree[n*2 + 1]/*.Dad*/ = tree[m*2 + 1]/*.Dad*/ = node; |
|
|
|
/* and insert the new node in the heap */ |
|
s.heap[1/*SMALLEST*/] = node++; |
|
pqdownheap(s, tree, 1/*SMALLEST*/); |
|
|
|
} while (s.heap_len >= 2); |
|
|
|
s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; |
|
|
|
/* At this point, the fields freq and dad are set. We can now |
|
* generate the bit lengths. |
|
*/ |
|
gen_bitlen(s, desc); |
|
|
|
/* The field len is now set, we can generate the bit codes */ |
|
gen_codes(tree, max_code, s.bl_count); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Scan a literal or distance tree to determine the frequencies of the codes |
|
* in the bit length tree. |
|
*/ |
|
function scan_tree(s, tree, max_code) |
|
// deflate_state *s; |
|
// ct_data *tree; /* the tree to be scanned */ |
|
// int max_code; /* and its largest code of non zero frequency */ |
|
{ |
|
var n; /* iterates over all tree elements */ |
|
var prevlen = -1; /* last emitted length */ |
|
var curlen; /* length of current code */ |
|
|
|
var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ |
|
|
|
var count = 0; /* repeat count of the current code */ |
|
var max_count = 7; /* max repeat count */ |
|
var min_count = 4; /* min repeat count */ |
|
|
|
if (nextlen === 0) { |
|
max_count = 138; |
|
min_count = 3; |
|
} |
|
tree[(max_code+1)*2 + 1]/*.Len*/ = 0xffff; /* guard */ |
|
|
|
for (n = 0; n <= max_code; n++) { |
|
curlen = nextlen; |
|
nextlen = tree[(n+1)*2 + 1]/*.Len*/; |
|
|
|
if (++count < max_count && curlen === nextlen) { |
|
continue; |
|
|
|
} else if (count < min_count) { |
|
s.bl_tree[curlen * 2]/*.Freq*/ += count; |
|
|
|
} else if (curlen !== 0) { |
|
|
|
if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } |
|
s.bl_tree[REP_3_6*2]/*.Freq*/++; |
|
|
|
} else if (count <= 10) { |
|
s.bl_tree[REPZ_3_10*2]/*.Freq*/++; |
|
|
|
} else { |
|
s.bl_tree[REPZ_11_138*2]/*.Freq*/++; |
|
} |
|
|
|
count = 0; |
|
prevlen = curlen; |
|
|
|
if (nextlen === 0) { |
|
max_count = 138; |
|
min_count = 3; |
|
|
|
} else if (curlen === nextlen) { |
|
max_count = 6; |
|
min_count = 3; |
|
|
|
} else { |
|
max_count = 7; |
|
min_count = 4; |
|
} |
|
} |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Send a literal or distance tree in compressed form, using the codes in |
|
* bl_tree. |
|
*/ |
|
function send_tree(s, tree, max_code) |
|
// deflate_state *s; |
|
// ct_data *tree; /* the tree to be scanned */ |
|
// int max_code; /* and its largest code of non zero frequency */ |
|
{ |
|
var n; /* iterates over all tree elements */ |
|
var prevlen = -1; /* last emitted length */ |
|
var curlen; /* length of current code */ |
|
|
|
var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ |
|
|
|
var count = 0; /* repeat count of the current code */ |
|
var max_count = 7; /* max repeat count */ |
|
var min_count = 4; /* min repeat count */ |
|
|
|
/* tree[max_code+1].Len = -1; */ /* guard already set */ |
|
if (nextlen === 0) { |
|
max_count = 138; |
|
min_count = 3; |
|
} |
|
|
|
for (n = 0; n <= max_code; n++) { |
|
curlen = nextlen; |
|
nextlen = tree[(n+1)*2 + 1]/*.Len*/; |
|
|
|
if (++count < max_count && curlen === nextlen) { |
|
continue; |
|
|
|
} else if (count < min_count) { |
|
do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); |
|
|
|
} else if (curlen !== 0) { |
|
if (curlen !== prevlen) { |
|
send_code(s, curlen, s.bl_tree); |
|
count--; |
|
} |
|
//Assert(count >= 3 && count <= 6, " 3_6?"); |
|
send_code(s, REP_3_6, s.bl_tree); |
|
send_bits(s, count-3, 2); |
|
|
|
} else if (count <= 10) { |
|
send_code(s, REPZ_3_10, s.bl_tree); |
|
send_bits(s, count-3, 3); |
|
|
|
} else { |
|
send_code(s, REPZ_11_138, s.bl_tree); |
|
send_bits(s, count-11, 7); |
|
} |
|
|
|
count = 0; |
|
prevlen = curlen; |
|
if (nextlen === 0) { |
|
max_count = 138; |
|
min_count = 3; |
|
|
|
} else if (curlen === nextlen) { |
|
max_count = 6; |
|
min_count = 3; |
|
|
|
} else { |
|
max_count = 7; |
|
min_count = 4; |
|
} |
|
} |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Construct the Huffman tree for the bit lengths and return the index in |
|
* bl_order of the last bit length code to send. |
|
*/ |
|
function build_bl_tree(s) { |
|
var max_blindex; /* index of last bit length code of non zero freq */ |
|
|
|
/* Determine the bit length frequencies for literal and distance trees */ |
|
scan_tree(s, s.dyn_ltree, s.l_desc.max_code); |
|
scan_tree(s, s.dyn_dtree, s.d_desc.max_code); |
|
|
|
/* Build the bit length tree: */ |
|
build_tree(s, s.bl_desc); |
|
/* opt_len now includes the length of the tree representations, except |
|
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
|
*/ |
|
|
|
/* Determine the number of bit length codes to send. The pkzip format |
|
* requires that at least 4 bit length codes be sent. (appnote.txt says |
|
* 3 but the actual value used is 4.) |
|
*/ |
|
for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { |
|
if (s.bl_tree[bl_order[max_blindex]*2 + 1]/*.Len*/ !== 0) { |
|
break; |
|
} |
|
} |
|
/* Update opt_len to include the bit length tree and counts */ |
|
s.opt_len += 3*(max_blindex+1) + 5+5+4; |
|
//Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", |
|
// s->opt_len, s->static_len)); |
|
|
|
return max_blindex; |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Send the header for a block using dynamic Huffman trees: the counts, the |
|
* lengths of the bit length codes, the literal tree and the distance tree. |
|
* IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
|
*/ |
|
function send_all_trees(s, lcodes, dcodes, blcodes) |
|
// deflate_state *s; |
|
// int lcodes, dcodes, blcodes; /* number of codes for each tree */ |
|
{ |
|
var rank; /* index in bl_order */ |
|
|
|
//Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); |
|
//Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, |
|
// "too many codes"); |
|
//Tracev((stderr, "\nbl counts: ")); |
|
send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ |
|
send_bits(s, dcodes-1, 5); |
|
send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ |
|
for (rank = 0; rank < blcodes; rank++) { |
|
//Tracev((stderr, "\nbl code %2d ", bl_order[rank])); |
|
send_bits(s, s.bl_tree[bl_order[rank]*2 + 1]/*.Len*/, 3); |
|
} |
|
//Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); |
|
|
|
send_tree(s, s.dyn_ltree, lcodes-1); /* literal tree */ |
|
//Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); |
|
|
|
send_tree(s, s.dyn_dtree, dcodes-1); /* distance tree */ |
|
//Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Check if the data type is TEXT or BINARY, using the following algorithm: |
|
* - TEXT if the two conditions below are satisfied: |
|
* a) There are no non-portable control characters belonging to the |
|
* "black list" (0..6, 14..25, 28..31). |
|
* b) There is at least one printable character belonging to the |
|
* "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). |
|
* - BINARY otherwise. |
|
* - The following partially-portable control characters form a |
|
* "gray list" that is ignored in this detection algorithm: |
|
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). |
|
* IN assertion: the fields Freq of dyn_ltree are set. |
|
*/ |
|
function detect_data_type(s) { |
|
/* black_mask is the bit mask of black-listed bytes |
|
* set bits 0..6, 14..25, and 28..31 |
|
* 0xf3ffc07f = binary 11110011111111111100000001111111 |
|
*/ |
|
var black_mask = 0xf3ffc07f; |
|
var n; |
|
|
|
/* Check for non-textual ("black-listed") bytes. */ |
|
for (n = 0; n <= 31; n++, black_mask >>>= 1) { |
|
if ((black_mask & 1) && (s.dyn_ltree[n*2]/*.Freq*/ !== 0)) { |
|
return Z_BINARY; |
|
} |
|
} |
|
|
|
/* Check for textual ("white-listed") bytes. */ |
|
if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || |
|
s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { |
|
return Z_TEXT; |
|
} |
|
for (n = 32; n < LITERALS; n++) { |
|
if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { |
|
return Z_TEXT; |
|
} |
|
} |
|
|
|
/* There are no "black-listed" or "white-listed" bytes: |
|
* this stream either is empty or has tolerated ("gray-listed") bytes only. |
|
*/ |
|
return Z_BINARY; |
|
} |
|
|
|
|
|
var static_init_done = false; |
|
|
|
/* =========================================================================== |
|
* Initialize the tree data structures for a new zlib stream. |
|
*/ |
|
function _tr_init(s) |
|
{ |
|
|
|
if (!static_init_done) { |
|
tr_static_init(); |
|
static_init_done = true; |
|
} |
|
|
|
s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); |
|
s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); |
|
s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); |
|
|
|
s.bi_buf = 0; |
|
s.bi_valid = 0; |
|
|
|
/* Initialize the first block of the first file: */ |
|
init_block(s); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Send a stored block |
|
*/ |
|
function _tr_stored_block(s, buf, stored_len, last) |
|
//DeflateState *s; |
|
//charf *buf; /* input block */ |
|
//ulg stored_len; /* length of input block */ |
|
//int last; /* one if this is the last block for a file */ |
|
{ |
|
send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ |
|
copy_block(s, buf, stored_len, true); /* with header */ |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Send one empty static block to give enough lookahead for inflate. |
|
* This takes 10 bits, of which 7 may remain in the bit buffer. |
|
*/ |
|
function _tr_align(s) { |
|
send_bits(s, STATIC_TREES<<1, 3); |
|
send_code(s, END_BLOCK, static_ltree); |
|
bi_flush(s); |
|
} |
|
|
|
|
|
/* =========================================================================== |
|
* Determine the best encoding for the current block: dynamic trees, static |
|
* trees or store, and output the encoded block to the zip file. |
|
*/ |
|
function _tr_flush_block(s, buf, stored_len, last) |
|
//DeflateState *s; |
|
//charf *buf; /* input block, or NULL if too old */ |
|
//ulg stored_len; /* length of input block */ |
|
//int last; /* one if this is the last block for a file */ |
|
{ |
|
var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ |
|
var max_blindex = 0; /* index of last bit length code of non zero freq */ |
|
|
|
/* Build the Huffman trees unless a stored block is forced */ |
|
if (s.level > 0) { |
|
|
|
/* Check if the file is binary or text */ |
|
if (s.strm.data_type === Z_UNKNOWN) { |
|
s.strm.data_type = detect_data_type(s); |
|
} |
|
|
|
/* Construct the literal and distance trees */ |
|
build_tree(s, s.l_desc); |
|
// Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, |
|
// s->static_len)); |
|
|
|
build_tree(s, s.d_desc); |
|
// Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, |
|
// s->static_len)); |
|
/* At this point, opt_len and static_len are the total bit lengths of |
|
* the compressed block data, excluding the tree representations. |
|
*/ |
|
|
|
/* Build the bit length tree for the above two trees, and get the index |
|
* in bl_order of the last bit length code to send. |
|
*/ |
|
max_blindex = build_bl_tree(s); |
|
|
|
/* Determine the best encoding. Compute the block lengths in bytes. */ |
|
opt_lenb = (s.opt_len+3+7) >>> 3; |
|
static_lenb = (s.static_len+3+7) >>> 3; |
|
|
|
// Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
|
// opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
|
// s->last_lit)); |
|
|
|
if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } |
|
|
|
} else { |
|
// Assert(buf != (char*)0, "lost buf"); |
|
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ |
|
} |
|
|
|
if ((stored_len+4 <= opt_lenb) && (buf !== -1)) { |
|
/* 4: two words for the lengths */ |
|
|
|
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
|
* Otherwise we can't have processed more than WSIZE input bytes since |
|
* the last block flush, because compression would have been |
|
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
|
* transform a block into a stored block. |
|
*/ |
|
_tr_stored_block(s, buf, stored_len, last); |
|
|
|
} else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { |
|
|
|
send_bits(s, (STATIC_TREES<<1) + (last ? 1 : 0), 3); |
|
compress_block(s, static_ltree, static_dtree); |
|
|
|
} else { |
|
send_bits(s, (DYN_TREES<<1) + (last ? 1 : 0), 3); |
|
send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1, max_blindex+1); |
|
compress_block(s, s.dyn_ltree, s.dyn_dtree); |
|
} |
|
// Assert (s->compressed_len == s->bits_sent, "bad compressed size"); |
|
/* The above check is made mod 2^32, for files larger than 512 MB |
|
* and uLong implemented on 32 bits. |
|
*/ |
|
init_block(s); |
|
|
|
if (last) { |
|
bi_windup(s); |
|
} |
|
// Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, |
|
// s->compressed_len-7*last)); |
|
} |
|
|
|
/* =========================================================================== |
|
* Save the match info and tally the frequency counts. Return true if |
|
* the current block must be flushed. |
|
*/ |
|
function _tr_tally(s, dist, lc) |
|
// deflate_state *s; |
|
// unsigned dist; /* distance of matched string */ |
|
// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ |
|
{ |
|
//var out_length, in_length, dcode; |
|
|
|
s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; |
|
s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; |
|
|
|
s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; |
|
s.last_lit++; |
|
|
|
if (dist === 0) { |
|
/* lc is the unmatched char */ |
|
s.dyn_ltree[lc*2]/*.Freq*/++; |
|
} else { |
|
s.matches++; |
|
/* Here, lc is the match length - MIN_MATCH */ |
|
dist--; /* dist = match distance - 1 */ |
|
//Assert((ush)dist < (ush)MAX_DIST(s) && |
|
// (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && |
|
// (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); |
|
|
|
s.dyn_ltree[(_length_code[lc]+LITERALS+1) * 2]/*.Freq*/++; |
|
s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; |
|
} |
|
|
|
// (!) This block is disabled in zlib defailts, |
|
// don't enable it for binary compatibility |
|
|
|
//#ifdef TRUNCATE_BLOCK |
|
// /* Try to guess if it is profitable to stop the current block here */ |
|
// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { |
|
// /* Compute an upper bound for the compressed length */ |
|
// out_length = s.last_lit*8; |
|
// in_length = s.strstart - s.block_start; |
|
// |
|
// for (dcode = 0; dcode < D_CODES; dcode++) { |
|
// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); |
|
// } |
|
// out_length >>>= 3; |
|
// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", |
|
// // s->last_lit, in_length, out_length, |
|
// // 100L - out_length*100L/in_length)); |
|
// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { |
|
// return true; |
|
// } |
|
// } |
|
//#endif |
|
|
|
return (s.last_lit === s.lit_bufsize-1); |
|
/* We avoid equality with lit_bufsize because of wraparound at 64K |
|
* on 16 bit machines and because stored blocks are restricted to |
|
* 64K-1 bytes. |
|
*/ |
|
} |
|
|
|
exports._tr_init = _tr_init; |
|
exports._tr_stored_block = _tr_stored_block; |
|
exports._tr_flush_block = _tr_flush_block; |
|
exports._tr_tally = _tr_tally; |
|
exports._tr_align = _tr_align; |
|
|
|
},{"../utils/common":16}],26:[function(require,module,exports){ |
|
'use strict'; |
|
|
|
|
|
function ZStream() { |
|
/* next input byte */ |
|
this.input = null; // JS specific, because we have no pointers |
|
this.next_in = 0; |
|
/* number of bytes available at input */ |
|
this.avail_in = 0; |
|
/* total number of input bytes read so far */ |
|
this.total_in = 0; |
|
/* next output byte should be put there */ |
|
this.output = null; // JS specific, because we have no pointers |
|
this.next_out = 0; |
|
/* remaining free space at output */ |
|
this.avail_out = 0; |
|
/* total number of bytes output so far */ |
|
this.total_out = 0; |
|
/* last error message, NULL if no error */ |
|
this.msg = ''/*Z_NULL*/; |
|
/* not visible by applications */ |
|
this.state = null; |
|
/* best guess about the data type: binary or text */ |
|
this.data_type = 2/*Z_UNKNOWN*/; |
|
/* adler32 value of the uncompressed data */ |
|
this.adler = 0; |
|
} |
|
|
|
module.exports = ZStream; |
|
|
|
},{}],27:[function(require,module,exports){ |
|
(function (process){ |
|
'use strict'; |
|
|
|
if (!process.version || |
|
process.version.indexOf('v0.') === 0 || |
|
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { |
|
module.exports = nextTick; |
|
} else { |
|
module.exports = process.nextTick; |
|
} |
|
|
|
function nextTick(fn) { |
|
var args = new Array(arguments.length - 1); |
|
var i = 0; |
|
while (i < args.length) { |
|
args[i++] = arguments[i]; |
|
} |
|
process.nextTick(function afterTick() { |
|
fn.apply(null, args); |
|
}); |
|
} |
|
|
|
}).call(this,require('_process')) |
|
},{"_process":28}],28:[function(require,module,exports){ |
|
// shim for using process in browser |
|
|
|
var process = module.exports = {}; |
|
var queue = []; |
|
var draining = false; |
|
var currentQueue; |
|
var queueIndex = -1; |
|
|
|
function cleanUpNextTick() { |
|
draining = false; |
|
if (currentQueue.length) { |
|
queue = currentQueue.concat(queue); |
|
} else { |
|
queueIndex = -1; |
|
} |
|
if (queue.length) { |
|
drainQueue(); |
|
} |
|
} |
|
|
|
function drainQueue() { |
|
if (draining) { |
|
return; |
|
} |
|
var timeout = setTimeout(cleanUpNextTick); |
|
draining = true; |
|
|
|
var len = queue.length; |
|
while(len) { |
|
currentQueue = queue; |
|
queue = []; |
|
while (++queueIndex < len) { |
|
if (currentQueue) { |
|
currentQueue[queueIndex].run(); |
|
} |
|
} |
|
queueIndex = -1; |
|
len = queue.length; |
|
} |
|
currentQueue = null; |
|
draining = false; |
|
clearTimeout(timeout); |
|
} |
|
|
|
process.nextTick = function (fun) { |
|
var args = new Array(arguments.length - 1); |
|
if (arguments.length > 1) { |
|
for (var i = 1; i < arguments.length; i++) { |
|
args[i - 1] = arguments[i]; |
|
} |
|
} |
|
queue.push(new Item(fun, args)); |
|
if (queue.length === 1 && !draining) { |
|
setTimeout(drainQueue, 0); |
|
} |
|
}; |
|
|
|
// v8 likes predictible objects |
|
function Item(fun, array) { |
|
this.fun = fun; |
|
this.array = array; |
|
} |
|
Item.prototype.run = function () { |
|
this.fun.apply(null, this.array); |
|
}; |
|
process.title = 'browser'; |
|
process.browser = true; |
|
process.env = {}; |
|
process.argv = []; |
|
process.version = ''; // empty string to avoid regexp issues |
|
process.versions = {}; |
|
|
|
function noop() {} |
|
|
|
process.on = noop; |
|
process.addListener = noop; |
|
process.once = noop; |
|
process.off = noop; |
|
process.removeListener = noop; |
|
process.removeAllListeners = noop; |
|
process.emit = noop; |
|
|
|
process.binding = function (name) { |
|
throw new Error('process.binding is not supported'); |
|
}; |
|
|
|
process.cwd = function () { return '/' }; |
|
process.chdir = function (dir) { |
|
throw new Error('process.chdir is not supported'); |
|
}; |
|
process.umask = function() { return 0; }; |
|
|
|
},{}],29:[function(require,module,exports){ |
|
// a duplex stream is just a stream that is both readable and writable. |
|
// Since JS doesn't have multiple prototypal inheritance, this class |
|
// prototypally inherits from Readable, and then parasitically from |
|
// Writable. |
|
|
|
'use strict'; |
|
|
|
/*<replacement>*/ |
|
var objectKeys = Object.keys || function (obj) { |
|
var keys = []; |
|
for (var key in obj) keys.push(key); |
|
return keys; |
|
} |
|
/*</replacement>*/ |
|
|
|
|
|
module.exports = Duplex; |
|
|
|
/*<replacement>*/ |
|
var processNextTick = require('process-nextick-args'); |
|
/*</replacement>*/ |
|
|
|
|
|
|
|
/*<replacement>*/ |
|
var util = require('core-util-is'); |
|
util.inherits = require('inherits'); |
|
/*</replacement>*/ |
|
|
|
var Readable = require('./_stream_readable'); |
|
var Writable = require('./_stream_writable'); |
|
|
|
util.inherits(Duplex, Readable); |
|
|
|
var keys = objectKeys(Writable.prototype); |
|
for (var v = 0; v < keys.length; v++) { |
|
var method = keys[v]; |
|
if (!Duplex.prototype[method]) |
|
Duplex.prototype[method] = Writable.prototype[method]; |
|
} |
|
|
|
function Duplex(options) { |
|
if (!(this instanceof Duplex)) |
|
return new Duplex(options); |
|
|
|
Readable.call(this, options); |
|
Writable.call(this, options); |
|
|
|
if (options && options.readable === false) |
|
this.readable = false; |
|
|
|
if (options && options.writable === false) |
|
this.writable = false; |
|
|
|
this.allowHalfOpen = true; |
|
if (options && options.allowHalfOpen === false) |
|
this.allowHalfOpen = false; |
|
|
|
this.once('end', onend); |
|
} |
|
|
|
// the no-half-open enforcer |
|
function onend() { |
|
// if we allow half-open state, or if the writable side ended, |
|
// then we're ok. |
|
if (this.allowHalfOpen || this._writableState.ended) |
|
return; |
|
|
|
// no more data can be written. |
|
// But allow more writes to happen in this tick. |
|
processNextTick(onEndNT, this); |
|
} |
|
|
|
function onEndNT(self) { |
|
self.end(); |
|
} |
|
|
|
function forEach (xs, f) { |
|
for (var i = 0, l = xs.length; i < l; i++) { |
|
f(xs[i], i); |
|
} |
|
} |
|
|
|
},{"./_stream_readable":30,"./_stream_writable":32,"core-util-is":10,"inherits":13,"process-nextick-args":27}],30:[function(require,module,exports){ |
|
(function (process){ |
|
'use strict'; |
|
|
|
module.exports = Readable; |
|
|
|
/*<replacement>*/ |
|
var processNextTick = require('process-nextick-args'); |
|
/*</replacement>*/ |
|
|
|
|
|
/*<replacement>*/ |
|
var isArray = require('isarray'); |
|
/*</replacement>*/ |
|
|
|
|
|
/*<replacement>*/ |
|
var Buffer = require('buffer').Buffer; |
|
/*</replacement>*/ |
|
|
|
Readable.ReadableState = ReadableState; |
|
|
|
var EE = require('events'); |
|
|
|
/*<replacement>*/ |
|
var EElistenerCount = function(emitter, type) { |
|
return emitter.listeners(type).length; |
|
}; |
|
/*</replacement>*/ |
|
|
|
|
|
|
|
/*<replacement>*/ |
|
var Stream; |
|
(function (){try{ |
|
Stream = require('st' + 'ream'); |
|
}catch(_){}finally{ |
|
if (!Stream) |
|
Stream = require('events').EventEmitter; |
|
}}()) |
|
/*</replacement>*/ |
|
|
|
var Buffer = require('buffer').Buffer; |
|
|
|
/*<replacement>*/ |
|
var util = require('core-util-is'); |
|
util.inherits = require('inherits'); |
|
/*</replacement>*/ |
|
|
|
|
|
|
|
/*<replacement>*/ |
|
var debugUtil = require('util'); |
|
var debug; |
|
if (debugUtil && debugUtil.debuglog) { |
|
debug = debugUtil.debuglog('stream'); |
|
} else { |
|
debug = function () {}; |
|
} |
|
/*</replacement>*/ |
|
|
|
var StringDecoder; |
|
|
|
util.inherits(Readable, Stream); |
|
|
|
var Duplex; |
|
function ReadableState(options, stream) { |
|
Duplex = Duplex || require('./_stream_duplex'); |
|
|
|
options = options || {}; |
|
|
|
// object stream flag. Used to make read(n) ignore n and to |
|
// make all the buffer merging and length checks go away |
|
this.objectMode = !!options.objectMode; |
|
|
|
if (stream instanceof Duplex) |
|
this.objectMode = this.objectMode || !!options.readableObjectMode; |
|
|
|
// the point at which it stops calling _read() to fill the buffer |
|
// Note: 0 is a valid value, means "don't call _read preemptively ever" |
|
var hwm = options.highWaterMark; |
|
var defaultHwm = this.objectMode ? 16 : 16 * 1024; |
|
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; |
|
|
|
// cast to ints. |
|
this.highWaterMark = ~~this.highWaterMark; |
|
|
|
this.buffer = []; |
|
this.length = 0; |
|
this.pipes = null; |
|
this.pipesCount = 0; |
|
this.flowing = null; |
|
this.ended = false; |
|
this.endEmitted = false; |
|
this.reading = false; |
|
|
|
// a flag to be able to tell if the onwrite cb is called immediately, |
|
// or on a later tick. We set this to true at first, because any |
|
// actions that shouldn't happen until "later" should generally also |
|
// not happen before the first write call. |
|
this.sync = true; |
|
|
|
// whenever we return null, then we set a flag to say |
|
// that we're awaiting a 'readable' event emission. |
|
this.needReadable = false; |
|
this.emittedReadable = false; |
|
this.readableListening = false; |
|
|
|
// Crypto is kind of old and crusty. Historically, its default string |
|
// encoding is 'binary' so we have to make this configurable. |
|
// Everything else in the universe uses 'utf8', though. |
|
this.defaultEncoding = options.defaultEncoding || 'utf8'; |
|
|
|
// when piping, we only care about 'readable' events that happen |
|
// after read()ing all the bytes and not getting any pushback. |
|
this.ranOut = false; |
|
|
|
// the number of writers that are awaiting a drain event in .pipe()s |
|
this.awaitDrain = 0; |
|
|
|
// if true, a maybeReadMore has been scheduled |
|
this.readingMore = false; |
|
|
|
this.decoder = null; |
|
this.encoding = null; |
|
if (options.encoding) { |
|
if (!StringDecoder) |
|
StringDecoder = require('string_decoder/').StringDecoder; |
|
this.decoder = new StringDecoder(options.encoding); |
|
this.encoding = options.encoding; |
|
} |
|
} |
|
|
|
var Duplex; |
|
function Readable(options) { |
|
Duplex = Duplex || require('./_stream_duplex'); |
|
|
|
if (!(this instanceof Readable)) |
|
return new Readable(options); |
|
|
|
this._readableState = new ReadableState(options, this); |
|
|
|
// legacy |
|
this.readable = true; |
|
|
|
if (options && typeof options.read === 'function') |
|
this._read = options.read; |
|
|
|
Stream.call(this); |
|
} |
|
|
|
// Manually shove something into the read() buffer. |
|
// This returns true if the highWaterMark has not been hit yet, |
|
// similar to how Writable.write() returns true if you should |
|
// write() some more. |
|
Readable.prototype.push = function(chunk, encoding) { |
|
var state = this._readableState; |
|
|
|
if (!state.objectMode && typeof chunk === 'string') { |
|
encoding = encoding || state.defaultEncoding; |
|
if (encoding !== state.encoding) { |
|
chunk = new Buffer(chunk, encoding); |
|
encoding = ''; |
|
} |
|
} |
|
|
|
return readableAddChunk(this, state, chunk, encoding, false); |
|
}; |
|
|
|
// Unshift should *always* be something directly out of read() |
|
Readable.prototype.unshift = function(chunk) { |
|
var state = this._readableState; |
|
return readableAddChunk(this, state, chunk, '', true); |
|
}; |
|
|
|
Readable.prototype.isPaused = function() { |
|
return this._readableState.flowing === false; |
|
}; |
|
|
|
function readableAddChunk(stream, state, chunk, encoding, addToFront) { |
|
var er = chunkInvalid(state, chunk); |
|
if (er) { |
|
stream.emit('error', er); |
|
} else if (chunk === null) { |
|
state.reading = false; |
|
onEofChunk(stream, state); |
|
} else if (state.objectMode || chunk && chunk.length > 0) { |
|
if (state.ended && !addToFront) { |
|
var e = new Error('stream.push() after EOF'); |
|
stream.emit('error', e); |
|
} else if (state.endEmitted && addToFront) { |
|
var e = new Error('stream.unshift() after end event'); |
|
stream.emit('error', e); |
|
} else { |
|
if (state.decoder && !addToFront && !encoding) |
|
chunk = state.decoder.write(chunk); |
|
|
|
if (!addToFront) |
|
state.reading = false; |
|
|
|
// if we want the data now, just emit it. |
|
if (state.flowing && state.length === 0 && !state.sync) { |
|
stream.emit('data', chunk); |
|
stream.read(0); |
|
} else { |
|
// update the buffer info. |
|
state.length += state.objectMode ? 1 : chunk.length; |
|
if (addToFront) |
|
state.buffer.unshift(chunk); |
|
else |
|
state.buffer.push(chunk); |
|
|
|
if (state.needReadable) |
|
emitReadable(stream); |
|
} |
|
|
|
maybeReadMore(stream, state); |
|
} |
|
} else if (!addToFront) { |
|
state.reading = false; |
|
} |
|
|
|
return needMoreData(state); |
|
} |
|
|
|
|
|
// if it's past the high water mark, we can push in some more. |
|
// Also, if we have no data yet, we can stand some |
|
// more bytes. This is to work around cases where hwm=0, |
|
// such as the repl. Also, if the push() triggered a |
|
// readable event, and the user called read(largeNumber) such that |
|
// needReadable was set, then we ought to push more, so that another |
|
// 'readable' event will be triggered. |
|
function needMoreData(state) { |
|
return !state.ended && |
|
(state.needReadable || |
|
state.length < state.highWaterMark || |
|
state.length === 0); |
|
} |
|
|
|
// backwards compatibility. |
|
Readable.prototype.setEncoding = function(enc) { |
|
if (!StringDecoder) |
|
StringDecoder = require('string_decoder/').StringDecoder; |
|
this._readableState.decoder = new StringDecoder(enc); |
|
this._readableState.encoding = enc; |
|
return this; |
|
}; |
|
|
|
// Don't raise the hwm > 8MB |
|
var MAX_HWM = 0x800000; |
|
function computeNewHighWaterMark(n) { |
|
if (n >= MAX_HWM) { |
|
n = MAX_HWM; |
|
} else { |
|
// Get the next highest power of 2 |
|
n--; |
|
n |= n >>> 1; |
|
n |= n >>> 2; |
|
n |= n >>> 4; |
|
n |= n >>> 8; |
|
n |= n >>> 16; |
|
n++; |
|
} |
|
return n; |
|
} |
|
|
|
function howMuchToRead(n, state) { |
|
if (state.length === 0 && state.ended) |
|
return 0; |
|
|
|
if (state.objectMode) |
|
return n === 0 ? 0 : 1; |
|
|
|
if (n === null || isNaN(n)) { |
|
// only flow one buffer at a time |
|
if (state.flowing && state.buffer.length) |
|
return state.buffer[0].length; |
|
else |
|
return state.length; |
|
} |
|
|
|
if (n <= 0) |
|
return 0; |
|
|
|
// If we're asking for more than the target buffer level, |
|
// then raise the water mark. Bump up to the next highest |
|
// power of 2, to prevent increasing it excessively in tiny |
|
// amounts. |
|
if (n > state.highWaterMark) |
|
state.highWaterMark = computeNewHighWaterMark(n); |
|
|
|
// don't have that much. return null, unless we've ended. |
|
if (n > state.length) { |
|
if (!state.ended) { |
|
state.needReadable = true; |
|
return 0; |
|
} else { |
|
return state.length; |
|
} |
|
} |
|
|
|
return n; |
|
} |
|
|
|
// you can override either this method, or the async _read(n) below. |
|
Readable.prototype.read = function(n) { |
|
debug('read', n); |
|
var state = this._readableState; |
|
var nOrig = n; |
|
|
|
if (typeof n !== 'number' || n > 0) |
|
state.emittedReadable = false; |
|
|
|
// if we're doing read(0) to trigger a readable event, but we |
|
// already have a bunch of data in the buffer, then just trigger |
|
// the 'readable' event and move on. |
|
if (n === 0 && |
|
state.needReadable && |
|
(state.length >= state.highWaterMark || state.ended)) { |
|
debug('read: emitReadable', state.length, state.ended); |
|
if (state.length === 0 && state.ended) |
|
endReadable(this); |
|
else |
|
emitReadable(this); |
|
return null; |
|
} |
|
|
|
n = howMuchToRead(n, state); |
|
|
|
// if we've ended, and we're now clear, then finish it up. |
|
if (n === 0 && state.ended) { |
|
if (state.length === 0) |
|
endReadable(this); |
|
return null; |
|
} |
|
|
|
// All the actual chunk generation logic needs to be |
|
// *below* the call to _read. The reason is that in certain |
|
// synthetic stream cases, such as passthrough streams, _read |
|
// may be a completely synchronous operation which may change |
|
// the state of the read buffer, providing enough data when |
|
// before there was *not* enough. |
|
// |
|
// So, the steps are: |
|
// 1. Figure out what the state of things will be after we do |
|
// a read from the buffer. |
|
// |
|
// 2. If that resulting state will trigger a _read, then call _read. |
|
// Note that this may be asynchronous, or synchronous. Yes, it is |
|
// deeply ugly to write APIs this way, but that still doesn't mean |
|
// that the Readable class should behave improperly, as streams are |
|
// designed to be sync/async agnostic. |
|
// Take note if the _read call is sync or async (ie, if the read call |
|
// has returned yet), so that we know whether or not it's safe to emit |
|
// 'readable' etc. |
|
// |
|
// 3. Actually pull the requested chunks out of the buffer and return. |
|
|
|
// if we need a readable event, then we need to do some reading. |
|
var doRead = state.needReadable; |
|
debug('need readable', doRead); |
|
|
|
// if we currently have less than the highWaterMark, then also read some |
|
if (state.length === 0 || state.length - n < state.highWaterMark) { |
|
doRead = true; |
|
debug('length less than watermark', doRead); |
|
} |
|
|
|
// however, if we've ended, then there's no point, and if we're already |
|
// reading, then it's unnecessary. |
|
if (state.ended || state.reading) { |
|
doRead = false; |
|
debug('reading or ended', doRead); |
|
} |
|
|
|
if (doRead) { |
|
debug('do read'); |
|
state.reading = true; |
|
state.sync = true; |
|
// if the length is currently zero, then we *need* a readable event. |
|
if (state.length === 0) |
|
state.needReadable = true; |
|
// call internal read method |
|
this._read(state.highWaterMark); |
|
state.sync = false; |
|
} |
|
|
|
// If _read pushed data synchronously, then `reading` will be false, |
|
// and we need to re-evaluate how much data we can return to the user. |
|
if (doRead && !state.reading) |
|
n = howMuchToRead(nOrig, state); |
|
|
|
var ret; |
|
if (n > 0) |
|
ret = fromList(n, state); |
|
else |
|
ret = null; |
|
|
|
if (ret === null) { |
|
state.needReadable = true; |
|
n = 0; |
|
} |
|
|
|
state.length -= n; |
|
|
|
// If we have nothing in the buffer, then we want to know |
|
// as soon as we *do* get something into the buffer. |
|
if (state.length === 0 && !state.ended) |
|
state.needReadable = true; |
|
|
|
// If we tried to read() past the EOF, then emit end on the next tick. |
|
if (nOrig !== n && state.ended && state.length === 0) |
|
endReadable(this); |
|
|
|
if (ret !== null) |
|
this.emit('data', ret); |
|
|
|
return ret; |
|
}; |
|
|
|
function chunkInvalid(state, chunk) { |
|
var er = null; |
|
if (!(Buffer.isBuffer(chunk)) && |
|
typeof chunk !== 'string' && |
|
chunk !== null && |
|
chunk !== undefined && |
|
!state.objectMode) { |
|
er = new TypeError('Invalid non-string/buffer chunk'); |
|
} |
|
return er; |
|
} |
|
|
|
|
|
function onEofChunk(stream, state) { |
|
if (state.ended) return; |
|
if (state.decoder) { |
|
var chunk = state.decoder.end(); |
|
if (chunk && chunk.length) { |
|
state.buffer.push(chunk); |
|
state.length += state.objectMode ? 1 : chunk.length; |
|
} |
|
} |
|
state.ended = true; |
|
|
|
// emit 'readable' now to make sure it gets picked up. |
|
emitReadable(stream); |
|
} |
|
|
|
// Don't emit readable right away in sync mode, because this can trigger |
|
// another read() call => stack overflow. This way, it might trigger |
|
// a nextTick recursion warning, but that's not so bad. |
|
function emitReadable(stream) { |
|
var state = stream._readableState; |
|
state.needReadable = false; |
|
if (!state.emittedReadable) { |
|
debug('emitReadable', state.flowing); |
|
state.emittedReadable = true; |
|
if (state.sync) |
|
processNextTick(emitReadable_, stream); |
|
else |
|
emitReadable_(stream); |
|
} |
|
} |
|
|
|
function emitReadable_(stream) { |
|
debug('emit readable'); |
|
stream.emit('readable'); |
|
flow(stream); |
|
} |
|
|
|
|
|
// at this point, the user has presumably seen the 'readable' event, |
|
// and called read() to consume some data. that may have triggered |
|
// in turn another _read(n) call, in which case reading = true if |
|
// it's in progress. |
|
// However, if we're not ended, or reading, and the length < hwm, |
|
// then go ahead and try to read some more preemptively. |
|
function maybeReadMore(stream, state) { |
|
if (!state.readingMore) { |
|
state.readingMore = true; |
|
processNextTick(maybeReadMore_, stream, state); |
|
} |
|
} |
|
|
|
function maybeReadMore_(stream, state) { |
|
var len = state.length; |
|
while (!state.reading && !state.flowing && !state.ended && |
|
state.length < state.highWaterMark) { |
|
debug('maybeReadMore read 0'); |
|
stream.read(0); |
|
if (len === state.length) |
|
// didn't get any data, stop spinning. |
|
break; |
|
else |
|
len = state.length; |
|
} |
|
state.readingMore = false; |
|
} |
|
|
|
// abstract method. to be overridden in specific implementation classes. |
|
// call cb(er, data) where data is <= n in length. |
|
// for virtual (non-string, non-buffer) streams, "length" is somewhat |
|
// arbitrary, and perhaps not very meaningful. |
|
Readable.prototype._read = function(n) { |
|
this.emit('error', new Error('not implemented')); |
|
}; |
|
|
|
Readable.prototype.pipe = function(dest, pipeOpts) { |
|
var src = this; |
|
var state = this._readableState; |
|
|
|
switch (state.pipesCount) { |
|
case 0: |
|
state.pipes = dest; |
|
break; |
|
case 1: |
|
state.pipes = [state.pipes, dest]; |
|
break; |
|
default: |
|
state.pipes.push(dest); |
|
break; |
|
} |
|
state.pipesCount += 1; |
|
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); |
|
|
|
var doEnd = (!pipeOpts || pipeOpts.end !== false) && |
|
dest !== process.stdout && |
|
dest !== process.stderr; |
|
|
|
var endFn = doEnd ? onend : cleanup; |
|
if (state.endEmitted) |
|
processNextTick(endFn); |
|
else |
|
src.once('end', endFn); |
|
|
|
dest.on('unpipe', onunpipe); |
|
function onunpipe(readable) { |
|
debug('onunpipe'); |
|
if (readable === src) { |
|
cleanup(); |
|
} |
|
} |
|
|
|
function onend() { |
|
debug('onend'); |
|
dest.end(); |
|
} |
|
|
|
// when the dest drains, it reduces the awaitDrain counter |
|
// on the source. This would be more elegant with a .once() |
|
// handler in flow(), but adding and removing repeatedly is |
|
// too slow. |
|
var ondrain = pipeOnDrain(src); |
|
dest.on('drain', ondrain); |
|
|
|
var cleanedUp = false; |
|
function cleanup() { |
|
debug('cleanup'); |
|
// cleanup event handlers once the pipe is broken |
|
dest.removeListener('close', onclose); |
|
dest.removeListener('finish', onfinish); |
|
dest.removeListener('drain', ondrain); |
|
dest.removeListener('error', onerror); |
|
dest.removeListener('unpipe', onunpipe); |
|
src.removeListener('end', onend); |
|
src.removeListener('end', cleanup); |
|
src.removeListener('data', ondata); |
|
|
|
cleanedUp = true; |
|
|
|
// if the reader is waiting for a drain event from this |
|
// specific writer, then it would cause it to never start |
|
// flowing again. |
|
// So, if this is awaiting a drain, then we just call it now. |
|
// If we don't know, then assume that we are waiting for one. |
|
if (state.awaitDrain && |
|
(!dest._writableState || dest._writableState.needDrain)) |
|
ondrain(); |
|
} |
|
|
|
src.on('data', ondata); |
|
function ondata(chunk) { |
|
debug('ondata'); |
|
var ret = dest.write(chunk); |
|
if (false === ret) { |
|
// If the user unpiped during `dest.write()`, it is possible |
|
// to get stuck in a permanently paused state if that write |
|
// also returned false. |
|
if (state.pipesCount === 1 && |
|
state.pipes[0] === dest && |
|
src.listenerCount('data') === 1 && |
|
!cleanedUp) { |
|
debug('false write response, pause', src._readableState.awaitDrain); |
|
src._readableState.awaitDrain++; |
|
} |
|
src.pause(); |
|
} |
|
} |
|
|
|
// if the dest has an error, then stop piping into it. |
|
// however, don't suppress the throwing behavior for this. |
|
function onerror(er) { |
|
debug('onerror', er); |
|
unpipe(); |
|
dest.removeListener('error', onerror); |
|
if (EElistenerCount(dest, 'error') === 0) |
|
dest.emit('error', er); |
|
} |
|
// This is a brutally ugly hack to make sure that our error handler |
|
// is attached before any userland ones. NEVER DO THIS. |
|
if (!dest._events || !dest._events.error) |
|
dest.on('error', onerror); |
|
else if (isArray(dest._events.error)) |
|
dest._events.error.unshift(onerror); |
|
else |
|
dest._events.error = [onerror, dest._events.error]; |
|
|
|
|
|
// Both close and finish should trigger unpipe, but only once. |
|
function onclose() { |
|
dest.removeListener('finish', onfinish); |
|
unpipe(); |
|
} |
|
dest.once('close', onclose); |
|
function onfinish() { |
|
debug('onfinish'); |
|
dest.removeListener('close', onclose); |
|
unpipe(); |
|
} |
|
dest.once('finish', onfinish); |
|
|
|
function unpipe() { |
|
debug('unpipe'); |
|
src.unpipe(dest); |
|
} |
|
|
|
// tell the dest that it's being piped to |
|
dest.emit('pipe', src); |
|
|
|
// start the flow if it hasn't been started already. |
|
if (!state.flowing) { |
|
debug('pipe resume'); |
|
src.resume(); |
|
} |
|
|
|
return dest; |
|
}; |
|
|
|
function pipeOnDrain(src) { |
|
return function() { |
|
var state = src._readableState; |
|
debug('pipeOnDrain', state.awaitDrain); |
|
if (state.awaitDrain) |
|
state.awaitDrain--; |
|
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { |
|
state.flowing = true; |
|
flow(src); |
|
} |
|
}; |
|
} |
|
|
|
|
|
Readable.prototype.unpipe = function(dest) { |
|
var state = this._readableState; |
|
|
|
// if we're not piping anywhere, then do nothing. |
|
if (state.pipesCount === 0) |
|
return this; |
|
|
|
// just one destination. most common case. |
|
if (state.pipesCount === 1) { |
|
// passed in one, but it's not the right one. |
|
if (dest && dest !== state.pipes) |
|
return this; |
|
|
|
if (!dest) |
|
dest = state.pipes; |
|
|
|
// got a match. |
|
state.pipes = null; |
|
state.pipesCount = 0; |
|
state.flowing = false; |
|
if (dest) |
|
dest.emit('unpipe', this); |
|
return this; |
|
} |
|
|
|
// slow case. multiple pipe destinations. |
|
|
|
if (!dest) { |
|
// remove all. |
|
var dests = state.pipes; |
|
var len = state.pipesCount; |
|
state.pipes = null; |
|
state.pipesCount = 0; |
|
state.flowing = false; |
|
|
|
for (var i = 0; i < len; i++) |
|
dests[i].emit('unpipe', this); |
|
return this; |
|
} |
|
|
|
// try to find the right one. |
|
var i = indexOf(state.pipes, dest); |
|
if (i === -1) |
|
return this; |
|
|
|
state.pipes.splice(i, 1); |
|
state.pipesCount -= 1; |
|
if (state.pipesCount === 1) |
|
state.pipes = state.pipes[0]; |
|
|
|
dest.emit('unpipe', this); |
|
|
|
return this; |
|
}; |
|
|
|
// set up data events if they are asked for |
|
// Ensure readable listeners eventually get something |
|
Readable.prototype.on = function(ev, fn) { |
|
var res = Stream.prototype.on.call(this, ev, fn); |
|
|
|
// If listening to data, and it has not explicitly been paused, |
|
// then call resume to start the flow of data on the next tick. |
|
if (ev === 'data' && false !== this._readableState.flowing) { |
|
this.resume(); |
|
} |
|
|
|
if (ev === 'readable' && this.readable) { |
|
var state = this._readableState; |
|
if (!state.readableListening) { |
|
state.readableListening = true; |
|
state.emittedReadable = false; |
|
state.needReadable = true; |
|
if (!state.reading) { |
|
processNextTick(nReadingNextTick, this); |
|
} else if (state.length) { |
|
emitReadable(this, state); |
|
} |
|
} |
|
} |
|
|
|
return res; |
|
}; |
|
Readable.prototype.addListener = Readable.prototype.on; |
|
|
|
function nReadingNextTick(self) { |
|
debug('readable nexttick read 0'); |
|
self.read(0); |
|
} |
|
|
|
// pause() and resume() are remnants of the legacy readable stream API |
|
// If the user uses them, then switch into old mode. |
|
Readable.prototype.resume = function() { |
|
var state = this._readableState; |
|
if (!state.flowing) { |
|
debug('resume'); |
|
state.flowing = true; |
|
resume(this, state); |
|
} |
|
return this; |
|
}; |
|
|
|
function resume(stream, state) { |
|
if (!state.resumeScheduled) { |
|
state.resumeScheduled = true; |
|
processNextTick(resume_, stream, state); |
|
} |
|
} |
|
|
|
function resume_(stream, state) { |
|
if (!state.reading) { |
|
debug('resume read 0'); |
|
stream.read(0); |
|
} |
|
|
|
state.resumeScheduled = false; |
|
stream.emit('resume'); |
|
flow(stream); |
|
if (state.flowing && !state.reading) |
|
stream.read(0); |
|
} |
|
|
|
Readable.prototype.pause = function() { |
|
debug('call pause flowing=%j', this._readableState.flowing); |
|
if (false !== this._readableState.flowing) { |
|
debug('pause'); |
|
this._readableState.flowing = false; |
|
this.emit('pause'); |
|
} |
|
return this; |
|
}; |
|
|
|
function flow(stream) { |
|
var state = stream._readableState; |
|
debug('flow', state.flowing); |
|
if (state.flowing) { |
|
do { |
|
var chunk = stream.read(); |
|
} while (null !== chunk && state.flowing); |
|
} |
|
} |
|
|
|
// wrap an old-style stream as the async data source. |
|
// This is *not* part of the readable stream interface. |
|
// It is an ugly unfortunate mess of history. |
|
Readable.prototype.wrap = function(stream) { |
|
var state = this._readableState; |
|
var paused = false; |
|
|
|
var self = this; |
|
stream.on('end', function() { |
|
debug('wrapped end'); |
|
if (state.decoder && !state.ended) { |
|
var chunk = state.decoder.end(); |
|
if (chunk && chunk.length) |
|
self.push(chunk); |
|
} |
|
|
|
self.push(null); |
|
}); |
|
|
|
stream.on('data', function(chunk) { |
|
debug('wrapped data'); |
|
if (state.decoder) |
|
chunk = state.decoder.write(chunk); |
|
|
|
// don't skip over falsy values in objectMode |
|
if (state.objectMode && (chunk === null || chunk === undefined)) |
|
return; |
|
else if (!state.objectMode && (!chunk || !chunk.length)) |
|
return; |
|
|
|
var ret = self.push(chunk); |
|
if (!ret) { |
|
paused = true; |
|
stream.pause(); |
|
} |
|
}); |
|
|
|
// proxy all the other methods. |
|
// important when wrapping filters and duplexes. |
|
for (var i in stream) { |
|
if (this[i] === undefined && typeof stream[i] === 'function') { |
|
this[i] = function(method) { return function() { |
|
return stream[method].apply(stream, arguments); |
|
}; }(i); |
|
} |
|
} |
|
|
|
// proxy certain important events. |
|
var events = ['error', 'close', 'destroy', 'pause', 'resume']; |
|
forEach(events, function(ev) { |
|
stream.on(ev, self.emit.bind(self, ev)); |
|
}); |
|
|
|
// when we try to consume some more bytes, simply unpause the |
|
// underlying stream. |
|
self._read = function(n) { |
|
debug('wrapped _read', n); |
|
if (paused) { |
|
paused = false; |
|
stream.resume(); |
|
} |
|
}; |
|
|
|
return self; |
|
}; |
|
|
|
|
|
// exposed for testing purposes only. |
|
Readable._fromList = fromList; |
|
|
|
// Pluck off n bytes from an array of buffers. |
|
// Length is the combined lengths of all the buffers in the list. |
|
function fromList(n, state) { |
|
var list = state.buffer; |
|
var length = state.length; |
|
var stringMode = !!state.decoder; |
|
var objectMode = !!state.objectMode; |
|
var ret; |
|
|
|
// nothing in the list, definitely empty. |
|
if (list.length === 0) |
|
return null; |
|
|
|
if (length === 0) |
|
ret = null; |
|
else if (objectMode) |
|
ret = list.shift(); |
|
else if (!n || n >= length) { |
|
// read it all, truncate the array. |
|
if (stringMode) |
|
ret = list.join(''); |
|
else if (list.length === 1) |
|
ret = list[0]; |
|
else |
|
ret = Buffer.concat(list, length); |
|
list.length = 0; |
|
} else { |
|
// read just some of it. |
|
if (n < list[0].length) { |
|
// just take a part of the first list item. |
|
// slice is the same for buffers and strings. |
|
var buf = list[0]; |
|
ret = buf.slice(0, n); |
|
list[0] = buf.slice(n); |
|
} else if (n === list[0].length) { |
|
// first list is a perfect match |
|
ret = list.shift(); |
|
} else { |
|
// complex case. |
|
// we have enough to cover it, but it spans past the first buffer. |
|
if (stringMode) |
|
ret = ''; |
|
else |
|
ret = new Buffer(n); |
|
|
|
var c = 0; |
|
for (var i = 0, l = list.length; i < l && c < n; i++) { |
|
var buf = list[0]; |
|
var cpy = Math.min(n - c, buf.length); |
|
|
|
if (stringMode) |
|
ret += buf.slice(0, cpy); |
|
else |
|
buf.copy(ret, c, 0, cpy); |
|
|
|
if (cpy < buf.length) |
|
list[0] = buf.slice(cpy); |
|
else |
|
list.shift(); |
|
|
|
c += cpy; |
|
} |
|
} |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
function endReadable(stream) { |
|
var state = stream._readableState; |
|
|
|
// If we get here before consuming all the bytes, then that is a |
|
// bug in node. Should never happen. |
|
if (state.length > 0) |
|
throw new Error('endReadable called on non-empty stream'); |
|
|
|
if (!state.endEmitted) { |
|
state.ended = true; |
|
processNextTick(endReadableNT, state, stream); |
|
} |
|
} |
|
|
|
function endReadableNT(state, stream) { |
|
// Check that we didn't get one last unshift. |
|
if (!state.endEmitted && state.length === 0) { |
|
state.endEmitted = true; |
|
stream.readable = false; |
|
stream.emit('end'); |
|
} |
|
} |
|
|
|
function forEach (xs, f) { |
|
for (var i = 0, l = xs.length; i < l; i++) { |
|
f(xs[i], i); |
|
} |
|
} |
|
|
|
function indexOf (xs, x) { |
|
for (var i = 0, l = xs.length; i < l; i++) { |
|
if (xs[i] === x) return i; |
|
} |
|
return -1; |
|
} |
|
|
|
}).call(this,require('_process')) |
|
},{"./_stream_duplex":29,"_process":28,"buffer":8,"core-util-is":10,"events":11,"inherits":13,"isarray":15,"process-nextick-args":27,"string_decoder/":34,"util":5}],31:[function(require,module,exports){ |
|
// a transform stream is a readable/writable stream where you do |
|
// something with the data. Sometimes it's called a "filter", |
|
// but that's not a great name for it, since that implies a thing where |
|
// some bits pass through, and others are simply ignored. (That would |
|
// be a valid example of a transform, of course.) |
|
// |
|
// While the output is causally related to the input, it's not a |
|
// necessarily symmetric or synchronous transformation. For example, |
|
// a zlib stream might take multiple plain-text writes(), and then |
|
// emit a single compressed chunk some time in the future. |
|
// |
|
// Here's how this works: |
|
// |
|
// The Transform stream has all the aspects of the readable and writable |
|
// stream classes. When you write(chunk), that calls _write(chunk,cb) |
|
// internally, and returns false if there's a lot of pending writes |
|
// buffered up. When you call read(), that calls _read(n) until |
|
// there's enough pending readable data buffered up. |
|
// |
|
// In a transform stream, the written data is placed in a buffer. When |
|
// _read(n) is called, it transforms the queued up data, calling the |
|
// buffered _write cb's as it consumes chunks. If consuming a single |
|
// written chunk would result in multiple output chunks, then the first |
|
// outputted bit calls the readcb, and subsequent chunks just go into |
|
// the read buffer, and will cause it to emit 'readable' if necessary. |
|
// |
|
// This way, back-pressure is actually determined by the reading side, |
|
// since _read has to be called to start processing a new chunk. However, |
|
// a pathological inflate type of transform can cause excessive buffering |
|
// here. For example, imagine a stream where every byte of input is |
|
// interpreted as an integer from 0-255, and then results in that many |
|
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in |
|
// 1kb of data being output. In this case, you could write a very small |
|
// amount of input, and end up with a very large amount of output. In |
|
// such a pathological inflating mechanism, there'd be no way to tell |
|
// the system to stop doing the transform. A single 4MB write could |
|
// cause the system to run out of memory. |
|
// |
|
// However, even in such a pathological case, only a single written chunk |
|
// would be consumed, and then the rest would wait (un-transformed) until |
|
// the results of the previous transformed chunk were consumed. |
|
|
|
'use strict'; |
|
|
|
module.exports = Transform; |
|
|
|
var Duplex = require('./_stream_duplex'); |
|
|
|
/*<replacement>*/ |
|
var util = require('core-util-is'); |
|
util.inherits = require('inherits'); |
|
/*</replacement>*/ |
|
|
|
util.inherits(Transform, Duplex); |
|
|
|
|
|
function TransformState(stream) { |
|
this.afterTransform = function(er, data) { |
|
return afterTransform(stream, er, data); |
|
}; |
|
|
|
this.needTransform = false; |
|
this.transforming = false; |
|
this.writecb = null; |
|
this.writechunk = null; |
|
} |
|
|
|
function afterTransform(stream, er, data) { |
|
var ts = stream._transformState; |
|
ts.transforming = false; |
|
|
|
var cb = ts.writecb; |
|
|
|
if (!cb) |
|
return stream.emit('error', new Error('no writecb in Transform class')); |
|
|
|
ts.writechunk = null; |
|
ts.writecb = null; |
|
|
|
if (data !== null && data !== undefined) |
|
stream.push(data); |
|
|
|
if (cb) |
|
cb(er); |
|
|
|
var rs = stream._readableState; |
|
rs.reading = false; |
|
if (rs.needReadable || rs.length < rs.highWaterMark) { |
|
stream._read(rs.highWaterMark); |
|
} |
|
} |
|
|
|
|
|
function Transform(options) { |
|
if (!(this instanceof Transform)) |
|
return new Transform(options); |
|
|
|
Duplex.call(this, options); |
|
|
|
this._transformState = new TransformState(this); |
|
|
|
// when the writable side finishes, then flush out anything remaining. |
|
var stream = this; |
|
|
|
// start out asking for a readable event once data is transformed. |
|
this._readableState.needReadable = true; |
|
|
|
// we have implemented the _read method, and done the other things |
|
// that Readable wants before the first _read call, so unset the |
|
// sync guard flag. |
|
this._readableState.sync = false; |
|
|
|
if (options) { |
|
if (typeof options.transform === 'function') |
|
this._transform = options.transform; |
|
|
|
if (typeof options.flush === 'function') |
|
this._flush = options.flush; |
|
} |
|
|
|
this.once('prefinish', function() { |
|
if (typeof this._flush === 'function') |
|
this._flush(function(er) { |
|
done(stream, er); |
|
}); |
|
else |
|
done(stream); |
|
}); |
|
} |
|
|
|
Transform.prototype.push = function(chunk, encoding) { |
|
this._transformState.needTransform = false; |
|
return Duplex.prototype.push.call(this, chunk, encoding); |
|
}; |
|
|
|
// This is the part where you do stuff! |
|
// override this function in implementation classes. |
|
// 'chunk' is an input chunk. |
|
// |
|
// Call `push(newChunk)` to pass along transformed output |
|
// to the readable side. You may call 'push' zero or more times. |
|
// |
|
// Call `cb(err)` when you are done with this chunk. If you pass |
|
// an error, then that'll put the hurt on the whole operation. If you |
|
// never call cb(), then you'll never get another chunk. |
|
Transform.prototype._transform = function(chunk, encoding, cb) { |
|
throw new Error('not implemented'); |
|
}; |
|
|
|
Transform.prototype._write = function(chunk, encoding, cb) { |
|
var ts = this._transformState; |
|
ts.writecb = cb; |
|
ts.writechunk = chunk; |
|
ts.writeencoding = encoding; |
|
if (!ts.transforming) { |
|
var rs = this._readableState; |
|
if (ts.needTransform || |
|
rs.needReadable || |
|
rs.length < rs.highWaterMark) |
|
this._read(rs.highWaterMark); |
|
} |
|
}; |
|
|
|
// Doesn't matter what the args are here. |
|
// _transform does all the work. |
|
// That we got here means that the readable side wants more data. |
|
Transform.prototype._read = function(n) { |
|
var ts = this._transformState; |
|
|
|
if (ts.writechunk !== null && ts.writecb && !ts.transforming) { |
|
ts.transforming = true; |
|
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); |
|
} else { |
|
// mark that we need a transform, so that any data that comes in |
|
// will get processed, now that we've asked for it. |
|
ts.needTransform = true; |
|
} |
|
}; |
|
|
|
|
|
function done(stream, er) { |
|
if (er) |
|
return stream.emit('error', er); |
|
|
|
// if there's nothing in the write buffer, then that means |
|
// that nothing more will ever be provided |
|
var ws = stream._writableState; |
|
var ts = stream._transformState; |
|
|
|
if (ws.length) |
|
throw new Error('calling transform done when ws.length != 0'); |
|
|
|
if (ts.transforming) |
|
throw new Error('calling transform done when still transforming'); |
|
|
|
return stream.push(null); |
|
} |
|
|
|
},{"./_stream_duplex":29,"core-util-is":10,"inherits":13}],32:[function(require,module,exports){ |
|
// A bit simpler than readable streams. |
|
// Implement an async ._write(chunk, encoding, cb), and it'll handle all |
|
// the drain event emission and buffering. |
|
|
|
'use strict'; |
|
|
|
module.exports = Writable; |
|
|
|
/*<replacement>*/ |
|
var processNextTick = require('process-nextick-args'); |
|
/*</replacement>*/ |
|
|
|
|
|
/*<replacement>*/ |
|
var Buffer = require('buffer').Buffer; |
|
/*</replacement>*/ |
|
|
|
Writable.WritableState = WritableState; |
|
|
|
|
|
/*<replacement>*/ |
|
var util = require('core-util-is'); |
|
util.inherits = require('inherits'); |
|
/*</replacement>*/ |
|
|
|
|
|
/*<replacement>*/ |
|
var internalUtil = { |
|
deprecate: require('util-deprecate') |
|
}; |
|
/*</replacement>*/ |
|
|
|
|
|
|
|
/*<replacement>*/ |
|
var Stream; |
|
(function (){try{ |
|
Stream = require('st' + 'ream'); |
|
}catch(_){}finally{ |
|
if (!Stream) |
|
Stream = require('events').EventEmitter; |
|
}}()) |
|
/*</replacement>*/ |
|
|
|
var Buffer = require('buffer').Buffer; |
|
|
|
util.inherits(Writable, Stream); |
|
|
|
function nop() {} |
|
|
|
function WriteReq(chunk, encoding, cb) { |
|
this.chunk = chunk; |
|
this.encoding = encoding; |
|
this.callback = cb; |
|
this.next = null; |
|
} |
|
|
|
var Duplex; |
|
function WritableState(options, stream) { |
|
Duplex = Duplex || require('./_stream_duplex'); |
|
|
|
options = options || {}; |
|
|
|
// object stream flag to indicate whether or not this stream |
|
// contains buffers or objects. |
|
this.objectMode = !!options.objectMode; |
|
|
|
if (stream instanceof Duplex) |
|
this.objectMode = this.objectMode || !!options.writableObjectMode; |
|
|
|
// the point at which write() starts returning false |
|
// Note: 0 is a valid value, means that we always return false if |
|
// the entire buffer is not flushed immediately on write() |
|
var hwm = options.highWaterMark; |
|
var defaultHwm = this.objectMode ? 16 : 16 * 1024; |
|
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; |
|
|
|
// cast to ints. |
|
this.highWaterMark = ~~this.highWaterMark; |
|
|
|
this.needDrain = false; |
|
// at the start of calling end() |
|
this.ending = false; |
|
// when end() has been called, and returned |
|
this.ended = false; |
|
// when 'finish' is emitted |
|
this.finished = false; |
|
|
|
// should we decode strings into buffers before passing to _write? |
|
// this is here so that some node-core streams can optimize string |
|
// handling at a lower level. |
|
var noDecode = options.decodeStrings === false; |
|
this.decodeStrings = !noDecode; |
|
|
|
// Crypto is kind of old and crusty. Historically, its default string |
|
// encoding is 'binary' so we have to make this configurable. |
|
// Everything else in the universe uses 'utf8', though. |
|
this.defaultEncoding = options.defaultEncoding || 'utf8'; |
|
|
|
// not an actual buffer we keep track of, but a measurement |
|
// of how much we're waiting to get pushed to some underlying |
|
// socket or file. |
|
this.length = 0; |
|
|
|
// a flag to see when we're in the middle of a write. |
|
this.writing = false; |
|
|
|
// when true all writes will be buffered until .uncork() call |
|
this.corked = 0; |
|
|
|
// a flag to be able to tell if the onwrite cb is called immediately, |
|
// or on a later tick. We set this to true at first, because any |
|
// actions that shouldn't happen until "later" should generally also |
|
// not happen before the first write call. |
|
this.sync = true; |
|
|
|
// a flag to know if we're processing previously buffered items, which |
|
// may call the _write() callback in the same tick, so that we don't |
|
// end up in an overlapped onwrite situation. |
|
this.bufferProcessing = false; |
|
|
|
// the callback that's passed to _write(chunk,cb) |
|
this.onwrite = function(er) { |
|
onwrite(stream, er); |
|
}; |
|
|
|
// the callback that the user supplies to write(chunk,encoding,cb) |
|
this.writecb = null; |
|
|
|
// the amount that is being written when _write is called. |
|
this.writelen = 0; |
|
|
|
this.bufferedRequest = null; |
|
this.lastBufferedRequest = null; |
|
|
|
// number of pending user-supplied write callbacks |
|
// this must be 0 before 'finish' can be emitted |
|
this.pendingcb = 0; |
|
|
|
// emit prefinish if the only thing we're waiting for is _write cbs |
|
// This is relevant for synchronous Transform streams |
|
this.prefinished = false; |
|
|
|
// True if the error was already emitted and should not be thrown again |
|
this.errorEmitted = false; |
|
} |
|
|
|
WritableState.prototype.getBuffer = function writableStateGetBuffer() { |
|
var current = this.bufferedRequest; |
|
var out = []; |
|
while (current) { |
|
out.push(current); |
|
current = current.next; |
|
} |
|
return out; |
|
}; |
|
|
|
(function (){try { |
|
Object.defineProperty(WritableState.prototype, 'buffer', { |
|
get: internalUtil.deprecate(function() { |
|
return this.getBuffer(); |
|
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + |
|
'instead.') |
|
}); |
|
}catch(_){}}()); |
|
|
|
|
|
var Duplex; |
|
function Writable(options) { |
|
Duplex = Duplex || require('./_stream_duplex'); |
|
|
|
// Writable ctor is applied to Duplexes, though they're not |
|
// instanceof Writable, they're instanceof Readable. |
|
if (!(this instanceof Writable) && !(this instanceof Duplex)) |
|
return new Writable(options); |
|
|
|
this._writableState = new WritableState(options, this); |
|
|
|
// legacy. |
|
this.writable = true; |
|
|
|
if (options) { |
|
if (typeof options.write === 'function') |
|
this._write = options.write; |
|
|
|
if (typeof options.writev === 'function') |
|
this._writev = options.writev; |
|
} |
|
|
|
Stream.call(this); |
|
} |
|
|
|
// Otherwise people can pipe Writable streams, which is just wrong. |
|
Writable.prototype.pipe = function() { |
|
this.emit('error', new Error('Cannot pipe. Not readable.')); |
|
}; |
|
|
|
|
|
function writeAfterEnd(stream, cb) { |
|
var er = new Error('write after end'); |
|
// TODO: defer error events consistently everywhere, not just the cb |
|
stream.emit('error', er); |
|
processNextTick(cb, er); |
|
} |
|
|
|
// If we get something that is not a buffer, string, null, or undefined, |
|
// and we're not in objectMode, then that's an error. |
|
// Otherwise stream chunks are all considered to be of length=1, and the |
|
// watermarks determine how many objects to keep in the buffer, rather than |
|
// how many bytes or characters. |
|
function validChunk(stream, state, chunk, cb) { |
|
var valid = true; |
|
|
|
if (!(Buffer.isBuffer(chunk)) && |
|
typeof chunk !== 'string' && |
|
chunk !== null && |
|
chunk !== undefined && |
|
!state.objectMode) { |
|
var er = new TypeError('Invalid non-string/buffer chunk'); |
|
stream.emit('error', er); |
|
processNextTick(cb, er); |
|
valid = false; |
|
} |
|
return valid; |
|
} |
|
|
|
Writable.prototype.write = function(chunk, encoding, cb) { |
|
var state = this._writableState; |
|
var ret = false; |
|
|
|
if (typeof encoding === 'function') { |
|
cb = encoding; |
|
encoding = null; |
|
} |
|
|
|
if (Buffer.isBuffer(chunk)) |
|
encoding = 'buffer'; |
|
else if (!encoding) |
|
encoding = state.defaultEncoding; |
|
|
|
if (typeof cb !== 'function') |
|
cb = nop; |
|
|
|
if (state.ended) |
|
writeAfterEnd(this, cb); |
|
else if (validChunk(this, state, chunk, cb)) { |
|
state.pendingcb++; |
|
ret = writeOrBuffer(this, state, chunk, encoding, cb); |
|
} |
|
|
|
return ret; |
|
}; |
|
|
|
Writable.prototype.cork = function() { |
|
var state = this._writableState; |
|
|
|
state.corked++; |
|
}; |
|
|
|
Writable.prototype.uncork = function() { |
|
var state = this._writableState; |
|
|
|
if (state.corked) { |
|
state.corked--; |
|
|
|
if (!state.writing && |
|
!state.corked && |
|
!state.finished && |
|
!state.bufferProcessing && |
|
state.bufferedRequest) |
|
clearBuffer(this, state); |
|
} |
|
}; |
|
|
|
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { |
|
// node::ParseEncoding() requires lower case. |
|
if (typeof encoding === 'string') |
|
encoding = encoding.toLowerCase(); |
|
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', |
|
'ucs2', 'ucs-2','utf16le', 'utf-16le', 'raw'] |
|
.indexOf((encoding + '').toLowerCase()) > -1)) |
|
throw new TypeError('Unknown encoding: ' + encoding); |
|
this._writableState.defaultEncoding = encoding; |
|
}; |
|
|
|
function decodeChunk(state, chunk, encoding) { |
|
if (!state.objectMode && |
|
state.decodeStrings !== false && |
|
typeof chunk === 'string') { |
|
chunk = new Buffer(chunk, encoding); |
|
} |
|
return chunk; |
|
} |
|
|
|
// if we're already writing something, then just put this |
|
// in the queue, and wait our turn. Otherwise, call _write |
|
// If we return false, then we need a drain event, so set that flag. |
|
function writeOrBuffer(stream, state, chunk, encoding, cb) { |
|
chunk = decodeChunk(state, chunk, encoding); |
|
|
|
if (Buffer.isBuffer(chunk)) |
|
encoding = 'buffer'; |
|
var len = state.objectMode ? 1 : chunk.length; |
|
|
|
state.length += len; |
|
|
|
var ret = state.length < state.highWaterMark; |
|
// we must ensure that previous needDrain will not be reset to false. |
|
if (!ret) |
|
state.needDrain = true; |
|
|
|
if (state.writing || state.corked) { |
|
var last = state.lastBufferedRequest; |
|
state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); |
|
if (last) { |
|
last.next = state.lastBufferedRequest; |
|
} else { |
|
state.bufferedRequest = state.lastBufferedRequest; |
|
} |
|
} else { |
|
doWrite(stream, state, false, len, chunk, encoding, cb); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
function doWrite(stream, state, writev, len, chunk, encoding, cb) { |
|
state.writelen = len; |
|
state.writecb = cb; |
|
state.writing = true; |
|
state.sync = true; |
|
if (writev) |
|
stream._writev(chunk, state.onwrite); |
|
else |
|
stream._write(chunk, encoding, state.onwrite); |
|
state.sync = false; |
|
} |
|
|
|
function onwriteError(stream, state, sync, er, cb) { |
|
--state.pendingcb; |
|
if (sync) |
|
processNextTick(cb, er); |
|
else |
|
cb(er); |
|
|
|
stream._writableState.errorEmitted = true; |
|
stream.emit('error', er); |
|
} |
|
|
|
function onwriteStateUpdate(state) { |
|
state.writing = false; |
|
state.writecb = null; |
|
state.length -= state.writelen; |
|
state.writelen = 0; |
|
} |
|
|
|
function onwrite(stream, er) { |
|
var state = stream._writableState; |
|
var sync = state.sync; |
|
var cb = state.writecb; |
|
|
|
onwriteStateUpdate(state); |
|
|
|
if (er) |
|
onwriteError(stream, state, sync, er, cb); |
|
else { |
|
// Check if we're actually ready to finish, but don't emit yet |
|
var finished = needFinish(state); |
|
|
|
if (!finished && |
|
!state.corked && |
|
!state.bufferProcessing && |
|
state.bufferedRequest) { |
|
clearBuffer(stream, state); |
|
} |
|
|
|
if (sync) { |
|
processNextTick(afterWrite, stream, state, finished, cb); |
|
} else { |
|
afterWrite(stream, state, finished, cb); |
|
} |
|
} |
|
} |
|
|
|
function afterWrite(stream, state, finished, cb) { |
|
if (!finished) |
|
onwriteDrain(stream, state); |
|
state.pendingcb--; |
|
cb(); |
|
finishMaybe(stream, state); |
|
} |
|
|
|
// Must force callback to be called on nextTick, so that we don't |
|
// emit 'drain' before the write() consumer gets the 'false' return |
|
// value, and has a chance to attach a 'drain' listener. |
|
function onwriteDrain(stream, state) { |
|
if (state.length === 0 && state.needDrain) { |
|
state.needDrain = false; |
|
stream.emit('drain'); |
|
} |
|
} |
|
|
|
|
|
// if there's something in the buffer waiting, then process it |
|
function clearBuffer(stream, state) { |
|
state.bufferProcessing = true; |
|
var entry = state.bufferedRequest; |
|
|
|
if (stream._writev && entry && entry.next) { |
|
// Fast case, write everything using _writev() |
|
var buffer = []; |
|
var cbs = []; |
|
while (entry) { |
|
cbs.push(entry.callback); |
|
buffer.push(entry); |
|
entry = entry.next; |
|
} |
|
|
|
// count the one we are adding, as well. |
|
// TODO(isaacs) clean this up |
|
state.pendingcb++; |
|
state.lastBufferedRequest = null; |
|
doWrite(stream, state, true, state.length, buffer, '', function(err) { |
|
for (var i = 0; i < cbs.length; i++) { |
|
state.pendingcb--; |
|
cbs[i](err); |
|
} |
|
}); |
|
|
|
// Clear buffer |
|
} else { |
|
// Slow case, write chunks one-by-one |
|
while (entry) { |
|
var chunk = entry.chunk; |
|
var encoding = entry.encoding; |
|
var cb = entry.callback; |
|
var len = state.objectMode ? 1 : chunk.length; |
|
|
|
doWrite(stream, state, false, len, chunk, encoding, cb); |
|
entry = entry.next; |
|
// if we didn't call the onwrite immediately, then |
|
// it means that we need to wait until it does. |
|
// also, that means that the chunk and cb are currently |
|
// being processed, so move the buffer counter past them. |
|
if (state.writing) { |
|
break; |
|
} |
|
} |
|
|
|
if (entry === null) |
|
state.lastBufferedRequest = null; |
|
} |
|
state.bufferedRequest = entry; |
|
state.bufferProcessing = false; |
|
} |
|
|
|
Writable.prototype._write = function(chunk, encoding, cb) { |
|
cb(new Error('not implemented')); |
|
}; |
|
|
|
Writable.prototype._writev = null; |
|
|
|
Writable.prototype.end = function(chunk, encoding, cb) { |
|
var state = this._writableState; |
|
|
|
if (typeof chunk === 'function') { |
|
cb = chunk; |
|
chunk = null; |
|
encoding = null; |
|
} else if (typeof encoding === 'function') { |
|
cb = encoding; |
|
encoding = null; |
|
} |
|
|
|
if (chunk !== null && chunk !== undefined) |
|
this.write(chunk, encoding); |
|
|
|
// .end() fully uncorks |
|
if (state.corked) { |
|
state.corked = 1; |
|
this.uncork(); |
|
} |
|
|
|
// ignore unnecessary end() calls. |
|
if (!state.ending && !state.finished) |
|
endWritable(this, state, cb); |
|
}; |
|
|
|
|
|
function needFinish(state) { |
|
return (state.ending && |
|
state.length === 0 && |
|
state.bufferedRequest === null && |
|
!state.finished && |
|
!state.writing); |
|
} |
|
|
|
function prefinish(stream, state) { |
|
if (!state.prefinished) { |
|
state.prefinished = true; |
|
stream.emit('prefinish'); |
|
} |
|
} |
|
|
|
function finishMaybe(stream, state) { |
|
var need = needFinish(state); |
|
if (need) { |
|
if (state.pendingcb === 0) { |
|
prefinish(stream, state); |
|
state.finished = true; |
|
stream.emit('finish'); |
|
} else { |
|
prefinish(stream, state); |
|
} |
|
} |
|
return need; |
|
} |
|
|
|
function endWritable(stream, state, cb) { |
|
state.ending = true; |
|
finishMaybe(stream, state); |
|
if (cb) { |
|
if (state.finished) |
|
processNextTick(cb); |
|
else |
|
stream.once('finish', cb); |
|
} |
|
state.ended = true; |
|
} |
|
|
|
},{"./_stream_duplex":29,"buffer":8,"core-util-is":10,"events":11,"inherits":13,"process-nextick-args":27,"util-deprecate":35}],33:[function(require,module,exports){ |
|
module.exports = require("./lib/_stream_transform.js") |
|
|
|
},{"./lib/_stream_transform.js":31}],34:[function(require,module,exports){ |
|
// Copyright Joyent, Inc. and other Node contributors. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the |
|
// "Software"), to deal in the Software without restriction, including |
|
// without limitation the rights to use, copy, modify, merge, publish, |
|
// distribute, sublicense, and/or sell copies of the Software, and to permit |
|
// persons to whom the Software is furnished to do so, subject to the |
|
// following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
var Buffer = require('buffer').Buffer; |
|
|
|
var isBufferEncoding = Buffer.isEncoding |
|
|| function(encoding) { |
|
switch (encoding && encoding.toLowerCase()) { |
|
case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; |
|
default: return false; |
|
} |
|
} |
|
|
|
|
|
function assertEncoding(encoding) { |
|
if (encoding && !isBufferEncoding(encoding)) { |
|
throw new Error('Unknown encoding: ' + encoding); |
|
} |
|
} |
|
|
|
// StringDecoder provides an interface for efficiently splitting a series of |
|
// buffers into a series of JS strings without breaking apart multi-byte |
|
// characters. CESU-8 is handled as part of the UTF-8 encoding. |
|
// |
|
// @TODO Handling all encodings inside a single object makes it very difficult |
|
// to reason about this code, so it should be split up in the future. |
|
// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code |
|
// points as used by CESU-8. |
|
var StringDecoder = exports.StringDecoder = function(encoding) { |
|
this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); |
|
assertEncoding(encoding); |
|
switch (this.encoding) { |
|
case 'utf8': |
|
// CESU-8 represents each of Surrogate Pair by 3-bytes |
|
this.surrogateSize = 3; |
|
break; |
|
case 'ucs2': |
|
case 'utf16le': |
|
// UTF-16 represents each of Surrogate Pair by 2-bytes |
|
this.surrogateSize = 2; |
|
this.detectIncompleteChar = utf16DetectIncompleteChar; |
|
break; |
|
case 'base64': |
|
// Base-64 stores 3 bytes in 4 chars, and pads the remainder. |
|
this.surrogateSize = 3; |
|
this.detectIncompleteChar = base64DetectIncompleteChar; |
|
break; |
|
default: |
|
this.write = passThroughWrite; |
|
return; |
|
} |
|
|
|
// Enough space to store all bytes of a single character. UTF-8 needs 4 |
|
// bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). |
|
this.charBuffer = new Buffer(6); |
|
// Number of bytes received for the current incomplete multi-byte character. |
|
this.charReceived = 0; |
|
// Number of bytes expected for the current incomplete multi-byte character. |
|
this.charLength = 0; |
|
}; |
|
|
|
|
|
// write decodes the given buffer and returns it as JS string that is |
|
// guaranteed to not contain any partial multi-byte characters. Any partial |
|
// character found at the end of the buffer is buffered up, and will be |
|
// returned when calling write again with the remaining bytes. |
|
// |
|
// Note: Converting a Buffer containing an orphan surrogate to a String |
|
// currently works, but converting a String to a Buffer (via `new Buffer`, or |
|
// Buffer#write) will replace incomplete surrogates with the unicode |
|
// replacement character. See https://codereview.chromium.org/121173009/ . |
|
StringDecoder.prototype.write = function(buffer) { |
|
var charStr = ''; |
|
// if our last write ended with an incomplete multibyte character |
|
while (this.charLength) { |
|
// determine how many remaining bytes this buffer has to offer for this char |
|
var available = (buffer.length >= this.charLength - this.charReceived) ? |
|
this.charLength - this.charReceived : |
|
buffer.length; |
|
|
|
// add the new bytes to the char buffer |
|
buffer.copy(this.charBuffer, this.charReceived, 0, available); |
|
this.charReceived += available; |
|
|
|
if (this.charReceived < this.charLength) { |
|
// still not enough chars in this buffer? wait for more ... |
|
return ''; |
|
} |
|
|
|
// remove bytes belonging to the current character from the buffer |
|
buffer = buffer.slice(available, buffer.length); |
|
|
|
// get the character that was split |
|
charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); |
|
|
|
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character |
|
var charCode = charStr.charCodeAt(charStr.length - 1); |
|
if (charCode >= 0xD800 && charCode <= 0xDBFF) { |
|
this.charLength += this.surrogateSize; |
|
charStr = ''; |
|
continue; |
|
} |
|
this.charReceived = this.charLength = 0; |
|
|
|
// if there are no more bytes in this buffer, just emit our char |
|
if (buffer.length === 0) { |
|
return charStr; |
|
} |
|
break; |
|
} |
|
|
|
// determine and set charLength / charReceived |
|
this.detectIncompleteChar(buffer); |
|
|
|
var end = buffer.length; |
|
if (this.charLength) { |
|
// buffer the incomplete character bytes we got |
|
buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); |
|
end -= this.charReceived; |
|
} |
|
|
|
charStr += buffer.toString(this.encoding, 0, end); |
|
|
|
var end = charStr.length - 1; |
|
var charCode = charStr.charCodeAt(end); |
|
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character |
|
if (charCode >= 0xD800 && charCode <= 0xDBFF) { |
|
var size = this.surrogateSize; |
|
this.charLength += size; |
|
this.charReceived += size; |
|
this.charBuffer.copy(this.charBuffer, size, 0, size); |
|
buffer.copy(this.charBuffer, 0, 0, size); |
|
return charStr.substring(0, end); |
|
} |
|
|
|
// or just emit the charStr |
|
return charStr; |
|
}; |
|
|
|
// detectIncompleteChar determines if there is an incomplete UTF-8 character at |
|
// the end of the given buffer. If so, it sets this.charLength to the byte |
|
// length that character, and sets this.charReceived to the number of bytes |
|
// that are available for this character. |
|
StringDecoder.prototype.detectIncompleteChar = function(buffer) { |
|
// determine how many bytes we have to check at the end of this buffer |
|
var i = (buffer.length >= 3) ? 3 : buffer.length; |
|
|
|
// Figure out if one of the last i bytes of our buffer announces an |
|
// incomplete char. |
|
for (; i > 0; i--) { |
|
var c = buffer[buffer.length - i]; |
|
|
|
// See http://en.wikipedia.org/wiki/UTF-8#Description |
|
|
|
// 110XXXXX |
|
if (i == 1 && c >> 5 == 0x06) { |
|
this.charLength = 2; |
|
break; |
|
} |
|
|
|
// 1110XXXX |
|
if (i <= 2 && c >> 4 == 0x0E) { |
|
this.charLength = 3; |
|
break; |
|
} |
|
|
|
// 11110XXX |
|
if (i <= 3 && c >> 3 == 0x1E) { |
|
this.charLength = 4; |
|
break; |
|
} |
|
} |
|
this.charReceived = i; |
|
}; |
|
|
|
StringDecoder.prototype.end = function(buffer) { |
|
var res = ''; |
|
if (buffer && buffer.length) |
|
res = this.write(buffer); |
|
|
|
if (this.charReceived) { |
|
var cr = this.charReceived; |
|
var buf = this.charBuffer; |
|
var enc = this.encoding; |
|
res += buf.slice(0, cr).toString(enc); |
|
} |
|
|
|
return res; |
|
}; |
|
|
|
function passThroughWrite(buffer) { |
|
return buffer.toString(this.encoding); |
|
} |
|
|
|
function utf16DetectIncompleteChar(buffer) { |
|
this.charReceived = buffer.length % 2; |
|
this.charLength = this.charReceived ? 2 : 0; |
|
} |
|
|
|
function base64DetectIncompleteChar(buffer) { |
|
this.charReceived = buffer.length % 3; |
|
this.charLength = this.charReceived ? 3 : 0; |
|
} |
|
|
|
},{"buffer":8}],35:[function(require,module,exports){ |
|
(function (global){ |
|
|
|
/** |
|
* Module exports. |
|
*/ |
|
|
|
module.exports = deprecate; |
|
|
|
/** |
|
* Mark that a method should not be used. |
|
* Returns a modified function which warns once by default. |
|
* |
|
* If `localStorage.noDeprecation = true` is set, then it is a no-op. |
|
* |
|
* If `localStorage.throwDeprecation = true` is set, then deprecated functions |
|
* will throw an Error when invoked. |
|
* |
|
* If `localStorage.traceDeprecation = true` is set, then deprecated functions |
|
* will invoke `console.trace()` instead of `console.error()`. |
|
* |
|
* @param {Function} fn - the function to deprecate |
|
* @param {String} msg - the string to print to the console when `fn` is invoked |
|
* @returns {Function} a new "deprecated" version of `fn` |
|
* @api public |
|
*/ |
|
|
|
function deprecate (fn, msg) { |
|
if (config('noDeprecation')) { |
|
return fn; |
|
} |
|
|
|
var warned = false; |
|
function deprecated() { |
|
if (!warned) { |
|
if (config('throwDeprecation')) { |
|
throw new Error(msg); |
|
} else if (config('traceDeprecation')) { |
|
console.trace(msg); |
|
} else { |
|
console.warn(msg); |
|
} |
|
warned = true; |
|
} |
|
return fn.apply(this, arguments); |
|
} |
|
|
|
return deprecated; |
|
} |
|
|
|
/** |
|
* Checks `localStorage` for boolean values for the given `name`. |
|
* |
|
* @param {String} name |
|
* @returns {Boolean} |
|
* @api private |
|
*/ |
|
|
|
function config (name) { |
|
// accessing global.localStorage can trigger a DOMException in sandboxed iframes |
|
try { |
|
if (!global.localStorage) return false; |
|
} catch (_) { |
|
return false; |
|
} |
|
var val = global.localStorage[name]; |
|
if (null == val) return false; |
|
return String(val).toLowerCase() === 'true'; |
|
} |
|
|
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
|
},{}],36:[function(require,module,exports){ |
|
module.exports = function isBuffer(arg) { |
|
return arg && typeof arg === 'object' |
|
&& typeof arg.copy === 'function' |
|
&& typeof arg.fill === 'function' |
|
&& typeof arg.readUInt8 === 'function'; |
|
} |
|
},{}],37:[function(require,module,exports){ |
|
(function (process,global){ |
|
// Copyright Joyent, Inc. and other Node contributors. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the |
|
// "Software"), to deal in the Software without restriction, including |
|
// without limitation the rights to use, copy, modify, merge, publish, |
|
// distribute, sublicense, and/or sell copies of the Software, and to permit |
|
// persons to whom the Software is furnished to do so, subject to the |
|
// following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included |
|
// in all copies or substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
|
|
var formatRegExp = /%[sdj%]/g; |
|
exports.format = function(f) { |
|
if (!isString(f)) { |
|
var objects = []; |
|
for (var i = 0; i < arguments.length; i++) { |
|
objects.push(inspect(arguments[i])); |
|
} |
|
return objects.join(' '); |
|
} |
|
|
|
var i = 1; |
|
var args = arguments; |
|
var len = args.length; |
|
var str = String(f).replace(formatRegExp, function(x) { |
|
if (x === '%%') return '%'; |
|
if (i >= len) return x; |
|
switch (x) { |
|
case '%s': return String(args[i++]); |
|
case '%d': return Number(args[i++]); |
|
case '%j': |
|
try { |
|
return JSON.stringify(args[i++]); |
|
} catch (_) { |
|
return '[Circular]'; |
|
} |
|
default: |
|
return x; |
|
} |
|
}); |
|
for (var x = args[i]; i < len; x = args[++i]) { |
|
if (isNull(x) || !isObject(x)) { |
|
str += ' ' + x; |
|
} else { |
|
str += ' ' + inspect(x); |
|
} |
|
} |
|
return str; |
|
}; |
|
|
|
|
|
// Mark that a method should not be used. |
|
// Returns a modified function which warns once by default. |
|
// If --no-deprecation is set, then it is a no-op. |
|
exports.deprecate = function(fn, msg) { |
|
// Allow for deprecating things in the process of starting up. |
|
if (isUndefined(global.process)) { |
|
return function() { |
|
return exports.deprecate(fn, msg).apply(this, arguments); |
|
}; |
|
} |
|
|
|
if (process.noDeprecation === true) { |
|
return fn; |
|
} |
|
|
|
var warned = false; |
|
function deprecated() { |
|
if (!warned) { |
|
if (process.throwDeprecation) { |
|
throw new Error(msg); |
|
} else if (process.traceDeprecation) { |
|
console.trace(msg); |
|
} else { |
|
console.error(msg); |
|
} |
|
warned = true; |
|
} |
|
return fn.apply(this, arguments); |
|
} |
|
|
|
return deprecated; |
|
}; |
|
|
|
|
|
var debugs = {}; |
|
var debugEnviron; |
|
exports.debuglog = function(set) { |
|
if (isUndefined(debugEnviron)) |
|
debugEnviron = process.env.NODE_DEBUG || ''; |
|
set = set.toUpperCase(); |
|
if (!debugs[set]) { |
|
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { |
|
var pid = process.pid; |
|
debugs[set] = function() { |
|
var msg = exports.format.apply(exports, arguments); |
|
console.error('%s %d: %s', set, pid, msg); |
|
}; |
|
} else { |
|
debugs[set] = function() {}; |
|
} |
|
} |
|
return debugs[set]; |
|
}; |
|
|
|
|
|
/** |
|
* Echos the value of a value. Trys to print the value out |
|
* in the best way possible given the different types. |
|
* |
|
* @param {Object} obj The object to print out. |
|
* @param {Object} opts Optional options object that alters the output. |
|
*/ |
|
/* legacy: obj, showHidden, depth, colors*/ |
|
function inspect(obj, opts) { |
|
// default options |
|
var ctx = { |
|
seen: [], |
|
stylize: stylizeNoColor |
|
}; |
|
// legacy... |
|
if (arguments.length >= 3) ctx.depth = arguments[2]; |
|
if (arguments.length >= 4) ctx.colors = arguments[3]; |
|
if (isBoolean(opts)) { |
|
// legacy... |
|
ctx.showHidden = opts; |
|
} else if (opts) { |
|
// got an "options" object |
|
exports._extend(ctx, opts); |
|
} |
|
// set default options |
|
if (isUndefined(ctx.showHidden)) ctx.showHidden = false; |
|
if (isUndefined(ctx.depth)) ctx.depth = 2; |
|
if (isUndefined(ctx.colors)) ctx.colors = false; |
|
if (isUndefined(ctx.customInspect)) ctx.customInspect = true; |
|
if (ctx.colors) ctx.stylize = stylizeWithColor; |
|
return formatValue(ctx, obj, ctx.depth); |
|
} |
|
exports.inspect = inspect; |
|
|
|
|
|
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics |
|
inspect.colors = { |
|
'bold' : [1, 22], |
|
'italic' : [3, 23], |
|
'underline' : [4, 24], |
|
'inverse' : [7, 27], |
|
'white' : [37, 39], |
|
'grey' : [90, 39], |
|
'black' : [30, 39], |
|
'blue' : [34, 39], |
|
'cyan' : [36, 39], |
|
'green' : [32, 39], |
|
'magenta' : [35, 39], |
|
'red' : [31, 39], |
|
'yellow' : [33, 39] |
|
}; |
|
|
|
// Don't use 'blue' not visible on cmd.exe |
|
inspect.styles = { |
|
'special': 'cyan', |
|
'number': 'yellow', |
|
'boolean': 'yellow', |
|
'undefined': 'grey', |
|
'null': 'bold', |
|
'string': 'green', |
|
'date': 'magenta', |
|
// "name": intentionally not styling |
|
'regexp': 'red' |
|
}; |
|
|
|
|
|
function stylizeWithColor(str, styleType) { |
|
var style = inspect.styles[styleType]; |
|
|
|
if (style) { |
|
return '\u001b[' + inspect.colors[style][0] + 'm' + str + |
|
'\u001b[' + inspect.colors[style][1] + 'm'; |
|
} else { |
|
return str; |
|
} |
|
} |
|
|
|
|
|
function stylizeNoColor(str, styleType) { |
|
return str; |
|
} |
|
|
|
|
|
function arrayToHash(array) { |
|
var hash = {}; |
|
|
|
array.forEach(function(val, idx) { |
|
hash[val] = true; |
|
}); |
|
|
|
return hash; |
|
} |
|
|
|
|
|
function formatValue(ctx, value, recurseTimes) { |
|
// Provide a hook for user-specified inspect functions. |
|
// Check that value is an object with an inspect function on it |
|
if (ctx.customInspect && |
|
value && |
|
isFunction(value.inspect) && |
|
// Filter out the util module, it's inspect function is special |
|
value.inspect !== exports.inspect && |
|
// Also filter out any prototype objects using the circular check. |
|
!(value.constructor && value.constructor.prototype === value)) { |
|
var ret = value.inspect(recurseTimes, ctx); |
|
if (!isString(ret)) { |
|
ret = formatValue(ctx, ret, recurseTimes); |
|
} |
|
return ret; |
|
} |
|
|
|
// Primitive types cannot have properties |
|
var primitive = formatPrimitive(ctx, value); |
|
if (primitive) { |
|
return primitive; |
|
} |
|
|
|
// Look up the keys of the object. |
|
var keys = Object.keys(value); |
|
var visibleKeys = arrayToHash(keys); |
|
|
|
if (ctx.showHidden) { |
|
keys = Object.getOwnPropertyNames(value); |
|
} |
|
|
|
// IE doesn't make error fields non-enumerable |
|
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx |
|
if (isError(value) |
|
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { |
|
return formatError(value); |
|
} |
|
|
|
// Some type of object without properties can be shortcutted. |
|
if (keys.length === 0) { |
|
if (isFunction(value)) { |
|
var name = value.name ? ': ' + value.name : ''; |
|
return ctx.stylize('[Function' + name + ']', 'special'); |
|
} |
|
if (isRegExp(value)) { |
|
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
|
} |
|
if (isDate(value)) { |
|
return ctx.stylize(Date.prototype.toString.call(value), 'date'); |
|
} |
|
if (isError(value)) { |
|
return formatError(value); |
|
} |
|
} |
|
|
|
var base = '', array = false, braces = ['{', '}']; |
|
|
|
// Make Array say that they are Array |
|
if (isArray(value)) { |
|
array = true; |
|
braces = ['[', ']']; |
|
} |
|
|
|
// Make functions say that they are functions |
|
if (isFunction(value)) { |
|
var n = value.name ? ': ' + value.name : ''; |
|
base = ' [Function' + n + ']'; |
|
} |
|
|
|
// Make RegExps say that they are RegExps |
|
if (isRegExp(value)) { |
|
base = ' ' + RegExp.prototype.toString.call(value); |
|
} |
|
|
|
// Make dates with properties first say the date |
|
if (isDate(value)) { |
|
base = ' ' + Date.prototype.toUTCString.call(value); |
|
} |
|
|
|
// Make error with message first say the error |
|
if (isError(value)) { |
|
base = ' ' + formatError(value); |
|
} |
|
|
|
if (keys.length === 0 && (!array || value.length == 0)) { |
|
return braces[0] + base + braces[1]; |
|
} |
|
|
|
if (recurseTimes < 0) { |
|
if (isRegExp(value)) { |
|
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
|
} else { |
|
return ctx.stylize('[Object]', 'special'); |
|
} |
|
} |
|
|
|
ctx.seen.push(value); |
|
|
|
var output; |
|
if (array) { |
|
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
|
} else { |
|
output = keys.map(function(key) { |
|
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
|
}); |
|
} |
|
|
|
ctx.seen.pop(); |
|
|
|
return reduceToSingleString(output, base, braces); |
|
} |
|
|
|
|
|
function formatPrimitive(ctx, value) { |
|
if (isUndefined(value)) |
|
return ctx.stylize('undefined', 'undefined'); |
|
if (isString(value)) { |
|
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
|
.replace(/'/g, "\\'") |
|
.replace(/\\"/g, '"') + '\''; |
|
return ctx.stylize(simple, 'string'); |
|
} |
|
if (isNumber(value)) |
|
return ctx.stylize('' + value, 'number'); |
|
if (isBoolean(value)) |
|
return ctx.stylize('' + value, 'boolean'); |
|
// For some reason typeof null is "object", so special case here. |
|
if (isNull(value)) |
|
return ctx.stylize('null', 'null'); |
|
} |
|
|
|
|
|
function formatError(value) { |
|
return '[' + Error.prototype.toString.call(value) + ']'; |
|
} |
|
|
|
|
|
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
|
var output = []; |
|
for (var i = 0, l = value.length; i < l; ++i) { |
|
if (hasOwnProperty(value, String(i))) { |
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
|
String(i), true)); |
|
} else { |
|
output.push(''); |
|
} |
|
} |
|
keys.forEach(function(key) { |
|
if (!key.match(/^\d+$/)) { |
|
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
|
key, true)); |
|
} |
|
}); |
|
return output; |
|
} |
|
|
|
|
|
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
|
var name, str, desc; |
|
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; |
|
if (desc.get) { |
|
if (desc.set) { |
|
str = ctx.stylize('[Getter/Setter]', 'special'); |
|
} else { |
|
str = ctx.stylize('[Getter]', 'special'); |
|
} |
|
} else { |
|
if (desc.set) { |
|
str = ctx.stylize('[Setter]', 'special'); |
|
} |
|
} |
|
if (!hasOwnProperty(visibleKeys, key)) { |
|
name = '[' + key + ']'; |
|
} |
|
if (!str) { |
|
if (ctx.seen.indexOf(desc.value) < 0) { |
|
if (isNull(recurseTimes)) { |
|
str = formatValue(ctx, desc.value, null); |
|
} else { |
|
str = formatValue(ctx, desc.value, recurseTimes - 1); |
|
} |
|
if (str.indexOf('\n') > -1) { |
|
if (array) { |
|
str = str.split('\n').map(function(line) { |
|
return ' ' + line; |
|
}).join('\n').substr(2); |
|
} else { |
|
str = '\n' + str.split('\n').map(function(line) { |
|
return ' ' + line; |
|
}).join('\n'); |
|
} |
|
} |
|
} else { |
|
str = ctx.stylize('[Circular]', 'special'); |
|
} |
|
} |
|
if (isUndefined(name)) { |
|
if (array && key.match(/^\d+$/)) { |
|
return str; |
|
} |
|
name = JSON.stringify('' + key); |
|
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
|
name = name.substr(1, name.length - 2); |
|
name = ctx.stylize(name, 'name'); |
|
} else { |
|
name = name.replace(/'/g, "\\'") |
|
.replace(/\\"/g, '"') |
|
.replace(/(^"|"$)/g, "'"); |
|
name = ctx.stylize(name, 'string'); |
|
} |
|
} |
|
|
|
return name + ': ' + str; |
|
} |
|
|
|
|
|
function reduceToSingleString(output, base, braces) { |
|
var numLinesEst = 0; |
|
var length = output.reduce(function(prev, cur) { |
|
numLinesEst++; |
|
if (cur.indexOf('\n') >= 0) numLinesEst++; |
|
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; |
|
}, 0); |
|
|
|
if (length > 60) { |
|
return braces[0] + |
|
(base === '' ? '' : base + '\n ') + |
|
' ' + |
|
output.join(',\n ') + |
|
' ' + |
|
braces[1]; |
|
} |
|
|
|
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
|
} |
|
|
|
|
|
// NOTE: These type checking functions intentionally don't use `instanceof` |
|
// because it is fragile and can be easily faked with `Object.create()`. |
|
function isArray(ar) { |
|
return Array.isArray(ar); |
|
} |
|
exports.isArray = isArray; |
|
|
|
function isBoolean(arg) { |
|
return typeof arg === 'boolean'; |
|
} |
|
exports.isBoolean = isBoolean; |
|
|
|
function isNull(arg) { |
|
return arg === null; |
|
} |
|
exports.isNull = isNull; |
|
|
|
function isNullOrUndefined(arg) { |
|
return arg == null; |
|
} |
|
exports.isNullOrUndefined = isNullOrUndefined; |
|
|
|
function isNumber(arg) { |
|
return typeof arg === 'number'; |
|
} |
|
exports.isNumber = isNumber; |
|
|
|
function isString(arg) { |
|
return typeof arg === 'string'; |
|
} |
|
exports.isString = isString; |
|
|
|
function isSymbol(arg) { |
|
return typeof arg === 'symbol'; |
|
} |
|
exports.isSymbol = isSymbol; |
|
|
|
function isUndefined(arg) { |
|
return arg === void 0; |
|
} |
|
exports.isUndefined = isUndefined; |
|
|
|
function isRegExp(re) { |
|
return isObject(re) && objectToString(re) === '[object RegExp]'; |
|
} |
|
exports.isRegExp = isRegExp; |
|
|
|
function isObject(arg) { |
|
return typeof arg === 'object' && arg !== null; |
|
} |
|
exports.isObject = isObject; |
|
|
|
function isDate(d) { |
|
return isObject(d) && objectToString(d) === '[object Date]'; |
|
} |
|
exports.isDate = isDate; |
|
|
|
function isError(e) { |
|
return isObject(e) && |
|
(objectToString(e) === '[object Error]' || e instanceof Error); |
|
} |
|
exports.isError = isError; |
|
|
|
function isFunction(arg) { |
|
return typeof arg === 'function'; |
|
} |
|
exports.isFunction = isFunction; |
|
|
|
function isPrimitive(arg) { |
|
return arg === null || |
|
typeof arg === 'boolean' || |
|
typeof arg === 'number' || |
|
typeof arg === 'string' || |
|
typeof arg === 'symbol' || // ES6 symbol |
|
typeof arg === 'undefined'; |
|
} |
|
exports.isPrimitive = isPrimitive; |
|
|
|
exports.isBuffer = require('./support/isBuffer'); |
|
|
|
function objectToString(o) { |
|
return Object.prototype.toString.call(o); |
|
} |
|
|
|
|
|
function pad(n) { |
|
return n < 10 ? '0' + n.toString(10) : n.toString(10); |
|
} |
|
|
|
|
|
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', |
|
'Oct', 'Nov', 'Dec']; |
|
|
|
// 26 Feb 16:19:34 |
|
function timestamp() { |
|
var d = new Date(); |
|
var time = [pad(d.getHours()), |
|
pad(d.getMinutes()), |
|
pad(d.getSeconds())].join(':'); |
|
return [d.getDate(), months[d.getMonth()], time].join(' '); |
|
} |
|
|
|
|
|
// log is just a thin wrapper to console.log that prepends a timestamp |
|
exports.log = function() { |
|
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); |
|
}; |
|
|
|
|
|
/** |
|
* Inherit the prototype methods from one constructor into another. |
|
* |
|
* The Function.prototype.inherits from lang.js rewritten as a standalone |
|
* function (not on Function.prototype). NOTE: If this file is to be loaded |
|
* during bootstrapping this function needs to be rewritten using some native |
|
* functions as prototype setup using normal JavaScript does not work as |
|
* expected during bootstrapping (see mirror.js in r114903). |
|
* |
|
* @param {function} ctor Constructor function which needs to inherit the |
|
* prototype. |
|
* @param {function} superCtor Constructor function to inherit prototype from. |
|
*/ |
|
exports.inherits = require('inherits'); |
|
|
|
exports._extend = function(origin, add) { |
|
// Don't do anything if add isn't an object |
|
if (!add || !isObject(add)) return origin; |
|
|
|
var keys = Object.keys(add); |
|
var i = keys.length; |
|
while (i--) { |
|
origin[keys[i]] = add[keys[i]]; |
|
} |
|
return origin; |
|
}; |
|
|
|
function hasOwnProperty(obj, prop) { |
|
return Object.prototype.hasOwnProperty.call(obj, prop); |
|
} |
|
|
|
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) |
|
},{"./support/isBuffer":36,"_process":28,"inherits":13}]},{},[2])(2) |
|
}); |