UNPKG

@hazae41/cursor

Version:

Rust-like Cursor for TypeScript

1 lines 14.9 kB
{"version":3,"file":"index.mjs","sources":["../../../../src/mods/cursor/index.ts"],"sourcesContent":["export * from \"./errors/index.js\"\n\nimport { Lengthed } from \"@hazae41/lengthed\"\nimport { Buffers } from \"libs/buffers/buffers.js\"\nimport { Bytes } from \"libs/bytes/index.js\"\nimport { Data } from \"libs/dataviews/dataviews.js\"\nimport { Utf8 } from \"libs/utf8/utf8.js\"\nimport { CursorReadLengthOverflowError, CursorReadNullOverflowError, CursorWriteLengthOverflowError, CursorWriteUnknownError } from \"./errors/index.js\"\n\nexport class Cursor {\n\n readonly #data: DataView\n\n readonly #bytes: Uint8Array\n\n readonly #buffer: Buffer\n\n offset: number\n\n /**\n * A cursor for bytes\n * @param inner \n * @param offset \n */\n constructor(buffer: ArrayBufferView, offset = 0) {\n this.offset = offset\n\n this.#data = Data.fromView(buffer)\n this.#bytes = Bytes.fromView(buffer)\n this.#buffer = Buffers.fromView(buffer)\n }\n\n static create<T extends Uint8Array>(buffer: T, offset?: number) {\n return new Cursor(buffer, offset)\n }\n\n /**\n * get bytes\n */\n get bytes() {\n return this.#bytes\n }\n\n /**\n * @returns total number of bytes\n */\n get length() {\n return this.#bytes.length\n }\n\n /**\n * @returns number of remaining bytes\n */\n get remaining() {\n return this.length - this.offset\n }\n\n /**\n * Get a subarray of the bytes before the current offset\n * @returns subarray of the bytes before the current offset\n */\n get before(): Uint8Array {\n return this.#bytes.subarray(0, this.offset)\n }\n\n /**\n * Get a subarray of the bytes after the current offset\n * @returns subarray of the bytes after the current offset\n */\n get after(): Uint8Array {\n return this.#bytes.subarray(this.offset)\n }\n\n /**\n * Get a subarray of the bytes\n * @param length \n * @returns subarray of the bytes\n */\n getOrThrow<N extends number>(length: N): Uint8Array & Lengthed<N> {\n if (this.remaining < length)\n throw CursorReadLengthOverflowError.from(this, length)\n\n const subarray = this.#bytes.subarray(this.offset, this.offset + length)\n\n return subarray as Uint8Array & Lengthed<N>\n }\n\n /**\n * Read a subarray of the bytes\n * @param length \n * @returns subarray of the bytes\n */\n readOrThrow<N extends number>(length: N): Uint8Array & Lengthed<N> {\n const subarray = this.getOrThrow(length)\n this.offset += length\n return subarray\n }\n\n /**\n * Set an array to the bytes\n * @param array array\n */\n setOrThrow(array: Uint8Array): void {\n if (this.remaining < array.length)\n throw CursorWriteLengthOverflowError.from(this, array.length)\n\n this.#bytes.set(array, this.offset)\n }\n\n /**\n * Write an array to the bytes\n * @param array array\n */\n writeOrThrow(array: Uint8Array): void {\n this.setOrThrow(array)\n this.offset += array.length\n }\n\n getUint8OrThrow(): number {\n return this.#bytes[this.offset]\n }\n\n readUint8OrThrow(): number {\n const x = this.getUint8OrThrow()\n this.offset++\n return x\n }\n\n setUint8OrThrow(x: number): void {\n this.#bytes[this.offset] = x\n }\n\n writeUint8OrThrow(x: number): void {\n this.setUint8OrThrow(x)\n this.offset++\n }\n\n getUint16OrThrow(littleEndian?: boolean): number {\n return this.#data.getUint16(this.offset, littleEndian)\n }\n\n readUint16OrThrow(littleEndian?: boolean): number {\n const x = this.getUint16OrThrow(littleEndian)\n this.offset += 2\n return x\n }\n\n setUint16OrThrow(x: number, littleEndian?: boolean): void {\n this.#data.setUint16(this.offset, x, littleEndian)\n }\n\n writeUint16OrThrow(x: number, littleEndian?: boolean): void {\n this.setUint16OrThrow(x, littleEndian)\n this.offset += 2\n }\n\n getUint24OrThrow(littleEndian?: boolean): number {\n if (littleEndian)\n return this.#buffer.readUIntLE(this.offset, 3)\n else\n return this.#buffer.readUIntBE(this.offset, 3)\n }\n\n readUint24OrThrow(littleEndian?: boolean): number {\n const x = this.getUint24OrThrow(littleEndian)\n this.offset += 3\n return x\n }\n\n setUint24OrThrow(x: number, littleEndian?: boolean): void {\n if (littleEndian)\n this.#buffer.writeUIntLE(x, this.offset, 3)\n else\n this.#buffer.writeUIntBE(x, this.offset, 3)\n }\n\n writeUint24OrThrow(x: number, littleEndian?: boolean): void {\n this.setUint24OrThrow(x, littleEndian)\n this.offset += 3\n }\n\n getUint32OrThrow(littleEndian?: boolean): number {\n return this.#data.getUint32(this.offset, littleEndian)\n }\n\n readUint32OrThrow(littleEndian?: boolean): number {\n const x = this.getUint32OrThrow(littleEndian)\n this.offset += 4\n return x\n }\n\n setUint32OrThrow(x: number, littleEndian?: boolean): void {\n this.#data.setUint32(this.offset, x, littleEndian)\n }\n\n writeUint32OrThrow(x: number, littleEndian?: boolean): void {\n this.setUint32OrThrow(x, littleEndian)\n this.offset += 4\n }\n\n getUint64OrThrow(littleEndian?: boolean): bigint {\n return this.#data.getBigUint64(this.offset, littleEndian)\n }\n\n readUint64OrThrow(littleEndian?: boolean): bigint {\n const x = this.getUint64OrThrow(littleEndian)\n this.offset += 8\n return x\n }\n\n setUint64OrThrow(x: bigint, littleEndian?: boolean): void {\n this.#data.setBigUint64(this.offset, x, littleEndian)\n }\n\n writeUint64OrThrow(x: bigint, littleEndian?: boolean): void {\n this.setUint64OrThrow(x, littleEndian)\n this.offset += 8\n }\n\n getUtf8OrThrow(length: number): string {\n return Utf8.decoder.decode(this.getOrThrow(length))\n }\n\n readUtf8OrThrow(length: number): string {\n return Utf8.decoder.decode(this.readOrThrow(length))\n }\n\n setUtf8OrThrow(text: string): void {\n const result = Utf8.encoder.encodeInto(text, this.after)\n\n if (result.read! !== text.length)\n throw new CursorWriteUnknownError()\n return\n }\n\n writeUtf8OrThrow(text: string): void {\n const result = Utf8.encoder.encodeInto(text, this.after)\n\n if (result.read! !== text.length)\n throw new CursorWriteUnknownError()\n\n this.offset += result.written!\n }\n\n getNullOrThrow(): number {\n let i = this.offset\n\n while (i < this.#bytes.length && this.#bytes[i] > 0)\n i++\n\n if (i === this.#bytes.length)\n throw CursorReadNullOverflowError.from(this)\n\n return i\n }\n\n getNulledOrThrow(): Uint8Array {\n return this.getOrThrow(this.getNullOrThrow())\n }\n\n readNulledOrThrow(): Uint8Array {\n return this.readOrThrow(this.getNullOrThrow())\n }\n\n setNulledOrThrow(array: Uint8Array): void {\n const start = this.offset\n\n try {\n this.writeNulledOrThrow(array)\n } finally {\n this.offset = start\n }\n }\n\n writeNulledOrThrow(array: Uint8Array): void {\n this.writeOrThrow(array)\n this.writeUint8OrThrow(0)\n }\n\n getNulledStringOrThrow(encoding?: BufferEncoding): string {\n return Buffers.fromView(this.getNulledOrThrow()).toString(encoding)\n }\n\n readNulledStringOrThrow(encoding?: BufferEncoding): string {\n return Buffers.fromView(this.readNulledOrThrow()).toString(encoding)\n }\n\n setNulledStringOrThrow(text: string, encoding?: BufferEncoding): void {\n this.setNulledOrThrow(Buffer.from(text, encoding))\n }\n\n writeNulledStringOrThrow(text: string, encoding?: BufferEncoding): void {\n this.writeNulledOrThrow(Buffer.from(text, encoding))\n }\n\n /**\n * Fill length bytes with value after offset\n * @param value value to fill\n * @param length length to fill\n */\n fillOrThrow(value: number, length: number): void {\n if (this.remaining < length)\n throw CursorWriteLengthOverflowError.from(this, length)\n\n this.#bytes.fill(value, this.offset, this.offset + length)\n this.offset += length\n }\n\n *splitOrThrow(length: number): Generator<Uint8Array, void> {\n while (this.remaining >= length)\n yield this.readOrThrow(length)\n\n if (this.remaining)\n yield this.readOrThrow(this.remaining)\n\n return\n }\n\n}"],"names":[],"mappings":"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"}