diff options
Diffstat (limited to 'node_modules/browserify-zlib/lib')
| -rw-r--r-- | node_modules/browserify-zlib/lib/binding.js | 409 | ||||
| -rw-r--r-- | node_modules/browserify-zlib/lib/index.js | 609 | 
2 files changed, 1018 insertions, 0 deletions
diff --git a/node_modules/browserify-zlib/lib/binding.js b/node_modules/browserify-zlib/lib/binding.js new file mode 100644 index 000000000..e0578b3ad --- /dev/null +++ b/node_modules/browserify-zlib/lib/binding.js @@ -0,0 +1,409 @@ +'use strict'; +/* eslint camelcase: "off" */ + +var assert = require('assert'); + +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; + +var GZIP_HEADER_ID1 = 0x1f; +var GZIP_HEADER_ID2 = 0x8b; + +/** + * Emulate Node's zlib C++ layer for use by the JS layer in index.js + */ +function Zlib(mode) { +  if (typeof mode !== 'number' || mode < exports.DEFLATE || mode > exports.UNZIP) { +    throw new TypeError('Bad argument'); +  } + +  this.dictionary = null; +  this.err = 0; +  this.flush = 0; +  this.init_done = false; +  this.level = 0; +  this.memLevel = 0; +  this.mode = mode; +  this.strategy = 0; +  this.windowBits = 0; +  this.write_in_progress = false; +  this.pending_close = false; +  this.gzip_id_bytes_read = 0; +} + +Zlib.prototype.close = function () { +  if (this.write_in_progress) { +    this.pending_close = true; +    return; +  } + +  this.pending_close = false; + +  assert(this.init_done, 'close before init'); +  assert(this.mode <= exports.UNZIP); + +  if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { +    zlib_deflate.deflateEnd(this.strm); +  } else if (this.mode === exports.INFLATE || this.mode === exports.GUNZIP || this.mode === exports.INFLATERAW || this.mode === exports.UNZIP) { +    zlib_inflate.inflateEnd(this.strm); +  } + +  this.mode = exports.NONE; + +  this.dictionary = null; +}; + +Zlib.prototype.write = function (flush, input, in_off, in_len, out, out_off, out_len) { +  return this._write(true, flush, input, in_off, in_len, out, out_off, out_len); +}; + +Zlib.prototype.writeSync = function (flush, input, in_off, in_len, out, out_off, out_len) { +  return this._write(false, flush, input, in_off, in_len, out, out_off, out_len); +}; + +Zlib.prototype._write = function (async, flush, input, in_off, in_len, out, out_off, out_len) { +  assert.equal(arguments.length, 8); + +  assert(this.init_done, 'write before init'); +  assert(this.mode !== exports.NONE, 'already finalized'); +  assert.equal(false, this.write_in_progress, 'write already in progress'); +  assert.equal(false, this.pending_close, 'close is pending'); + +  this.write_in_progress = true; + +  assert.equal(false, flush === undefined, 'must provide flush value'); + +  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 = Buffer.alloc(0); +    in_len = 0; +    in_off = 0; +  } + +  this.strm.avail_in = in_len; +  this.strm.input = input; +  this.strm.next_in = in_off; +  this.strm.avail_out = out_len; +  this.strm.output = out; +  this.strm.next_out = out_off; +  this.flush = flush; + +  if (!async) { +    // sync version +    this._process(); + +    if (this._checkError()) { +      return this._afterSync(); +    } +    return; +  } + +  // async version +  var self = this; +  process.nextTick(function () { +    self._process(); +    self._after(); +  }); + +  return this; +}; + +Zlib.prototype._afterSync = function () { +  var avail_out = this.strm.avail_out; +  var avail_in = this.strm.avail_in; + +  this.write_in_progress = false; + +  return [avail_in, avail_out]; +}; + +Zlib.prototype._process = function () { +  var next_expected_header_byte = null; + +  // If the avail_out is left at 0, then it means that it ran out +  // of room.  If there was avail_out left over, then it means +  // that all of the input was consumed. +  switch (this.mode) { +    case exports.DEFLATE: +    case exports.GZIP: +    case exports.DEFLATERAW: +      this.err = zlib_deflate.deflate(this.strm, this.flush); +      break; +    case exports.UNZIP: +      if (this.strm.avail_in > 0) { +        next_expected_header_byte = this.strm.next_in; +      } + +      switch (this.gzip_id_bytes_read) { +        case 0: +          if (next_expected_header_byte === null) { +            break; +          } + +          if (this.strm.input[next_expected_header_byte] === GZIP_HEADER_ID1) { +            this.gzip_id_bytes_read = 1; +            next_expected_header_byte++; + +            if (this.strm.avail_in === 1) { +              // The only available byte was already read. +              break; +            } +          } else { +            this.mode = exports.INFLATE; +            break; +          } + +        // fallthrough +        case 1: +          if (next_expected_header_byte === null) { +            break; +          } + +          if (this.strm.input[next_expected_header_byte] === GZIP_HEADER_ID2) { +            this.gzip_id_bytes_read = 2; +            this.mode = exports.GUNZIP; +          } else { +            // There is no actual difference between INFLATE and INFLATERAW +            // (after initialization). +            this.mode = exports.INFLATE; +          } + +          break; +        default: +          throw new Error('invalid number of gzip magic number bytes read'); +      } + +    // fallthrough +    case exports.INFLATE: +    case exports.GUNZIP: +    case exports.INFLATERAW: +      this.err = zlib_inflate.inflate(this.strm, this.flush + +      // If data was encoded with dictionary +      );if (this.err === exports.Z_NEED_DICT && this.dictionary) { +        // Load it +        this.err = zlib_inflate.inflateSetDictionary(this.strm, this.dictionary); +        if (this.err === exports.Z_OK) { +          // And try to decode again +          this.err = zlib_inflate.inflate(this.strm, this.flush); +        } else if (this.err === exports.Z_DATA_ERROR) { +          // Both inflateSetDictionary() and inflate() return Z_DATA_ERROR. +          // Make it possible for After() to tell a bad dictionary from bad +          // input. +          this.err = exports.Z_NEED_DICT; +        } +      } +      while (this.strm.avail_in > 0 && this.mode === exports.GUNZIP && this.err === exports.Z_STREAM_END && this.strm.next_in[0] !== 0x00) { +        // Bytes remain in input buffer. Perhaps this is another compressed +        // member in the same archive, or just trailing garbage. +        // Trailing zero bytes are okay, though, since they are frequently +        // used for padding. + +        this.reset(); +        this.err = zlib_inflate.inflate(this.strm, this.flush); +      } +      break; +    default: +      throw new Error('Unknown mode ' + this.mode); +  } +}; + +Zlib.prototype._checkError = function () { +  // Acceptable error states depend on the type of zlib stream. +  switch (this.err) { +    case exports.Z_OK: +    case exports.Z_BUF_ERROR: +      if (this.strm.avail_out !== 0 && this.flush === exports.Z_FINISH) { +        this._error('unexpected end of file'); +        return false; +      } +      break; +    case exports.Z_STREAM_END: +      // normal statuses, not fatal +      break; +    case exports.Z_NEED_DICT: +      if (this.dictionary == null) { +        this._error('Missing dictionary'); +      } else { +        this._error('Bad dictionary'); +      } +      return false; +    default: +      // something else. +      this._error('Zlib error'); +      return false; +  } + +  return true; +}; + +Zlib.prototype._after = function () { +  if (!this._checkError()) { +    return; +  } + +  var avail_out = this.strm.avail_out; +  var avail_in = this.strm.avail_in; + +  this.write_in_progress = false; + +  // call the write() cb +  this.callback(avail_in, avail_out); + +  if (this.pending_close) { +    this.close(); +  } +}; + +Zlib.prototype._error = function (message) { +  if (this.strm.msg) { +    message = this.strm.msg; +  } +  this.onerror(message, this.err + +  // no hope of rescue. +  );this.write_in_progress = false; +  if (this.pending_close) { +    this.close(); +  } +}; + +Zlib.prototype.init = function (windowBits, level, memLevel, strategy, dictionary) { +  assert(arguments.length === 4 || arguments.length === 5, 'init(windowBits, level, memLevel, strategy, [dictionary])'); + +  assert(windowBits >= 8 && windowBits <= 15, 'invalid windowBits'); +  assert(level >= -1 && level <= 9, 'invalid compression level'); + +  assert(memLevel >= 1 && memLevel <= 9, 'invalid memlevel'); + +  assert(strategy === exports.Z_FILTERED || strategy === exports.Z_HUFFMAN_ONLY || strategy === exports.Z_RLE || strategy === exports.Z_FIXED || strategy === exports.Z_DEFAULT_STRATEGY, 'invalid strategy'); + +  this._init(level, windowBits, memLevel, strategy, dictionary); +  this._setDictionary(); +}; + +Zlib.prototype.params = function () { +  throw new Error('deflateParams Not supported'); +}; + +Zlib.prototype.reset = function () { +  this._reset(); +  this._setDictionary(); +}; + +Zlib.prototype._init = function (level, windowBits, memLevel, strategy, dictionary) { +  this.level = level; +  this.windowBits = windowBits; +  this.memLevel = memLevel; +  this.strategy = strategy; + +  this.flush = exports.Z_NO_FLUSH; + +  this.err = exports.Z_OK; + +  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 = -1 * this.windowBits; +  } + +  this.strm = new Zstream(); + +  switch (this.mode) { +    case exports.DEFLATE: +    case exports.GZIP: +    case exports.DEFLATERAW: +      this.err = 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: +      this.err = zlib_inflate.inflateInit2(this.strm, this.windowBits); +      break; +    default: +      throw new Error('Unknown mode ' + this.mode); +  } + +  if (this.err !== exports.Z_OK) { +    this._error('Init error'); +  } + +  this.dictionary = dictionary; + +  this.write_in_progress = false; +  this.init_done = true; +}; + +Zlib.prototype._setDictionary = function () { +  if (this.dictionary == null) { +    return; +  } + +  this.err = exports.Z_OK; + +  switch (this.mode) { +    case exports.DEFLATE: +    case exports.DEFLATERAW: +      this.err = zlib_deflate.deflateSetDictionary(this.strm, this.dictionary); +      break; +    default: +      break; +  } + +  if (this.err !== exports.Z_OK) { +    this._error('Failed to set dictionary'); +  } +}; + +Zlib.prototype._reset = function () { +  this.err = exports.Z_OK; + +  switch (this.mode) { +    case exports.DEFLATE: +    case exports.DEFLATERAW: +    case exports.GZIP: +      this.err = zlib_deflate.deflateReset(this.strm); +      break; +    case exports.INFLATE: +    case exports.INFLATERAW: +    case exports.GUNZIP: +      this.err = zlib_inflate.inflateReset(this.strm); +      break; +    default: +      break; +  } + +  if (this.err !== exports.Z_OK) { +    this._error('Failed to reset stream'); +  } +}; + +exports.Zlib = Zlib;
\ No newline at end of file diff --git a/node_modules/browserify-zlib/lib/index.js b/node_modules/browserify-zlib/lib/index.js new file mode 100644 index 000000000..15013f03c --- /dev/null +++ b/node_modules/browserify-zlib/lib/index.js @@ -0,0 +1,609 @@ +'use strict'; + +var Buffer = require('buffer').Buffer; +var Transform = require('stream').Transform; +var binding = require('./binding'); +var util = require('util'); +var assert = require('assert').ok; +var kMaxLength = require('buffer').kMaxLength; +var kRangeErrorMessage = 'Cannot create final Buffer. It would be larger ' + 'than 0x' + kMaxLength.toString(16) + ' bytes'; + +// 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 +var bkeys = Object.keys(binding); +for (var bk = 0; bk < bkeys.length; bk++) { +  var bkey = bkeys[bk]; +  if (bkey.match(/^Z/)) { +    Object.defineProperty(exports, bkey, { +      enumerable: true, value: binding[bkey], writable: false +    }); +  } +} + +// translation table for return codes. +var 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 +}; + +var ckeys = Object.keys(codes); +for (var ck = 0; ck < ckeys.length; ck++) { +  var ckey = ckeys[ck]; +  codes[codes[ckey]] = ckey; +} + +Object.defineProperty(exports, 'codes', { +  enumerable: true, value: Object.freeze(codes), writable: false +}); + +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; +    var err = null; + +    if (nread >= kMaxLength) { +      err = new RangeError(kRangeErrorMessage); +    } else { +      buf = Buffer.concat(buffers, nread); +    } + +    buffers = []; +    engine.close(); +    callback(err, buf); +  } +} + +function zlibBufferSync(engine, buffer) { +  if (typeof buffer === 'string') buffer = Buffer.from(buffer); + +  if (!Buffer.isBuffer(buffer)) throw new TypeError('Not a string or buffer'); + +  var flushFlag = engine._finishFlushFlag; + +  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); +} + +function isValidFlushFlag(flag) { +  return flag === binding.Z_NO_FLUSH || flag === binding.Z_PARTIAL_FLUSH || flag === binding.Z_SYNC_FLUSH || flag === binding.Z_FULL_FLUSH || flag === binding.Z_FINISH || flag === binding.Z_BLOCK; +} + +// 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) { +  var _this = this; + +  this._opts = opts = opts || {}; +  this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK; + +  Transform.call(this, opts); + +  if (opts.flush && !isValidFlushFlag(opts.flush)) { +    throw new Error('Invalid flush flag: ' + opts.flush); +  } +  if (opts.finishFlush && !isValidFlushFlag(opts.finishFlush)) { +    throw new Error('Invalid flush flag: ' + opts.finishFlush); +  } + +  this._flushFlag = opts.flush || binding.Z_NO_FLUSH; +  this._finishFlushFlag = typeof opts.finishFlush !== 'undefined' ? opts.finishFlush : binding.Z_FINISH; + +  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._handle = new binding.Zlib(mode); + +  var self = this; +  this._hadError = false; +  this._handle.onerror = function (message, errno) { +    // there is no way to cleanly recover. +    // continuing only obscures problems. +    _close(self); +    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._handle.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS, level, opts.memLevel || exports.Z_DEFAULT_MEMLEVEL, strategy, opts.dictionary); + +  this._buffer = Buffer.allocUnsafe(this._chunkSize); +  this._offset = 0; +  this._level = level; +  this._strategy = strategy; + +  this.once('end', this.close); + +  Object.defineProperty(this, '_closed', { +    get: function () { +      return !_this._handle; +    }, +    configurable: true, +    enumerable: true +  }); +} + +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 () { +      assert(self._handle, 'zlib binding closed'); +      self._handle.params(level, strategy); +      if (!self._hadError) { +        self._level = level; +        self._strategy = strategy; +        if (callback) callback(); +      } +    }); +  } else { +    process.nextTick(callback); +  } +}; + +Zlib.prototype.reset = function () { +  assert(this._handle, 'zlib binding closed'); +  return this._handle.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(Buffer.alloc(0), '', callback); +}; + +Zlib.prototype.flush = function (kind, callback) { +  var _this2 = this; + +  var ws = this._writableState; + +  if (typeof kind === 'function' || kind === undefined && !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) { +    if (callback) { +      this.once('drain', function () { +        return _this2.flush(kind, callback); +      }); +    } +  } else { +    this._flushFlag = kind; +    this.write(Buffer.alloc(0), '', callback); +  } +}; + +Zlib.prototype.close = function (callback) { +  _close(this, callback); +  process.nextTick(emitCloseNT, this); +}; + +function _close(engine, callback) { +  if (callback) process.nextTick(callback); + +  // Caller may invoke .close after a zlib error (which will null _handle). +  if (!engine._handle) return; + +  engine._handle.close(); +  engine._handle = null; +} + +function emitCloseNT(self) { +  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 (!this._handle) return cb(new Error('zlib binding closed')); + +  // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag +  // (or whatever flag was provided using opts.finishFlush). +  // 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 = this._finishFlushFlag;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; +    } +  } + +  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; +    }); + +    assert(this._handle, 'zlib binding closed'); +    do { +      var res = this._handle.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; +    } + +    if (nread >= kMaxLength) { +      _close(this); +      throw new RangeError(kRangeErrorMessage); +    } + +    var buf = Buffer.concat(buffers, nread); +    _close(this); + +    return buf; +  } + +  assert(this._handle, 'zlib binding closed'); +  var req = this._handle.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) { +    // When the callback is used in an async write, the callback's +    // context is the `req` object that was created. The req object +    // is === this._handle, and that's why it's important to null +    // out the values after they are done being used. `this._handle` +    // can stay in memory longer than the callback and buffer are needed. +    if (this) { +      this.buffer = null; +      this.callback = null; +    } + +    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 = Buffer.allocUnsafe(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._handle.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);
\ No newline at end of file  | 
