UNPKG

9.82 kBJavaScriptView Raw
1// Copyright 2012 The Obvious Corporation.
2
3/*
4 * leb: LEB128 utilities.
5 */
6
7/*
8 * Modules used
9 */
10"use strict";
11
12function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
13
14Object.defineProperty(exports, "__esModule", {
15 value: true
16});
17exports["default"] = void 0;
18
19var _long = _interopRequireDefault(require("@xtuc/long"));
20
21var bits = _interopRequireWildcard(require("./bits"));
22
23var bufs = _interopRequireWildcard(require("./bufs"));
24
25function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
26
27function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
28
29function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
30
31/*
32 * Module variables
33 */
34
35/** The minimum possible 32-bit signed int. */
36var MIN_INT32 = -0x80000000;
37/** The maximum possible 32-bit signed int. */
38
39var MAX_INT32 = 0x7fffffff;
40/** The maximum possible 32-bit unsigned int. */
41
42var MAX_UINT32 = 0xffffffff;
43/** The minimum possible 64-bit signed int. */
44// const MIN_INT64 = -0x8000000000000000;
45
46/**
47 * The maximum possible 64-bit signed int that is representable as a
48 * JavaScript number.
49 */
50// const MAX_INT64 = 0x7ffffffffffffc00;
51
52/**
53 * The maximum possible 64-bit unsigned int that is representable as a
54 * JavaScript number.
55 */
56// const MAX_UINT64 = 0xfffffffffffff800;
57
58/*
59 * Helper functions
60 */
61
62/**
63 * Determines the number of bits required to encode the number
64 * represented in the given buffer as a signed value. The buffer is
65 * taken to represent a signed number in little-endian form.
66 *
67 * The number of bits to encode is the (zero-based) bit number of the
68 * highest-order non-sign-matching bit, plus two. For example:
69 *
70 * 11111011 01110101
71 * high low
72 *
73 * The sign bit here is 1 (that is, it's a negative number). The highest
74 * bit number that doesn't match the sign is bit #10 (where the lowest-order
75 * bit is bit #0). So, we have to encode at least 12 bits total.
76 *
77 * As a special degenerate case, the numbers 0 and -1 each require just one bit.
78 */
79
80function signedBitCount(buffer) {
81 return bits.highOrder(bits.getSign(buffer) ^ 1, buffer) + 2;
82}
83/**
84 * Determines the number of bits required to encode the number
85 * represented in the given buffer as an unsigned value. The buffer is
86 * taken to represent an unsigned number in little-endian form.
87 *
88 * The number of bits to encode is the (zero-based) bit number of the
89 * highest-order 1 bit, plus one. For example:
90 *
91 * 00011000 01010011
92 * high low
93 *
94 * The highest-order 1 bit here is bit #12 (where the lowest-order bit
95 * is bit #0). So, we have to encode at least 13 bits total.
96 *
97 * As a special degenerate case, the number 0 requires 1 bit.
98 */
99
100
101function unsignedBitCount(buffer) {
102 var result = bits.highOrder(1, buffer) + 1;
103 return result ? result : 1;
104}
105/**
106 * Common encoder for both signed and unsigned ints. This takes a
107 * bigint-ish buffer, returning an LEB128-encoded buffer.
108 */
109
110
111function encodeBufferCommon(buffer, signed) {
112 var signBit;
113 var bitCount;
114
115 if (signed) {
116 signBit = bits.getSign(buffer);
117 bitCount = signedBitCount(buffer);
118 } else {
119 signBit = 0;
120 bitCount = unsignedBitCount(buffer);
121 }
122
123 var byteCount = Math.ceil(bitCount / 7);
124 var result = bufs.alloc(byteCount);
125
126 for (var i = 0; i < byteCount; i++) {
127 var payload = bits.extract(buffer, i * 7, 7, signBit);
128 result[i] = payload | 0x80;
129 } // Mask off the top bit of the last byte, to indicate the end of the
130 // encoding.
131
132
133 result[byteCount - 1] &= 0x7f;
134 return result;
135}
136/**
137 * Gets the byte-length of the value encoded in the given buffer at
138 * the given index.
139 */
140
141
142function encodedLength(encodedBuffer, index) {
143 var result = 0;
144
145 while (encodedBuffer[index + result] >= 0x80) {
146 result++;
147 }
148
149 result++; // to account for the last byte
150
151 if (index + result > encodedBuffer.length) {// FIXME(sven): seems to cause false positives
152 // throw new Error("integer representation too long");
153 }
154
155 return result;
156}
157/**
158 * Common decoder for both signed and unsigned ints. This takes an
159 * LEB128-encoded buffer, returning a bigint-ish buffer.
160 */
161
162
163function decodeBufferCommon(encodedBuffer, index, signed) {
164 index = index === undefined ? 0 : index;
165 var length = encodedLength(encodedBuffer, index);
166 var bitLength = length * 7;
167 var byteLength = Math.ceil(bitLength / 8);
168 var result = bufs.alloc(byteLength);
169 var outIndex = 0;
170
171 while (length > 0) {
172 bits.inject(result, outIndex, 7, encodedBuffer[index]);
173 outIndex += 7;
174 index++;
175 length--;
176 }
177
178 var signBit;
179 var signByte;
180
181 if (signed) {
182 // Sign-extend the last byte.
183 var lastByte = result[byteLength - 1];
184 var endBit = outIndex % 8;
185
186 if (endBit !== 0) {
187 var shift = 32 - endBit; // 32 because JS bit ops work on 32-bit ints.
188
189 lastByte = result[byteLength - 1] = lastByte << shift >> shift & 0xff;
190 }
191
192 signBit = lastByte >> 7;
193 signByte = signBit * 0xff;
194 } else {
195 signBit = 0;
196 signByte = 0;
197 } // Slice off any superfluous bytes, that is, ones that add no meaningful
198 // bits (because the value would be the same if they were removed).
199
200
201 while (byteLength > 1 && result[byteLength - 1] === signByte && (!signed || result[byteLength - 2] >> 7 === signBit)) {
202 byteLength--;
203 }
204
205 result = bufs.resize(result, byteLength);
206 return {
207 value: result,
208 nextIndex: index
209 };
210}
211/*
212 * Exported bindings
213 */
214
215
216function encodeIntBuffer(buffer) {
217 return encodeBufferCommon(buffer, true);
218}
219
220function decodeIntBuffer(encodedBuffer, index) {
221 return decodeBufferCommon(encodedBuffer, index, true);
222}
223
224function encodeInt32(num) {
225 var buf = new Uint8Array(4);
226 buf[0] = num & 0xff;
227 buf[1] = num >> 8 & 0xff;
228 buf[2] = num >> 16 & 0xff;
229 buf[3] = num >> 24 & 0xff;
230 var result = encodeIntBuffer(buf);
231 return result;
232}
233
234function decodeInt32(encodedBuffer, index) {
235 var result = decodeIntBuffer(encodedBuffer, index);
236 var parsed = bufs.readInt(result.value);
237 var value = parsed.value;
238 bufs.free(result.value);
239
240 if (value < MIN_INT32 || value > MAX_INT32) {
241 throw new Error("integer too large");
242 }
243
244 return {
245 value: value,
246 nextIndex: result.nextIndex
247 };
248}
249
250function encodeInt64(num) {
251 var buf = bufs.alloc(8);
252 bufs.writeInt64(num, buf);
253 var result = encodeIntBuffer(buf);
254 bufs.free(buf);
255 return result;
256}
257
258function decodeInt64(encodedBuffer, index) {
259 var result = decodeIntBuffer(encodedBuffer, index); // sign-extend if necessary
260
261 var length = result.value.length;
262
263 if (result.value[length - 1] >> 7) {
264 result.value = bufs.resize(result.value, 8);
265 result.value.fill(255, length);
266 }
267
268 var value = _long["default"].fromBytesLE(result.value, false);
269
270 bufs.free(result.value);
271 return {
272 value: value,
273 nextIndex: result.nextIndex,
274 lossy: false
275 };
276}
277
278function encodeUIntBuffer(buffer) {
279 return encodeBufferCommon(buffer, false);
280}
281
282function decodeUIntBuffer(encodedBuffer, index) {
283 return decodeBufferCommon(encodedBuffer, index, false);
284}
285
286function encodeUInt32(num) {
287 var buf = new Uint8Array(4);
288 buf[0] = num & 0xff;
289 buf[1] = num >> 8 & 0xff;
290 buf[2] = num >> 16 & 0xff;
291 buf[3] = num >> 24 & 0xff;
292 var result = encodeUIntBuffer(buf);
293 return result;
294}
295
296function decodeUInt32(encodedBuffer, index) {
297 var result = decodeUIntBuffer(encodedBuffer, index);
298 var parsed = bufs.readUInt(result.value);
299 var value = parsed.value;
300 bufs.free(result.value);
301
302 if (value > MAX_UINT32) {
303 throw new Error("integer too large");
304 }
305
306 return {
307 value: value,
308 nextIndex: result.nextIndex
309 };
310}
311
312function encodeUInt64(num) {
313 var buf = bufs.alloc(8);
314 bufs.writeUInt64(num, buf);
315 var result = encodeUIntBuffer(buf);
316 bufs.free(buf);
317 return result;
318}
319
320function decodeUInt64(encodedBuffer, index) {
321 var result = decodeUIntBuffer(encodedBuffer, index);
322
323 var value = _long["default"].fromBytesLE(result.value, true);
324
325 bufs.free(result.value);
326 return {
327 value: value,
328 nextIndex: result.nextIndex,
329 lossy: false
330 };
331}
332
333var _default = {
334 decodeInt32: decodeInt32,
335 decodeInt64: decodeInt64,
336 decodeIntBuffer: decodeIntBuffer,
337 decodeUInt32: decodeUInt32,
338 decodeUInt64: decodeUInt64,
339 decodeUIntBuffer: decodeUIntBuffer,
340 encodeInt32: encodeInt32,
341 encodeInt64: encodeInt64,
342 encodeIntBuffer: encodeIntBuffer,
343 encodeUInt32: encodeUInt32,
344 encodeUInt64: encodeUInt64,
345 encodeUIntBuffer: encodeUIntBuffer
346};
347exports["default"] = _default;
\No newline at end of file