@ankhzet/goo
Version:
Elegoo .goo file format reader/writer
60 lines (59 loc) • 1.91 kB
JavaScript
import { assert } from './utils.js';
export class BinaryReader {
constructor(readable) {
this.buffers = {};
this.readable = readable;
}
buffer(size) {
let got = this.buffers[size];
if (!got) {
got = Buffer.alloc(size);
this.buffers[size] = got;
}
return got;
}
async assert(data, message) {
const { buffer, bytesRead } = await this.binary(data.length);
assert((bytesRead === data.length) && !buffer.compare(data), message);
}
async skip(count) {
return this.readable.read(this.buffer(count), 0, count).then(({ bytesRead }) => bytesRead);
}
async binary(count) {
return this.readable.read(this.buffer(count), 0, count, null);
}
async bool() {
return this.binary(1).then(({ buffer }) => !!buffer.readUint8());
}
async u8() {
return this.binary(1).then(({ buffer }) => buffer.readUint8());
}
async u16() {
return this.binary(2).then(({ buffer }) => buffer.readUint16BE());
}
async u24() {
return this.binary(3).then(({ buffer }) => {
const b16 = buffer.readUint16BE();
const b8 = buffer.readUint8(2);
return (b16 << 8) | b8;
});
}
async u32() {
return this.binary(4).then(({ buffer }) => buffer.readUint32BE());
}
async f32() {
return this.binary(4).then(({ buffer }) => buffer.readFloatBE());
}
async string(length) {
return this.binary(length).then(({ buffer }) => {
const terminatorIndex = buffer.indexOf(0);
return buffer.toString('utf8', 0, terminatorIndex >= 0 ? terminatorIndex : length);
});
}
async struct(target, map) {
for (const [key, reader] of Object.entries(map)) {
target[key] = await reader();
}
return target;
}
}