11cb0ef41Sopenharmony_ci'use strict' 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst assert = require('assert') 41cb0ef41Sopenharmony_ciconst Buffer = require('buffer').Buffer 51cb0ef41Sopenharmony_ciconst realZlib = require('zlib') 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst constants = exports.constants = require('./constants.js') 81cb0ef41Sopenharmony_ciconst Minipass = require('minipass') 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst OriginalBufferConcat = Buffer.concat 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst _superWrite = Symbol('_superWrite') 131cb0ef41Sopenharmony_ciclass ZlibError extends Error { 141cb0ef41Sopenharmony_ci constructor (err) { 151cb0ef41Sopenharmony_ci super('zlib: ' + err.message) 161cb0ef41Sopenharmony_ci this.code = err.code 171cb0ef41Sopenharmony_ci this.errno = err.errno 181cb0ef41Sopenharmony_ci /* istanbul ignore if */ 191cb0ef41Sopenharmony_ci if (!this.code) 201cb0ef41Sopenharmony_ci this.code = 'ZLIB_ERROR' 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci this.message = 'zlib: ' + err.message 231cb0ef41Sopenharmony_ci Error.captureStackTrace(this, this.constructor) 241cb0ef41Sopenharmony_ci } 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci get name () { 271cb0ef41Sopenharmony_ci return 'ZlibError' 281cb0ef41Sopenharmony_ci } 291cb0ef41Sopenharmony_ci} 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci// the Zlib class they all inherit from 321cb0ef41Sopenharmony_ci// This thing manages the queue of requests, and returns 331cb0ef41Sopenharmony_ci// true or false if there is anything in the queue when 341cb0ef41Sopenharmony_ci// you call the .write() method. 351cb0ef41Sopenharmony_ciconst _opts = Symbol('opts') 361cb0ef41Sopenharmony_ciconst _flushFlag = Symbol('flushFlag') 371cb0ef41Sopenharmony_ciconst _finishFlushFlag = Symbol('finishFlushFlag') 381cb0ef41Sopenharmony_ciconst _fullFlushFlag = Symbol('fullFlushFlag') 391cb0ef41Sopenharmony_ciconst _handle = Symbol('handle') 401cb0ef41Sopenharmony_ciconst _onError = Symbol('onError') 411cb0ef41Sopenharmony_ciconst _sawError = Symbol('sawError') 421cb0ef41Sopenharmony_ciconst _level = Symbol('level') 431cb0ef41Sopenharmony_ciconst _strategy = Symbol('strategy') 441cb0ef41Sopenharmony_ciconst _ended = Symbol('ended') 451cb0ef41Sopenharmony_ciconst _defaultFullFlush = Symbol('_defaultFullFlush') 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciclass ZlibBase extends Minipass { 481cb0ef41Sopenharmony_ci constructor (opts, mode) { 491cb0ef41Sopenharmony_ci if (!opts || typeof opts !== 'object') 501cb0ef41Sopenharmony_ci throw new TypeError('invalid options for ZlibBase constructor') 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci super(opts) 531cb0ef41Sopenharmony_ci this[_sawError] = false 541cb0ef41Sopenharmony_ci this[_ended] = false 551cb0ef41Sopenharmony_ci this[_opts] = opts 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci this[_flushFlag] = opts.flush 581cb0ef41Sopenharmony_ci this[_finishFlushFlag] = opts.finishFlush 591cb0ef41Sopenharmony_ci // this will throw if any options are invalid for the class selected 601cb0ef41Sopenharmony_ci try { 611cb0ef41Sopenharmony_ci this[_handle] = new realZlib[mode](opts) 621cb0ef41Sopenharmony_ci } catch (er) { 631cb0ef41Sopenharmony_ci // make sure that all errors get decorated properly 641cb0ef41Sopenharmony_ci throw new ZlibError(er) 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci this[_onError] = (err) => { 681cb0ef41Sopenharmony_ci // no sense raising multiple errors, since we abort on the first one. 691cb0ef41Sopenharmony_ci if (this[_sawError]) 701cb0ef41Sopenharmony_ci return 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci this[_sawError] = true 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci // there is no way to cleanly recover. 751cb0ef41Sopenharmony_ci // continuing only obscures problems. 761cb0ef41Sopenharmony_ci this.close() 771cb0ef41Sopenharmony_ci this.emit('error', err) 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci this[_handle].on('error', er => this[_onError](new ZlibError(er))) 811cb0ef41Sopenharmony_ci this.once('end', () => this.close) 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci close () { 851cb0ef41Sopenharmony_ci if (this[_handle]) { 861cb0ef41Sopenharmony_ci this[_handle].close() 871cb0ef41Sopenharmony_ci this[_handle] = null 881cb0ef41Sopenharmony_ci this.emit('close') 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci reset () { 931cb0ef41Sopenharmony_ci if (!this[_sawError]) { 941cb0ef41Sopenharmony_ci assert(this[_handle], 'zlib binding closed') 951cb0ef41Sopenharmony_ci return this[_handle].reset() 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci flush (flushFlag) { 1001cb0ef41Sopenharmony_ci if (this.ended) 1011cb0ef41Sopenharmony_ci return 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci if (typeof flushFlag !== 'number') 1041cb0ef41Sopenharmony_ci flushFlag = this[_fullFlushFlag] 1051cb0ef41Sopenharmony_ci this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag })) 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci end (chunk, encoding, cb) { 1091cb0ef41Sopenharmony_ci if (chunk) 1101cb0ef41Sopenharmony_ci this.write(chunk, encoding) 1111cb0ef41Sopenharmony_ci this.flush(this[_finishFlushFlag]) 1121cb0ef41Sopenharmony_ci this[_ended] = true 1131cb0ef41Sopenharmony_ci return super.end(null, null, cb) 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci get ended () { 1171cb0ef41Sopenharmony_ci return this[_ended] 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci write (chunk, encoding, cb) { 1211cb0ef41Sopenharmony_ci // process the chunk using the sync process 1221cb0ef41Sopenharmony_ci // then super.write() all the outputted chunks 1231cb0ef41Sopenharmony_ci if (typeof encoding === 'function') 1241cb0ef41Sopenharmony_ci cb = encoding, encoding = 'utf8' 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci if (typeof chunk === 'string') 1271cb0ef41Sopenharmony_ci chunk = Buffer.from(chunk, encoding) 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci if (this[_sawError]) 1301cb0ef41Sopenharmony_ci return 1311cb0ef41Sopenharmony_ci assert(this[_handle], 'zlib binding closed') 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci // _processChunk tries to .close() the native handle after it's done, so we 1341cb0ef41Sopenharmony_ci // intercept that by temporarily making it a no-op. 1351cb0ef41Sopenharmony_ci const nativeHandle = this[_handle]._handle 1361cb0ef41Sopenharmony_ci const originalNativeClose = nativeHandle.close 1371cb0ef41Sopenharmony_ci nativeHandle.close = () => {} 1381cb0ef41Sopenharmony_ci const originalClose = this[_handle].close 1391cb0ef41Sopenharmony_ci this[_handle].close = () => {} 1401cb0ef41Sopenharmony_ci // It also calls `Buffer.concat()` at the end, which may be convenient 1411cb0ef41Sopenharmony_ci // for some, but which we are not interested in as it slows us down. 1421cb0ef41Sopenharmony_ci Buffer.concat = (args) => args 1431cb0ef41Sopenharmony_ci let result 1441cb0ef41Sopenharmony_ci try { 1451cb0ef41Sopenharmony_ci const flushFlag = typeof chunk[_flushFlag] === 'number' 1461cb0ef41Sopenharmony_ci ? chunk[_flushFlag] : this[_flushFlag] 1471cb0ef41Sopenharmony_ci result = this[_handle]._processChunk(chunk, flushFlag) 1481cb0ef41Sopenharmony_ci // if we don't throw, reset it back how it was 1491cb0ef41Sopenharmony_ci Buffer.concat = OriginalBufferConcat 1501cb0ef41Sopenharmony_ci } catch (err) { 1511cb0ef41Sopenharmony_ci // or if we do, put Buffer.concat() back before we emit error 1521cb0ef41Sopenharmony_ci // Error events call into user code, which may call Buffer.concat() 1531cb0ef41Sopenharmony_ci Buffer.concat = OriginalBufferConcat 1541cb0ef41Sopenharmony_ci this[_onError](new ZlibError(err)) 1551cb0ef41Sopenharmony_ci } finally { 1561cb0ef41Sopenharmony_ci if (this[_handle]) { 1571cb0ef41Sopenharmony_ci // Core zlib resets `_handle` to null after attempting to close the 1581cb0ef41Sopenharmony_ci // native handle. Our no-op handler prevented actual closure, but we 1591cb0ef41Sopenharmony_ci // need to restore the `._handle` property. 1601cb0ef41Sopenharmony_ci this[_handle]._handle = nativeHandle 1611cb0ef41Sopenharmony_ci nativeHandle.close = originalNativeClose 1621cb0ef41Sopenharmony_ci this[_handle].close = originalClose 1631cb0ef41Sopenharmony_ci // `_processChunk()` adds an 'error' listener. If we don't remove it 1641cb0ef41Sopenharmony_ci // after each call, these handlers start piling up. 1651cb0ef41Sopenharmony_ci this[_handle].removeAllListeners('error') 1661cb0ef41Sopenharmony_ci // make sure OUR error listener is still attached tho 1671cb0ef41Sopenharmony_ci } 1681cb0ef41Sopenharmony_ci } 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci if (this[_handle]) 1711cb0ef41Sopenharmony_ci this[_handle].on('error', er => this[_onError](new ZlibError(er))) 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci let writeReturn 1741cb0ef41Sopenharmony_ci if (result) { 1751cb0ef41Sopenharmony_ci if (Array.isArray(result) && result.length > 0) { 1761cb0ef41Sopenharmony_ci // The first buffer is always `handle._outBuffer`, which would be 1771cb0ef41Sopenharmony_ci // re-used for later invocations; so, we always have to copy that one. 1781cb0ef41Sopenharmony_ci writeReturn = this[_superWrite](Buffer.from(result[0])) 1791cb0ef41Sopenharmony_ci for (let i = 1; i < result.length; i++) { 1801cb0ef41Sopenharmony_ci writeReturn = this[_superWrite](result[i]) 1811cb0ef41Sopenharmony_ci } 1821cb0ef41Sopenharmony_ci } else { 1831cb0ef41Sopenharmony_ci writeReturn = this[_superWrite](Buffer.from(result)) 1841cb0ef41Sopenharmony_ci } 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci if (cb) 1881cb0ef41Sopenharmony_ci cb() 1891cb0ef41Sopenharmony_ci return writeReturn 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci [_superWrite] (data) { 1931cb0ef41Sopenharmony_ci return super.write(data) 1941cb0ef41Sopenharmony_ci } 1951cb0ef41Sopenharmony_ci} 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ciclass Zlib extends ZlibBase { 1981cb0ef41Sopenharmony_ci constructor (opts, mode) { 1991cb0ef41Sopenharmony_ci opts = opts || {} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci opts.flush = opts.flush || constants.Z_NO_FLUSH 2021cb0ef41Sopenharmony_ci opts.finishFlush = opts.finishFlush || constants.Z_FINISH 2031cb0ef41Sopenharmony_ci super(opts, mode) 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci this[_fullFlushFlag] = constants.Z_FULL_FLUSH 2061cb0ef41Sopenharmony_ci this[_level] = opts.level 2071cb0ef41Sopenharmony_ci this[_strategy] = opts.strategy 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci params (level, strategy) { 2111cb0ef41Sopenharmony_ci if (this[_sawError]) 2121cb0ef41Sopenharmony_ci return 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci if (!this[_handle]) 2151cb0ef41Sopenharmony_ci throw new Error('cannot switch params when binding is closed') 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci // no way to test this without also not supporting params at all 2181cb0ef41Sopenharmony_ci /* istanbul ignore if */ 2191cb0ef41Sopenharmony_ci if (!this[_handle].params) 2201cb0ef41Sopenharmony_ci throw new Error('not supported in this implementation') 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci if (this[_level] !== level || this[_strategy] !== strategy) { 2231cb0ef41Sopenharmony_ci this.flush(constants.Z_SYNC_FLUSH) 2241cb0ef41Sopenharmony_ci assert(this[_handle], 'zlib binding closed') 2251cb0ef41Sopenharmony_ci // .params() calls .flush(), but the latter is always async in the 2261cb0ef41Sopenharmony_ci // core zlib. We override .flush() temporarily to intercept that and 2271cb0ef41Sopenharmony_ci // flush synchronously. 2281cb0ef41Sopenharmony_ci const origFlush = this[_handle].flush 2291cb0ef41Sopenharmony_ci this[_handle].flush = (flushFlag, cb) => { 2301cb0ef41Sopenharmony_ci this.flush(flushFlag) 2311cb0ef41Sopenharmony_ci cb() 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci try { 2341cb0ef41Sopenharmony_ci this[_handle].params(level, strategy) 2351cb0ef41Sopenharmony_ci } finally { 2361cb0ef41Sopenharmony_ci this[_handle].flush = origFlush 2371cb0ef41Sopenharmony_ci } 2381cb0ef41Sopenharmony_ci /* istanbul ignore else */ 2391cb0ef41Sopenharmony_ci if (this[_handle]) { 2401cb0ef41Sopenharmony_ci this[_level] = level 2411cb0ef41Sopenharmony_ci this[_strategy] = strategy 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci} 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci// minimal 2-byte header 2481cb0ef41Sopenharmony_ciclass Deflate extends Zlib { 2491cb0ef41Sopenharmony_ci constructor (opts) { 2501cb0ef41Sopenharmony_ci super(opts, 'Deflate') 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci} 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ciclass Inflate extends Zlib { 2551cb0ef41Sopenharmony_ci constructor (opts) { 2561cb0ef41Sopenharmony_ci super(opts, 'Inflate') 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci} 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci// gzip - bigger header, same deflate compression 2611cb0ef41Sopenharmony_ciconst _portable = Symbol('_portable') 2621cb0ef41Sopenharmony_ciclass Gzip extends Zlib { 2631cb0ef41Sopenharmony_ci constructor (opts) { 2641cb0ef41Sopenharmony_ci super(opts, 'Gzip') 2651cb0ef41Sopenharmony_ci this[_portable] = opts && !!opts.portable 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci [_superWrite] (data) { 2691cb0ef41Sopenharmony_ci if (!this[_portable]) 2701cb0ef41Sopenharmony_ci return super[_superWrite](data) 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci // we'll always get the header emitted in one first chunk 2731cb0ef41Sopenharmony_ci // overwrite the OS indicator byte with 0xFF 2741cb0ef41Sopenharmony_ci this[_portable] = false 2751cb0ef41Sopenharmony_ci data[9] = 255 2761cb0ef41Sopenharmony_ci return super[_superWrite](data) 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci} 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ciclass Gunzip extends Zlib { 2811cb0ef41Sopenharmony_ci constructor (opts) { 2821cb0ef41Sopenharmony_ci super(opts, 'Gunzip') 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci} 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci// raw - no header 2871cb0ef41Sopenharmony_ciclass DeflateRaw extends Zlib { 2881cb0ef41Sopenharmony_ci constructor (opts) { 2891cb0ef41Sopenharmony_ci super(opts, 'DeflateRaw') 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ciclass InflateRaw extends Zlib { 2941cb0ef41Sopenharmony_ci constructor (opts) { 2951cb0ef41Sopenharmony_ci super(opts, 'InflateRaw') 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci} 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci// auto-detect header. 3001cb0ef41Sopenharmony_ciclass Unzip extends Zlib { 3011cb0ef41Sopenharmony_ci constructor (opts) { 3021cb0ef41Sopenharmony_ci super(opts, 'Unzip') 3031cb0ef41Sopenharmony_ci } 3041cb0ef41Sopenharmony_ci} 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ciclass Brotli extends ZlibBase { 3071cb0ef41Sopenharmony_ci constructor (opts, mode) { 3081cb0ef41Sopenharmony_ci opts = opts || {} 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS 3111cb0ef41Sopenharmony_ci opts.finishFlush = opts.finishFlush || constants.BROTLI_OPERATION_FINISH 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci super(opts, mode) 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci this[_fullFlushFlag] = constants.BROTLI_OPERATION_FLUSH 3161cb0ef41Sopenharmony_ci } 3171cb0ef41Sopenharmony_ci} 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ciclass BrotliCompress extends Brotli { 3201cb0ef41Sopenharmony_ci constructor (opts) { 3211cb0ef41Sopenharmony_ci super(opts, 'BrotliCompress') 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci} 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ciclass BrotliDecompress extends Brotli { 3261cb0ef41Sopenharmony_ci constructor (opts) { 3271cb0ef41Sopenharmony_ci super(opts, 'BrotliDecompress') 3281cb0ef41Sopenharmony_ci } 3291cb0ef41Sopenharmony_ci} 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ciexports.Deflate = Deflate 3321cb0ef41Sopenharmony_ciexports.Inflate = Inflate 3331cb0ef41Sopenharmony_ciexports.Gzip = Gzip 3341cb0ef41Sopenharmony_ciexports.Gunzip = Gunzip 3351cb0ef41Sopenharmony_ciexports.DeflateRaw = DeflateRaw 3361cb0ef41Sopenharmony_ciexports.InflateRaw = InflateRaw 3371cb0ef41Sopenharmony_ciexports.Unzip = Unzip 3381cb0ef41Sopenharmony_ci/* istanbul ignore else */ 3391cb0ef41Sopenharmony_ciif (typeof realZlib.BrotliCompress === 'function') { 3401cb0ef41Sopenharmony_ci exports.BrotliCompress = BrotliCompress 3411cb0ef41Sopenharmony_ci exports.BrotliDecompress = BrotliDecompress 3421cb0ef41Sopenharmony_ci} else { 3431cb0ef41Sopenharmony_ci exports.BrotliCompress = exports.BrotliDecompress = class { 3441cb0ef41Sopenharmony_ci constructor () { 3451cb0ef41Sopenharmony_ci throw new Error('Brotli is not supported in this version of Node.js') 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci } 3481cb0ef41Sopenharmony_ci} 349