Skip to main content
Module

x/bytebuf/bytebuf.ts

A byte buffer for encoding and decoding binary data in JavaScript.
Go to Latest
File
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
export { ByteBuf }export type { IntResult, StringResult }
/** * A byte buffer. * * Supports the following data types: * - Bool * - Int (8, 16, 32, 64) * - Uint (8, 16, 32, 64) * - BigInt (64) * - VarInt (unsigned, signed, and zigzag) * - String (utf8, utf16, and delimited) * - TypedArray * * @extends DataView */class ByteBuf extends DataView {
/** * Creates a byte buffer. * @param source The data source. * @param byteOffset The byte offset. * @param byteLength The byte length. * @returns A byte buffer. */ static from(source: BufferSource, byteOffset?: number, byteLength?: number): ByteBuf { const buffer = source instanceof ArrayBuffer ? source : source.buffer
if (ArrayBuffer.isView(source)) { byteOffset = source.byteOffset + (byteOffset || 0) }
return byteLength === undefined ? new ByteBuf(buffer, byteOffset) : new ByteBuf(buffer, byteOffset, Math.min(source.byteLength, byteLength)) } /** * The byte offset. */ #byteOffset: number = super.byteOffset
/** * The byte offset. * @returns The byte offset. */ get byteOffset(): number { return this.#byteOffset }
/** * Gets the number of remaining bytes. * @returns The number of bytes remaining. */ get bytesRemaining(): number { return this.byteLength - this.#byteOffset }
/** * Skips the byte offset. * @param byteLength The byte length. */ skip(byteLength: number): void { this.#byteOffset += byteLength }
/** * Resets the byte offset. */ reset(): void { this.#byteOffset = super.byteOffset }
/** * Gets a boolean. * @param byteOffset The byte offset. */ getBool(byteOffset: number): boolean { return this.getInt8(byteOffset) !== 0 }
/** * Reads the next boolean. */ readBool(): boolean { return this.getInt8(this.#byteOffset++) !== 0 }
/** * Sets a boolean. * @param byteOffset The byte offset. * @param value The value. */ setBool(byteOffset: number, value: boolean): void { super.setInt8(byteOffset, value ? 1 : 0) }
/** * Writes the next boolean. * @param value The value. */ writeBool(value: boolean): void { this.setInt8(this.#byteOffset++, value ? 1 : 0) }
/** * Gets an signed byte. * @param byteOffset The byte offset. * @returns The value. */ getInt8(byteOffset: number): number { return super.getInt8(byteOffset) }
/** * Reads the next signed byte. * @returns The value. */ readInt8(): number { return this.getInt8(this.#byteOffset++) }
/** * Sets a signed byte. * @param byteOffset The byte offset. * @param value The value. */ setInt8(byteOffset: number, value: number): void { super.setInt8(byteOffset, value) }
/** * Writes the next signed byte. * @param value The value. */ writeInt8(value: number): void { this.setInt8(this.#byteOffset++, value) }
/** * Gets an unsigned byte. * @param byteOffset The byte offset. * @returns The value. */ getUint8(byteOffset: number): number { return super.getUint8(byteOffset) }
/** * Reads the next unsigned byte. * @returns The value. */ readUint8(): number { return this.getUint8(this.#byteOffset++) }
/** * Sets an unsigned byte. * @param byteOffset The byte offset. * @param value The value. */ setUint8(byteOffset: number, value: number): void { super.setUint8(byteOffset, value) }
/** * Writes the next signed byte. * @param value The value. */ writeUint8(value: number): void { this.setUint8(this.#byteOffset++, value) }
/** * Gets an signed short. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getInt16(byteOffset: number, littleEndian?: boolean): number { return super.getInt16(byteOffset, littleEndian) }
/** * Reads the next signed short. * @param littleEndian If the value is little endian. * @returns The value. */ readInt16(littleEndian?: boolean): number { const value = this.getInt16(this.#byteOffset, littleEndian) this.#byteOffset += 2 return value }
/** * Sets a signed short. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { super.setInt16(byteOffset, value, littleEndian) }
/** * Writes the next signed short. * @param value The value. * @param littleEndian If the value is little endian. */ writeInt16(value: number, littleEndian?: boolean): void { this.setInt16(this.#byteOffset, value, littleEndian) this.#byteOffset += 2 }
/** * Gets an unsigned short. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getUint16(byteOffset: number, littleEndian?: boolean): number { return super.getUint16(byteOffset, littleEndian) }
/** * Reads the next unsigned short. * @param littleEndian If the value is little endian. * @returns The value. */ readUint16(littleEndian?: boolean): number { const value = this.getUint16(this.#byteOffset, littleEndian) this.#byteOffset += 2 return value }
/** * Sets an unsigned short. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { super.setUint16(byteOffset, value, littleEndian) }
/** * Writes the next signed short. * @param value The value. * @param littleEndian If the value is little endian. */ writeUint16(value: number, littleEndian?: boolean): void { this.setUint16(this.#byteOffset, value, littleEndian) this.#byteOffset += 2 }
/** * Gets an signed integer. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getInt32(byteOffset: number, littleEndian?: boolean): number { return super.getInt32(byteOffset, littleEndian) }
/** * Reads the next signed integer. * @param littleEndian If the value is little endian. * @returns The value. */ readInt32(littleEndian?: boolean): number { const value = this.getInt32(this.#byteOffset, littleEndian) this.#byteOffset += 4 return value }
/** * Sets a signed integer. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { super.setInt32(byteOffset, value, littleEndian) }
/** * Writes the next signed integer. * @param value The value. * @param littleEndian If the value is little endian. */ writeInt32(value: number, littleEndian?: boolean): void { this.setInt32(this.#byteOffset, value, littleEndian) this.#byteOffset += 4 }
/** * Gets an unsigned integer. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getUint32(byteOffset: number, littleEndian?: boolean): number { return super.getUint32(byteOffset, littleEndian) }
/** * Reads the next unsigned integer. * @param littleEndian If the value is little endian. * @returns The value. */ readUint32(littleEndian?: boolean): number { const value = this.getUint32(this.#byteOffset, littleEndian) this.#byteOffset += 4 return value }
/** * Sets an unsigned integer. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { super.setUint32(byteOffset, value, littleEndian) }
/** * Writes the next signed integer. * @param value The value. * @param littleEndian If the value is little endian. */ writeUint32(value: number, littleEndian?: boolean): void { this.setUint32(this.#byteOffset, value, littleEndian) this.#byteOffset += 4 }
/** * Gets a float. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getFloat32(byteOffset: number, littleEndian?: boolean): number { return super.getFloat32(byteOffset, littleEndian) }
/** * Reads the next float. * @param littleEndian If the value is little endian. * @returns The value. */ readFloat32(littleEndian?: boolean): number { const value = this.getFloat32(this.#byteOffset, littleEndian) this.#byteOffset += 4 return value }
/** * Sets a float. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { super.setFloat32(byteOffset, value, littleEndian) }
/** * Writes the next float. * @param value The value. * @param littleEndian If the value is little endian. */ writeFloat32(value: number, littleEndian?: boolean): void { this.setFloat32(this.#byteOffset, value, littleEndian) this.#byteOffset += 4 }
/** * Gets a double. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getFloat64(byteOffset: number, littleEndian?: boolean): number { return super.getFloat64(byteOffset, littleEndian) }
/** * Reads the next double. * @param littleEndian If the value is little endian. * @returns The value. */ readFloat64(littleEndian?: boolean): number { const value = this.getFloat64(this.#byteOffset, littleEndian) this.#byteOffset += 8 return value }
/** * Sets a double. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { super.setFloat64(byteOffset, value, littleEndian) }
/** * Writes the next double. * @param value The value. * @param littleEndian If the value is little endian. */ writeFloat64(value: number, littleEndian?: boolean): void { this.setFloat64(this.#byteOffset, value, littleEndian) this.#byteOffset += 8 }
/** * Gets an signed long. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { return super.getBigInt64(byteOffset, littleEndian) }
/** * Reads the next signed long. * @param littleEndian If the value is little endian. * @returns The value. */ readBigInt64(littleEndian?: boolean): bigint { const value = this.getBigInt64(this.#byteOffset, littleEndian) this.#byteOffset += 8 return value }
/** * Sets a signed long. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { super.setBigInt64(byteOffset, value, littleEndian) }
/** * Writes the next signed long. * @param value The value. * @param littleEndian If the value is little endian. */ writeBigInt64(value: bigint, littleEndian?: boolean): void { this.setBigInt64(this.#byteOffset, value, littleEndian) this.#byteOffset += 8 }
/** * Gets an unsigned long. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { return super.getBigUint64(byteOffset, littleEndian) }
/** * Reads the next unsigned long. * @param littleEndian If the value is little endian. * @returns The value. */ readBigUint64(littleEndian?: boolean): bigint { const value = this.getBigUint64(this.#byteOffset, littleEndian) this.#byteOffset += 8 return value }
/** * Sets an unsigned long. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { super.setBigUint64(byteOffset, value, littleEndian) }
/** * Writes the next unsigned long. * @param value The value. * @param littleEndian If the value is little endian. */ writeBigUint64(value: bigint, littleEndian?: boolean): void { this.setBigUint64(this.#byteOffset, value, littleEndian) this.#byteOffset += 8 }
/** * Gets an signed long. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getInt64(byteOffset: number, littleEndian?: boolean): number { return Number(this.getBigInt64(byteOffset, littleEndian)) }
/** * Reads the next signed long. * @param littleEndian If the value is little endian. * @returns The value. */ readInt64(littleEndian?: boolean): number { const value = this.getInt64(this.#byteOffset, littleEndian) this.#byteOffset += 8 return value }
/** * Sets a signed long. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { this.setBigInt64(byteOffset, BigInt(value), littleEndian) }
/** * Writes the next signed long. * @param value The value. * @param littleEndian If the value is little endian. */ writeInt64(value: number, littleEndian?: boolean): void { this.setInt64(this.#byteOffset, value, littleEndian) this.#byteOffset += 8 }
/** * Gets an unsigned long. * @param byteOffset The byte offset. * @param littleEndian If the value is little endian. * @returns The value. */ getUint64(byteOffset: number, littleEndian?: boolean): number { return Number(this.getBigUint64(byteOffset, littleEndian)) }
/** * Reads the next unsigned long. * @param littleEndian If the value is little endian. * @returns The value. */ readUint64(littleEndian?: boolean): number { const value = this.getUint64(this.#byteOffset, littleEndian) this.#byteOffset += 8 return value }
/** * Sets an unsigned long. * @param byteOffset The byte offset. * @param value The value. * @param littleEndian If the value is little endian. */ setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { this.setBigUint64(byteOffset, BigInt(value), littleEndian) }
/** * Writes the next signed long. * @param value The value. * @param littleEndian If the value is little endian. */ writeUint64(value: number, littleEndian?: boolean): void { this.setUint64(this.#byteOffset, value, littleEndian) this.#byteOffset += 8 }
/** * Gets a signed, variable-length integer. * @param byteOffset The byte offset. * @param maxByteLength The maximum byte length. * @returns The result. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ getVarInt(byteOffset: number, maxByteLength: number = 10): IntResult { let value = 0 let byteLength = 0 for (let bitShift = 0; byteLength < maxByteLength; bitShift += 7) { const byte = this.getUint8(byteOffset + byteLength++) value |= (byte & 0b0111_1111) << bitShift if ((byte & 0b1000_0000) === 0) { return { value, byteLength } } } throw new RangeError("VarInt must be between 1 and " + maxByteLength + " bytes.") }
/** * Reads the next signed, variable-length integer. * @param maxByteLength The maximum byte length. * @returns The value. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ readVarInt(maxByteLength?: number): number { const { value, byteLength } = this.getVarInt(this.#byteOffset, maxByteLength) this.#byteOffset += byteLength return value }
/** * Sets a signed, variable-length integer. * @param byteOffset The byte offset. * @param value The value. * @param maxByteLength The maximum byte length. * @returns The byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ setVarInt(byteOffset: number, value: number, maxByteLength: number = 10): number { for (let byteLength = 1; byteLength <= maxByteLength; byteLength++) { let byte = value & 0b0111_1111 value >>>= 7 if (value !== 0) { byte |= 0b1000_0000 } this.setUint8(byteOffset++, byte) if (value === 0) { return byteLength } } throw new RangeError("VarInt must be between 1 and " + maxByteLength + " bytes.") }
/** * Writes the next signed, variable-length integer. * @param value The value. * @param maxByteLength The maximum byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ writeVarInt(value: number, maxByteLength?: number): void { const byteLength = this.setVarInt(this.#byteOffset, value, maxByteLength) this.#byteOffset += byteLength }
/** * Gets an unsigned, variable-length integer. * @param byteOffset The byte offset. * @param maxByteLength The maximum byte length. * @returns The result. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ getVarUint(byteOffset: number, maxByteLength?: number): IntResult { const { value, byteLength } = this.getVarInt(byteOffset, maxByteLength) return { value: value >>> 0, byteLength } }
/** * Reads the next unsigned, variable-length integer. * @param maxByteLength The maximum byte length. * @returns The value. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ readVarUint(maxByteLength?: number): number { const { value, byteLength } = this.getVarUint(this.#byteOffset, maxByteLength) this.#byteOffset += byteLength return value }
/** * Sets an unsigned, variable-length integer. * @param byteOffset The byte offset. * @param value The value. * @param maxByteLength The maximum byte length. * @returns The byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ setVarUint(byteOffset: number, value: number, maxByteLength?: number): number { return this.setVarInt(byteOffset, value >>> 0, maxByteLength) }
/** * Writes the next unsigned, variable-length integer. * @param value The value. * @param maxByteLength The maximum byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ writeVarUint(value: number, maxByteLength?: number): void { const byteLength = this.setVarUint(this.#byteOffset, value, maxByteLength) this.#byteOffset += byteLength } /** * Gets a signed, variable-length integer with zigzag encoding. * @param byteOffset The byte offset. * @param maxByteLength The maximum byte length. * @returns The result. * @link https://developers.google.com/protocol-buffers/docs/encoding#signed_integers */ getVarZint(byteOffset: number, maxByteLength?: number): IntResult { const { value, byteLength } = this.getVarInt(byteOffset, maxByteLength) return { value: (value >> 1) ^ -(value & 1), byteLength } }
/** * Reads the next signed, variable-length integer with zigzag encoding. * @param maxByteLength The maximum byte length. * @returns The value. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ readVarZint(maxByteLength?: number): number { const { value, byteLength } = this.getVarZint(this.#byteOffset, maxByteLength) this.#byteOffset += byteLength return value }
/** * Sets a signed, variable-length integer with zigzag encoding. * @param byteOffset The byte offset. * @param value The value. * @param maxByteLength The maximum byte length. * @returns The byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#signed_integers */ setVarZint(byteOffset: number, value: number, maxByteLength?: number): number { return this.setVarInt(byteOffset, (value >> 31) ^ (value << 1), maxByteLength) }
/** * Writes the next unsigned, variable-length integer with zigzag encoding. * @param value The value. * @param maxByteLength The maximum byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#varints */ writeVarZint(value: number, maxByteLength?: number): void { const byteLength = this.setVarZint(this.#byteOffset, value, maxByteLength) this.#byteOffset += byteLength }
/** * Gets an array of unsigned bytes. * @param byteOffset The byte offset. * @param byteLength The byte length. * @returns The value. */ getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { return new Uint8Array(this.buffer, super.byteOffset + byteOffset, byteLength) }
/** * Reads the next array of unsigned bytes. * @param byteLength The byte length. * @returns The value. */ readUint8Array(byteLength?: number): Uint8Array { const value = this.getUint8Array(this.#byteOffset, byteLength) this.#byteOffset += value.byteLength return value }
/** * Sets an array of unsigned bytes. * @param byteOffset The byte offset. * @param value The value. */ setUint8Array(byteOffset: number, value: Uint8Array): void { const byteLength = value.byteLength this.getUint8Array(byteOffset, byteLength).set(value) }
/** * Writes the next array of unsigned bytes. * @param value The value. */ writeUint8Array(value: Uint8Array): void { this.setUint8Array(this.#byteOffset, value) this.#byteOffset += value.byteLength }
/** * Gets an array of unsigned shorts. * @param byteOffset The byte offset. * @param byteLength The byte length. * @returns The value. */ getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { if (byteLength !== undefined) { byteLength = Math.floor(byteLength / 2) } return new Uint16Array(this.buffer, super.byteOffset + byteOffset, byteLength) }
/** * Reads the next array of unsigned shorts. * @param byteLength The byte length. * @returns The value. */ readUint16Array(byteLength?: number): Uint16Array { const value = this.getUint16Array(this.#byteOffset, byteLength) this.#byteOffset += value.byteLength return value }
/** * Sets an array of unsigned bytes. * @param byteOffset The byte offset. * @param value The value. */ setUint16Array(byteOffset: number, value: Uint16Array): void { const byteLength = value.byteLength this.getUint16Array(byteOffset, byteLength).set(value) }
/** * Writes the next array of unsigned bytes. * @param value The value. */ writeUint16Array(value: Uint16Array): void { this.setUint16Array(this.#byteOffset, value) this.#byteOffset += value.byteLength }
/** * Gets a string. * @param byteOffset The byte offset. * @param byteLength The byte length. * @param byteEncoding The byte encoding. * @returns The value. */ getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { const decoder = new TextDecoder(byteEncoding || "utf-8") const encoded = this.getUint8Array(byteOffset, byteLength) return decoder.decode(encoded) }
/** * Reads the next string. * @param byteLength The byte length. * @param byteEncoding The byte encoding. * @returns The value. */ readString(byteLength?: number, byteEncoding?: string): string { const value = this.getString(this.#byteOffset, byteLength, byteEncoding) if (byteLength === undefined) { this.#byteOffset = this.byteLength } else { this.#byteOffset += byteLength } return value }
/** * Sets a string. * @param byteOffset The byte offset. * @param value The string. * @param byteEncoding The byte encoding. * @returns The byte length. */ setString(byteOffset: number, value: string, byteEncoding?: string): number { // TODO: add support for "utf-16-be" and "utf-16-le" if (byteEncoding && byteEncoding !== "utf-8") { throw new TypeError("String encoding '" + byteEncoding + "' is not supported") } const encoder = new TextEncoder() const byteLength = Math.min(this.byteLength - byteOffset, value.length * 4) const destination = this.getUint8Array(byteOffset, byteLength) const { written } = encoder.encodeInto(value, destination) return written || 0 }
/** * Writes the next a string. * @param value The string. * @param byteEncoding The byte encoding. */ writeString(value: string, byteEncoding?: string): void { const byteLength = this.setString(this.#byteOffset, value, byteEncoding) this.#byteOffset += byteLength }
/** * Gets a String with a variable-length delimeter. * @param byteOffset The byte offset. * @param maxByteLength The maximum byte length. * @returns The result. * @link https://developers.google.com/protocol-buffers/docs/encoding#strings */ getVarString(byteOffset: number, maxByteLength?: number): StringResult { const { value: byteLength, byteLength: delimeterOffset } = this.getVarUint(byteOffset, maxByteLength) // FIXME: byteLength of VarInt !== byteLength of String const value = this.getString(byteOffset + delimeterOffset, byteLength) return { value, byteLength: byteLength + delimeterOffset } }
/** * Reads the next String with a variable-length delimeter. * @param maxByteLength The maximum byte length. * @returns The value. * @link https://developers.google.com/protocol-buffers/docs/encoding#strings */ readVarString(maxByteLength?: number): string { const { value, byteLength } = this.getVarString(this.#byteOffset, maxByteLength) this.#byteOffset += byteLength return value }
/** * Sets a String with a variable-length delimeter. * @param byteOffset The byte offset. * @param value The value. * @returns The byte length. * @link https://developers.google.com/protocol-buffers/docs/encoding#strings */ setVarString(byteOffset: number, value: string): number { const encoder = new TextEncoder() const encoded = encoder.encode(value) const byteLength = encoded.byteLength const delimeterOffset = this.setVarInt(byteOffset, byteLength) this.setUint8Array(byteOffset + delimeterOffset, encoded) return delimeterOffset + byteLength }
/** * Writes the next String with a variable-length delimeter. * @param value The value. * @link https://developers.google.com/protocol-buffers/docs/encoding#strings */ writeVarString(value: string): number { const byteLength = this.setVarString(this.#byteOffset, value) this.#byteOffset += byteLength return byteLength }
/** * Formats to a string. * @param format The string format. * @returns The string. */ toString(format?: string): string { return Array.prototype.map.call(this.getUint8Array(0), function(byte: number): string { switch(format) { case "hex": return ("00" + byte.toString(16)).slice(-2) default: return byte.toString(10) } }).join(" ") }}
/** * A number result. */interface IntResult { /** * The byte length. */ byteLength: number /** * The value. */ value: number}
/** * A string result. */interface StringResult { /** * The byte length. */ byteLength: number /** * The value. */ value: string}