@@ -207,21 +207,10 @@ function checkRangesOrGetDefault(number, name, lower, upper, def) {
207
207
return number ;
208
208
}
209
209
210
- // the Zlib class they all inherit from
211
- // This thing manages the queue of requests, and returns
212
- // true or false if there is anything in the queue when
213
- // you call the .write() method.
214
- function Zlib ( opts , mode ) {
210
+ // The base class for all Zlib-style streams.
211
+ function ZlibBase ( opts , mode , handle , { flush, finishFlush, fullFlush } ) {
215
212
var chunkSize = Z_DEFAULT_CHUNK ;
216
- var flush = Z_NO_FLUSH ;
217
- var finishFlush = Z_FINISH ;
218
- var windowBits = Z_DEFAULT_WINDOWBITS ;
219
- var level = Z_DEFAULT_COMPRESSION ;
220
- var memLevel = Z_DEFAULT_MEMLEVEL ;
221
- var strategy = Z_DEFAULT_STRATEGY ;
222
- var dictionary ;
223
-
224
- // The Zlib class is not exported to user land, the mode should only be
213
+ // The ZlibBase class is not exported to user land, the mode should only be
225
214
// passed in by us.
226
215
assert ( typeof mode === 'number' ) ;
227
216
assert ( mode >= DEFLATE && mode <= UNZIP ) ;
@@ -237,50 +226,11 @@ function Zlib(opts, mode) {
237
226
238
227
flush = checkRangesOrGetDefault (
239
228
opts . flush , 'options.flush' ,
240
- Z_NO_FLUSH , Z_BLOCK , Z_NO_FLUSH ) ;
229
+ Z_NO_FLUSH , Z_BLOCK , flush ) ;
241
230
242
231
finishFlush = checkRangesOrGetDefault (
243
232
opts . finishFlush , 'options.finishFlush' ,
244
- Z_NO_FLUSH , Z_BLOCK , Z_FINISH ) ;
245
-
246
- // windowBits is special. On the compression side, 0 is an invalid value.
247
- // But on the decompression side, a value of 0 for windowBits tells zlib
248
- // to use the window size in the zlib header of the compressed stream.
249
- if ( ( opts . windowBits == null || opts . windowBits === 0 ) &&
250
- ( mode === INFLATE ||
251
- mode === GUNZIP ||
252
- mode === UNZIP ) ) {
253
- windowBits = 0 ;
254
- } else {
255
- windowBits = checkRangesOrGetDefault (
256
- opts . windowBits , 'options.windowBits' ,
257
- Z_MIN_WINDOWBITS , Z_MAX_WINDOWBITS , Z_DEFAULT_WINDOWBITS ) ;
258
- }
259
-
260
- level = checkRangesOrGetDefault (
261
- opts . level , 'options.level' ,
262
- Z_MIN_LEVEL , Z_MAX_LEVEL , Z_DEFAULT_COMPRESSION ) ;
263
-
264
- memLevel = checkRangesOrGetDefault (
265
- opts . memLevel , 'options.memLevel' ,
266
- Z_MIN_MEMLEVEL , Z_MAX_MEMLEVEL , Z_DEFAULT_MEMLEVEL ) ;
267
-
268
- strategy = checkRangesOrGetDefault (
269
- opts . strategy , 'options.strategy' ,
270
- Z_DEFAULT_STRATEGY , Z_FIXED , Z_DEFAULT_STRATEGY ) ;
271
-
272
- dictionary = opts . dictionary ;
273
- if ( dictionary !== undefined && ! isArrayBufferView ( dictionary ) ) {
274
- if ( isAnyArrayBuffer ( dictionary ) ) {
275
- dictionary = Buffer . from ( dictionary ) ;
276
- } else {
277
- throw new ERR_INVALID_ARG_TYPE (
278
- 'options.dictionary' ,
279
- [ 'Buffer' , 'TypedArray' , 'DataView' , 'ArrayBuffer' ] ,
280
- dictionary
281
- ) ;
282
- }
283
- }
233
+ Z_NO_FLUSH , Z_BLOCK , finishFlush ) ;
284
234
285
235
if ( opts . encoding || opts . objectMode || opts . writableObjectMode ) {
286
236
opts = _extend ( { } , opts ) ;
@@ -289,40 +239,29 @@ function Zlib(opts, mode) {
289
239
opts . writableObjectMode = false ;
290
240
}
291
241
}
242
+
292
243
Transform . call ( this , opts ) ;
244
+ this . _hadError = false ;
293
245
this . bytesWritten = 0 ;
294
- this . _handle = new binding . Zlib ( mode ) ;
246
+ this . _handle = handle ;
247
+ handle [ owner_symbol ] = this ;
295
248
// Used by processCallback() and zlibOnError()
296
- this . _handle [ owner_symbol ] = this ;
297
- this . _handle . onerror = zlibOnError ;
298
- this . _hadError = false ;
299
- this . _writeState = new Uint32Array ( 2 ) ;
300
-
301
- if ( ! this . _handle . init ( windowBits ,
302
- level ,
303
- memLevel ,
304
- strategy ,
305
- this . _writeState ,
306
- processCallback ,
307
- dictionary ) ) {
308
- throw new ERR_ZLIB_INITIALIZATION_FAILED ( ) ;
309
- }
310
-
249
+ handle . onerror = zlibOnError ;
311
250
this . _outBuffer = Buffer . allocUnsafe ( chunkSize ) ;
312
251
this . _outOffset = 0 ;
313
- this . _level = level ;
314
- this . _strategy = strategy ;
252
+
315
253
this . _chunkSize = chunkSize ;
316
254
this . _defaultFlushFlag = flush ;
317
255
this . _finishFlushFlag = finishFlush ;
318
256
this . _nextFlush = - 1 ;
319
- this . _info = opts && opts . info ;
257
+ this . _defaultFullFlushFlag = fullFlush ;
320
258
this . once ( 'end' , this . close ) ;
259
+ this . _info = opts && opts . info ;
321
260
}
322
- Object . setPrototypeOf ( Zlib . prototype , Transform . prototype ) ;
323
- Object . setPrototypeOf ( Zlib , Transform ) ;
261
+ Object . setPrototypeOf ( ZlibBase . prototype , Transform . prototype ) ;
262
+ Object . setPrototypeOf ( ZlibBase , Transform ) ;
324
263
325
- Object . defineProperty ( Zlib . prototype , '_closed' , {
264
+ Object . defineProperty ( ZlibBase . prototype , '_closed' , {
326
265
configurable : true ,
327
266
enumerable : true ,
328
267
get ( ) {
@@ -334,7 +273,7 @@ Object.defineProperty(Zlib.prototype, '_closed', {
334
273
// perspective, but it is inconsistent with all other streams exposed by Node.js
335
274
// that have this concept, where it stands for the number of bytes read
336
275
// *from* the stream (that is, net.Socket/tls.Socket & file system streams).
337
- Object . defineProperty ( Zlib . prototype , 'bytesRead' , {
276
+ Object . defineProperty ( ZlibBase . prototype , 'bytesRead' , {
338
277
configurable : true ,
339
278
enumerable : true ,
340
279
get : deprecate ( function ( ) {
@@ -347,41 +286,15 @@ Object.defineProperty(Zlib.prototype, 'bytesRead', {
347
286
'This feature will be removed in the future.' , 'DEP0108' )
348
287
} ) ;
349
288
350
- // This callback is used by `.params()` to wait until a full flush happened
351
- // before adjusting the parameters. In particular, the call to the native
352
- // `params()` function should not happen while a write is currently in progress
353
- // on the threadpool.
354
- function paramsAfterFlushCallback ( level , strategy , callback ) {
355
- assert ( this . _handle , 'zlib binding closed' ) ;
356
- this . _handle . params ( level , strategy ) ;
357
- if ( ! this . _hadError ) {
358
- this . _level = level ;
359
- this . _strategy = strategy ;
360
- if ( callback ) callback ( ) ;
361
- }
362
- }
363
-
364
- Zlib . prototype . params = function params ( level , strategy , callback ) {
365
- checkRangesOrGetDefault ( level , 'level' , Z_MIN_LEVEL , Z_MAX_LEVEL ) ;
366
- checkRangesOrGetDefault ( strategy , 'strategy' , Z_DEFAULT_STRATEGY , Z_FIXED ) ;
367
-
368
- if ( this . _level !== level || this . _strategy !== strategy ) {
369
- this . flush ( Z_SYNC_FLUSH ,
370
- paramsAfterFlushCallback . bind ( this , level , strategy , callback ) ) ;
371
- } else {
372
- process . nextTick ( callback ) ;
373
- }
374
- } ;
375
-
376
- Zlib . prototype . reset = function reset ( ) {
289
+ ZlibBase . prototype . reset = function ( ) {
377
290
if ( ! this . _handle )
378
291
assert ( false , 'zlib binding closed' ) ;
379
292
return this . _handle . reset ( ) ;
380
293
} ;
381
294
382
295
// This is the _flush function called by the transform class,
383
296
// internally, when the last chunk has been written.
384
- Zlib . prototype . _flush = function _flush ( callback ) {
297
+ ZlibBase . prototype . _flush = function ( callback ) {
385
298
this . _transform ( Buffer . alloc ( 0 ) , '' , callback ) ;
386
299
} ;
387
300
@@ -402,12 +315,12 @@ function maxFlush(a, b) {
402
315
}
403
316
404
317
const flushBuffer = Buffer . alloc ( 0 ) ;
405
- Zlib . prototype . flush = function flush ( kind , callback ) {
318
+ ZlibBase . prototype . flush = function ( kind , callback ) {
406
319
var ws = this . _writableState ;
407
320
408
321
if ( typeof kind === 'function' || ( kind === undefined && ! callback ) ) {
409
322
callback = kind ;
410
- kind = Z_FULL_FLUSH ;
323
+ kind = this . _defaultFullFlushFlag ;
411
324
}
412
325
413
326
if ( ws . ended ) {
@@ -426,17 +339,17 @@ Zlib.prototype.flush = function flush(kind, callback) {
426
339
}
427
340
} ;
428
341
429
- Zlib . prototype . close = function close ( callback ) {
342
+ ZlibBase . prototype . close = function ( callback ) {
430
343
_close ( this , callback ) ;
431
344
this . destroy ( ) ;
432
345
} ;
433
346
434
- Zlib . prototype . _destroy = function _destroy ( err , callback ) {
347
+ ZlibBase . prototype . _destroy = function ( err , callback ) {
435
348
_close ( this ) ;
436
349
callback ( err ) ;
437
350
} ;
438
351
439
- Zlib . prototype . _transform = function _transform ( chunk , encoding , cb ) {
352
+ ZlibBase . prototype . _transform = function ( chunk , encoding , cb ) {
440
353
var flushFlag = this . _defaultFlushFlag ;
441
354
// We use a 'fake' zero-length chunk to carry information about flushes from
442
355
// the public API to the actual stream implementation.
@@ -453,7 +366,7 @@ Zlib.prototype._transform = function _transform(chunk, encoding, cb) {
453
366
processChunk ( this , chunk , flushFlag , cb ) ;
454
367
} ;
455
368
456
- Zlib . prototype . _processChunk = function _processChunk ( chunk , flushFlag , cb ) {
369
+ ZlibBase . prototype . _processChunk = function ( chunk , flushFlag , cb ) {
457
370
// _processChunk() is left for backwards compatibility
458
371
if ( typeof cb === 'function' )
459
372
processChunk ( this , chunk , flushFlag , cb ) ;
@@ -643,6 +556,110 @@ function _close(engine, callback) {
643
556
engine . _handle = null ;
644
557
}
645
558
559
+ const zlibDefaultOpts = {
560
+ flush : Z_NO_FLUSH ,
561
+ finishFlush : Z_FINISH ,
562
+ fullFlush : Z_FULL_FLUSH
563
+ } ;
564
+ // Base class for all streams actually backed by zlib and using zlib-specific
565
+ // parameters.
566
+ function Zlib ( opts , mode ) {
567
+ var windowBits = Z_DEFAULT_WINDOWBITS ;
568
+ var level = Z_DEFAULT_COMPRESSION ;
569
+ var memLevel = Z_DEFAULT_MEMLEVEL ;
570
+ var strategy = Z_DEFAULT_STRATEGY ;
571
+ var dictionary ;
572
+
573
+ if ( opts ) {
574
+ // windowBits is special. On the compression side, 0 is an invalid value.
575
+ // But on the decompression side, a value of 0 for windowBits tells zlib
576
+ // to use the window size in the zlib header of the compressed stream.
577
+ if ( ( opts . windowBits == null || opts . windowBits === 0 ) &&
578
+ ( mode === INFLATE ||
579
+ mode === GUNZIP ||
580
+ mode === UNZIP ) ) {
581
+ windowBits = 0 ;
582
+ } else {
583
+ windowBits = checkRangesOrGetDefault (
584
+ opts . windowBits , 'options.windowBits' ,
585
+ Z_MIN_WINDOWBITS , Z_MAX_WINDOWBITS , Z_DEFAULT_WINDOWBITS ) ;
586
+ }
587
+
588
+ level = checkRangesOrGetDefault (
589
+ opts . level , 'options.level' ,
590
+ Z_MIN_LEVEL , Z_MAX_LEVEL , Z_DEFAULT_COMPRESSION ) ;
591
+
592
+ memLevel = checkRangesOrGetDefault (
593
+ opts . memLevel , 'options.memLevel' ,
594
+ Z_MIN_MEMLEVEL , Z_MAX_MEMLEVEL , Z_DEFAULT_MEMLEVEL ) ;
595
+
596
+ strategy = checkRangesOrGetDefault (
597
+ opts . strategy , 'options.strategy' ,
598
+ Z_DEFAULT_STRATEGY , Z_FIXED , Z_DEFAULT_STRATEGY ) ;
599
+
600
+ dictionary = opts . dictionary ;
601
+ if ( dictionary !== undefined && ! isArrayBufferView ( dictionary ) ) {
602
+ if ( isAnyArrayBuffer ( dictionary ) ) {
603
+ dictionary = Buffer . from ( dictionary ) ;
604
+ } else {
605
+ throw new ERR_INVALID_ARG_TYPE (
606
+ 'options.dictionary' ,
607
+ [ 'Buffer' , 'TypedArray' , 'DataView' , 'ArrayBuffer' ] ,
608
+ dictionary
609
+ ) ;
610
+ }
611
+ }
612
+ }
613
+
614
+ const handle = new binding . Zlib ( mode ) ;
615
+ // Ideally, we could let ZlibBase() set up _writeState. I haven't been able
616
+ // to come up with a good solution that doesn't break our internal API,
617
+ // and with it all supported npm versions at the time of writing.
618
+ this . _writeState = new Uint32Array ( 2 ) ;
619
+ if ( ! handle . init ( windowBits ,
620
+ level ,
621
+ memLevel ,
622
+ strategy ,
623
+ this . _writeState ,
624
+ processCallback ,
625
+ dictionary ) ) {
626
+ throw new ERR_ZLIB_INITIALIZATION_FAILED ( ) ;
627
+ }
628
+
629
+ ZlibBase . call ( this , opts , mode , handle , zlibDefaultOpts ) ;
630
+
631
+ this . _level = level ;
632
+ this . _strategy = strategy ;
633
+ }
634
+ Object . setPrototypeOf ( Zlib . prototype , ZlibBase . prototype ) ;
635
+ Object . setPrototypeOf ( Zlib , ZlibBase ) ;
636
+
637
+ // This callback is used by `.params()` to wait until a full flush happened
638
+ // before adjusting the parameters. In particular, the call to the native
639
+ // `params()` function should not happen while a write is currently in progress
640
+ // on the threadpool.
641
+ function paramsAfterFlushCallback ( level , strategy , callback ) {
642
+ assert ( this . _handle , 'zlib binding closed' ) ;
643
+ this . _handle . params ( level , strategy ) ;
644
+ if ( ! this . _hadError ) {
645
+ this . _level = level ;
646
+ this . _strategy = strategy ;
647
+ if ( callback ) callback ( ) ;
648
+ }
649
+ }
650
+
651
+ Zlib . prototype . params = function params ( level , strategy , callback ) {
652
+ checkRangesOrGetDefault ( level , 'level' , Z_MIN_LEVEL , Z_MAX_LEVEL ) ;
653
+ checkRangesOrGetDefault ( strategy , 'strategy' , Z_DEFAULT_STRATEGY , Z_FIXED ) ;
654
+
655
+ if ( this . _level !== level || this . _strategy !== strategy ) {
656
+ this . flush ( Z_SYNC_FLUSH ,
657
+ paramsAfterFlushCallback . bind ( this , level , strategy , callback ) ) ;
658
+ } else {
659
+ process . nextTick ( callback ) ;
660
+ }
661
+ } ;
662
+
646
663
// generic zlib
647
664
// minimal 2-byte header
648
665
function Deflate ( opts ) {
0 commit comments