proof of work, bug fixes, reorg, more
This commit is contained in:
197
src/lib/buffer.ts
Normal file
197
src/lib/buffer.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
// nodejs like buffer class for browser
|
||||
export class WebBuffer {
|
||||
private data: Uint8Array<ArrayBuffer>;
|
||||
// the number of bytes read from the buffer, this allows for you to read the buffer without having to specify the offset every time
|
||||
private count = 0;
|
||||
private dataView: DataView;
|
||||
|
||||
constructor(data: ArrayBuffer) {
|
||||
this.data = new Uint8Array(data);
|
||||
this.dataView = new DataView(data);
|
||||
|
||||
return new Proxy(this, {
|
||||
get(target, prop, receiver) {
|
||||
// Check if the property is a string that represents a valid number (array index)
|
||||
if (typeof prop === 'string' && /^\d+$/.test(prop)) {
|
||||
const index = parseInt(prop, 10);
|
||||
// Delegate array-like access to the underlying Uint8Array
|
||||
return target.data[index];
|
||||
}
|
||||
// For all other properties (methods like slice, getters like length, etc.),
|
||||
// use the default property access behavior on the target object.
|
||||
return Reflect.get(target, prop, receiver);
|
||||
},
|
||||
set(target, prop, value, receiver) {
|
||||
// Check if the property is a string that represents a valid number (array index)
|
||||
if (typeof prop === 'string' && /^\d+$/.test(prop)) {
|
||||
const index = parseInt(prop, 10);
|
||||
// Delegate array-like assignment to the underlying Uint8Array
|
||||
target.data[index] = value;
|
||||
return true; // Indicate success
|
||||
}
|
||||
// For all other properties, use the default property assignment behavior.
|
||||
return Reflect.set(target, prop, value, receiver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[index: number]: number;
|
||||
|
||||
get length(): number {
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
get buffer(): ArrayBuffer {
|
||||
return this.data.buffer;
|
||||
}
|
||||
|
||||
slice(start: number, end?: number): WebBuffer {
|
||||
return new WebBuffer(this.data.slice(start, end).buffer);
|
||||
}
|
||||
|
||||
set(data: number, offset: number) {
|
||||
this.dataView.setUint8(offset, data);
|
||||
// this.data.set(data, offset);
|
||||
}
|
||||
|
||||
read(length?: number, offset?: number): Uint8Array {
|
||||
if (length === undefined) {
|
||||
length = this.length - this.count;
|
||||
}
|
||||
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += length;
|
||||
}
|
||||
|
||||
return this.data.slice(offset, offset + length);
|
||||
}
|
||||
|
||||
write(data: Uint8Array, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += data.byteLength;
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.byteLength; i++) {
|
||||
this.dataView.setUint8(offset + i, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
readInt8(offset?: number): number {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 1;
|
||||
}
|
||||
|
||||
return this.dataView.getUint8(offset);
|
||||
}
|
||||
|
||||
writeInt8(value: number, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 1;
|
||||
}
|
||||
|
||||
this.dataView.setUint8(offset, value);
|
||||
}
|
||||
|
||||
readInt16LE(offset?: number): number {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 2;
|
||||
}
|
||||
|
||||
return this.dataView.getInt16(offset, true);
|
||||
}
|
||||
|
||||
writeInt16LE(value: number, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 2;
|
||||
}
|
||||
|
||||
this.dataView.setInt16(offset, value, true);
|
||||
}
|
||||
|
||||
readInt32LE(offset?: number): number {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 4;
|
||||
}
|
||||
|
||||
return this.dataView.getInt32(offset, true);
|
||||
}
|
||||
|
||||
writeInt32LE(value: number, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 4;
|
||||
}
|
||||
|
||||
this.dataView.setInt32(offset, value, true);
|
||||
}
|
||||
|
||||
readBigInt64LE(offset?: number): bigint {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 8;
|
||||
}
|
||||
|
||||
return this.dataView.getBigInt64(offset, true);
|
||||
}
|
||||
|
||||
writeBigInt64LE(value: bigint, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += 8;
|
||||
}
|
||||
|
||||
this.dataView.setBigInt64(offset, value, true);
|
||||
}
|
||||
|
||||
// if no length is specified, reads until the end of the buffer
|
||||
readString(length?: number, offset?: number): string {
|
||||
if (length === undefined) {
|
||||
length = this.length - this.count;
|
||||
}
|
||||
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += length;
|
||||
}
|
||||
|
||||
let textDeccoder = new TextDecoder();
|
||||
let readTextBuf = this.data.slice(offset, offset + length);
|
||||
let value = textDeccoder.decode(readTextBuf);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
writeString(value: string, offset?: number) {
|
||||
if (offset === undefined) {
|
||||
offset = this.count;
|
||||
this.count += value.length;
|
||||
}
|
||||
|
||||
let textEncoder = new TextEncoder();
|
||||
let textBuf = textEncoder.encode(value);
|
||||
|
||||
this.data.set(textBuf, offset);
|
||||
}
|
||||
|
||||
// lets you peek at the next byte without advancing the read pointer
|
||||
peek(): number {
|
||||
return this.data[this.count];
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
// Return an iterator over the values of the underlying Uint8Array
|
||||
return this.data.values();
|
||||
}
|
||||
|
||||
// Optional: Add Symbol.toStringTag for better console output
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'WebBuffer';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user