2024-02-04 17:55:48 -06:00
|
|
|
export class ReadStream {
|
2023-12-25 12:37:37 -06:00
|
|
|
public index = 0;
|
2024-01-29 15:53:47 -06:00
|
|
|
constructor(public buffer: Buffer) {}
|
2023-12-25 12:37:37 -06:00
|
|
|
|
|
|
|
|
skip(size: number) {
|
|
|
|
|
this.index += size;
|
|
|
|
|
}
|
|
|
|
|
read(size: number) {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.subarray(this.index, this.index + size);
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
consume(size: number) {
|
|
|
|
|
const subarray = this.read(size);
|
|
|
|
|
this.skip(size);
|
|
|
|
|
|
|
|
|
|
return subarray;
|
|
|
|
|
}
|
2024-01-29 15:53:47 -06:00
|
|
|
increment(size: number) {
|
|
|
|
|
return (this.index += size) - size;
|
|
|
|
|
}
|
2023-12-25 12:37:37 -06:00
|
|
|
|
|
|
|
|
readRemaining() {
|
|
|
|
|
return this.read(Number.POSITIVE_INFINITY);
|
|
|
|
|
}
|
|
|
|
|
readRemainingLength() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.length - this.index;
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
consumeRemaining() {
|
|
|
|
|
return this.consume(Number.POSITIVE_INFINITY);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-25 16:49:40 -06:00
|
|
|
byte(size: number) {
|
2023-12-25 12:37:37 -06:00
|
|
|
return this.consume(size);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-25 16:49:40 -06:00
|
|
|
ascii(size: number) {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.toString('ascii', this.increment(size), this.index);
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
2024-02-05 18:06:18 -06:00
|
|
|
utf8(size: number) {
|
|
|
|
|
return this.buffer.toString('utf8', this.increment(size), this.index);
|
|
|
|
|
}
|
2023-12-25 12:37:37 -06:00
|
|
|
|
|
|
|
|
int8() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readInt8(this.increment(1));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
int16() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readInt16LE(this.increment(2));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
int32() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readInt32LE(this.increment(4));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
int64() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readBigInt64LE(this.increment(8));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
uint8() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readUInt8(this.increment(1));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
uint16() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readUInt16LE(this.increment(2));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
uint32() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readUInt32LE(this.increment(4));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
uint64() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readBigUInt64LE(this.increment(8));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
2024-02-04 11:06:26 -06:00
|
|
|
float32() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readFloatLE(this.increment(4));
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
2024-02-04 11:06:26 -06:00
|
|
|
float64() {
|
|
|
|
|
return this.buffer.readDoubleLE(this.increment(8));
|
|
|
|
|
}
|
2023-12-25 12:37:37 -06:00
|
|
|
|
|
|
|
|
boolean() {
|
2024-01-29 15:53:47 -06:00
|
|
|
return this.buffer.readUInt8(this.increment(1)) === 1;
|
2023-12-25 12:37:37 -06:00
|
|
|
}
|
|
|
|
|
}
|
2024-02-04 18:48:39 -06:00
|
|
|
|
|
|
|
|
export class WriteStream {
|
|
|
|
|
private array: number[] = [];
|
|
|
|
|
|
|
|
|
|
get buffer() {
|
|
|
|
|
return Buffer.from(this.array);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
constructor(buffer?: Buffer) {
|
|
|
|
|
if (buffer) this.array = Array.from(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte(value: Uint8Array) {
|
|
|
|
|
this.array.push(...value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ascii(value: string) {
|
|
|
|
|
for (let index = 0; index < value.length; index++) {
|
|
|
|
|
this.array.push(value.charCodeAt(index));
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2024-02-05 18:06:18 -06:00
|
|
|
utf8(value: string) {
|
|
|
|
|
const buffer = Buffer.alloc(Buffer.byteLength(value));
|
|
|
|
|
|
|
|
|
|
buffer.write(value, 'utf8');
|
|
|
|
|
buffer.forEach((value) => {
|
|
|
|
|
this.array.push(value);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2024-02-04 18:48:39 -06:00
|
|
|
|
|
|
|
|
private uintN(bytes: number, value: number) {
|
|
|
|
|
for (let index = 0; index < bytes; index++) {
|
|
|
|
|
this.array.push((value >>> (8 * index)) & 0xff);
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
uint8(value: number) {
|
|
|
|
|
this.uintN(1, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
uint16(value: number) {
|
|
|
|
|
this.uintN(2, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
uint32(value: number) {
|
|
|
|
|
this.uintN(4, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
uint64(value: bigint) {
|
|
|
|
|
for (let index = 0n; index < 8n; index++) {
|
|
|
|
|
this.uint8(Number((value >> (8n * index)) & 0xffn));
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
private intN(bytes: number, value: number) {
|
|
|
|
|
for (let index = 0; index < bytes; index++) {
|
|
|
|
|
this.array.push((value >> (8 * index)) & 0xff);
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
int8(value: number) {
|
|
|
|
|
this.intN(1, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
int16(value: number) {
|
|
|
|
|
this.intN(2, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
int32(value: number) {
|
|
|
|
|
this.intN(4, value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
int64(value: bigint) {
|
|
|
|
|
for (let index = 0n; index < 8n; index++) {
|
|
|
|
|
this.int8(Number((value >> (8n * index)) & 0xffn));
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2024-02-04 21:40:40 -06:00
|
|
|
float32(value: number) {
|
|
|
|
|
const array = new Float32Array([value]);
|
|
|
|
|
this.array.push(...new Uint8Array(array.buffer));
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
float64(value: number) {
|
|
|
|
|
const array = new Float64Array([value]);
|
|
|
|
|
this.array.push(...new Uint8Array(array.buffer));
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2024-02-04 18:48:39 -06:00
|
|
|
}
|