@thi.ng/leb128
Version:
WASM based LEB128 encoder / decoder (signed & unsigned)
52 lines (51 loc) • 1.79 kB
JavaScript
import { hasWASM } from "@thi.ng/checks/has-wasm";
import { ensureIndex } from "@thi.ng/errors/out-of-bounds";
import { unsupported } from "@thi.ng/errors/unsupported";
import { base64Decode } from "@thi.ng/transducers-binary/base64";
import { BINARY } from "./binary.js";
let wasm;
let U8;
if (hasWASM()) {
const inst = new WebAssembly.Instance(
new WebAssembly.Module(base64Decode(BINARY))
);
wasm = inst.exports;
U8 = new Uint8Array(wasm.memory.buffer, wasm.buf, 16);
}
const __ensureWASM = () => !wasm && unsupported("WASM module unavailable");
const __encode = (op, signed) => (x) => {
__ensureWASM();
const value = signed ? BigInt.asIntN(64, BigInt(x)) : BigInt.asUintN(64, BigInt(x));
return U8.slice(0, wasm[op](value));
};
const __encodeInto = (op, signed) => (dst, x, pos = 0) => {
__ensureWASM();
const value = signed ? BigInt.asIntN(64, BigInt(x)) : BigInt.asUintN(64, BigInt(x));
const size = wasm[op](value);
ensureIndex(pos, 0, dst.length - size + 1);
dst.set(U8.subarray(0, size), pos);
return size;
};
const __decode = (op, signed) => (src, idx = 0) => {
__ensureWASM();
U8.set(src.subarray(idx, Math.min(idx + 10, src.length)), 0);
const value = wasm[op](0, 0);
return [
signed ? BigInt.asIntN(64, value) : BigInt.asUintN(64, value),
U8[0]
];
};
const encodeSLEB128 = __encode("leb128EncodeI64", true);
const decodeSLEB128 = __decode("leb128DecodeI64", true);
const encodeSLEB128Into = __encodeInto("leb128EncodeI64", true);
const encodeULEB128 = __encode("leb128EncodeU64", false);
const decodeULEB128 = __decode("leb128DecodeU64", false);
const encodeULEB128Into = __encodeInto("leb128EncodeU64", true);
export {
decodeSLEB128,
decodeULEB128,
encodeSLEB128,
encodeSLEB128Into,
encodeULEB128,
encodeULEB128Into
};