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