UNPKG

@liskhq/lisk-codec

Version:

Implementation of decoder and encoder using Lisk JSON schema according to the Lisk protocol

124 lines 4.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readSInt64 = exports.readSInt32 = exports.readUInt64 = exports.readUInt32 = exports.writeSInt64 = exports.writeUInt64 = exports.writeSInt32 = exports.writeUInt32 = void 0; const lisk_validator_1 = require("@liskhq/lisk-validator"); const msg = 0x80; const rest = 0x7f; const writeUInt32 = (value) => { if (value > lisk_validator_1.MAX_UINT32) { throw new Error('Value out of range of uint32'); } const result = []; let index = 0; while (value > rest) { result[index] = msg | ((value & rest) >>> 0); value = (value >>> 7) >>> 0; index += 1; } result[index] = value; return Buffer.from(result); }; exports.writeUInt32 = writeUInt32; const writeSInt32 = (value) => { if (value > lisk_validator_1.MAX_SINT32) { throw new Error('Value out of range of sint32'); } if (value >= 0) { return (0, exports.writeUInt32)(2 * value); } return (0, exports.writeUInt32)(-2 * value - 1); }; exports.writeSInt32 = writeSInt32; const writeUInt64 = (value) => { if (value > lisk_validator_1.MAX_UINT64) { throw new Error('Value out of range of uint64'); } const result = []; let index = 0; while (value > BigInt(rest)) { result[index] = Number(BigInt(msg) | (value & BigInt(rest))); value >>= BigInt(7); index += 1; } result[Number(index)] = Number(value); return Buffer.from(result); }; exports.writeUInt64 = writeUInt64; const writeSInt64 = (value) => { if (value > lisk_validator_1.MAX_SINT64) { throw new Error('Value out of range of sint64'); } if (value >= BigInt(0)) { return (0, exports.writeUInt64)(BigInt(2) * value); } return (0, exports.writeUInt64)(BigInt(-2) * value - BigInt(1)); }; exports.writeSInt64 = writeSInt64; const readUInt32 = (buffer, offset) => { let result = 0; let index = offset; for (let shift = 0; shift < 32; shift += 7) { if (index >= buffer.length) { throw new Error('Invalid buffer length'); } const bit = buffer[index]; index += 1; if (index === offset + 5 && bit > 0x0f) { throw new Error('Value out of range of uint32'); } result = (result | ((bit & rest) << shift)) >>> 0; if ((bit & msg) === 0) { validateVarintSize(BigInt(result), index - offset); return [result, index - offset]; } } throw new Error('Terminating bit not found'); }; exports.readUInt32 = readUInt32; const readUInt64 = (buffer, offset) => { let result = BigInt(0); let index = offset; for (let shift = BigInt(0); shift < BigInt(64); shift += BigInt(7)) { if (index >= buffer.length) { throw new Error('Invalid buffer length'); } const bit = BigInt(buffer[index]); index += 1; if (index === 10 + offset && bit > 0x01) { throw new Error('Value out of range of uint64'); } result |= (bit & BigInt(rest)) << shift; if ((bit & BigInt(msg)) === BigInt(0)) { validateVarintSize(result, index - offset); return [result, index - offset]; } } throw new Error('Terminating bit not found'); }; exports.readUInt64 = readUInt64; const readSInt32 = (buffer, offset) => { const [varInt, size] = (0, exports.readUInt32)(buffer, offset); if (varInt % 2 === 0) { return [varInt / 2, size]; } return [-(varInt + 1) / 2, size]; }; exports.readSInt32 = readSInt32; const readSInt64 = (buffer, offset) => { const [varInt, size] = (0, exports.readUInt64)(buffer, offset); if (varInt % BigInt(2) === BigInt(0)) { return [varInt / BigInt(2), size]; } return [-(varInt + BigInt(1)) / BigInt(2), size]; }; exports.readSInt64 = readSInt64; const validateVarintSize = (result, size) => { if (result === BigInt(0) && size === 1) { return; } const min = BigInt(1) << BigInt(7 * (size - 1)); if (result < min) { throw new Error('invalid varint bytes. vartint must be in shortest form.'); } }; //# sourceMappingURL=varint.js.map