3 var assert = require('assert').ok;
4 var zlib = require('zlib');
5 var util = require('util');
7 var kMaxLength = require('buffer').kMaxLength;
9 function Inflate(opts) {
10 if (!(this instanceof Inflate)) {
11 return new Inflate(opts);
14 if (opts && opts.chunkSize < zlib.Z_MIN_CHUNK) {
15 opts.chunkSize = zlib.Z_MIN_CHUNK;
18 zlib.Inflate.call(this, opts);
20 // Node 8 --> 9 compatibility check
21 this._offset = this._offset === undefined ? this._outOffset : this._offset;
22 this._buffer = this._buffer || this._outBuffer;
24 if (opts && opts.maxLength != null) {
25 this._maxLength = opts.maxLength;
29 function createInflate(opts) {
30 return new Inflate(opts);
33 function _close(engine, callback) {
35 process.nextTick(callback);
38 // Caller may invoke .close after a zlib error (which will null _handle).
39 if (!engine._handle) {
43 engine._handle.close();
44 engine._handle = null;
47 Inflate.prototype._processChunk = function(chunk, flushFlag, asyncCb) {
48 if (typeof asyncCb === 'function') {
49 return zlib.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
54 var availInBefore = chunk && chunk.length;
55 var availOutBefore = this._chunkSize - this._offset;
56 var leftToInflate = this._maxLength;
63 this.on('error', function(err) {
67 function handleChunk(availInAfter, availOutAfter) {
72 var have = availOutBefore - availOutAfter;
73 assert(have >= 0, 'have should not go down');
76 var out = self._buffer.slice(self._offset, self._offset + have);
79 if (out.length > leftToInflate) {
80 out = out.slice(0, leftToInflate);
85 leftToInflate -= out.length;
87 if (leftToInflate === 0) {
92 if (availOutAfter === 0 || self._offset >= self._chunkSize) {
93 availOutBefore = self._chunkSize;
95 self._buffer = Buffer.allocUnsafe(self._chunkSize);
98 if (availOutAfter === 0) {
99 inOff += (availInBefore - availInAfter);
100 availInBefore = availInAfter;
108 assert(this._handle, 'zlib binding closed');
110 var res = this._handle.writeSync(flushFlag,
113 availInBefore, // in_len
115 this._offset, //out_off
116 availOutBefore); // out_len
117 // Node 8 --> 9 compatibility check
118 res = res || this._writeState;
119 } while (!this._hadError && handleChunk(res[0], res[1]));
121 if (this._hadError) {
125 if (nread >= kMaxLength) {
127 throw new RangeError('Cannot create final Buffer. It would be larger than 0x' + kMaxLength.toString(16) + ' bytes');
130 var buf = Buffer.concat(buffers, nread);
136 util.inherits(Inflate, zlib.Inflate);
138 function zlibBufferSync(engine, buffer) {
139 if (typeof buffer === 'string') {
140 buffer = Buffer.from(buffer);
142 if (!(buffer instanceof Buffer)) {
143 throw new TypeError('Not a string or buffer');
146 var flushFlag = engine._finishFlushFlag;
147 if (flushFlag == null) {
148 flushFlag = zlib.Z_FINISH;
151 return engine._processChunk(buffer, flushFlag);
154 function inflateSync(buffer, opts) {
155 return zlibBufferSync(new Inflate(opts), buffer);
158 module.exports = exports = inflateSync;
159 exports.Inflate = Inflate;
160 exports.createInflate = createInflate;
161 exports.inflateSync = inflateSync;