@mrhiden/cstruct
Version:
For packing and unpacking bytes (C like structures) in/from Buffer based on Object/Array type for parsing.
97 lines (96 loc) • 3.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReadBuffer = void 0;
const base_buffer_1 = require("./base-buffer");
class ReadBuffer extends base_buffer_1.BaseBuffer {
u8() {
const val = this._buffer.readUInt8(this._offset);
this.moveOffset(1);
return val;
}
i8() {
const val = this._buffer.readInt8(this._offset);
this.moveOffset(1);
return val;
}
s(size) {
if (size === undefined || size < 0) {
throw new Error(`Invalid string size ${size ?? typeof size}`);
}
if (size === 0) {
size = this._buffer.indexOf('\0', this._offset, 'utf8') - this._offset + 1;
}
const val = this._buffer
.toString('utf8', this._offset, this._offset + size)
.split('\0', 1).pop(); // remove all trailing null bytes
this.moveOffset(size);
return val;
}
ws(size) {
if (size === undefined || size < 0) {
throw new Error(`Invalid string size ${size ?? typeof size}`);
}
if (size === 0) {
// size already in bytes
size = this._buffer.indexOf('\u0000', this._offset, 'utf16le') - this._offset + 2;
}
else {
size *= 2; // utf16le 2 bytes per character
}
const val = this._buffer
.toString('utf16le', this._offset, this._offset + size)
.split('\u0000', 1).pop(); // remove all trailing null bytes
this.moveOffset(size);
return val;
}
buf(size) {
if (!size || size < 0) {
throw new Error(`Invalid buffer size ${size ?? typeof size}`);
}
const val = this._buffer
.slice(this._offset, this._offset + size);
this.moveOffset(size);
return val;
}
constructor(buffer, offset = 0) {
super();
this._buffer = buffer;
this._offset = offset;
this._beginOffset = offset;
this._atomFunctions = new Map([
['b8', () => Boolean(this.i8())],
['u8', () => this.u8()],
['i8', () => this.i8()],
['s', (size) => this.s(size)],
['ws', (size) => this.ws(size)],
['buf', (size) => this.buf(size)],
['j', (size) => this.s(size)]
]);
}
read(type, size) {
if (size === undefined) {
const groups = type.match(this._stringOrBufferAtomOrJsonGroups)?.groups;
if (groups) {
type = groups.type;
size = +groups.size;
}
}
if (this._atomFunctions.has(type)) {
const reader = this._atomFunctions.get(type);
return reader(size);
}
else {
throw new Error(`Unknown type ${type}`);
}
}
get size() {
return this._offset - this._beginOffset;
}
get offset() {
return this._offset;
}
moveOffset(size) {
this._offset += size;
}
}
exports.ReadBuffer = ReadBuffer;