71 lines
1.7 KiB
TypeScript
71 lines
1.7 KiB
TypeScript
import { Utils } from "../..";
|
|
|
|
/** Utility class to sequentially fetch data from byte array. EOF checks included. */
|
|
export class SequentialDataReader {
|
|
private bytes: Uint8Array;
|
|
private offset: number;
|
|
|
|
constructor(bytes: Uint8Array) {
|
|
this.bytes = bytes;
|
|
this.offset = 0;
|
|
}
|
|
|
|
/** Check available bytes bytes and throw exception if EOF met */
|
|
private willRead(count: number) {
|
|
// console.log(`willRead ${count} (offset becomes ${this.offset+count} / ${this.bytes.length})`)
|
|
if (this.offset + count > this.bytes.length) {
|
|
throw new Error("Tried to read too much data");
|
|
}
|
|
}
|
|
|
|
/** Skip bytes */
|
|
skip(len: number): void {
|
|
this.willRead(len);
|
|
this.offset += len;
|
|
}
|
|
|
|
/** Read fixed length bytes */
|
|
readBytes(len: number): Uint8Array {
|
|
this.willRead(len);
|
|
const part = this.bytes.slice(this.offset, this.offset + len);
|
|
this.offset += len;
|
|
return part;
|
|
}
|
|
|
|
/** Read variable length bytes */
|
|
readVBytes(): Uint8Array {
|
|
let len = this.readI8();
|
|
let part: Uint8Array = this.readBytes(len);
|
|
return part;
|
|
}
|
|
|
|
/** Read variable length string */
|
|
readVString(): string {
|
|
let part: Uint8Array = this.readVBytes();
|
|
return Utils.u8ArrayToString(part);
|
|
}
|
|
|
|
/** Read 8 bit int (big endian) */
|
|
readI8(): number {
|
|
this.willRead(1);
|
|
const result = this.bytes[this.offset];
|
|
this.offset += 1;
|
|
return result;
|
|
}
|
|
|
|
/** Read 16 bit int (big endian) */
|
|
readI16(): number {
|
|
this.willRead(2);
|
|
const part = this.bytes.slice(this.offset, this.offset + 2);
|
|
this.offset += 2;
|
|
return Utils.bytesToI16(part);
|
|
}
|
|
|
|
/** Check EOF condition */
|
|
end() {
|
|
if (this.offset != this.bytes.length) {
|
|
throw new Error("Extra data left");
|
|
}
|
|
}
|
|
}
|