UNPKG

@lavacoffee/datarw

Version:

A binary data reader/writer aim to work with lavaplayer MessageIO

141 lines (140 loc) 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataWriter = void 0; const InitialSize = 2048; /** Binary data writer */ class DataWriter { constructor() { /** The binary data */ this.bytes = new Uint8Array(InitialSize); /** The data view of the binary data */ this.view = new DataView(this.bytes.buffer, this.bytes.byteOffset, this.bytes.byteLength); /** The binary data size */ this.size = 0; } /** Finish and get the binary data */ finish(flags) { let info = this.size; if (typeof flags === "number" && !isNaN(flags)) { info |= flags << 30; } const bytes = new Uint8Array(4 + this.size); const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); view.setInt32(0, info); bytes.set(this.bytes.slice(0, this.size), 4); this.size = 0; return bytes; } /** Write 8 bit integer */ write(int) { this.view.setInt8(this._advance(), int); } /** Write 8 bit unsigned integer */ writeU(uint) { this.view.setUint8(this._advance(), uint); } /** Write 8 bit boolean */ writeBool(bool) { this.write(bool ? 1 : 0); } /** Write 16 bit integer */ writeShort(int) { this.view.setInt16(this._advance(2), int); } /** Write 16 bit unsigned integer */ writeUShort(uint) { this.view.setUint16(this._advance(2), uint); } /** Write 32 bit integer */ writeInt(int) { this.view.setInt32(this._advance(4), int); } /** Write 32 bit unsigned integer */ writeUInt(uint) { this.view.setUint32(this._advance(4), uint); } /** Write 32 bit float */ writeFloat(float) { this.view.setFloat32(this._advance(4), float); } /** Write 64 bit bigint long */ writeBigLong(long) { this.view.setBigInt64(this._advance(8), long); } /** Write 64 bit bigint unsigned long */ writeBigULong(ulong) { this.view.setBigUint64(this._advance(8), ulong); } /** Write 64 bit long */ writeLong(long) { this.writeBigLong(BigInt(long)); } /** Write 64 bit unsigned long */ writeULong(ulong) { this.writeBigULong(BigInt(ulong)); } /** Write 64 bit double */ writeDouble(double) { this.view.setFloat64(this._advance(8), double); } /** Write modified utf-8 string */ writeUTF(str) { const strLength = str.length; let utfLength = strLength; for (let i = 0; i < strLength; i++) { const char = str.charCodeAt(i); if (char >= 0x80 || char === 0) { utfLength = (char >= 0x800) ? 2 : 1; } } if (utfLength > 65535) throw new Error("String is too long (max 65535)"); this.writeUShort(utfLength); this._ensure(utfLength); let index = 0; for (; index < strLength; index++) { const char = str.charCodeAt(index); if (char >= 0x80 || char === 0) break; this.writeU(char); } for (; index < strLength; index++) { const char = str.charCodeAt(index); if (char < 0x80 && char !== 0) { this.writeU(char); } else if (char >= 0x800) { this.writeU(0xe0 | ((char >> 12) & 0x0f)); this.writeU(0x80 | ((char >> 6) & 0x3f)); this.writeU(0x80 | ((char >> 0) & 0x3f)); } else { this.writeU(0xc0 | ((char >> 6) & 0x1f)); this.writeU(0x80 | ((char >> 0) & 0x3f)); } } } /** Write modified utf-8 string, only if the provided value is a string */ writeNullableText(str) { this.writeBool(typeof str === "string"); if (typeof str !== "string") return; this.writeUTF(str); } _advance(amount = 1) { const before = this.size; this._ensure(amount); this.size += amount; return before; } _ensure(size) { if (this.bytes.byteLength < this.size + size) { const bytes = new Uint8Array(this.size * 2); const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); bytes.set(this.bytes); this.bytes = bytes; this.view = view; } } } exports.DataWriter = DataWriter;