1 | "use strict";
|
2 |
|
3 | let assert = require("assert").ok;
|
4 | let zlib = require("zlib");
|
5 | let util = require("util");
|
6 |
|
7 | let kMaxLength = require("buffer").kMaxLength;
|
8 |
|
9 | function Inflate(opts) {
|
10 | if (!(this instanceof Inflate)) {
|
11 | return new Inflate(opts);
|
12 | }
|
13 |
|
14 | if (opts && opts.chunkSize < zlib.Z_MIN_CHUNK) {
|
15 | opts.chunkSize = zlib.Z_MIN_CHUNK;
|
16 | }
|
17 |
|
18 | zlib.Inflate.call(this, opts);
|
19 |
|
20 |
|
21 | this._offset = this._offset === undefined ? this._outOffset : this._offset;
|
22 | this._buffer = this._buffer || this._outBuffer;
|
23 |
|
24 | if (opts && opts.maxLength != null) {
|
25 | this._maxLength = opts.maxLength;
|
26 | }
|
27 | }
|
28 |
|
29 | function createInflate(opts) {
|
30 | return new Inflate(opts);
|
31 | }
|
32 |
|
33 | function _close(engine, callback) {
|
34 | if (callback) {
|
35 | process.nextTick(callback);
|
36 | }
|
37 |
|
38 |
|
39 | if (!engine._handle) {
|
40 | return;
|
41 | }
|
42 |
|
43 | engine._handle.close();
|
44 | engine._handle = null;
|
45 | }
|
46 |
|
47 | Inflate.prototype._processChunk = function (chunk, flushFlag, asyncCb) {
|
48 | if (typeof asyncCb === "function") {
|
49 | return zlib.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
|
50 | }
|
51 |
|
52 | let self = this;
|
53 |
|
54 | let availInBefore = chunk && chunk.length;
|
55 | let availOutBefore = this._chunkSize - this._offset;
|
56 | let leftToInflate = this._maxLength;
|
57 | let inOff = 0;
|
58 |
|
59 | let buffers = [];
|
60 | let nread = 0;
|
61 |
|
62 | let error;
|
63 | this.on("error", function (err) {
|
64 | error = err;
|
65 | });
|
66 |
|
67 | function handleChunk(availInAfter, availOutAfter) {
|
68 | if (self._hadError) {
|
69 | return;
|
70 | }
|
71 |
|
72 | let have = availOutBefore - availOutAfter;
|
73 | assert(have >= 0, "have should not go down");
|
74 |
|
75 | if (have > 0) {
|
76 | let out = self._buffer.slice(self._offset, self._offset + have);
|
77 | self._offset += have;
|
78 |
|
79 | if (out.length > leftToInflate) {
|
80 | out = out.slice(0, leftToInflate);
|
81 | }
|
82 |
|
83 | buffers.push(out);
|
84 | nread += out.length;
|
85 | leftToInflate -= out.length;
|
86 |
|
87 | if (leftToInflate === 0) {
|
88 | return false;
|
89 | }
|
90 | }
|
91 |
|
92 | if (availOutAfter === 0 || self._offset >= self._chunkSize) {
|
93 | availOutBefore = self._chunkSize;
|
94 | self._offset = 0;
|
95 | self._buffer = Buffer.allocUnsafe(self._chunkSize);
|
96 | }
|
97 |
|
98 | if (availOutAfter === 0) {
|
99 | inOff += availInBefore - availInAfter;
|
100 | availInBefore = availInAfter;
|
101 |
|
102 | return true;
|
103 | }
|
104 |
|
105 | return false;
|
106 | }
|
107 |
|
108 | assert(this._handle, "zlib binding closed");
|
109 | let res;
|
110 | do {
|
111 | res = this._handle.writeSync(
|
112 | flushFlag,
|
113 | chunk,
|
114 | inOff,
|
115 | availInBefore,
|
116 | this._buffer,
|
117 | this._offset,
|
118 | availOutBefore
|
119 | );
|
120 |
|
121 | res = res || this._writeState;
|
122 | } while (!this._hadError && handleChunk(res[0], res[1]));
|
123 |
|
124 | if (this._hadError) {
|
125 | throw error;
|
126 | }
|
127 |
|
128 | if (nread >= kMaxLength) {
|
129 | _close(this);
|
130 | throw new RangeError(
|
131 | "Cannot create final Buffer. It would be larger than 0x" +
|
132 | kMaxLength.toString(16) +
|
133 | " bytes"
|
134 | );
|
135 | }
|
136 |
|
137 | let buf = Buffer.concat(buffers, nread);
|
138 | _close(this);
|
139 |
|
140 | return buf;
|
141 | };
|
142 |
|
143 | util.inherits(Inflate, zlib.Inflate);
|
144 |
|
145 | function zlibBufferSync(engine, buffer) {
|
146 | if (typeof buffer === "string") {
|
147 | buffer = Buffer.from(buffer);
|
148 | }
|
149 | if (!(buffer instanceof Buffer)) {
|
150 | throw new TypeError("Not a string or buffer");
|
151 | }
|
152 |
|
153 | let flushFlag = engine._finishFlushFlag;
|
154 | if (flushFlag == null) {
|
155 | flushFlag = zlib.Z_FINISH;
|
156 | }
|
157 |
|
158 | return engine._processChunk(buffer, flushFlag);
|
159 | }
|
160 |
|
161 | function inflateSync(buffer, opts) {
|
162 | return zlibBufferSync(new Inflate(opts), buffer);
|
163 | }
|
164 |
|
165 | module.exports = exports = inflateSync;
|
166 | exports.Inflate = Inflate;
|
167 | exports.createInflate = createInflate;
|
168 | exports.inflateSync = inflateSync;
|