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