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