PageRenderTime 60ms CodeModel.GetById 12ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 1ms

/node_modules/minizlib/index.js

https://bitbucket.org/coleman333/smartsite
JavaScript | 364 lines | 280 code | 57 blank | 27 comment | 46 complexity | 3d4b62f7168fadf8dd848b0578777b2e MD5 | raw file
  1'use strict'
  2
  3const assert = require('assert')
  4const Buffer = require('buffer').Buffer
  5const binding = process.binding('zlib')
  6
  7const constants = exports.constants = require('./constants.js')
  8const MiniPass = require('minipass')
  9
 10class ZlibError extends Error {
 11  constructor (msg, errno) {
 12    super('zlib: ' + msg)
 13    this.errno = errno
 14    this.code = codes.get(errno)
 15  }
 16
 17  get name () {
 18    return 'ZlibError'
 19  }
 20}
 21
 22// translation table for return codes.
 23const codes = new Map([
 24  [constants.Z_OK, 'Z_OK'],
 25  [constants.Z_STREAM_END, 'Z_STREAM_END'],
 26  [constants.Z_NEED_DICT, 'Z_NEED_DICT'],
 27  [constants.Z_ERRNO, 'Z_ERRNO'],
 28  [constants.Z_STREAM_ERROR, 'Z_STREAM_ERROR'],
 29  [constants.Z_DATA_ERROR, 'Z_DATA_ERROR'],
 30  [constants.Z_MEM_ERROR, 'Z_MEM_ERROR'],
 31  [constants.Z_BUF_ERROR, 'Z_BUF_ERROR'],
 32  [constants.Z_VERSION_ERROR, 'Z_VERSION_ERROR']
 33])
 34
 35const validFlushFlags = new Set([
 36  constants.Z_NO_FLUSH,
 37  constants.Z_PARTIAL_FLUSH,
 38  constants.Z_SYNC_FLUSH,
 39  constants.Z_FULL_FLUSH,
 40  constants.Z_FINISH,
 41  constants.Z_BLOCK
 42])
 43
 44const strategies = new Set([
 45  constants.Z_FILTERED,
 46  constants.Z_HUFFMAN_ONLY,
 47  constants.Z_RLE,
 48  constants.Z_FIXED,
 49  constants.Z_DEFAULT_STRATEGY
 50])
 51
 52// the Zlib class they all inherit from
 53// This thing manages the queue of requests, and returns
 54// true or false if there is anything in the queue when
 55// you call the .write() method.
 56const _opts = Symbol('opts')
 57const _chunkSize = Symbol('chunkSize')
 58const _flushFlag = Symbol('flushFlag')
 59const _finishFlush = Symbol('finishFlush')
 60const _handle = Symbol('handle')
 61const _hadError = Symbol('hadError')
 62const _buffer = Symbol('buffer')
 63const _offset = Symbol('offset')
 64const _level = Symbol('level')
 65const _strategy = Symbol('strategy')
 66const _ended = Symbol('ended')
 67const _writeState = Symbol('writeState')
 68
 69class Zlib extends MiniPass {
 70  constructor (opts, mode) {
 71    super(opts)
 72    this[_ended] = false
 73    this[_opts] = opts = opts || {}
 74    this[_chunkSize] = opts.chunkSize || constants.Z_DEFAULT_CHUNK
 75    if (opts.flush && !validFlushFlags.has(opts.flush)) {
 76      throw new TypeError('Invalid flush flag: ' + opts.flush)
 77    }
 78    if (opts.finishFlush && !validFlushFlags.has(opts.finishFlush)) {
 79      throw new TypeError('Invalid flush flag: ' + opts.finishFlush)
 80    }
 81
 82    this[_flushFlag] = opts.flush || constants.Z_NO_FLUSH
 83    this[_finishFlush] = typeof opts.finishFlush !== 'undefined' ?
 84      opts.finishFlush : constants.Z_FINISH
 85
 86    if (opts.chunkSize) {
 87      if (opts.chunkSize < constants.Z_MIN_CHUNK) {
 88        throw new RangeError('Invalid chunk size: ' + opts.chunkSize)
 89      }
 90    }
 91
 92    if (opts.windowBits) {
 93      if (opts.windowBits < constants.Z_MIN_WINDOWBITS ||
 94          opts.windowBits > constants.Z_MAX_WINDOWBITS) {
 95        throw new RangeError('Invalid windowBits: ' + opts.windowBits)
 96      }
 97    }
 98
 99    if (opts.level) {
100      if (opts.level < constants.Z_MIN_LEVEL ||
101          opts.level > constants.Z_MAX_LEVEL) {
102        throw new RangeError('Invalid compression level: ' + opts.level)
103      }
104    }
105
106    if (opts.memLevel) {
107      if (opts.memLevel < constants.Z_MIN_MEMLEVEL ||
108          opts.memLevel > constants.Z_MAX_MEMLEVEL) {
109        throw new RangeError('Invalid memLevel: ' + opts.memLevel)
110      }
111    }
112
113    if (opts.strategy && !(strategies.has(opts.strategy)))
114      throw new TypeError('Invalid strategy: ' + opts.strategy)
115
116    if (opts.dictionary) {
117      if (!(opts.dictionary instanceof Buffer)) {
118        throw new TypeError('Invalid dictionary: it should be a Buffer instance')
119      }
120    }
121
122    this[_handle] = new binding.Zlib(mode)
123
124    this[_hadError] = false
125    this[_handle].onerror = (message, errno) => {
126      // there is no way to cleanly recover.
127      // continuing only obscures problems.
128      this.close()
129      this[_hadError] = true
130
131      const error = new ZlibError(message, errno)
132      this.emit('error', error)
133    }
134
135    const level = typeof opts.level === 'number' ? opts.level
136                : constants.Z_DEFAULT_COMPRESSION
137
138    var strategy = typeof opts.strategy === 'number' ? opts.strategy
139                 : constants.Z_DEFAULT_STRATEGY
140
141    this[_writeState] = new Uint32Array(2);
142    const window = opts.windowBits || constants.Z_DEFAULT_WINDOWBITS
143    const memLevel = opts.memLevel || constants.Z_DEFAULT_MEMLEVEL
144
145    // API changed in node v9
146    /* istanbul ignore next */
147    if (/^v[0-8]\./.test(process.version)) {
148      this[_handle].init(window,
149                         level,
150                         memLevel,
151                         strategy,
152                         opts.dictionary)
153    } else {
154      this[_handle].init(window,
155                         level,
156                         memLevel,
157                         strategy,
158                         this[_writeState],
159                         () => {},
160                         opts.dictionary)
161    }
162
163    this[_buffer] = Buffer.allocUnsafe(this[_chunkSize])
164    this[_offset] = 0
165    this[_level] = level
166    this[_strategy] = strategy
167
168    this.once('end', this.close)
169  }
170
171  close () {
172    if (this[_handle]) {
173      this[_handle].close()
174      this[_handle] = null
175      this.emit('close')
176    }
177  }
178
179  params (level, strategy) {
180    if (!this[_handle])
181      throw new Error('cannot switch params when binding is closed')
182
183    // no way to test this without also not supporting params at all
184    /* istanbul ignore if */
185    if (!this[_handle].params)
186      throw new Error('not supported in this implementation')
187
188    if (level < constants.Z_MIN_LEVEL ||
189        level > constants.Z_MAX_LEVEL) {
190      throw new RangeError('Invalid compression level: ' + level)
191    }
192
193    if (!(strategies.has(strategy)))
194      throw new TypeError('Invalid strategy: ' + strategy)
195
196    if (this[_level] !== level || this[_strategy] !== strategy) {
197      this.flush(constants.Z_SYNC_FLUSH)
198      assert(this[_handle], 'zlib binding closed')
199      this[_handle].params(level, strategy)
200      /* istanbul ignore else */
201      if (!this[_hadError]) {
202        this[_level] = level
203        this[_strategy] = strategy
204      }
205    }
206  }
207
208  reset () {
209    assert(this[_handle], 'zlib binding closed')
210    return this[_handle].reset()
211  }
212
213  flush (kind) {
214    if (kind === undefined)
215      kind = constants.Z_FULL_FLUSH
216
217    if (this.ended)
218      return
219
220    const flushFlag = this[_flushFlag]
221    this[_flushFlag] = kind
222    this.write(Buffer.alloc(0))
223    this[_flushFlag] = flushFlag
224  }
225
226  end (chunk, encoding, cb) {
227    if (chunk)
228      this.write(chunk, encoding)
229    this.flush(this[_finishFlush])
230    this[_ended] = true
231    return super.end(null, null, cb)
232  }
233
234  get ended () {
235    return this[_ended]
236  }
237
238  write (chunk, encoding, cb) {
239    // process the chunk using the sync process
240    // then super.write() all the outputted chunks
241    if (typeof encoding === 'function')
242      cb = encoding, encoding = 'utf8'
243
244    if (typeof chunk === 'string')
245      chunk = new Buffer(chunk, encoding)
246
247    let availInBefore = chunk && chunk.length
248    let availOutBefore = this[_chunkSize] - this[_offset]
249    let inOff = 0 // the offset of the input buffer
250    const flushFlag = this[_flushFlag]
251    let writeReturn = true
252
253    assert(this[_handle], 'zlib binding closed')
254    do {
255      let res = this[_handle].writeSync(
256        flushFlag,
257        chunk, // in
258        inOff, // in_off
259        availInBefore, // in_len
260        this[_buffer], // out
261        this[_offset], //out_off
262        availOutBefore // out_len
263      )
264
265      if (this[_hadError])
266        break
267
268      // API changed in v9
269      /* istanbul ignore next */
270      let availInAfter = res ? res[0] : this[_writeState][1]
271      /* istanbul ignore next */
272      let availOutAfter = res ? res[1] : this[_writeState][0]
273
274      const have = availOutBefore - availOutAfter
275      assert(have >= 0, 'have should not go down')
276
277      if (have > 0) {
278        const out = this[_buffer].slice(
279          this[_offset], this[_offset] + have
280        )
281
282        this[_offset] += have
283        // serve some output to the consumer.
284        writeReturn = super.write(out) && writeReturn
285      }
286
287      // exhausted the output buffer, or used all the input create a new one.
288      if (availOutAfter === 0 || this[_offset] >= this[_chunkSize]) {
289        availOutBefore = this[_chunkSize]
290        this[_offset] = 0
291        this[_buffer] = Buffer.allocUnsafe(this[_chunkSize])
292      }
293
294      if (availOutAfter === 0) {
295        // Not actually done.  Need to reprocess.
296        // Also, update the availInBefore to the availInAfter value,
297        // so that if we have to hit it a third (fourth, etc.) time,
298        // it'll have the correct byte counts.
299        inOff += (availInBefore - availInAfter)
300        availInBefore = availInAfter
301        continue
302      }
303      break
304    } while (!this[_hadError])
305
306    if (cb)
307      cb()
308    return writeReturn
309  }
310}
311
312// minimal 2-byte header
313class Deflate extends Zlib {
314  constructor (opts) {
315    super(opts, constants.DEFLATE)
316  }
317}
318
319class Inflate extends Zlib {
320  constructor (opts) {
321    super(opts, constants.INFLATE)
322  }
323}
324
325// gzip - bigger header, same deflate compression
326class Gzip extends Zlib {
327  constructor (opts) {
328    super(opts, constants.GZIP)
329  }
330}
331
332class Gunzip extends Zlib {
333  constructor (opts) {
334    super(opts, constants.GUNZIP)
335  }
336}
337
338// raw - no header
339class DeflateRaw extends Zlib {
340  constructor (opts) {
341    super(opts, constants.DEFLATERAW)
342  }
343}
344
345class InflateRaw extends Zlib {
346  constructor (opts) {
347    super(opts, constants.INFLATERAW)
348  }
349}
350
351// auto-detect header.
352class Unzip extends Zlib {
353  constructor (opts) {
354    super(opts, constants.UNZIP)
355  }
356}
357
358exports.Deflate = Deflate
359exports.Inflate = Inflate
360exports.Gzip = Gzip
361exports.Gunzip = Gunzip
362exports.DeflateRaw = DeflateRaw
363exports.InflateRaw = InflateRaw
364exports.Unzip = Unzip