import msg from './messages'; import zstream from './zstream'; import {deflateInit2, deflateEnd, deflateReset, deflate} from './deflate'; import {inflateInit2, inflate, inflateEnd, inflateReset} from './inflate'; // import constants from './constants'; // zlib modes export var NONE = 0; export var DEFLATE = 1; export var INFLATE = 2; export var GZIP = 3; export var GUNZIP = 4; export var DEFLATERAW = 5; export var INFLATERAW = 6; export var UNZIP = 7; export var Z_NO_FLUSH= 0, Z_PARTIAL_FLUSH= 1, Z_SYNC_FLUSH= 2, Z_FULL_FLUSH= 3, Z_FINISH= 4, Z_BLOCK= 5, Z_TREES= 6, /* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */ Z_OK= 0, Z_STREAM_END= 1, Z_NEED_DICT= 2, Z_ERRNO= -1, Z_STREAM_ERROR= -2, Z_DATA_ERROR= -3, //Z_MEM_ERROR: -4, Z_BUF_ERROR= -5, //Z_VERSION_ERROR: -6, /* compression levels */ Z_NO_COMPRESSION= 0, Z_BEST_SPEED= 1, Z_BEST_COMPRESSION= 9, Z_DEFAULT_COMPRESSION= -1, Z_FILTERED= 1, Z_HUFFMAN_ONLY= 2, Z_RLE= 3, Z_FIXED= 4, Z_DEFAULT_STRATEGY= 0, /* Possible values of the data_type field (though see inflate()) */ Z_BINARY= 0, Z_TEXT= 1, //Z_ASCII: 1, // = Z_TEXT (deprecated) Z_UNKNOWN= 2, /* The deflate compression method */ Z_DEFLATED= 8; export function Zlib(mode) { if (mode < DEFLATE || mode > 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 === GZIP || this.mode === GUNZIP) this.windowBits += 16; if (this.mode === UNZIP) this.windowBits += 32; if (this.mode === DEFLATERAW || this.mode === INFLATERAW) this.windowBits = -this.windowBits; this.strm = new zstream(); var status; switch (this.mode) { case DEFLATE: case GZIP: case DEFLATERAW: status = deflateInit2( this.strm, this.level, Z_DEFLATED, this.windowBits, this.memLevel, this.strategy ); break; case INFLATE: case GUNZIP: case INFLATERAW: case UNZIP: status = inflateInit2( this.strm, this.windowBits ); break; default: throw new Error('Unknown mode ' + this.mode); } if (status !== 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 === 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 !== Z_NO_FLUSH && flush !== Z_PARTIAL_FLUSH && flush !== Z_SYNC_FLUSH && flush !== Z_FULL_FLUSH && flush !== Z_FINISH && flush !== 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; var status; switch (this.mode) { case DEFLATE: case GZIP: case DEFLATERAW: status = deflate(strm, flush); break; case UNZIP: case INFLATE: case GUNZIP: case INFLATERAW: status = inflate(strm, flush); break; default: throw new Error('Unknown mode ' + this.mode); } if (status !== Z_STREAM_END && status !== 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 === DEFLATE || this.mode === GZIP || this.mode === DEFLATERAW) { deflateEnd(this.strm); } else { inflateEnd(this.strm); } this.mode = NONE; }; var status Zlib.prototype.reset = function() { switch (this.mode) { case DEFLATE: case DEFLATERAW: status = deflateReset(this.strm); break; case INFLATE: case INFLATERAW: status = inflateReset(this.strm); break; } if (status !== 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(); };