UNPKG

@lavacoffee/datarw

Version:

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

143 lines (142 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataReader = void 0; const UTFChunks = 4096; /** Binary data reader */ class DataReader { constructor(data) { /** Current reading position */ this.position = 0; this.bytes = data; this.view = new DataView(data.buffer, data.byteOffset, data.byteLength); const info = this.readInt(); this.size = info & 0x3FFFFFFF; this.flags = (info & 0xC0000000) >> 30; } /** Read 8 bit integer */ read() { return this.view.getInt8(this._advance()); } /** Read 8 bit unsigned integer */ readU() { return this.view.getUint8(this._advance()); } /** Read 8 bit boolean */ readBool() { return this.read() !== 0; } /** Read 16 bit integer */ readShort() { return this.view.getInt16(this._advance(2)); } /** Read 16 bit unsigned integer */ readUShort() { return this.view.getUint16(this._advance(2)); } /** Read 32 bit integer */ readInt() { return this.view.getInt32(this._advance(4)); } /** Read 32 bit unsigned integer */ readUInt() { return this.view.getUint32(this._advance(4)); } /** Read 32 bit float */ readFloat() { return this.view.getFloat32(this._advance(4)); } /** Read 64 bit bigint long */ readBigLong() { return this.view.getBigInt64(this._advance(8)); } /** Read 64 bit bigint unsigned long */ readBigULong() { return this.view.getBigUint64(this._advance(8)); } /** Read 64 bit long */ readLong() { return Number(this.readBigLong()); } /** Read 64 bit unsigned long */ readULong() { return Number(this.readBigULong()); } /** Read 64 bit double */ readDouble() { return this.view.getFloat64(this._advance(8)); } /** Read modified utf-8 string */ readUTF() { const len = this.readShort(); let str = ""; const chars = []; const bytes = this.bytes.slice(this._advance(len), this.position); let index = 0; while (index < len) { const char = bytes[index] & 0xff; if (char > 127) break; index++; chars.push(char); if (chars.length >= UTFChunks) { str += String.fromCharCode(...chars); chars.length = 0; } } while (index < len) { const char = bytes[index++] & 0xff; switch (char >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx chars.push(char); break; case 12: case 13: // 110xxxxx 10xxxxxx { const char2 = bytes[index++]; chars.push(((char & 0x1f) << 6) | (char2 & 0x3f)); } break; case 14: // 1110xxxx 10xxxxxx 10xxxxxx { const char2 = bytes[index++]; const char3 = bytes[index++]; chars.push(((char & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)); } break; } if (chars.length >= UTFChunks) { str += String.fromCharCode(...chars); chars.length = 0; } } if (chars.length) { str += String.fromCharCode(...chars); chars.length = 0; } return str; } /** Read modified utf-8 string, if exist */ readNullableText() { const isExist = this.readBool(); if (isExist) return this.readUTF(); } _advance(amount = 1) { const before = this.position; this.position += amount; if (this.position - 4 > this.size) throw new RangeError("Unexpected position > size"); return before; } } exports.DataReader = DataReader;