UNPKG

libnexa-ts

Version:

A pure and powerful Nexa SDK library.

186 lines (161 loc) 4.6 kB
import type { BufferWriterOptions } from "../common/interfaces"; import type BN from "../crypto/bn.extension"; import BufferUtils from "../utils/buffer.utils"; import ValidationUtils from "../utils/validation.utils"; export default class BufferWriter { private bufs: Uint8Array[]; private bufLen: number; constructor(obj?: BufferWriterOptions) { this.bufs = []; this.bufLen = 0; if (obj) { this.set(obj); } } public set(obj: BufferWriterOptions): this { this.bufs = obj.bufs || this.bufs; this.bufLen = this.bufs.reduce((prev, buf) => prev + buf.length, 0); return this; } public toBuffer(): Uint8Array { return this.concat(); } public concat(): Uint8Array { return BufferUtils.concat(this.bufs, this.bufLen); } public write(buf: Uint8Array): this { ValidationUtils.validateArgument(BufferUtils.isBuffer(buf), "buf"); this.bufs.push(buf); this.bufLen += buf.length; return this; } public writeReverse(buf: Uint8Array): this { ValidationUtils.validateArgument(BufferUtils.isBuffer(buf), "buf"); this.bufs.push(BufferUtils.reverse(buf)); this.bufLen += buf.length; return this; } public writeUInt8(n: number): this { const buf = new Uint8Array(1); new DataView(buf.buffer).setUint8(0, n); this.write(buf); return this; } public writeUInt16BE(n: number): this { const buf = new Uint8Array(2); new DataView(buf.buffer).setUint16(0, n); this.write(buf); return this; } public writeUInt16LE(n: number): this { const buf = new Uint8Array(2); new DataView(buf.buffer).setUint16(0, n, true); this.write(buf); return this; } public writeUInt32BE(n: number): this { const buf = new Uint8Array(4); new DataView(buf.buffer).setUint32(0, n); this.write(buf); return this; } public writeInt32LE(n: number): this { const buf = new Uint8Array(4); new DataView(buf.buffer).setInt32(0, n, true); this.write(buf); return this; } public writeUInt32LE(n: number): this { const buf = new Uint8Array(4); new DataView(buf.buffer).setUint32(0, n, true); this.write(buf); return this; } public writeUInt64BEBN(bn: BN): this { let buf = bn.toByteArray({size: 8}); this.write(buf); return this; } public writeUInt64LEBN(bn: BN): this { let buf = bn.toByteArray({size: 8}); this.writeReverse(buf); return this; } public writeVarintNum(n: number): this { let buf = BufferWriter.varintBufNum(n); this.write(buf); return this; } public writeVarintBN(bn: BN): this { let buf = BufferWriter.varintBufBN(bn); this.write(buf); return this; } public writeVarLengthBuf(buf: Uint8Array): this { ValidationUtils.validateArgument(BufferUtils.isBuffer(buf), "buf"); this.writeVarintNum(buf.length); this.write(buf); return this; } public writeCoreVarintNum(n: number): this { let tmp = []; let len = 0; while (true) { tmp.push((n & 0x7F) | (len ? 0x80 : 0x00)); if (n <= 0x7F) break; n = (n >> 7) - 1; len++; } this.write(Uint8Array.from(tmp).reverse()); return this; } public static varintBufNum(n: number): Uint8Array { let buf = undefined; if (n < 253) { buf = new Uint8Array(1); buf[0] = n & 0xff; } else if (n < 0x10000) { buf = new Uint8Array(1 + 2); const view = new DataView(buf.buffer); buf[0] = 253; view.setUint16(1, n, true); } else if (n < 0x100000000) { buf = new Uint8Array(1 + 4); const view = new DataView(buf.buffer); buf[0] = 254; view.setUint32(1, n, true); } else { buf = new Uint8Array(1 + 8); const view = new DataView(buf.buffer); buf[0] = 255; view.setBigUint64(1, BigInt(n), true); } return buf; } public static varintBufBN(bn: BN): Uint8Array { let buf = undefined; let n = bn.toNumber(); if (n < 253) { buf = new Uint8Array(1); buf[0] = n & 0xff; } else if (n < 0x10000) { buf = new Uint8Array(1 + 2); const view = new DataView(buf.buffer); buf[0] = 253; view.setUint16(1, n, true); } else if (n < 0x100000000) { buf = new Uint8Array(1 + 4); const view = new DataView(buf.buffer); buf[0] = 254; view.setUint32(1, n, true); } else { buf = new Uint8Array(1 + 8); const view = new DataView(buf.buffer); buf[0] = 255; view.setBigUint64(1, bn.toBigInt(), true); } return buf; } }