@ -1,31 +1,16 @@
'use strict' ;
const Buffer = require ( 'buffer' ) . Buffer ;
const internalUtil = require ( 'internal/util' ) ;
const Transform = require ( '_stream_transform' ) ;
const binding = process . binding ( 'zlib' ) ;
const util = require ( 'util' ) ;
const assert = require ( 'assert' ) . ok ;
const kMaxLength = require ( 'buffer' ) . kMaxLength ;
const kRangeErrorMessage = 'Cannot create final Buffer. It would be larger ' +
'than 0x' + kMaxLength . toString ( 16 ) + ' bytes' ;
` than 0x ${ kMaxLength . toString ( 16 ) } bytes ` ;
const constants = process . binding ( 'constants' ) . zlib ;
// These should be considered deprecated
// expose all the zlib constants
const bkeys = Object . keys ( constants ) ;
for ( var bk = 0 ; bk < bkeys . length ; bk ++ ) {
var bkey = bkeys [ bk ] ;
Object . defineProperty ( exports , bkey , {
enumerable : true , value : constants [ bkey ] , writable : false
} ) ;
}
Object . defineProperty ( exports , 'constants' , {
configurable : false ,
enumerable : true ,
value : constants
} ) ;
const createClassWrapper = internalUtil . createClassWrapper ;
// translation table for return codes.
const codes = {
@ -46,132 +31,29 @@ for (var ck = 0; ck < ckeys.length; 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 ) ;
} ;
function isValidFlushFlag ( flag ) {
return flag >= constants . Z_NO_FLUSH &&
flag <= constants . Z_BLOCK ;
// Covers: constants.Z_NO_FLUSH (0),
// constants.Z_PARTIAL_FLUSH (1),
// constants.Z_SYNC_FLUSH (2),
// constants.Z_FULL_FLUSH (3),
// constants.Z_FINISH (4), and
// constants.Z_BLOCK (5)
}
exports . inflateRaw = function ( buffer , opts , callback ) {
if ( typeof opts === 'function' ) {
callback = opts ;
opts = { } ;
}
return zlibBuffer ( new InflateRaw ( opts ) , buffer , callback ) ;
} ;
function isInvalidStrategy ( strategy ) {
return typeof strategy !== 'number' ||
strategy < constants . Z_DEFAULT_STRATEGY ||
strategy > constants . Z_FIXED ;
exports . inflateRawSync = function ( buffer , opts ) {
return zlibBufferSync ( new InflateRaw ( opts ) , buffer ) ;
} ;
// Covers: constants.Z_FILTERED, (1)
// constants.Z_HUFFMAN_ONLY (2),
// constants.Z_RLE (3),
// constants.Z_FIXED (4), and
// constants.Z_DEFAULT_STRATEGY (0)
}
function zlibBuffer ( engine , buffer , callback ) {
var buffers = [ ] ;
@ -225,230 +107,326 @@ function zlibBufferSync(engine, buffer) {
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 , constants . DEFLATE ) ;
function zlibOnError ( message , errno ) {
// there is no way to cleanly recover.
// continuing only obscures problems.
_ close ( this ) ;
this . _ hadError = true ;
var error = new Error ( message ) ;
error . errno = errno ;
error . code = codes [ errno ] ;
this . emit ( 'error' , error ) ;
}
function Inflate ( opts ) {
if ( ! ( this instanceof Inflate ) ) return new Inflate ( opts ) ;
Zlib . call ( this , opts , constants . INFLATE ) ;
function flushCallback ( level , strategy , callback ) {
assert ( this . _ handle , 'zlib binding closed' ) ;
this . _ handle . params ( level , strategy ) ;
if ( ! this . _ hadError ) {
this . _ level = level ;
this . _ strategy = strategy ;
if ( callback ) callback ( ) ;
}
}
// 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.
class Zlib extends Transform {
constructor ( opts , mode ) {
opts = opts || { } ;
super ( opts ) ;
// gzip - bigger header, same deflate compression
function Gzip ( opts ) {
if ( ! ( this instanceof Gzip ) ) return new Gzip ( opts ) ;
Zlib . call ( this , opts , constants . GZIP ) ;
}
this . _ opts = opts ;
this . _ chunkSize = opts . chunkSize || constants . Z_DEFAULT_CHUNK ;
function Gunzip ( opts ) {
if ( ! ( this instanceof Gunzip ) ) return new Gunzip ( opts ) ;
Zlib . call ( this , opts , constants . GUNZIP ) ;
}
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 || constants . Z_NO_FLUSH ;
this . _ finishFlushFlag = opts . finishFlush !== undefined ?
opts . finishFlush : constants . Z_FINISH ;
// raw - no header
function DeflateRaw ( opts ) {
if ( ! ( this instanceof DeflateRaw ) ) return new DeflateRaw ( opts ) ;
Zlib . call ( this , opts , constants . DEFLATERAW ) ;
}
if ( opts . chunkSize ) {
if ( opts . chunkSize < constants . Z_MIN_CHUNK ) {
throw new Error ( 'Invalid chunk size: ' + opts . chunkSize ) ;
}
}
function InflateRaw ( opts ) {
if ( ! ( this instanceof InflateRaw ) ) return new InflateRaw ( opts ) ;
Zlib . call ( this , opts , constants . INFLATERAW ) ;
}
if ( opts . windowBits ) {
if ( opts . windowBits < constants . Z_MIN_WINDOWBITS ||
opts . windowBits > constants . Z_MAX_WINDOWBITS ) {
throw new Error ( 'Invalid windowBits: ' + opts . windowBits ) ;
}
}
if ( opts . level ) {
if ( opts . level < constants . Z_MIN_LEVEL ||
opts . level > constants . Z_MAX_LEVEL ) {
throw new Error ( 'Invalid compression level: ' + opts . level ) ;
}
}
// auto-detect header.
function Unzip ( opts ) {
if ( ! ( this instanceof Unzip ) ) return new Unzip ( opts ) ;
Zlib . call ( this , opts , constants . UNZIP ) ;
}
if ( opts . memLevel ) {
if ( opts . memLevel < constants . Z_MIN_MEMLEVEL ||
opts . memLevel > constants . Z_MAX_MEMLEVEL ) {
throw new Error ( 'Invalid memLevel: ' + opts . memLevel ) ;
}
}
function isValidFlushFlag ( flag ) {
return flag === constants . Z_NO_FLUSH ||
flag === constants . Z_PARTIAL_FLUSH ||
flag === constants . Z_SYNC_FLUSH ||
flag === constants . Z_FULL_FLUSH ||
flag === constants . Z_FINISH ||
flag === constants . Z_BLOCK ;
}
if ( opts . strategy && isInvalidStrategy ( opts . strategy ) )
throw new Error ( 'Invalid strategy: ' + opts . strategy ) ;
const strategies = [ constants . Z_FILTERED ,
constants . Z_HUFFMAN_ONLY ,
constants . Z_RLE ,
constants . Z_FIXED ,
constants . Z_DEFAULT_STRATEGY ] ;
if ( opts . dictionary ) {
if ( ! ( opts . dictionary instanceof Buffer ) ) {
throw new Error ( 'Invalid dictionary: it should be a Buffer instance' ) ;
}
}
// 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.
this . _ handle = new binding . Zlib ( mode ) ;
this . _ handle . onerror = zlibOnError . bind ( this ) ;
this . _ hadError = false ;
function Zlib ( opts , mode ) {
this . _ opts = opts = opts || { } ;
this . _ chunkSize = opts . chunkSize || constants . Z_DEFAULT_CHUNK ;
var level = constants . Z_DEFAULT_COMPRESSION ;
if ( typeof opts . level === 'number' ) level = opts . level ;
Transform . call ( this , opts ) ;
var strategy = constants . Z_DEFAULT_STRATEGY ;
if ( typeof opts . strategy === 'number' ) strategy = opts . strategy ;
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 . _ handle . init ( opts . windowBits || constants . Z_DEFAULT_WINDOWBITS ,
level ,
opts . memLevel || constants . Z_DEFAULT_MEMLEVEL ,
strategy ,
opts . dictionary ) ;
this . _ flushFlag = opts . flush || constants . Z_NO_FLUSH ;
this . _ finishFlushFlag = typeof opts . finishFlush !== 'undefined' ?
opts . finishFlush : constants . Z_FINISH ;
this . _ buffer = Buffer . allocUnsafe ( this . _ chunkSize ) ;
this . _ offset = 0 ;
this . _ level = level ;
this . _ strategy = strategy ;
if ( opts . chunkSize ) {
if ( opts . chunkSize < constants . Z_MIN_CHUNK ) {
throw new Error ( 'Invalid chunk size: ' + opts . chunkSize ) ;
}
this . once ( 'end' , this . close ) ;
}
if ( opts . windowBits ) {
if ( opts . windowBits < constants . Z_MIN_WINDOWBITS ||
opts . windowBits > constants . Z_MAX_WINDOWBITS ) {
throw new Error ( 'Invalid windowBits: ' + opts . windowBits ) ;
}
get _ closed ( ) {
return ! this . _ handle ;
}
if ( opts . level ) {
if ( opts . level < constants . Z_MIN_LEVEL ||
opts . level > constants . Z_MAX_LEVEL ) {
throw new Error ( 'Invalid compression level: ' + opts . level ) ;
params ( level , strategy , callback ) {
if ( level < constants . Z_MIN_LEVEL ||
level > constants . Z_MAX_LEVEL ) {
throw new Range Error( 'Invalid compression level: ' + level ) ;
}
}
if ( isInvalidStrategy ( strategy ) )
throw new TypeError ( 'Invalid strategy: ' + strategy ) ;
if ( opts . memLevel ) {
if ( opts . memLevel < constants . Z_MIN_MEMLEVEL ||
opts . memLevel > constants . Z_MAX_MEMLEVEL ) {
throw new Error ( 'Invalid memLevel: ' + opts . memLevel ) ;
if ( this . _ level !== level || this . _ strategy !== strategy ) {
this . flush ( constants . Z_SYNC_FLUSH ,
flushCallback . bind ( this , level , strategy , callback ) ) ;
} else {
process . nextTick ( callback ) ;
}
}
if ( opts . strategy && ! ( strategies . includes ( opts . strategy ) ) )
throw new Error ( 'Invalid strategy: ' + opts . strategy ) ;
reset ( ) {
assert ( this . _ handle , 'zlib binding closed' ) ;
return this . _ handle . reset ( ) ;
}
if ( opts . dictionary ) {
if ( ! ( opts . dictionary instanceof Buffer ) ) {
throw new Error ( 'Invalid dictionary: it should be a Buffer instance' ) ;
}
// This is the _flush function called by the transform class,
// internally, when the last chunk has been written.
_ flush ( callback ) {
this . _ transform ( Buffer . alloc ( 0 ) , '' , callback ) ;
}
this . _ handle = new binding . Zlib ( mode ) ;
flush ( kind , callback ) {
var ws = this . _ writableState ;
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 ;
if ( typeof kind === 'function' || ( kind === undefined && ! callback ) ) {
callback = kind ;
kind = constants . Z_FULL_FLUSH ;
}
var error = new Error ( message ) ;
error . errno = errno ;
error . code = exports . codes [ errno ] ;
self . emit ( 'error' , error ) ;
} ;
if ( ws . ended ) {
if ( callback )
process . nextTick ( callback ) ;
} else if ( ws . ending ) {
if ( callback )
this . once ( 'end' , callback ) ;
} else if ( ws . needDrain ) {
if ( callback ) {
const drainHandler = ( ) => this . flush ( kind , callback ) ;
this . once ( 'drain' , drainHandler ) ;
}
} else {
this . _ flushFlag = kind ;
this . write ( Buffer . alloc ( 0 ) , '' , callback ) ;
}
}
var level = constants . Z_DEFAULT_COMPRESSION ;
if ( typeof opts . level === 'number' ) level = opts . level ;
close ( callback ) {
_ close ( this , callback ) ;
process . nextTick ( emitCloseNT , this ) ;
}
var strategy = constants . Z_DEFAULT_STRATEGY ;
if ( typeof opts . strategy === 'number' ) strategy = opts . strategy ;
_ transform ( 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 && ! ( chunk instanceof Buffer ) )
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 || constants . Z_NO_FLUSH ;
}
}
this . _ handle . init ( opts . windowBits || constants . Z_DEFAULT_WINDOWBITS ,
level ,
opts . memLevel || constants . Z_DEFAULT_MEMLEVEL ,
strategy ,
opts . dictionary ) ;
this . _ processChunk ( chunk , flushFlag , cb ) ;
}
this . _ buffer = Buffer . allocUnsafe ( this . _ chunkSize ) ;
this . _ offset = 0 ;
this . _ level = level ;
this . _ strategy = strategy ;
_ processChunk ( chunk , flushFlag , cb ) {
var availInBefore = chunk && chunk . length ;
var availOutBefore = this . _ chunkSize - this . _ offset ;
var inOff = 0 ;
this . once ( 'end' , this . close ) ;
var self = this ;
Object . defineProperty ( this , '_closed' , {
get : ( ) => ! this . _ handle ,
configurable : true ,
enumerable : true
} ) ;
}
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 ;
}
util . inherits ( Zlib , Transform ) ;
if ( nread >= kMaxLength ) {
_ close ( this ) ;
throw new RangeError ( kRangeErrorMessage ) ;
}
Zlib . prototype . params = function ( level , strategy , callback ) {
if ( level < constants . Z_MIN_LEVEL ||
level > constants . Z_MAX_LEVEL ) {
throw new RangeError ( 'Invalid compression level: ' + level ) ;
}
if ( ! ( strategies . includes ( strategy ) ) )
throw new TypeError ( 'Invalid strategy: ' + strategy ) ;
var buf = Buffer . concat ( buffers , nread ) ;
_ close ( this ) ;
if ( this . _ level !== level || this . _ strategy !== strategy ) {
var self = this ;
this . flush ( constants . Z_SYNC_FLUSH , function flushCallback ( ) {
assert ( self . _ handle , 'zlib binding closed' ) ;
self . _ handle . params ( level , strategy ) ;
if ( ! self . _ hadError ) {
self . _ level = level ;
self . _ strategy = strategy ;
if ( callback ) callback ( ) ;
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 ;
}
} ) ;
} else {
process . nextTick ( callback ) ;
}
} ;
Zlib . prototype . reset = function ( ) {
assert ( this . _ handle , 'zlib binding closed' ) ;
return this . _ handle . reset ( ) ;
} ;
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 ;
}
}
// 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 ) ;
} ;
// 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 ) ;
}
Zlib . prototype . flush = function ( kind , callback ) {
var ws = this . _ writableState ;
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 ( typeof kind === 'function' || ( kind === undefined && ! callback ) ) {
callback = kind ;
kind = constants . Z_FULL_FLUSH ;
}
if ( ! async )
return false ;
if ( ws . ended ) {
if ( callback )
process . nextTick ( callback ) ;
} else if ( ws . ending ) {
if ( callback )
this . once ( 'end' , callback ) ;
} else if ( ws . needDrain ) {
if ( callback ) {
const drainHandler = ( ) => this . flush ( kind , callback ) ;
this . once ( 'drain' , drainHandler ) ;
// finished with the chunk.
cb ( ) ;
}
} 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 )
@ -466,164 +444,127 @@ 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 && ! ( chunk instanceof Buffer ) )
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 || constants . Z_NO_FLUSH ;
}
// generic zlib
// minimal 2-byte header
class Deflate extends Zlib {
constructor ( opts ) {
super ( opts , constants . DEFLATE ) ;
}
}
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 ;
} ) ;
class Inflate extends Zlib {
constructor ( opts ) {
super ( opts , constants . INFLATE ) ;
}
}
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 ;
}
class Gzip extends Zlib {
constructor ( opts ) {
super ( opts , constants . GZIP ) ;
}
}
if ( nread >= kMaxLength ) {
_ close ( this ) ;
throw new RangeError ( kRangeErrorMessage ) ;
}
class Gunzip extends Zlib {
constructor ( opts ) {
super ( opts , constants . GUNZIP ) ;
}
}
var buf = Buffer . concat ( buffers , nread ) ;
_ close ( this ) ;
class DeflateRaw extends Zlib {
constructor ( opts ) {
super ( opts , constants . DEFLATERAW ) ;
}
}
return buf ;
class InflateRaw extends Zlib {
constructor ( opts ) {
super ( opts , constants . INFLATERAW ) ;
}
}
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 ;
}
class Unzip extends Zlib {
constructor ( opts ) {
super ( opts , constants . UNZIP ) ;
}
}
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 ;
function createConvenienceMethod ( type , sync ) {
if ( sync ) {
return function ( buffer , opts ) {
return zlibBufferSync ( new type ( opts ) , buffer ) ;
} ;
} else {
return function ( buffer , opts , callback ) {
if ( typeof opts === 'function' ) {
callback = opts ;
opts = { } ;
}
}
// 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 ;
return zlibBuffer ( new type ( opts ) , buffer , callback ) ;
} ;
}
}
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 ;
}
function createProperty ( type ) {
return {
configurable : true ,
enumerable : true ,
value : type
} ;
}
if ( ! async )
return false ;
module . exports = {
Deflate : createClassWrapper ( Deflate ) ,
Inflate : createClassWrapper ( Inflate ) ,
Gzip : createClassWrapper ( Gzip ) ,
Gunzip : createClassWrapper ( Gunzip ) ,
DeflateRaw : createClassWrapper ( DeflateRaw ) ,
InflateRaw : createClassWrapper ( InflateRaw ) ,
Unzip : createClassWrapper ( Unzip ) ,
// Convenience methods.
// compress/decompress a string or buffer in one step.
deflate : createConvenienceMethod ( Deflate , false ) ,
deflateSync : createConvenienceMethod ( Deflate , true ) ,
gzip : createConvenienceMethod ( Gzip , false ) ,
gzipSync : createConvenienceMethod ( Gzip , true ) ,
deflateRaw : createConvenienceMethod ( DeflateRaw , false ) ,
deflateRawSync : createConvenienceMethod ( DeflateRaw , true ) ,
unzip : createConvenienceMethod ( Unzip , false ) ,
unzipSync : createConvenienceMethod ( Unzip , true ) ,
inflate : createConvenienceMethod ( Inflate , false ) ,
inflateSync : createConvenienceMethod ( Inflate , true ) ,
gunzip : createConvenienceMethod ( Gunzip , false ) ,
gunzipSync : createConvenienceMethod ( Gunzip , true ) ,
inflateRaw : createConvenienceMethod ( InflateRaw , false ) ,
inflateRawSync : createConvenienceMethod ( InflateRaw , true )
} ;
// finished with the chunk.
cb ( ) ;
Object . defineProperties ( module . exports , {
createDeflate : createProperty ( module . exports . Deflate ) ,
createInflate : createProperty ( module . exports . Inflate ) ,
createDeflateRaw : createProperty ( module . exports . DeflateRaw ) ,
createInflateRaw : createProperty ( module . exports . InflateRaw ) ,
createGzip : createProperty ( module . exports . Gzip ) ,
createGunzip : createProperty ( module . exports . Gunzip ) ,
createUnzip : createProperty ( module . exports . Unzip ) ,
constants : {
configurable : false ,
enumerable : true ,
value : constants
} ,
codes : {
enumerable : true ,
writable : false ,
value : Object . freeze ( codes )
}
} ;
} ) ;
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 ) ;
// These should be considered deprecated
// expose all the zlib constants
const bkeys = Object . keys ( constants ) ;
for ( var bk = 0 ; bk < bkeys . length ; bk ++ ) {
var bkey = bkeys [ bk ] ;
Object . defineProperty ( module . exports , bkey , {
enumerable : true , value : constants [ bkey ] , writable : false
} ) ;
}