Files
sdk/js/data/varint.ts
2023-02-07 15:21:24 -08:00

63 lines
1.3 KiB
TypeScript

// adapted from github.com/chrisdickinson/varint
const MSB = 0x80,
REST = 0x7f,
MSBALL = ~REST,
INT = Math.pow(2, 31);
/**
* Encodes a number as a varint.
* @param num - the number to encode
* @returns a `Uint8Array` encoding the number as a varint
*/
export function encode(num: number): Uint8Array {
if (Number.MAX_SAFE_INTEGER && num > Number.MAX_SAFE_INTEGER) {
throw new RangeError("Could not encode varint");
}
const out = [];
let offset = 0;
while (num >= INT) {
out[offset++] = (num & 0xff) | MSB;
num /= 128;
}
while (num & MSBALL) {
out[offset++] = (num & 0xff) | MSB;
num >>>= 7;
}
out[offset] = num | 0;
return new Uint8Array(out);
}
/**
* Decodes a varint.
* @param buf - the buffer to decode
* @returns `value`, the value of the varint,
* and `bytesProcessed`, the number of bytes consumed
*/
export function decode(buf: Uint8Array): {
value: number;
bytesProcessed: number;
} {
let res = 0,
shift = 0,
counter = 0,
b;
const l = buf.length;
do {
if (counter >= l || shift > 49) {
throw new RangeError("Could not decode varint");
}
b = buf[counter++];
res += shift < 28 ? (b & REST) << shift : (b & REST) * Math.pow(2, shift);
shift += 7;
} while (b >= MSB);
return {
value: res,
bytesProcessed: counter,
};
}