UNPKG

@thi.ng/leb128

Version:

WASM based LEB128 encoder / decoder (signed & unsigned)

52 lines (51 loc) 1.79 kB
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 };