heatshrink-compression-ts 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +20 -19
  2. package/dist/docs/assets/css/main.css +865 -0
  3. package/dist/docs/assets/css/main.css.map +7 -0
  4. package/dist/docs/assets/images/icons.png +0 -0
  5. package/dist/docs/assets/images/icons@2x.png +0 -0
  6. package/dist/docs/assets/images/widgets.png +0 -0
  7. package/dist/docs/assets/images/widgets@2x.png +0 -0
  8. package/dist/docs/assets/js/main.js +5 -0
  9. package/dist/docs/assets/js/search.js +3 -0
  10. package/dist/docs/classes/bitwriter.html +1265 -0
  11. package/dist/docs/classes/heatshrinkdecoder.html +1744 -0
  12. package/dist/docs/classes/heatshrinkencoder.html +1195 -0
  13. package/dist/docs/classes/hsconfigerror.html +1124 -0
  14. package/dist/docs/classes/hscorruptdataerror.html +1112 -0
  15. package/dist/docs/classes/hserror.html +1152 -0
  16. package/dist/docs/classes/hsinternalerror.html +1112 -0
  17. package/dist/docs/enums/hsstate.html +1151 -0
  18. package/dist/docs/globals.html +1271 -0
  19. package/dist/docs/index.html +1272 -0
  20. package/dist/docs/interfaces/hsbitstreamstate.html +1117 -0
  21. package/dist/heatshrink-basic.d.ts +42 -0
  22. package/dist/heatshrink-decoder.d.ts +66 -0
  23. package/dist/heatshrink-encoder.d.ts +11 -0
  24. package/dist/heatshrink-ts.d.ts +3 -0
  25. package/dist/heatshrink-ts.es5.js +568 -0
  26. package/dist/heatshrink-ts.es5.js.map +1 -0
  27. package/dist/heatshrink-ts.umd.js +582 -0
  28. package/dist/heatshrink-ts.umd.js.map +1 -0
  29. package/dist/heatshrink-utils.d.ts +29 -0
  30. package/dist/lib/heatshrink-basic.js +74 -0
  31. package/dist/lib/heatshrink-basic.js.map +1 -0
  32. package/dist/lib/heatshrink-decoder.js +274 -0
  33. package/dist/lib/heatshrink-decoder.js.map +1 -0
  34. package/dist/lib/heatshrink-encoder.js +146 -0
  35. package/dist/lib/heatshrink-encoder.js.map +1 -0
  36. package/dist/lib/heatshrink-ts.js +11 -0
  37. package/dist/lib/heatshrink-ts.js.map +1 -0
  38. package/dist/lib/heatshrink-utils.js +75 -0
  39. package/dist/lib/heatshrink-utils.js.map +1 -0
  40. package/dist/types/heatshrink-basic.d.ts +42 -0
  41. package/dist/types/heatshrink-decoder.d.ts +66 -0
  42. package/dist/types/heatshrink-encoder.d.ts +11 -0
  43. package/dist/types/heatshrink-ts.d.ts +3 -0
  44. package/dist/types/heatshrink-utils.d.ts +29 -0
  45. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ export declare enum HSState {
2
+ TAG_BIT = 0,
3
+ YIELD_LITERAL = 1,
4
+ BACKREF_INDEX_MSB = 2,
5
+ BACKREF_INDEX_LSB = 3,
6
+ BACKREF_COUNT_MSB = 4,
7
+ BACKREF_COUNT_LSB = 5,
8
+ YIELD_BACKREF = 6,
9
+ }
10
+ export interface HSBitstreamState {
11
+ size: number;
12
+ index: number;
13
+ currentByte: number;
14
+ bitIndex: number;
15
+ }
16
+ /**
17
+ * All errors thrown by the heatshrink-ts package will inherit from
18
+ * this class. Different subclasses are thrown for different kinds of
19
+ * errors. All errors have a string message that indicates what exactly
20
+ * went wrong.
21
+ *
22
+ * @category Errors
23
+ */
24
+ export declare class HSError extends Error {
25
+ }
26
+ /**
27
+ * The heatshrink engine has been misconfigured.
28
+ *
29
+ * @category Errors
30
+ */
31
+ export declare class HSConfigError extends HSError {
32
+ }
33
+ export declare class HSInternalError extends HSError {
34
+ }
35
+ export declare class HSCorruptDataError extends HSError {
36
+ }
37
+ export declare const HS_MIN_WINDOW_BITS: number;
38
+ export declare const HS_MAX_WINDOW_BITS: number;
39
+ export declare const HS_MIN_LOOKAHEAD_BITS: number;
40
+ export declare const HS_LITERAL_MARKER: number;
41
+ export declare const HS_BACKREF_MARKER: number;
42
+ export declare const HS_NOBITS: number;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * A typescript implementation of the heatshrink compression library.
3
+ *
4
+ * Heatshrink is an open-source LZSS based compression library suitable
5
+ * for use in embedded systems since it has a very small and bounded
6
+ * memory footprint. This is an adaptation of the heatshink code to
7
+ * typescript with a slightly more user-fiendly API.
8
+ */
9
+ export declare class HeatshrinkDecoder {
10
+ inputBuffer: Uint8Array;
11
+ outputBuffer: Uint8Array;
12
+ outputSize: number;
13
+ private windowBuffer;
14
+ private headIndex;
15
+ private outputIndex;
16
+ private outputCount;
17
+ private state;
18
+ private inputState;
19
+ private windowBits;
20
+ private lookaheadBits;
21
+ constructor(windowBits: number, lookaheadBits: number, inputBufferSize: number);
22
+ reset(): void;
23
+ /**
24
+ * Feed data into the heatshrink decoder state machine.
25
+ *
26
+ * This function will take the chunk of input data and turn it into as
27
+ * much expanded output as it can. Decoding a stream of data should be
28
+ * done by calling this function repeatedly with chunks of data from the
29
+ * stream.
30
+ *
31
+ * You can call isFinished() to check and see if all of the data that you
32
+ * have fed in from previous calls to process() has been successfully
33
+ * decoded.
34
+ *
35
+ * @param rawInput A chunk of data that has encoded using the heatshrink
36
+ * library. You can push data a little bit at a time and stop at
37
+ * any byte boundary.
38
+ */
39
+ process(rawInput: Uint8Array | ArrayBuffer): void;
40
+ sink(input: Uint8Array): number;
41
+ poll(): void;
42
+ isFinished(): boolean;
43
+ /**
44
+ * Get all output data and truncate the output buffer.
45
+ *
46
+ * Calling this function repeatedly will have the effect of
47
+ * pulling the output in chunks from the HeatshrinkDecoder.
48
+ * It will return all data currently available and remove it
49
+ * from the output buffer so another call to getOutput() will
50
+ * not return duplicate data.
51
+ *
52
+ * @returns All data currently in the output buffer.
53
+ */
54
+ getOutput(): Uint8Array;
55
+ private assureUint8Array(buffer);
56
+ private processTag();
57
+ private yieldLiteral();
58
+ private processBackrefIndexMSB();
59
+ private processBackrefIndexLSB();
60
+ private processBackrefCountMSB();
61
+ private processBackrefCountLSB();
62
+ private yieldBackref();
63
+ private ensureOutputSpace(neededBytes);
64
+ private emitByte(byte);
65
+ private storeByte(byte);
66
+ }
@@ -0,0 +1,11 @@
1
+ export declare class HeatshrinkEncoder {
2
+ private windowBits;
3
+ private lookaheadBits;
4
+ private windowSize;
5
+ private lookaheadSize;
6
+ constructor(windowBits: number, lookaheadBits: number);
7
+ /**
8
+ * Compress input and return compressed Uint8Array in heatshrink bitstream format.
9
+ */
10
+ compress(rawInput: Uint8Array | ArrayBuffer): Uint8Array;
11
+ }
@@ -0,0 +1,3 @@
1
+ export { HeatshrinkEncoder } from "./heatshrink-encoder";
2
+ export { HeatshrinkDecoder } from "./heatshrink-decoder";
3
+ export { HSConfigError, HSInternalError, HSError } from "./heatshrink-basic";
@@ -0,0 +1,568 @@
1
+ /*! *****************************************************************************
2
+ Copyright (c) Microsoft Corporation. All rights reserved.
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4
+ this file except in compliance with the License. You may obtain a copy of the
5
+ License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
9
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
10
+ MERCHANTABLITY OR NON-INFRINGEMENT.
11
+
12
+ See the Apache Version 2.0 License for specific language governing permissions
13
+ and limitations under the License.
14
+ ***************************************************************************** */
15
+ /* global Reflect, Promise */
16
+
17
+ var extendStatics = Object.setPrototypeOf ||
18
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
19
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
20
+
21
+ function __extends(d, b) {
22
+ extendStatics(d, b);
23
+ function __() { this.constructor = d; }
24
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
25
+ }
26
+
27
+ var HSState;
28
+ (function (HSState) {
29
+ HSState[HSState["TAG_BIT"] = 0] = "TAG_BIT";
30
+ HSState[HSState["YIELD_LITERAL"] = 1] = "YIELD_LITERAL";
31
+ HSState[HSState["BACKREF_INDEX_MSB"] = 2] = "BACKREF_INDEX_MSB";
32
+ HSState[HSState["BACKREF_INDEX_LSB"] = 3] = "BACKREF_INDEX_LSB";
33
+ HSState[HSState["BACKREF_COUNT_MSB"] = 4] = "BACKREF_COUNT_MSB";
34
+ HSState[HSState["BACKREF_COUNT_LSB"] = 5] = "BACKREF_COUNT_LSB";
35
+ HSState[HSState["YIELD_BACKREF"] = 6] = "YIELD_BACKREF";
36
+ })(HSState || (HSState = {}));
37
+ /**
38
+ * All errors thrown by the heatshrink-ts package will inherit from
39
+ * this class. Different subclasses are thrown for different kinds of
40
+ * errors. All errors have a string message that indicates what exactly
41
+ * went wrong.
42
+ *
43
+ * @category Errors
44
+ */
45
+ var HSError = /** @class */ (function (_super) {
46
+ __extends(HSError, _super);
47
+ function HSError() {
48
+ return _super !== null && _super.apply(this, arguments) || this;
49
+ }
50
+ return HSError;
51
+ }(Error));
52
+ /**
53
+ * The heatshrink engine has been misconfigured.
54
+ *
55
+ * @category Errors
56
+ */
57
+ var HSConfigError = /** @class */ (function (_super) {
58
+ __extends(HSConfigError, _super);
59
+ function HSConfigError() {
60
+ return _super !== null && _super.apply(this, arguments) || this;
61
+ }
62
+ return HSConfigError;
63
+ }(HSError));
64
+ var HSInternalError = /** @class */ (function (_super) {
65
+ __extends(HSInternalError, _super);
66
+ function HSInternalError() {
67
+ return _super !== null && _super.apply(this, arguments) || this;
68
+ }
69
+ return HSInternalError;
70
+ }(HSError));
71
+ var HSCorruptDataError = /** @class */ (function (_super) {
72
+ __extends(HSCorruptDataError, _super);
73
+ function HSCorruptDataError() {
74
+ return _super !== null && _super.apply(this, arguments) || this;
75
+ }
76
+ return HSCorruptDataError;
77
+ }(HSError));
78
+ var HS_MIN_WINDOW_BITS = 4;
79
+ var HS_MAX_WINDOW_BITS = 15;
80
+
81
+ var HS_LITERAL_MARKER = 0x01;
82
+ var HS_BACKREF_MARKER = 0x00;
83
+ var HS_NOBITS = -1;
84
+
85
+ /**
86
+ * Heatshrink encoder implementation for heatshrink-ts
87
+ *
88
+ * Produces the same bitstream format that HeatshrinkDecoder reads.
89
+ */
90
+ var BitWriter = /** @class */ (function () {
91
+ function BitWriter(initialSize) {
92
+ if (initialSize === void 0) { initialSize = 256; }
93
+ this.pos = 0;
94
+ this.currentByte = 0;
95
+ this.bitIndex = 1 << 7; // MSB-first
96
+ this.buffer = new Uint8Array(initialSize);
97
+ }
98
+ BitWriter.prototype.writeBits = function (value, count) {
99
+ if (count <= 0)
100
+ return;
101
+ // Write from MSB to LSB of the 'count' bits
102
+ for (var i = count - 1; i >= 0; --i) {
103
+ var bit = (value >> i) & 1;
104
+ if (bit) {
105
+ this.currentByte |= this.bitIndex;
106
+ }
107
+ this.bitIndex >>= 1;
108
+ if (this.bitIndex === 0) {
109
+ this.ensure(1);
110
+ this.buffer[this.pos++] = this.currentByte & 0xff;
111
+ this.currentByte = 0;
112
+ this.bitIndex = 1 << 7;
113
+ }
114
+ }
115
+ };
116
+ BitWriter.prototype.writeByte = function (b) {
117
+ this.writeBits(b & 0xff, 8);
118
+ };
119
+ BitWriter.prototype.flush = function () {
120
+ // if there are remaining bits in currentByte, flush them (pad with zeros)
121
+ if (this.bitIndex !== (1 << 7)) {
122
+ this.ensure(1);
123
+ this.buffer[this.pos++] = this.currentByte & 0xff;
124
+ this.currentByte = 0;
125
+ this.bitIndex = 1 << 7;
126
+ }
127
+ return this.buffer.subarray(0, this.pos);
128
+ };
129
+ BitWriter.prototype.ensure = function (needed) {
130
+ if (this.pos + needed <= this.buffer.length) {
131
+ return;
132
+ }
133
+ var newSize = Math.max(this.buffer.length * 2, this.pos + needed);
134
+ var nb = new Uint8Array(newSize);
135
+ nb.set(this.buffer.subarray(0, this.pos));
136
+ this.buffer = nb;
137
+ };
138
+ return BitWriter;
139
+ }());
140
+ var HeatshrinkEncoder = /** @class */ (function () {
141
+ function HeatshrinkEncoder(windowBits, lookaheadBits) {
142
+ if (lookaheadBits >= windowBits) {
143
+ throw new Error("Invalid lookahead must be smaller than window bits");
144
+ }
145
+ if (lookaheadBits <= 0 || windowBits <= 0) {
146
+ throw new Error("windowBits and lookaheadBits must be > 0");
147
+ }
148
+ if (windowBits < HS_MIN_WINDOW_BITS || windowBits > HS_MAX_WINDOW_BITS) {
149
+ throw new Error("windowBits must be in [" + HS_MIN_WINDOW_BITS + ", " + HS_MAX_WINDOW_BITS + "]");
150
+ }
151
+ this.windowBits = windowBits;
152
+ this.lookaheadBits = lookaheadBits;
153
+ this.windowSize = 1 << this.windowBits;
154
+ this.lookaheadSize = 1 << this.lookaheadBits;
155
+ }
156
+ /**
157
+ * Compress input and return compressed Uint8Array in heatshrink bitstream format.
158
+ */
159
+ HeatshrinkEncoder.prototype.compress = function (rawInput) {
160
+ var input = rawInput instanceof ArrayBuffer ? new Uint8Array(rawInput) : rawInput;
161
+ var writer = new BitWriter(Math.max(256, input.length >> 1));
162
+ var inputLen = input.length;
163
+ var pos = 0;
164
+ while (pos < inputLen) {
165
+ // search window for longest match
166
+ var windowStart = Math.max(0, pos - this.windowSize);
167
+ var maxMatch = Math.min(this.lookaheadSize, inputLen - pos);
168
+ var bestLen = 0;
169
+ var bestOffset = 0;
170
+ // naive search: for each potential start in window
171
+ for (var i = windowStart; i < pos; ++i) {
172
+ if (input[i] !== input[pos])
173
+ continue;
174
+ var len = 1;
175
+ while (len < maxMatch && input[i + len] === input[pos + len]) {
176
+ ++len;
177
+ }
178
+ if (len > bestLen) {
179
+ bestLen = len;
180
+ bestOffset = pos - i; // offset > 0
181
+ if (bestLen === maxMatch)
182
+ break;
183
+ }
184
+ }
185
+ // Choose threshold for backref. Use backref when length >= 2 (saves bits normally).
186
+ if (bestLen >= 2) {
187
+ // Emit backref tag (0)
188
+ writer.writeBits(HS_BACKREF_MARKER, 1);
189
+ // Decoder expects encoded index = offset - 1, encoded across windowBits bits but split
190
+ var encodedIndex = bestOffset - 1;
191
+ if (this.windowBits > 8) {
192
+ var msbCount = this.windowBits - 8;
193
+ var msb = encodedIndex >>> 8;
194
+ writer.writeBits(msb, msbCount);
195
+ var lsb = encodedIndex & 0xff;
196
+ writer.writeBits(lsb, 8);
197
+ }
198
+ else {
199
+ writer.writeBits(encodedIndex, this.windowBits);
200
+ }
201
+ // write count: decoder expects encoded count = length - 1 across lookaheadBits
202
+ var encodedCount = bestLen - 1;
203
+ if (this.lookaheadBits > 8) {
204
+ var msbCount = this.lookaheadBits - 8;
205
+ var msb = encodedCount >>> 8;
206
+ writer.writeBits(msb, msbCount);
207
+ var lsb = encodedCount & 0xff;
208
+ writer.writeBits(lsb, 8);
209
+ }
210
+ else {
211
+ writer.writeBits(encodedCount, this.lookaheadBits);
212
+ }
213
+ pos += bestLen;
214
+ }
215
+ else {
216
+ // Emit literal: tag 1 then 8-bit literal
217
+ writer.writeBits(HS_LITERAL_MARKER, 1);
218
+ writer.writeByte(input[pos]);
219
+ pos += 1;
220
+ }
221
+ }
222
+ return writer.flush();
223
+ };
224
+ return HeatshrinkEncoder;
225
+ }());
226
+
227
+ /**
228
+ * @module heatshrink-utils
229
+ * @external
230
+ * @preferred
231
+ *
232
+ * This internal module contains private utility functions that are used inside
233
+ * the heatshrink-ts package. They are not meant to be used externally nor are
234
+ * they externally visible.
235
+ */
236
+ /**
237
+ * Get a specific number of bits from the input buffer. You can get between
238
+ * 1 and 15 bits at a time and those bits are popped from the input buffer and
239
+ * returned. If there are not enough bits remaining in buffer according to the
240
+ * state information in state, then HS_NOBITS is returned as a sentinal value
241
+ * and no bits are consumed from teh buffer.
242
+ *
243
+ * @param count The number of bits to return, must be in the range [1, 15]
244
+ * @param state The current state of the input bitstream. This parameter is
245
+ * modified with every invocation of this function to maintain state between
246
+ * calls.
247
+ * @param buffer A buffer of input data that will be used to retrieve a fixed
248
+ * number of bits. This parameter is never modified. The state of what
249
+ * bits have and have not been extracted is stored in the state parameter.
250
+ * @returns The bits that were popped from the input buffer. If there are not
251
+ * enough bits left in the buffer then HS_NOBITS is returned and state is left
252
+ * unchanged.
253
+ */
254
+ function getBits(count, buffer, state) {
255
+ if (count > 15) {
256
+ throw new HSInternalError("getBits called with invalid number of bits requested (" + count + " not in [1, 15])");
257
+ }
258
+ /*
259
+ * Make sure that we have enough available bits to satisfy this call. There are two cases where
260
+ * we could fail to have enough bits:
261
+ * 1. We are on the last byte and there are fewer bits left than count
262
+ * 2. We are on the penultimate byte and there are fewers bits left in the byte than count - 8
263
+ * so that when we move to the next byte
264
+ */
265
+ if (state.size === 0 && state.bitIndex < 1 << (count - 1)) {
266
+ return HS_NOBITS;
267
+ }
268
+ else if (state.size - state.index === 1 && count > 8) {
269
+ var requiredBitmask = 1 << (count - 8 - 1);
270
+ if (state.bitIndex < requiredBitmask) {
271
+ return HS_NOBITS;
272
+ }
273
+ }
274
+ var accum = 0;
275
+ for (var i = 0; i < count; ++i) {
276
+ if (state.bitIndex === 0 && state.size === 0) {
277
+ return HS_NOBITS;
278
+ }
279
+ if (state.bitIndex === 0) {
280
+ state.currentByte = buffer[state.index];
281
+ state.index += 1;
282
+ // Keep track of when the inputBuffer is used up and mark it as empty again
283
+ if (state.index === state.size) {
284
+ state.index = 0;
285
+ state.size = 0;
286
+ }
287
+ state.bitIndex = 1 << 7;
288
+ }
289
+ accum <<= 1;
290
+ if (state.currentByte & state.bitIndex) {
291
+ accum |= 1;
292
+ }
293
+ state.bitIndex >>= 1;
294
+ }
295
+ return accum;
296
+ }
297
+
298
+ /**
299
+ * A typescript implementation of the heatshrink compression library.
300
+ *
301
+ * Heatshrink is an open-source LZSS based compression library suitable
302
+ * for use in embedded systems since it has a very small and bounded
303
+ * memory footprint. This is an adaptation of the heatshink code to
304
+ * typescript with a slightly more user-fiendly API.
305
+ */
306
+ var HeatshrinkDecoder = /** @class */ (function () {
307
+ function HeatshrinkDecoder(windowBits, lookaheadBits, inputBufferSize) {
308
+ this.outputSize = 0;
309
+ this.headIndex = 0;
310
+ this.outputIndex = 0;
311
+ this.outputCount = 0;
312
+ this.state = HSState.TAG_BIT;
313
+ this.inputState = {
314
+ size: 0,
315
+ index: 0,
316
+ currentByte: 0,
317
+ bitIndex: 0
318
+ };
319
+ if (lookaheadBits >= windowBits) {
320
+ throw new HSConfigError("Invalid lookahead size (" + lookaheadBits + ") that is not smaller than the specified window " + windowBits);
321
+ }
322
+ else if (lookaheadBits <= 0 || windowBits <= 0 || inputBufferSize <= 0) {
323
+ throw new HSConfigError("Invalid lookahead (" + lookaheadBits + "), window (" + windowBits + ") or input (" + inputBufferSize + ") size that must be greater than 0");
324
+ }
325
+ else if (windowBits < HS_MIN_WINDOW_BITS || windowBits > HS_MAX_WINDOW_BITS) {
326
+ throw new HSConfigError("Invalid window bit size that is not in [" + HS_MIN_WINDOW_BITS + ", " + HS_MAX_WINDOW_BITS + "]");
327
+ }
328
+ this.windowBits = windowBits;
329
+ this.lookaheadBits = lookaheadBits;
330
+ this.inputBuffer = new Uint8Array(inputBufferSize);
331
+ this.outputBuffer = new Uint8Array(0);
332
+ this.windowBuffer = new Uint8Array(Math.pow(2, this.windowBits));
333
+ this.reset();
334
+ }
335
+ HeatshrinkDecoder.prototype.reset = function () {
336
+ this.inputState = {
337
+ size: 0,
338
+ index: 0,
339
+ currentByte: 0,
340
+ bitIndex: 0
341
+ };
342
+ this.state = HSState.TAG_BIT;
343
+ this.headIndex = 0;
344
+ this.outputIndex = 0;
345
+ this.outputCount = 0;
346
+ this.outputSize = 0;
347
+ this.inputBuffer.fill(0);
348
+ this.windowBuffer.fill(0);
349
+ this.outputBuffer.fill(0);
350
+ };
351
+ /**
352
+ * Feed data into the heatshrink decoder state machine.
353
+ *
354
+ * This function will take the chunk of input data and turn it into as
355
+ * much expanded output as it can. Decoding a stream of data should be
356
+ * done by calling this function repeatedly with chunks of data from the
357
+ * stream.
358
+ *
359
+ * You can call isFinished() to check and see if all of the data that you
360
+ * have fed in from previous calls to process() has been successfully
361
+ * decoded.
362
+ *
363
+ * @param rawInput A chunk of data that has encoded using the heatshrink
364
+ * library. You can push data a little bit at a time and stop at
365
+ * any byte boundary.
366
+ */
367
+ HeatshrinkDecoder.prototype.process = function (rawInput) {
368
+ var input = this.assureUint8Array(rawInput);
369
+ while (input.byteLength > 0) {
370
+ var remaining = this.sink(input);
371
+ this.poll();
372
+ input = input.slice(input.byteLength - remaining);
373
+ }
374
+ };
375
+ HeatshrinkDecoder.prototype.sink = function (input) {
376
+ var remaining = this.inputBuffer.byteLength - this.inputState.size;
377
+ var copySize = input.byteLength;
378
+ if (copySize > remaining) {
379
+ copySize = remaining;
380
+ }
381
+ this.inputBuffer.set(input.slice(0, copySize), this.inputState.size);
382
+ this.inputState.size += copySize;
383
+ return input.byteLength - copySize;
384
+ };
385
+ HeatshrinkDecoder.prototype.poll = function () {
386
+ while (true) {
387
+ var inState = this.state;
388
+ switch (inState) {
389
+ case HSState.TAG_BIT:
390
+ this.state = this.processTag();
391
+ break;
392
+ case HSState.YIELD_LITERAL:
393
+ this.state = this.yieldLiteral();
394
+ break;
395
+ case HSState.BACKREF_COUNT_MSB:
396
+ this.state = this.processBackrefCountMSB();
397
+ break;
398
+ case HSState.BACKREF_COUNT_LSB:
399
+ this.state = this.processBackrefCountLSB();
400
+ break;
401
+ case HSState.BACKREF_INDEX_MSB:
402
+ this.state = this.processBackrefIndexMSB();
403
+ break;
404
+ case HSState.BACKREF_INDEX_LSB:
405
+ this.state = this.processBackrefIndexLSB();
406
+ break;
407
+ case HSState.YIELD_BACKREF:
408
+ this.state = this.yieldBackref();
409
+ break;
410
+ }
411
+ /*
412
+ * If our state didn't change, we can't process any more input data so return.
413
+ */
414
+ if (this.state === inState) {
415
+ return;
416
+ }
417
+ }
418
+ };
419
+ HeatshrinkDecoder.prototype.isFinished = function () {
420
+ return this.inputState.size === 0;
421
+ };
422
+ /**
423
+ * Get all output data and truncate the output buffer.
424
+ *
425
+ * Calling this function repeatedly will have the effect of
426
+ * pulling the output in chunks from the HeatshrinkDecoder.
427
+ * It will return all data currently available and remove it
428
+ * from the output buffer so another call to getOutput() will
429
+ * not return duplicate data.
430
+ *
431
+ * @returns All data currently in the output buffer.
432
+ */
433
+ HeatshrinkDecoder.prototype.getOutput = function () {
434
+ var size = this.outputSize;
435
+ var output = this.outputBuffer.slice(0, size);
436
+ this.outputBuffer = this.outputBuffer.slice(size);
437
+ this.outputSize = 0;
438
+ return output;
439
+ };
440
+ HeatshrinkDecoder.prototype.assureUint8Array = function (buffer) {
441
+ if (buffer instanceof ArrayBuffer) {
442
+ return new Uint8Array(buffer);
443
+ }
444
+ return buffer;
445
+ };
446
+ HeatshrinkDecoder.prototype.processTag = function () {
447
+ var bit = getBits(1, this.inputBuffer, this.inputState);
448
+ if (bit === HS_NOBITS) {
449
+ return HSState.TAG_BIT;
450
+ }
451
+ else if (bit === HS_LITERAL_MARKER) {
452
+ return HSState.YIELD_LITERAL;
453
+ }
454
+ else if (this.windowBits > 8) {
455
+ return HSState.BACKREF_INDEX_MSB;
456
+ }
457
+ else {
458
+ this.outputIndex = 0;
459
+ return HSState.BACKREF_INDEX_LSB;
460
+ }
461
+ };
462
+ HeatshrinkDecoder.prototype.yieldLiteral = function () {
463
+ var byte = getBits(8, this.inputBuffer, this.inputState);
464
+ if (byte === HS_NOBITS) {
465
+ return HSState.YIELD_LITERAL;
466
+ }
467
+ this.emitByte(byte);
468
+ this.storeByte(byte);
469
+ return HSState.TAG_BIT;
470
+ };
471
+ HeatshrinkDecoder.prototype.processBackrefIndexMSB = function () {
472
+ if (this.windowBits <= 8) {
473
+ throw new HSInternalError("There should not be any index MSB handling when the backref index is <= 8 bits.");
474
+ }
475
+ var msb = getBits(this.windowBits - 8, this.inputBuffer, this.inputState);
476
+ if (msb === HS_NOBITS) {
477
+ return HSState.BACKREF_INDEX_MSB;
478
+ }
479
+ this.outputIndex = msb << 8;
480
+ return HSState.BACKREF_INDEX_LSB;
481
+ };
482
+ HeatshrinkDecoder.prototype.processBackrefIndexLSB = function () {
483
+ var bitCount = this.windowBits;
484
+ if (bitCount > 8) {
485
+ bitCount = 8;
486
+ }
487
+ var lsb = getBits(bitCount, this.inputBuffer, this.inputState);
488
+ if (lsb === HS_NOBITS) {
489
+ return HSState.BACKREF_INDEX_LSB;
490
+ }
491
+ this.outputIndex |= lsb;
492
+ this.outputIndex += 1;
493
+ this.outputCount = 0;
494
+ if (this.lookaheadBits > 8) {
495
+ return HSState.BACKREF_COUNT_MSB;
496
+ }
497
+ return HSState.BACKREF_COUNT_LSB;
498
+ };
499
+ HeatshrinkDecoder.prototype.processBackrefCountMSB = function () {
500
+ if (this.lookaheadBits <= 8) {
501
+ throw new HSInternalError("There should not be any count MSB handling when the backref index is <= 8 bits.");
502
+ }
503
+ var msb = getBits(this.lookaheadBits - 8, this.inputBuffer, this.inputState);
504
+ if (msb === HS_NOBITS) {
505
+ return HSState.BACKREF_COUNT_MSB;
506
+ }
507
+ this.outputCount = msb << 8;
508
+ return HSState.BACKREF_COUNT_LSB;
509
+ };
510
+ HeatshrinkDecoder.prototype.processBackrefCountLSB = function () {
511
+ var bitCount = this.lookaheadBits;
512
+ if (bitCount > 8) {
513
+ bitCount = 8;
514
+ }
515
+ var lsb = getBits(bitCount, this.inputBuffer, this.inputState);
516
+ if (lsb === HS_NOBITS) {
517
+ return HSState.BACKREF_COUNT_LSB;
518
+ }
519
+ this.outputCount |= lsb;
520
+ this.outputCount += 1;
521
+ return HSState.YIELD_BACKREF;
522
+ };
523
+ HeatshrinkDecoder.prototype.yieldBackref = function () {
524
+ var negativeOffset = this.outputIndex;
525
+ if (negativeOffset > this.windowBuffer.byteLength) {
526
+ throw new HSCorruptDataError("A negative offset was received that was larger than our window size.");
527
+ }
528
+ if (this.outputCount > this.windowBuffer.byteLength) {
529
+ throw new HSCorruptDataError("A backreference size was received that was larger than our window size.");
530
+ }
531
+ for (var i = 0; i < this.outputCount; ++i) {
532
+ var index = this.headIndex - negativeOffset;
533
+ if (index < 0) {
534
+ index += this.windowBuffer.byteLength;
535
+ }
536
+ var byte = this.windowBuffer[index];
537
+ this.emitByte(byte);
538
+ this.storeByte(byte);
539
+ }
540
+ return HSState.TAG_BIT;
541
+ };
542
+ HeatshrinkDecoder.prototype.ensureOutputSpace = function (neededBytes) {
543
+ var remaining = this.outputBuffer.byteLength - this.outputSize;
544
+ if (remaining < neededBytes) {
545
+ var newSize = 2 * Math.max(this.outputBuffer.byteLength, 1);
546
+ var newBuffer = new Uint8Array(newSize);
547
+ newBuffer.set(this.outputBuffer.slice(0, this.outputSize));
548
+ this.outputBuffer = newBuffer;
549
+ }
550
+ };
551
+ HeatshrinkDecoder.prototype.emitByte = function (byte) {
552
+ this.ensureOutputSpace(1);
553
+ this.outputBuffer[this.outputSize] = byte;
554
+ this.outputSize += 1;
555
+
556
+ };
557
+ HeatshrinkDecoder.prototype.storeByte = function (byte) {
558
+ this.windowBuffer[this.headIndex] = byte;
559
+ this.headIndex += 1;
560
+ if (this.headIndex >= this.windowBuffer.byteLength) {
561
+ this.headIndex %= this.windowBuffer.byteLength;
562
+ }
563
+ };
564
+ return HeatshrinkDecoder;
565
+ }());
566
+
567
+ export { HeatshrinkEncoder, HeatshrinkDecoder, HSConfigError, HSInternalError, HSError };
568
+ //# sourceMappingURL=heatshrink-ts.es5.js.map