UNPKG

leb128

Version:

LEB128 encoding and decoding for signed and unsinged intergers

79 lines (71 loc) 1.42 kB
const Bn = require('bn.js') const Pipe = require('buffer-pipe') module.exports = { encode, decode, write, read, readBn } function read (stream) { return readBn(stream).toString() } function readBn (stream) { const num = new Bn(0) let shift = 0 let byt while (true) { byt = stream.read(1)[0] num.ior(new Bn(byt & 0x7f).shln(shift)) shift += 7 if (byt >> 7 === 0) { break } } // sign extend if negitive if (byt & 0x40) { num.setn(shift) } return num.fromTwos(shift) } function write (number, stream) { let num = new Bn(number) const isNeg = num.isNeg() if (isNeg) { // add 8 bits for padding num = num.toTwos(num.bitLength() + 8) } while (true) { const i = num.maskn(7).toNumber() num.ishrn(7) if ((isNegOne(num) && (i & 0x40) !== 0) || (num.isZero() && (i & 0x40) === 0)) { stream.write([i]) break } else { stream.write([i | 0x80]) } } function isNegOne (num) { return isNeg && num.toString(2).indexOf('0') < 0 } } /** * LEB128 encodeds an interger * @param {String|Number} num * @return {Buffer} */ function encode (num) { const stream = new Pipe() write(num, stream) return stream.buffer } /** * decodes a LEB128 encoded interger * @param {Buffer} buffer * @return {String} */ function decode (buffer) { const stream = new Pipe(buffer) return read(stream) }