@lavacoffee/datarw
Version:
A binary data reader/writer aim to work with lavaplayer MessageIO
143 lines (142 loc) • 4.44 kB
JavaScript
"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;