UNPKG

iso-base

Version:
494 lines 11.9 kB
/** * Cross-platform binary buffer with auto-advancing cursor. * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * // Create from size * const buf = new ISOBuffer(256) * * // Write some data * buf.writeUint8(0x01) * buf.writeUint32(0xdeadbeef) * buf.writeUtf8('hello') * * // Rewind and read back * buf.rewind() * console.log(buf.readUint8()) // 1 * console.log(buf.readUint32().toString(16)) // 'deadbeef' * console.log(buf.readUtf8(5)) // 'hello' * ``` */ export class ISOBuffer { /** * Create a new ISOBuffer. * * @param {ISOBufferInput} [data] - Initial data or size. Defaults to 8KB. * - If a number, creates a new buffer of that size * - If ArrayBuffer/Uint8Array/ISOBuffer, wraps it (zero-copy view) * @param {ISOBufferOptions} [options] - Configuration options * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * // From size * const buf1 = new ISOBuffer(256) * * // From Uint8Array (zero-copy) * const arr = new Uint8Array([1, 2, 3, 4]) * const buf2 = new ISOBuffer(arr) * * // From ArrayBuffer with offset * const ab = new ArrayBuffer(100) * const buf3 = new ISOBuffer(ab, { offset: 10 }) * * // Big-endian mode * const buf4 = new ISOBuffer(64, { littleEndian: false }) * ``` */ constructor(data?: ISOBufferInput, options?: ISOBufferOptions); /** * The underlying ArrayBuffer * * @type {ArrayBuffer} */ buffer: ArrayBuffer; /** * Uint8Array view over the buffer * * @type {Uint8Array} */ bytes: Uint8Array; /** * Current cursor position * * @type {number} */ offset: number; /** * Byte length of the buffer * * @type {number} */ length: number; /** * Byte offset within the underlying ArrayBuffer * * @type {number} */ byteOffset: number; /** * Byte length of the buffer (alias for length, for compatibility) * * @type {number} */ get byteLength(): number; /** * @type {boolean} * @private */ private littleEndian; /** * @type {DataView} * @private */ private _data; /** * @type {number} * @private */ private _mark; /** * @type {number[]} * @private */ private _marks; /** * Tracks the last written byte position for toArray() * * @type {number} * @private */ private _lastWrittenByte; /** * Check if there's enough space to read/write n bytes from current offset. * * @param {number} [byteLength=1] - Number of bytes needed * @returns {boolean} True if space is available * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * const buf = new ISOBuffer(4) * buf.available(4) // true * buf.skip(2) * buf.available(4) // false * buf.available(2) // true * ``` */ available(byteLength?: number): boolean; /** * Ensure buffer has enough space, growing if necessary. * Growth strategy: double the required size. * * @param {number} [byteLength=1] - Number of bytes needed * @returns {this} * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * const buf = new ISOBuffer(4) * buf.seek(4) * buf.ensureAvailable(10) // Buffer grows to accommodate * buf.available(10) // true * ``` */ ensureAvailable(byteLength?: number): this; /** * Check if little-endian mode is active. * * @returns {boolean} */ isLittleEndian(): boolean; /** * Check if big-endian mode is active. * * @returns {boolean} */ isBigEndian(): boolean; /** * Switch to little-endian mode. * * @returns {this} */ setLittleEndian(): this; /** * Switch to big-endian mode. * * @returns {this} */ setBigEndian(): this; /** * Move cursor forward by n bytes. * * @param {number} [n=1] - Bytes to skip * @returns {this} */ skip(n?: number): this; /** * Move cursor backward by n bytes. * * @param {number} [n=1] - Bytes to go back * @returns {this} */ back(n?: number): this; /** * Move cursor to specific offset. * * @param {number} offset - Target offset * @returns {this} */ seek(offset: number): this; /** * Move cursor back to start (offset 0). * * @returns {this} */ rewind(): this; /** * Store current offset for later reset. * * @returns {this} * @see {@link ISOBuffer#reset} */ mark(): this; /** * Return to last marked offset. * * @returns {this} * @see {@link ISOBuffer#mark} */ reset(): this; /** * Push current offset onto mark stack. * * @returns {this} * @see {@link ISOBuffer#popMark} */ pushMark(): this; /** * Pop offset from mark stack and seek to it. * * @returns {this} * @throws {Error} If mark stack is empty * @see {@link ISOBuffer#pushMark} */ popMark(): this; /** * Read signed 8-bit integer, advance cursor by 1. * * @returns {number} */ readInt8(): number; /** * Read unsigned 8-bit integer, advance cursor by 1. * * @returns {number} */ readUint8(): number; /** * Read signed 16-bit integer, advance cursor by 2. * * @returns {number} */ readInt16(): number; /** * Read unsigned 16-bit integer, advance cursor by 2. * * @returns {number} */ readUint16(): number; /** * Read signed 32-bit integer, advance cursor by 4. * * @returns {number} */ readInt32(): number; /** * Read unsigned 32-bit integer, advance cursor by 4. * * @returns {number} */ readUint32(): number; /** * Read signed 64-bit BigInt, advance cursor by 8. * * @returns {bigint} */ readBigInt64(): bigint; /** * Read unsigned 64-bit BigInt, advance cursor by 8. * * @returns {bigint} */ readBigUint64(): bigint; /** * Read 32-bit float, advance cursor by 4. * * @returns {number} */ readFloat32(): number; /** * Read 64-bit double, advance cursor by 8. * * @returns {number} */ readFloat64(): number; /** * Read n bytes as Uint8Array (zero-copy subarray), advance cursor. * * @param {number} n - Number of bytes to read * @returns {Uint8Array} */ readBytes(n: number): Uint8Array; /** * Read n bytes and decode as UTF-8 string. * * @param {number} n - Number of bytes to read * @returns {string} */ readUtf8(n: number): string; /** * Read a boolean (1 byte, false if 0, true otherwise). * * @returns {boolean} */ readBoolean(): boolean; /** * Read unsigned varint (multiformats style), advance cursor. * * @returns {number} The decoded value * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * const buf = new ISOBuffer(new Uint8Array([0xac, 0x02])) * console.log(buf.readVarint()) // 300 * ``` */ readVarint(): number; /** * Read unsigned LEB128 encoded bigint, advance cursor. * * @returns {bigint} The decoded value */ readLeb128(): bigint; /** * Update lastWrittenByte tracker after write. * * @private */ private _updateLastWrittenByte; /** * Write signed 8-bit integer, advance cursor by 1. * * @param {number} value * @returns {this} */ writeInt8(value: number): this; /** * Write unsigned 8-bit integer, advance cursor by 1. * * @param {number} value * @returns {this} */ writeUint8(value: number): this; /** * Write signed 16-bit integer, advance cursor by 2. * * @param {number} value * @returns {this} */ writeInt16(value: number): this; /** * Write unsigned 16-bit integer, advance cursor by 2. * * @param {number} value * @returns {this} */ writeUint16(value: number): this; /** * Write signed 32-bit integer, advance cursor by 4. * * @param {number} value * @returns {this} */ writeInt32(value: number): this; /** * Write unsigned 32-bit integer, advance cursor by 4. * * @param {number} value * @returns {this} */ writeUint32(value: number): this; /** * Write signed 64-bit BigInt, advance cursor by 8. * * @param {bigint} value * @returns {this} */ writeBigInt64(value: bigint): this; /** * Write unsigned 64-bit BigInt, advance cursor by 8. * * @param {bigint} value * @returns {this} */ writeBigUint64(value: bigint): this; /** * Write 32-bit float, advance cursor by 4. * * @param {number} value * @returns {this} */ writeFloat32(value: number): this; /** * Write 64-bit double, advance cursor by 8. * * @param {number} value * @returns {this} */ writeFloat64(value: number): this; /** * Write bytes from Uint8Array, advance cursor. * * @param {Uint8Array | ArrayLike<number>} bytes * @returns {this} */ writeBytes(bytes: Uint8Array | ArrayLike<number>): this; /** * Write string as UTF-8 encoded bytes. * * @param {string} str * @returns {this} */ writeUtf8(str: string): this; /** * Write boolean as single byte (0xff for true, 0x00 for false). * * @param {boolean} value * @returns {this} */ writeBoolean(value: boolean): this; /** * Write unsigned varint (multiformats style), advance cursor. * * @param {number} value - Value to encode (must be non-negative safe integer) * @returns {this} * * @example * ```ts twoslash * import { ISOBuffer } from 'iso-base/buffer' * * const buf = new ISOBuffer(16) * buf.writeVarint(300) * console.log(buf.toArray()) // Uint8Array([0xac, 0x02]) * ``` */ writeVarint(value: number): this; /** * Write unsigned LEB128 encoded bigint. * * @param {number | bigint | string} value - Value to encode * @returns {this} */ writeLeb128(value: number | bigint | string): this; /** * Get a Uint8Array of the written portion of the buffer. * This is a view from byteOffset to lastWrittenByte. * * @returns {Uint8Array} */ toArray(): Uint8Array; /** * Get a zero-copy subarray view. * * @param {number} [start=0] - Start offset * @param {number} [end] - End offset (defaults to length) * @returns {Uint8Array} */ subarray(start?: number, end?: number): Uint8Array; /** * Get number of bytes written so far. * * @returns {number} */ getWrittenLength(): number; /** * Get remaining bytes available from current offset. * * @returns {number} */ remaining(): number; /** * Create a new ISOBuffer wrapping the same underlying buffer. * Changes to either buffer affect the other. * * @returns {ISOBuffer} */ clone(): ISOBuffer; /** * Create a deep copy with its own ArrayBuffer. * * @returns {ISOBuffer} */ deepClone(): ISOBuffer; } import type { ISOBufferInput } from './types.js'; import type { ISOBufferOptions } from './types.js'; //# sourceMappingURL=buffer.d.ts.map