UNPKG

@ton3/liteclient

Version:
122 lines (87 loc) 2.92 kB
import { bytesToUint } from './utils' import { Utils } from 'ton3-core' import { TLBoolean } from '../types/boolean' export class StreamReader { private offset = 0 private readonly buffer: ArrayBuffer private readonly view: DataView constructor (buffer: Buffer | Uint8Array) { const temp = new Uint8Array(buffer.byteLength) if (Buffer.isBuffer(buffer)) { buffer.copy(temp, 0, 0, buffer.byteLength) } else { temp.set(buffer) } this.buffer = temp.buffer this.view = new DataView(this.buffer) } readBytes (): Uint8Array { let length = this.readUint8() let lengthSize = 1 if (length === 0xfe) { // Read 3 bytes number in little-endian order length = bytesToUint(new Uint8Array(this.buffer.slice(this.offset, this.offset + 3)).reverse()) this.offset += 3 lengthSize += 3 } const buffer = this.readBuffer(length) // Padding this.offset += 4 - (((lengthSize + length) % 4) || 4) return new Uint8Array(buffer) } public readBuffer (length: number): Uint8Array { const value = this.buffer.slice(this.offset, this.offset + length) this.offset += length return new Uint8Array(value) } public readBool (): boolean { const result = this.readUint32LE() if (result === TLBoolean.TRUE) { return true } if (result === TLBoolean.FALSE) { return false } throw new Error('Cannot parse boolean - unexpected value reached.') } public readUint8 (): number { const value = this.view.getUint8(this.offset) this.offset += 1 return value } public readInt32LE (): number { const value = this.view.getInt32(this.offset, true) this.offset += 4 return value } public readUint32LE (): number { const value = this.view.getUint32(this.offset, true) this.offset += 4 return value } public readInt64LE (): bigint { const value = this.readUint64LE() const sign = 1n << 63n return value >= sign ? value - sign * 2n : value } public readUint64LE (): bigint { return BigInt(this.readUint32LE()) | (BigInt(this.readUint32LE()) << 32n) } public readVector<T> (reader: (bufferReader: StreamReader) => T): T[] { const length = this.readUint32LE() const result = [] for (let i = 0; i < length; i++) { result.push(reader(this)) } return result } public readString (): string { return Utils.Helpers.bytesToString(this.tail) } public get position () { return this.offset } public get tail (): Uint8Array { return new Uint8Array(this.buffer.slice(this.offset)) } }