| var msg = require('pako/lib/zlib/messages'); |
| var zstream = require('pako/lib/zlib/zstream'); |
| var zlib_deflate = require('pako/lib/zlib/deflate.js'); |
| var zlib_inflate = require('pako/lib/zlib/inflate.js'); |
| var constants = require('pako/lib/zlib/constants'); |
| |
| for (var key in constants) { |
| exports[key] = constants[key]; |
| } |
| |
| // zlib modes |
| exports.NONE = 0; |
| exports.DEFLATE = 1; |
| exports.INFLATE = 2; |
| exports.GZIP = 3; |
| exports.GUNZIP = 4; |
| exports.DEFLATERAW = 5; |
| exports.INFLATERAW = 6; |
| exports.UNZIP = 7; |
| |
| /** |
| * Emulate Node's zlib C++ layer for use by the JS layer in index.js |
| */ |
| function Zlib(mode) { |
| if (mode < exports.DEFLATE || mode > exports.UNZIP) |
| throw new TypeError("Bad argument"); |
| |
| this.mode = mode; |
| this.init_done = false; |
| this.write_in_progress = false; |
| this.pending_close = false; |
| this.windowBits = 0; |
| this.level = 0; |
| this.memLevel = 0; |
| this.strategy = 0; |
| this.dictionary = null; |
| } |
| |
| Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) { |
| this.windowBits = windowBits; |
| this.level = level; |
| this.memLevel = memLevel; |
| this.strategy = strategy; |
| // dictionary not supported. |
| |
| if (this.mode === exports.GZIP || this.mode === exports.GUNZIP) |
| this.windowBits += 16; |
| |
| if (this.mode === exports.UNZIP) |
| this.windowBits += 32; |
| |
| if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW) |
| this.windowBits = -this.windowBits; |
| |
| this.strm = new zstream(); |
| |
| switch (this.mode) { |
| case exports.DEFLATE: |
| case exports.GZIP: |
| case exports.DEFLATERAW: |
| var status = zlib_deflate.deflateInit2( |
| this.strm, |
| this.level, |
| exports.Z_DEFLATED, |
| this.windowBits, |
| this.memLevel, |
| this.strategy |
| ); |
| break; |
| case exports.INFLATE: |
| case exports.GUNZIP: |
| case exports.INFLATERAW: |
| case exports.UNZIP: |
| var status = zlib_inflate.inflateInit2( |
| this.strm, |
| this.windowBits |
| ); |
| break; |
| default: |
| throw new Error("Unknown mode " + this.mode); |
| } |
| |
| if (status !== exports.Z_OK) { |
| this._error(status); |
| return; |
| } |
| |
| this.write_in_progress = false; |
| this.init_done = true; |
| }; |
| |
| Zlib.prototype.params = function() { |
| throw new Error("deflateParams Not supported"); |
| }; |
| |
| Zlib.prototype._writeCheck = function() { |
| if (!this.init_done) |
| throw new Error("write before init"); |
| |
| if (this.mode === exports.NONE) |
| throw new Error("already finalized"); |
| |
| if (this.write_in_progress) |
| throw new Error("write already in progress"); |
| |
| if (this.pending_close) |
| throw new Error("close is pending"); |
| }; |
| |
| Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) { |
| this._writeCheck(); |
| this.write_in_progress = true; |
| |
| var self = this; |
| process.nextTick(function() { |
| self.write_in_progress = false; |
| var res = self._write(flush, input, in_off, in_len, out, out_off, out_len); |
| self.callback(res[0], res[1]); |
| |
| if (self.pending_close) |
| self.close(); |
| }); |
| |
| return this; |
| }; |
| |
| // set method for Node buffers, used by pako |
| function bufferSet(data, offset) { |
| for (var i = 0; i < data.length; i++) { |
| this[offset + i] = data[i]; |
| } |
| } |
| |
| Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) { |
| this._writeCheck(); |
| return this._write(flush, input, in_off, in_len, out, out_off, out_len); |
| }; |
| |
| Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) { |
| this.write_in_progress = true; |
| |
| if (flush !== exports.Z_NO_FLUSH && |
| flush !== exports.Z_PARTIAL_FLUSH && |
| flush !== exports.Z_SYNC_FLUSH && |
| flush !== exports.Z_FULL_FLUSH && |
| flush !== exports.Z_FINISH && |
| flush !== exports.Z_BLOCK) { |
| throw new Error("Invalid flush value"); |
| } |
| |
| if (input == null) { |
| input = new Buffer(0); |
| in_len = 0; |
| in_off = 0; |
| } |
| |
| if (out._set) |
| out.set = out._set; |
| else |
| out.set = bufferSet; |
| |
| var strm = this.strm; |
| strm.avail_in = in_len; |
| strm.input = input; |
| strm.next_in = in_off; |
| strm.avail_out = out_len; |
| strm.output = out; |
| strm.next_out = out_off; |
| |
| switch (this.mode) { |
| case exports.DEFLATE: |
| case exports.GZIP: |
| case exports.DEFLATERAW: |
| var status = zlib_deflate.deflate(strm, flush); |
| break; |
| case exports.UNZIP: |
| case exports.INFLATE: |
| case exports.GUNZIP: |
| case exports.INFLATERAW: |
| var status = zlib_inflate.inflate(strm, flush); |
| break; |
| default: |
| throw new Error("Unknown mode " + this.mode); |
| } |
| |
| if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) { |
| this._error(status); |
| } |
| |
| this.write_in_progress = false; |
| return [strm.avail_in, strm.avail_out]; |
| }; |
| |
| Zlib.prototype.close = function() { |
| if (this.write_in_progress) { |
| this.pending_close = true; |
| return; |
| } |
| |
| this.pending_close = false; |
| |
| if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) { |
| zlib_deflate.deflateEnd(this.strm); |
| } else { |
| zlib_inflate.inflateEnd(this.strm); |
| } |
| |
| this.mode = exports.NONE; |
| }; |
| |
| Zlib.prototype.reset = function() { |
| switch (this.mode) { |
| case exports.DEFLATE: |
| case exports.DEFLATERAW: |
| var status = zlib_deflate.deflateReset(this.strm); |
| break; |
| case exports.INFLATE: |
| case exports.INFLATERAW: |
| var status = zlib_inflate.inflateReset(this.strm); |
| break; |
| } |
| |
| if (status !== exports.Z_OK) { |
| this._error(status); |
| } |
| }; |
| |
| Zlib.prototype._error = function(status) { |
| this.onerror(msg[status] + ': ' + this.strm.msg, status); |
| |
| this.write_in_progress = false; |
| if (this.pending_close) |
| this.close(); |
| }; |
| |
| exports.Zlib = Zlib; |