UNPKG

protodef

Version:

A simple yet powerful way to define binary protocols

132 lines (117 loc) 4.2 kB
const { PartialReadError } = require('../utils') class SignedBigInt extends Array { valueOf () { return BigInt.asIntN(64, BigInt(this[0]) << 32n) | BigInt.asUintN(32, BigInt(this[1])) } toString () { return this.valueOf().toString() } [Symbol.for('nodejs.util.inspect.custom')] () { return this.valueOf() } } class UnsignedBigInt extends Array { valueOf () { return BigInt.asUintN(64, BigInt(this[0]) << 32n) | BigInt.asUintN(32, BigInt(this[1])) } toString () { return this.valueOf().toString() } [Symbol.for('nodejs.util.inspect.custom')] () { return this.valueOf() } } function readI64 (buffer, offset) { if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: new SignedBigInt(buffer.readInt32BE(offset), buffer.readInt32BE(offset + 4)), size: 8 } } function writeI64 (value, buffer, offset) { if (typeof value === 'bigint') { buffer.writeBigInt64BE(value, offset) } else { buffer.writeInt32BE(value[0], offset) buffer.writeInt32BE(value[1], offset + 4) } return offset + 8 } function readLI64 (buffer, offset) { if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: new SignedBigInt(buffer.readInt32LE(offset + 4), buffer.readInt32LE(offset)), size: 8 } } function writeLI64 (value, buffer, offset) { if (typeof value === 'bigint') { buffer.writeBigInt64LE(value, offset) } else { buffer.writeInt32LE(value[0], offset + 4) buffer.writeInt32LE(value[1], offset) } return offset + 8 } function readU64 (buffer, offset) { if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: new UnsignedBigInt(buffer.readUInt32BE(offset), buffer.readUInt32BE(offset + 4)), size: 8 } } function writeU64 (value, buffer, offset) { if (typeof value === 'bigint') { buffer.writeBigUInt64BE(value, offset) } else { buffer.writeUInt32BE(value[0], offset) buffer.writeUInt32BE(value[1], offset + 4) } return offset + 8 } function readLU64 (buffer, offset) { if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: new UnsignedBigInt(buffer.readUInt32LE(offset + 4), buffer.readUInt32LE(offset)), size: 8 } } function writeLU64 (value, buffer, offset) { if (typeof value === 'bigint') { buffer.writeBigUInt64LE(value, offset) } else { buffer.writeUInt32LE(value[0], offset + 4) buffer.writeUInt32LE(value[1], offset) } return offset + 8 } function generateFunctions (bufferReader, bufferWriter, size, schema) { const reader = (buffer, offset) => { if (offset + size > buffer.length) { throw new PartialReadError() } const value = buffer[bufferReader](offset) return { value, size } } const writer = (value, buffer, offset) => { buffer[bufferWriter](value, offset) return offset + size } return [reader, writer, size, schema] } const nums = { i8: ['readInt8', 'writeInt8', 1], u8: ['readUInt8', 'writeUInt8', 1], i16: ['readInt16BE', 'writeInt16BE', 2], u16: ['readUInt16BE', 'writeUInt16BE', 2], i32: ['readInt32BE', 'writeInt32BE', 4], u32: ['readUInt32BE', 'writeUInt32BE', 4], f32: ['readFloatBE', 'writeFloatBE', 4], f64: ['readDoubleBE', 'writeDoubleBE', 8], li8: ['readInt8', 'writeInt8', 1], lu8: ['readUInt8', 'writeUInt8', 1], li16: ['readInt16LE', 'writeInt16LE', 2], lu16: ['readUInt16LE', 'writeUInt16LE', 2], li32: ['readInt32LE', 'writeInt32LE', 4], lu32: ['readUInt32LE', 'writeUInt32LE', 4], lf32: ['readFloatLE', 'writeFloatLE', 4], lf64: ['readDoubleLE', 'writeDoubleLE', 8] } const types = Object.keys(nums).reduce((types, num) => { types[num] = generateFunctions(nums[num][0], nums[num][1], nums[num][2], require('../../ProtoDef/schemas/numeric.json')[num]) return types }, {}) types.i64 = [readI64, writeI64, 8, require('../../ProtoDef/schemas/numeric.json').i64] types.li64 = [readLI64, writeLI64, 8, require('../../ProtoDef/schemas/numeric.json').li64] types.u64 = [readU64, writeU64, 8, require('../../ProtoDef/schemas/numeric.json').u64] types.lu64 = [readLU64, writeLU64, 8, require('../../ProtoDef/schemas/numeric.json').lu64] module.exports = types