-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathcompression.js
140 lines (107 loc) · 15.6 KB
/
compression.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = Compressor;
var _zstream = _interopRequireDefault(require("pako/lib/zlib/zstream"));
var _deflate = require("pako/lib/zlib/deflate");
var _inflate = require("pako/lib/zlib/inflate");
var _messages = _interopRequireDefault(require("pako/lib/zlib/messages.js"));
var _constants = require("pako/lib/zlib/constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const CHUNK_SIZE = 16384;
const WINDOW_BITS = 15;
/**
* Handles de-/compression via #inflate() and #deflate(), calls you back via #deflatedReady() and #inflatedReady().
* The chunk we get from deflater is actually a view of a 16kB arraybuffer, so we need to copy the relevant parts
* memory to a new arraybuffer.
*/
function Compressor(inflatedReady, deflatedReady) {
this.inflatedReady = inflatedReady;
this.deflatedReady = deflatedReady;
this._inflate = inflater(chunk => this.inflatedReady(chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.length)));
this._deflate = deflater(chunk => this.deflatedReady(chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.length)));
}
Compressor.prototype.inflate = function (buffer) {
this._inflate(new Uint8Array(buffer));
};
Compressor.prototype.deflate = function (buffer) {
this._deflate(new Uint8Array(buffer));
};
function deflater(emit) {
const stream = new _zstream.default();
const status = (0, _deflate.deflateInit2)(stream, _constants.Z_DEFAULT_COMPRESSION, _constants.Z_DEFLATED, WINDOW_BITS, 8, _constants.Z_DEFAULT_STRATEGY);
if (status !== _constants.Z_OK) {
throw new Error('Problem initializing deflate stream: ' + _messages.default[status]);
}
return function (data) {
if (data === undefined) return emit(); // Attach the input data
stream.input = data;
stream.next_in = 0;
stream.avail_in = stream.input.length;
let status;
let output;
let start;
let ret = true;
do {
// When the stream gets full, we need to create new space.
if (stream.avail_out === 0) {
stream.output = new Uint8Array(CHUNK_SIZE);
start = stream.next_out = 0;
stream.avail_out = CHUNK_SIZE;
} // Perform the deflate
status = (0, _deflate.deflate)(stream, _constants.Z_SYNC_FLUSH);
if (status !== _constants.Z_STREAM_END && status !== _constants.Z_OK) {
throw new Error('Deflate problem: ' + _messages.default[status]);
} // If the output buffer got full, flush the data.
if (stream.avail_out === 0 && stream.next_out > start) {
output = stream.output.subarray(start, start = stream.next_out);
ret = emit(output);
}
} while ((stream.avail_in > 0 || stream.avail_out === 0) && status !== _constants.Z_STREAM_END); // Emit whatever is left in output.
if (stream.next_out > start) {
output = stream.output.subarray(start, start = stream.next_out);
ret = emit(output);
}
return ret;
};
}
function inflater(emit) {
const stream = new _zstream.default();
const status = (0, _inflate.inflateInit2)(stream, WINDOW_BITS);
if (status !== _constants.Z_OK) {
throw new Error('Problem initializing inflate stream: ' + _messages.default[status]);
}
return function (data) {
if (data === undefined) return emit();
let start;
stream.input = data;
stream.next_in = 0;
stream.avail_in = stream.input.length;
let status, output;
let ret = true;
do {
if (stream.avail_out === 0) {
stream.output = new Uint8Array(CHUNK_SIZE);
start = stream.next_out = 0;
stream.avail_out = CHUNK_SIZE;
}
status = (0, _inflate.inflate)(stream, _constants.Z_NO_FLUSH);
if (status !== _constants.Z_STREAM_END && status !== _constants.Z_OK) {
throw new Error('inflate problem: ' + _messages.default[status]);
}
if (stream.next_out) {
if (stream.avail_out === 0 || status === _constants.Z_STREAM_END) {
output = stream.output.subarray(start, start = stream.next_out);
ret = emit(output);
}
}
} while (stream.avail_in > 0 && status !== _constants.Z_STREAM_END);
if (stream.next_out > start) {
output = stream.output.subarray(start, start = stream.next_out);
ret = emit(output);
}
return ret;
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wcmVzc2lvbi5qcyJdLCJuYW1lcyI6WyJDSFVOS19TSVpFIiwiV0lORE9XX0JJVFMiLCJDb21wcmVzc29yIiwiaW5mbGF0ZWRSZWFkeSIsImRlZmxhdGVkUmVhZHkiLCJfaW5mbGF0ZSIsImluZmxhdGVyIiwiY2h1bmsiLCJidWZmZXIiLCJzbGljZSIsImJ5dGVPZmZzZXQiLCJsZW5ndGgiLCJfZGVmbGF0ZSIsImRlZmxhdGVyIiwicHJvdG90eXBlIiwiaW5mbGF0ZSIsIlVpbnQ4QXJyYXkiLCJkZWZsYXRlIiwiZW1pdCIsInN0cmVhbSIsIlpTdHJlYW0iLCJzdGF0dXMiLCJaX0RFRkFVTFRfQ09NUFJFU1NJT04iLCJaX0RFRkxBVEVEIiwiWl9ERUZBVUxUX1NUUkFURUdZIiwiWl9PSyIsIkVycm9yIiwibWVzc2FnZXMiLCJkYXRhIiwidW5kZWZpbmVkIiwiaW5wdXQiLCJuZXh0X2luIiwiYXZhaWxfaW4iLCJvdXRwdXQiLCJzdGFydCIsInJldCIsImF2YWlsX291dCIsIm5leHRfb3V0IiwiWl9TWU5DX0ZMVVNIIiwiWl9TVFJFQU1fRU5EIiwic3ViYXJyYXkiLCJaX05PX0ZMVVNIIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFNQSxNQUFNQSxVQUFVLEdBQUcsS0FBbkI7QUFDQSxNQUFNQyxXQUFXLEdBQUcsRUFBcEI7QUFFQTs7Ozs7O0FBS2UsU0FBU0MsVUFBVCxDQUFxQkMsYUFBckIsRUFBb0NDLGFBQXBDLEVBQW1EO0FBQ2hFLE9BQUtELGFBQUwsR0FBcUJBLGFBQXJCO0FBQ0EsT0FBS0MsYUFBTCxHQUFxQkEsYUFBckI7QUFDQSxPQUFLQyxRQUFMLEdBQWdCQyxRQUFRLENBQUNDLEtBQUssSUFBSSxLQUFLSixhQUFMLENBQW1CSSxLQUFLLENBQUNDLE1BQU4sQ0FBYUMsS0FBYixDQUFtQkYsS0FBSyxDQUFDRyxVQUF6QixFQUFxQ0gsS0FBSyxDQUFDRyxVQUFOLEdBQW1CSCxL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OlsiaW1wb3J0IFpTdHJlYW0gZnJvbSAncGFrby9saWIvemxpYi96c3RyZWFtJ1xuaW1wb3J0IHsgZGVmbGF0ZUluaXQyLCBkZWZsYXRlIH0gZnJvbSAncGFrby9saWIvemxpYi9kZWZsYXRlJ1xuaW1wb3J0IHsgaW5mbGF0ZSwgaW5mbGF0ZUluaXQyIH0gZnJvbSAncGFrby9saWIvemxpYi9pbmZsYXRlJ1xuaW1wb3J0IG1lc3NhZ2VzIGZyb20gJ3Bha28vbGliL3psaWIvbWVzc2FnZXMuanMnXG5pbXBvcnQge1xuICBaX05PX0ZMVVNILCBaX1NZTkNfRkxVU0gsIFpfT0ssXG4gIFpfU1RSRUFNX0VORCwgWl9ERUZBVUxUX0NPTVBSRVNTSU9OLFxuICBaX0RFRkFVTFRfU1RSQVRFR1ksIFpfREVGTEFURURcbn0gZnJvbSAncGFrby9saWIvemxpYi9jb25zdGFudHMnXG5cbmNvbnN0IENIVU5LX1NJWkUgPSAxNjM4NFxuY29uc3QgV0lORE9XX0JJVFMgPSAxNVxuXG4vKipcbiAqIEhhbmRsZXMgZGUtL2NvbXByZXNzaW9uIHZpYSAjaW5mbGF0ZSgpIGFuZCAjZGVmbGF0ZSgpLCBjYWxscyB5b3UgYmFjayB2aWEgI2RlZmxhdGVkUmVhZHkoKSBhbmQgI2luZmxhdGVkUmVhZHkoKS5cbiAqIFRoZSBjaHVuayB3ZSBnZXQgZnJvbSBkZWZsYXRlciBpcyBhY3R1YWxseSBhIHZpZXcgb2YgYSAxNmtCIGFycmF5YnVmZmVyLCBzbyB3ZSBuZWVkIHRvIGNvcHkgdGhlIHJlbGV2YW50IHBhcnRzXG4gKiBtZW1vcnkgdG8gYSBuZXcgYXJyYXlidWZmZXIuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbXByZXNzb3IgKGluZmxhdGVkUmVhZHksIGRlZmxhdGVkUmVhZHkpIHtcbiAgdGhpcy5pbmZsYXRlZFJlYWR5ID0gaW5mbGF0ZWRSZWFkeVxuICB0aGlzLmRlZmxhdGVkUmVhZHkgPSBkZWZsYXRlZFJlYWR5XG4gIHRoaXMuX2luZmxhdGUgPSBpbmZsYXRlcihjaHVuayA9PiB0aGlzLmluZmxhdGVkUmVhZHkoY2h1bmsuYnVmZmVyLnNsaWNlKGNodW5rLmJ5dGVPZmZzZXQsIGNodW5rLmJ5dGVPZmZzZXQgKyBjaHVuay5sZW5ndGgpKSlcbiAgdGhpcy5fZGVmbGF0ZSA9IGRlZmxhdGVyKGNodW5rID0+IHRoaXMuZGVmbGF0ZWRSZWFkeShjaHVuay5idWZmZXIuc2xpY2UoY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZU9mZnNldCArIGNodW5rLmxlbmd0aCkpKVxufVxuXG5Db21wcmVzc29yLnByb3RvdHlwZS5pbmZsYXRlID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICB0aGlzLl9pbmZsYXRlKG5ldyBVaW50OEFycmF5KGJ1ZmZlcikpXG59XG5cbkNvbXByZXNzb3IucHJvdG90eXBlLmRlZmxhdGUgPSBmdW5jdGlvbiAoYnVmZmVyKSB7XG4gIHRoaXMuX2RlZmxhdGUobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSlcbn1cblxuZnVuY3Rpb24gZGVmbGF0ZXIgKGVtaXQpIHtcbiAgY29uc3Qgc3RyZWFtID0gbmV3IFpTdHJlYW0oKVxuICBjb25zdCBzdGF0dXMgPSBkZWZsYXRlSW5pdDIoc3RyZWFtLCBaX0RFRkFVTFRfQ09NUFJFU1NJT04sIFpfREVGTEFURUQsIFdJTkRPV19CSVRTLCA4LCBaX0RFRkFVTFRfU1RSQVRFR1kpXG4gIGlmIChzdGF0dXMgIT09IFpfT0spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2JsZW0gaW5pdGlhbGl6aW5nIGRlZmxhdGUgc3RyZWFtOiAnICsgbWVzc2FnZXNbc3RhdHVzXSlcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHJldHVybiBlbWl0KClcblxuICAgIC8vIEF0dGFjaCB0aGUgaW5wdXQgZGF0YVxuICAgIHN0cmVhbS5pbnB1dCA9IGRhdGFcbiAgICBzdHJlYW0ubmV4dF9pbiA9IDBcbiAgICBzdHJlYW0uYXZhaWxfaW4gPSBzdHJlYW0uaW5wdXQubGVuZ3RoXG5cbiAgICBsZXQgc3RhdHVzXG4gICAgbGV0IG91dHB1dFxuICAgIGxldCBzdGFydFxuICAgIGxldCByZXQgPSB0cnVlXG5cbiAgICBkbyB7XG4gICAgICAvLyBXaGVuIHRoZSBzdHJlYW0gZ2V0cyBmdWxsLCB3ZSBuZWVkIHRvIGNyZWF0ZSBuZXcgc3BhY2UuXG4gICAgICBpZiAoc3RyZWFtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICBzdHJlYW0ub3V0cHV0ID0gbmV3IFVpbnQ4QXJyYXkoQ0hVTktfU0laRSlcbiAgICAgICAgc3RhcnQgPSBzdHJlYW0ubmV4dF9vdXQgPSAwXG4gICAgICAgIHN0cmVhbS5hdmFpbF9vdXQgPSBDSFVOS19TSVpFXG4gICAgICB9XG5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGRlZmxhdGVcbiAgICAgIHN0YXR1cyA9IGRlZmxhdGUoc3RyZWFtLCBaX1NZTkNfRkxVU0gpXG4gICAgICBpZiAoc3RhdHVzICE9PSBaX1NUUkVBTV9FTkQgJiYgc3RhdHVzICE9PSBaX09LKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGVmbGF0ZSBwcm9ibGVtOiAnICsgbWVzc2FnZXNbc3RhdHVzXSlcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIG91dHB1dCBidWZmZXIgZ290IGZ1bGwsIGZsdXNoIHRoZSBkYXRhLlxuICAgICAgaWYgKHN0cmVhbS5hdmFpbF9vdXQgPT09IDAgJiYgc3RyZWFtLm5leHRfb3V0ID4gc3RhcnQpIHtcbiAgICAgICAgb3V0cHV0ID0gc3RyZWFtLm91dHB1dC5zdWJhcnJheShzdGFydCwgc3RhcnQgPSBzdHJlYW0ubmV4dF9vdXQpXG4gICAgICAgIHJldCA9IGVtaXQob3V0cHV0KVxuICAgICAgfVxuICAgIH0gd2hpbGUgKChzdHJlYW0uYXZhaWxfaW4gPiAwIHx8IHN0cmVhbS5hdmFpbF9vdXQgPT09IDApICYmIHN0YXR1cyAhPT0gWl9TVFJFQU1fRU5EKVxuXG4gICAgLy8gRW1pdCB3aGF0ZXZlciBpcyBsZWZ0IGluIG91dHB1dC5cbiAgICBpZiAoc3RyZWFtLm5leHRfb3V0ID4gc3RhcnQpIHtcbiAgICAgIG91dHB1dCA9IHN0cmVhbS5vdXRwdXQuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ID0gc3RyZWFtLm5leHRfb3V0KVxuICAgICAgcmV0ID0gZW1pdChvdXRwdXQpXG4gICAgfVxuICAgIHJldHVybiByZXRcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmZsYXRlciAoZW1pdCkge1xuICBjb25zdCBzdHJlYW0gPSBuZXcgWlN0cmVhbSgpXG5cbiAgY29uc3Qgc3RhdHVzID0gaW5mbGF0ZUluaXQyKHN0cmVhbSwgV0lORE9XX0JJVFMpXG4gIGlmIChzdGF0dXMgIT09IFpfT0spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb2JsZW0gaW5pdGlhbGl6aW5nIGluZmxhdGUgc3RyZWFtOiAnICsgbWVzc2FnZXNbc3RhdHVzXSlcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZGF0YSkge1xuICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHJldHVybiBlbWl0KClcblxuICAgIGxldCBzdGFydFxuICAgIHN0cmVhbS5pbnB1dCA9IGRhdGFcbiAgICBzdHJlYW0ubmV4dF9pbiA9IDBcbiAgICBzdHJlYW0uYXZhaWxfaW4gPSBzdHJlYW0uaW5wdXQubGVuZ3RoXG5cbiAgICBsZXQgc3RhdHVzLCBvdXRwdXRcbiAgICBsZXQgcmV0ID0gdHJ1ZVxuXG4gICAgZG8ge1xuICAgICAgaWYgKHN0cmVhbS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgc3RyZWFtLm91dHB1dCA9IG5ldyBVaW50OEFycmF5KENIVU5LX1NJWkUpXG4gICAgICAgIHN0YXJ0ID0gc3RyZWFtLm5leHRfb3V0ID0gMFxuICAgICAgICBzdHJlYW0uYXZhaWxfb3V0ID0gQ0hVTktfU0laRVxuICAgICAgfVxuXG4gICAgICBzdGF0dXMgPSBpbmZsYXRlKHN0cmVhbSwgWl9OT19GTFVTSClcbiAgICAgIGlmIChzdGF0dXMgIT09IFpfU1RSRUFNX0VORCAmJiBzdGF0dXMgIT09IFpfT0spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbmZsYXRlIHByb2JsZW06ICcgKyBtZXNzYWdlc1tzdGF0dXNdKVxuICAgICAgfVxuXG4gICAgICBpZiAoc3RyZWFtLm5leHRfb3V0KSB7XG4gICAgICAgIGlmIChzdHJlYW0uYXZhaWxfb3V0ID09PSAwIHx8IHN0YXR1cyA9PT0gWl9TVFJFQU1fRU5EKSB7XG4gICAgICAgICAgb3V0cHV0ID0gc3RyZWFtLm91dHB1dC5zdWJhcnJheShzdGFydCwgc3RhcnQgPSBzdHJlYW0ubmV4dF9vdXQpXG4gICAgICAgICAgcmV0ID0gZW1pdChvdXRwdXQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICgoc3RyZWFtLmF2YWlsX2luID4gMCkgJiYgc3RhdHVzICE9PSBaX1NUUkVBTV9FTkQpXG5cbiAgICBpZiAoc3RyZWFtLm5leHRfb3V0ID4gc3RhcnQpIHtcbiAgICAgIG91dHB1dCA9IHN0cmVhbS5vdXRwdXQuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ID0gc3RyZWFtLm5leHRfb3V0KVxuICAgICAgcmV0ID0gZW1pdChvdXRwdXQpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJldFxuICB9XG59XG4iXX0=