diff --git a/src/cjs/browser.cjs b/src/cjs/browser.cjs index 8c1facf..5893dbf 100644 --- a/src/cjs/browser.cjs +++ b/src/cjs/browser.cjs @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.readUInt64 = exports.readUInt32 = exports.readUInt16 = exports.readUInt8 = exports.writeUInt64 = exports.writeUInt32 = exports.writeUInt16 = exports.writeUInt8 = exports.compare = exports.fromBase64 = exports.toBase64 = exports.fromHex = exports.toHex = exports.concat = exports.fromUtf8 = exports.toUtf8 = void 0; +exports.readInt64 = exports.readInt32 = exports.readInt16 = exports.readInt8 = exports.writeInt64 = exports.writeInt32 = exports.writeInt16 = exports.writeInt8 = exports.readUInt64 = exports.readUInt32 = exports.readUInt16 = exports.readUInt8 = exports.writeUInt64 = exports.writeUInt32 = exports.writeUInt16 = exports.writeUInt8 = exports.compare = exports.fromBase64 = exports.toBase64 = exports.fromHex = exports.toHex = exports.concat = exports.fromUtf8 = exports.toUtf8 = void 0; const HEX_STRINGS = "0123456789abcdefABCDEF"; const HEX_CODES = HEX_STRINGS.split("").map((c) => c.codePointAt(0)); const HEX_CODEPOINTS = Array(256) @@ -107,6 +107,7 @@ function writeUInt8(buffer, offset, value) { throw new Error(`The value of "value" is out of range. It must be >= 0 and <= ${0xff}. Received ${value}`); } buffer[offset] = value; + return offset + 1; } exports.writeUInt8 = writeUInt8; function writeUInt16(buffer, offset, value, littleEndian) { @@ -125,6 +126,7 @@ function writeUInt16(buffer, offset, value, littleEndian) { buffer[offset] = (value >> 8) & 0xff; buffer[offset + 1] = value & 0xff; } + return offset + 2; } exports.writeUInt16 = writeUInt16; function writeUInt32(buffer, offset, value, littleEndian) { @@ -147,6 +149,7 @@ function writeUInt32(buffer, offset, value, littleEndian) { buffer[offset + 2] = (value >> 8) & 0xff; buffer[offset + 3] = value & 0xff; } + return offset + 4; } exports.writeUInt32 = writeUInt32; function writeUInt64(buffer, offset, value, littleEndian) { @@ -177,6 +180,7 @@ function writeUInt64(buffer, offset, value, littleEndian) { buffer[offset + 6] = Number((value >> 8n) & 0xffn); buffer[offset + 7] = Number(value & 0xffn); } + return offset + 8; } exports.writeUInt64 = writeUInt64; function readUInt8(buffer, offset) { @@ -259,3 +263,167 @@ function readUInt64(buffer, offset, littleEndian) { } } exports.readUInt64 = readUInt64; +function writeInt8(buffer, offset, value) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7f || value < -0x80) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x80} and <= ${0x7f}. Received ${value}`); + } + buffer[offset] = value; + return offset + 1; +} +exports.writeInt8 = writeInt8; +function writeInt16(buffer, offset, value, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fff || value < -0x8000) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000} and <= ${0x7fff}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + } + else { + buffer[offset] = (value >> 8) & 0xff; + buffer[offset + 1] = value & 0xff; + } + return offset + 2; +} +exports.writeInt16 = writeInt16; +function writeInt32(buffer, offset, value, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffff || value < -0x80000000) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x80000000} and <= ${0x7fffffff}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + buffer[offset + 2] = (value >> 16) & 0xff; + buffer[offset + 3] = (value >> 24) & 0xff; + } + else { + buffer[offset] = (value >> 24) & 0xff; + buffer[offset + 1] = (value >> 16) & 0xff; + buffer[offset + 2] = (value >> 8) & 0xff; + buffer[offset + 3] = value & 0xff; + } + return offset + 4; +} +exports.writeInt32 = writeInt32; +function writeInt64(buffer, offset, value, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = Number(value & 0xffn); + buffer[offset + 1] = Number((value >> 8n) & 0xffn); + buffer[offset + 2] = Number((value >> 16n) & 0xffn); + buffer[offset + 3] = Number((value >> 24n) & 0xffn); + buffer[offset + 4] = Number((value >> 32n) & 0xffn); + buffer[offset + 5] = Number((value >> 40n) & 0xffn); + buffer[offset + 6] = Number((value >> 48n) & 0xffn); + buffer[offset + 7] = Number((value >> 56n) & 0xffn); + } + else { + buffer[offset] = Number((value >> 56n) & 0xffn); + buffer[offset + 1] = Number((value >> 48n) & 0xffn); + buffer[offset + 2] = Number((value >> 40n) & 0xffn); + buffer[offset + 3] = Number((value >> 32n) & 0xffn); + buffer[offset + 4] = Number((value >> 24n) & 0xffn); + buffer[offset + 5] = Number((value >> 16n) & 0xffn); + buffer[offset + 6] = Number((value >> 8n) & 0xffn); + buffer[offset + 7] = Number(value & 0xffn); + } + return offset + 8; +} +exports.writeInt64 = writeInt64; +function readInt8(buffer, offset) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const val = buffer[offset]; + if (val <= 0x7f) { + return val; + } + else { + return val - 0x100; + } +} +exports.readInt8 = readInt8; +function readInt16(buffer, offset, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + const val = buffer[offset] + (buffer[offset + 1] << 8); + return buffer[offset + 1] <= 0x7f ? val : val - 0x10000; + } + else { + const val = (buffer[offset] << 8) + buffer[offset + 1]; + return buffer[offset] <= 0x7f ? val : val - 0x10000; + } +} +exports.readInt16 = readInt16; +function readInt32(buffer, offset, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + const val = buffer[offset] + + (buffer[offset + 1] << 8) + + (buffer[offset + 2] << 16) + + ((buffer[offset + 3] << 24) >>> 0); + return buffer[offset + 3] <= 0x7f ? val : val - 0x100000000; + } + else { + const val = ((buffer[offset] << 24) >>> 0) + + (buffer[offset + 1] << 16) + + (buffer[offset + 2] << 8) + + buffer[offset + 3]; + return buffer[offset] <= 0x7f ? val : val - 0x100000000; + } +} +exports.readInt32 = readInt32; +function readInt64(buffer, offset, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + let num = 0n; + if (littleEndian === "LE") { + num = (num << 8n) + BigInt(buffer[offset + 7]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset]); + return buffer[offset + 7] <= 0x7f ? num : num - 0x10000000000000000n; + } + else { + let num = 0n; + num = (num << 8n) + BigInt(buffer[offset]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 7]); + return buffer[offset] <= 0x7f ? num : num - 0x10000000000000000n; + } +} +exports.readInt64 = readInt64; diff --git a/src/cjs/index.cjs b/src/cjs/index.cjs index 8665c71..ba01ad8 100644 --- a/src/cjs/index.cjs +++ b/src/cjs/index.cjs @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.readUInt64 = exports.readUInt32 = exports.readUInt16 = exports.readUInt8 = exports.writeUInt64 = exports.writeUInt32 = exports.writeUInt16 = exports.writeUInt8 = exports.compare = exports.fromBase64 = exports.toBase64 = exports.fromHex = exports.toHex = exports.concat = exports.fromUtf8 = exports.toUtf8 = void 0; +exports.readInt64 = exports.readInt32 = exports.readInt16 = exports.readInt8 = exports.writeInt64 = exports.writeInt32 = exports.writeInt16 = exports.writeInt8 = exports.readUInt64 = exports.readUInt32 = exports.readUInt16 = exports.readUInt8 = exports.writeUInt64 = exports.writeUInt32 = exports.writeUInt16 = exports.writeUInt8 = exports.compare = exports.fromBase64 = exports.toBase64 = exports.fromHex = exports.toHex = exports.concat = exports.fromUtf8 = exports.toUtf8 = void 0; function toUtf8(bytes) { return Buffer.from(bytes || []).toString(); } @@ -40,6 +40,7 @@ function writeUInt8(buffer, offset, value) { const buf = Buffer.alloc(1); buf.writeUInt8(value, 0); buffer.set(Uint8Array.from(buf), offset); + return offset + 1; } exports.writeUInt8 = writeUInt8; function writeUInt16(buffer, offset, value, littleEndian) { @@ -55,6 +56,7 @@ function writeUInt16(buffer, offset, value, littleEndian) { buf.writeUInt16BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 2; } exports.writeUInt16 = writeUInt16; function writeUInt32(buffer, offset, value, littleEndian) { @@ -70,6 +72,7 @@ function writeUInt32(buffer, offset, value, littleEndian) { buf.writeUInt32BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 4; } exports.writeUInt32 = writeUInt32; function writeUInt64(buffer, offset, value, littleEndian) { @@ -88,6 +91,7 @@ function writeUInt64(buffer, offset, value, littleEndian) { buf.writeBigUInt64BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 8; } exports.writeUInt64 = writeUInt64; function readUInt8(buffer, offset) { @@ -140,3 +144,111 @@ function readUInt64(buffer, offset, littleEndian) { } } exports.readUInt64 = readUInt64; +function writeInt8(buffer, offset, value) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const buf = Buffer.alloc(1); + buf.writeInt8(value, 0); + buffer.set(Uint8Array.from(buf), offset); + return offset + 1; +} +exports.writeInt8 = writeInt8; +function writeInt16(buffer, offset, value, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(2); + if (littleEndian === "LE") { + buf.writeInt16LE(value, 0); + } + else { + buf.writeInt16BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 2; +} +exports.writeInt16 = writeInt16; +function writeInt32(buffer, offset, value, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(4); + if (littleEndian === "LE") { + buf.writeInt32LE(value, 0); + } + else { + buf.writeInt32BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 4; +} +exports.writeInt32 = writeInt32; +function writeInt64(buffer, offset, value, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(8); + if (littleEndian === "LE") { + buf.writeBigInt64LE(value, 0); + } + else { + buf.writeBigInt64BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 8; +} +exports.writeInt64 = writeInt64; +function readInt8(buffer, offset) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const buf = Buffer.from(buffer); + return buf.readInt8(offset); +} +exports.readInt8 = readInt8; +function readInt16(buffer, offset, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt16LE(offset); + } + else { + return Buffer.from(buffer).readInt16BE(offset); + } +} +exports.readInt16 = readInt16; +function readInt32(buffer, offset, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt32LE(offset); + } + else { + return Buffer.from(buffer).readInt32BE(offset); + } +} +exports.readInt32 = readInt32; +function readInt64(buffer, offset, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readBigInt64LE(offset); + } + else { + return Buffer.from(buffer).readBigInt64BE(offset); + } +} +exports.readInt64 = readInt64; diff --git a/src/cjs/index.d.ts b/src/cjs/index.d.ts index 5cbe104..14ae044 100644 --- a/src/cjs/index.d.ts +++ b/src/cjs/index.d.ts @@ -8,11 +8,19 @@ export declare function fromBase64(base64: string): Uint8Array; export declare type CompareResult = -1 | 0 | 1; export declare function compare(v1: Uint8Array, v2: Uint8Array): CompareResult; export declare type endian = "LE" | "BE" | "le" | "be"; -export declare function writeUInt8(buffer: Uint8Array, offset: number, value: number): void; -export declare function writeUInt16(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): void; -export declare function writeUInt32(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): void; -export declare function writeUInt64(buffer: Uint8Array, offset: number, value: bigint, littleEndian: endian): void; +export declare function writeUInt8(buffer: Uint8Array, offset: number, value: number): number; +export declare function writeUInt16(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): number; +export declare function writeUInt32(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): number; +export declare function writeUInt64(buffer: Uint8Array, offset: number, value: bigint, littleEndian: endian): number; export declare function readUInt8(buffer: Uint8Array, offset: number): number; export declare function readUInt16(buffer: Uint8Array, offset: number, littleEndian: endian): number; export declare function readUInt32(buffer: Uint8Array, offset: number, littleEndian: endian): number; export declare function readUInt64(buffer: Uint8Array, offset: number, littleEndian: endian): bigint; +export declare function writeInt8(buffer: Uint8Array, offset: number, value: number): number; +export declare function writeInt16(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): number; +export declare function writeInt32(buffer: Uint8Array, offset: number, value: number, littleEndian: endian): number; +export declare function writeInt64(buffer: Uint8Array, offset: number, value: bigint, littleEndian: endian): number; +export declare function readInt8(buffer: Uint8Array, offset: number): number; +export declare function readInt16(buffer: Uint8Array, offset: number, littleEndian: endian): number; +export declare function readInt32(buffer: Uint8Array, offset: number, littleEndian: endian): number; +export declare function readInt64(buffer: Uint8Array, offset: number, littleEndian: endian): bigint; diff --git a/src/mjs/browser.js b/src/mjs/browser.js index aaab7e4..7d815c1 100644 --- a/src/mjs/browser.js +++ b/src/mjs/browser.js @@ -96,6 +96,7 @@ export function writeUInt8(buffer, offset, value) { throw new Error(`The value of "value" is out of range. It must be >= 0 and <= ${0xff}. Received ${value}`); } buffer[offset] = value; + return offset + 1; } export function writeUInt16(buffer, offset, value, littleEndian) { if (offset + 2 > buffer.length) { @@ -113,6 +114,7 @@ export function writeUInt16(buffer, offset, value, littleEndian) { buffer[offset] = (value >> 8) & 0xff; buffer[offset + 1] = value & 0xff; } + return offset + 2; } export function writeUInt32(buffer, offset, value, littleEndian) { if (offset + 4 > buffer.length) { @@ -134,6 +136,7 @@ export function writeUInt32(buffer, offset, value, littleEndian) { buffer[offset + 2] = (value >> 8) & 0xff; buffer[offset + 3] = value & 0xff; } + return offset + 4; } export function writeUInt64(buffer, offset, value, littleEndian) { if (offset + 8 > buffer.length) { @@ -163,6 +166,7 @@ export function writeUInt64(buffer, offset, value, littleEndian) { buffer[offset + 6] = Number((value >> 8n) & 0xffn); buffer[offset + 7] = Number(value & 0xffn); } + return offset + 8; } export function readUInt8(buffer, offset) { if (offset + 1 > buffer.length) { @@ -240,3 +244,159 @@ export function readUInt64(buffer, offset, littleEndian) { return num; } } +export function writeInt8(buffer, offset, value) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7f || value < -0x80) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x80} and <= ${0x7f}. Received ${value}`); + } + buffer[offset] = value; + return offset + 1; +} +export function writeInt16(buffer, offset, value, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fff || value < -0x8000) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000} and <= ${0x7fff}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + } + else { + buffer[offset] = (value >> 8) & 0xff; + buffer[offset + 1] = value & 0xff; + } + return offset + 2; +} +export function writeInt32(buffer, offset, value, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffff || value < -0x80000000) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x80000000} and <= ${0x7fffffff}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + buffer[offset + 2] = (value >> 16) & 0xff; + buffer[offset + 3] = (value >> 24) & 0xff; + } + else { + buffer[offset] = (value >> 24) & 0xff; + buffer[offset + 1] = (value >> 16) & 0xff; + buffer[offset + 2] = (value >> 8) & 0xff; + buffer[offset + 3] = value & 0xff; + } + return offset + 4; +} +export function writeInt64(buffer, offset, value, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + buffer[offset] = Number(value & 0xffn); + buffer[offset + 1] = Number((value >> 8n) & 0xffn); + buffer[offset + 2] = Number((value >> 16n) & 0xffn); + buffer[offset + 3] = Number((value >> 24n) & 0xffn); + buffer[offset + 4] = Number((value >> 32n) & 0xffn); + buffer[offset + 5] = Number((value >> 40n) & 0xffn); + buffer[offset + 6] = Number((value >> 48n) & 0xffn); + buffer[offset + 7] = Number((value >> 56n) & 0xffn); + } + else { + buffer[offset] = Number((value >> 56n) & 0xffn); + buffer[offset + 1] = Number((value >> 48n) & 0xffn); + buffer[offset + 2] = Number((value >> 40n) & 0xffn); + buffer[offset + 3] = Number((value >> 32n) & 0xffn); + buffer[offset + 4] = Number((value >> 24n) & 0xffn); + buffer[offset + 5] = Number((value >> 16n) & 0xffn); + buffer[offset + 6] = Number((value >> 8n) & 0xffn); + buffer[offset + 7] = Number(value & 0xffn); + } + return offset + 8; +} +export function readInt8(buffer, offset) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const val = buffer[offset]; + if (val <= 0x7f) { + return val; + } + else { + return val - 0x100; + } +} +export function readInt16(buffer, offset, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + const val = buffer[offset] + (buffer[offset + 1] << 8); + return buffer[offset + 1] <= 0x7f ? val : val - 0x10000; + } + else { + const val = (buffer[offset] << 8) + buffer[offset + 1]; + return buffer[offset] <= 0x7f ? val : val - 0x10000; + } +} +export function readInt32(buffer, offset, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + const val = buffer[offset] + + (buffer[offset + 1] << 8) + + (buffer[offset + 2] << 16) + + ((buffer[offset + 3] << 24) >>> 0); + return buffer[offset + 3] <= 0x7f ? val : val - 0x100000000; + } + else { + const val = ((buffer[offset] << 24) >>> 0) + + (buffer[offset + 1] << 16) + + (buffer[offset + 2] << 8) + + buffer[offset + 3]; + return buffer[offset] <= 0x7f ? val : val - 0x100000000; + } +} +export function readInt64(buffer, offset, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + let num = 0n; + if (littleEndian === "LE") { + num = (num << 8n) + BigInt(buffer[offset + 7]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset]); + return buffer[offset + 7] <= 0x7f ? num : num - 0x10000000000000000n; + } + else { + let num = 0n; + num = (num << 8n) + BigInt(buffer[offset]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 7]); + return buffer[offset] <= 0x7f ? num : num - 0x10000000000000000n; + } +} diff --git a/src/mjs/index.js b/src/mjs/index.js index 8e41336..3e3a85b 100644 --- a/src/mjs/index.js +++ b/src/mjs/index.js @@ -29,6 +29,7 @@ export function writeUInt8(buffer, offset, value) { const buf = Buffer.alloc(1); buf.writeUInt8(value, 0); buffer.set(Uint8Array.from(buf), offset); + return offset + 1; } export function writeUInt16(buffer, offset, value, littleEndian) { if (offset + 2 > buffer.length) { @@ -43,6 +44,7 @@ export function writeUInt16(buffer, offset, value, littleEndian) { buf.writeUInt16BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 2; } export function writeUInt32(buffer, offset, value, littleEndian) { if (offset + 4 > buffer.length) { @@ -57,6 +59,7 @@ export function writeUInt32(buffer, offset, value, littleEndian) { buf.writeUInt32BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 4; } export function writeUInt64(buffer, offset, value, littleEndian) { if (offset + 8 > buffer.length) { @@ -74,6 +77,7 @@ export function writeUInt64(buffer, offset, value, littleEndian) { buf.writeBigUInt64BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + return offset + 8; } export function readUInt8(buffer, offset) { if (offset + 1 > buffer.length) { @@ -121,3 +125,103 @@ export function readUInt64(buffer, offset, littleEndian) { return buf.readBigUInt64BE(offset); } } +export function writeInt8(buffer, offset, value) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const buf = Buffer.alloc(1); + buf.writeInt8(value, 0); + buffer.set(Uint8Array.from(buf), offset); + return offset + 1; +} +export function writeInt16(buffer, offset, value, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(2); + if (littleEndian === "LE") { + buf.writeInt16LE(value, 0); + } + else { + buf.writeInt16BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 2; +} +export function writeInt32(buffer, offset, value, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(4); + if (littleEndian === "LE") { + buf.writeInt32LE(value, 0); + } + else { + buf.writeInt32BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 4; +} +export function writeInt64(buffer, offset, value, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error(`The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}`); + } + littleEndian = littleEndian.toUpperCase(); + const buf = Buffer.alloc(8); + if (littleEndian === "LE") { + buf.writeBigInt64LE(value, 0); + } + else { + buf.writeBigInt64BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 8; +} +export function readInt8(buffer, offset) { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + const buf = Buffer.from(buffer); + return buf.readInt8(offset); +} +export function readInt16(buffer, offset, littleEndian) { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt16LE(offset); + } + else { + return Buffer.from(buffer).readInt16BE(offset); + } +} +export function readInt32(buffer, offset, littleEndian) { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt32LE(offset); + } + else { + return Buffer.from(buffer).readInt32BE(offset); + } +} +export function readInt64(buffer, offset, littleEndian) { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + littleEndian = littleEndian.toUpperCase(); + if (littleEndian === "LE") { + return Buffer.from(buffer).readBigInt64LE(offset); + } + else { + return Buffer.from(buffer).readBigInt64BE(offset); + } +} diff --git a/ts_src/browser.ts b/ts_src/browser.ts index b2bcad5..d91f6e7 100644 --- a/ts_src/browser.ts +++ b/ts_src/browser.ts @@ -104,7 +104,7 @@ export function writeUInt8( buffer: Uint8Array, offset: number, value: number -): void { +): number { if (offset + 1 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -116,6 +116,8 @@ export function writeUInt8( } buffer[offset] = value; + + return offset + 1; } export function writeUInt16( @@ -123,7 +125,7 @@ export function writeUInt16( offset: number, value: number, littleEndian: endian -): void { +): number { if (offset + 2 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -141,6 +143,8 @@ export function writeUInt16( buffer[offset] = (value >> 8) & 0xff; buffer[offset + 1] = value & 0xff; } + + return offset + 2; } export function writeUInt32( @@ -148,7 +152,7 @@ export function writeUInt32( offset: number, value: number, littleEndian: endian -): void { +): number { if (offset + 4 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -172,6 +176,8 @@ export function writeUInt32( buffer[offset + 2] = (value >> 8) & 0xff; buffer[offset + 3] = value & 0xff; } + + return offset + 4; } export function writeUInt64( @@ -179,7 +185,7 @@ export function writeUInt64( offset: number, value: bigint, littleEndian: endian -): void { +): number { if (offset + 8 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -210,6 +216,8 @@ export function writeUInt64( buffer[offset + 6] = Number((value >> 8n) & 0xffn); buffer[offset + 7] = Number(value & 0xffn); } + + return offset + 8; } export function readUInt8(buffer: Uint8Array, offset: number): number { @@ -306,3 +314,223 @@ export function readUInt64( return num; } } + +export function writeInt8( + buffer: Uint8Array, + offset: number, + value: number +): number { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + if (value > 0x7f || value < -0x80) { + throw new Error( + `The value of "value" is out of range. It must be >= ${-0x80} and <= ${0x7f}. Received ${value}` + ); + } + + buffer[offset] = value; + return offset + 1; +} + +export function writeInt16( + buffer: Uint8Array, + offset: number, + value: number, + littleEndian: endian +): number { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + if (value > 0x7fff || value < -0x8000) { + throw new Error( + `The value of "value" is out of range. It must be >= ${-0x8000} and <= ${0x7fff}. Received ${value}` + ); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + } else { + buffer[offset] = (value >> 8) & 0xff; + buffer[offset + 1] = value & 0xff; + } + return offset + 2; +} + +export function writeInt32( + buffer: Uint8Array, + offset: number, + value: number, + littleEndian: endian +): number { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + if (value > 0x7fffffff || value < -0x80000000) { + throw new Error( + `The value of "value" is out of range. It must be >= ${-0x80000000} and <= ${0x7fffffff}. Received ${value}` + ); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + buffer[offset] = value & 0xff; + buffer[offset + 1] = (value >> 8) & 0xff; + buffer[offset + 2] = (value >> 16) & 0xff; + buffer[offset + 3] = (value >> 24) & 0xff; + } else { + buffer[offset] = (value >> 24) & 0xff; + buffer[offset + 1] = (value >> 16) & 0xff; + buffer[offset + 2] = (value >> 8) & 0xff; + buffer[offset + 3] = value & 0xff; + } + return offset + 4; +} + +export function writeInt64( + buffer: Uint8Array, + offset: number, + value: bigint, + littleEndian: endian +): number { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error( + `The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}` + ); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + buffer[offset] = Number(value & 0xffn); + buffer[offset + 1] = Number((value >> 8n) & 0xffn); + buffer[offset + 2] = Number((value >> 16n) & 0xffn); + buffer[offset + 3] = Number((value >> 24n) & 0xffn); + buffer[offset + 4] = Number((value >> 32n) & 0xffn); + buffer[offset + 5] = Number((value >> 40n) & 0xffn); + buffer[offset + 6] = Number((value >> 48n) & 0xffn); + buffer[offset + 7] = Number((value >> 56n) & 0xffn); + } else { + buffer[offset] = Number((value >> 56n) & 0xffn); + buffer[offset + 1] = Number((value >> 48n) & 0xffn); + buffer[offset + 2] = Number((value >> 40n) & 0xffn); + buffer[offset + 3] = Number((value >> 32n) & 0xffn); + buffer[offset + 4] = Number((value >> 24n) & 0xffn); + buffer[offset + 5] = Number((value >> 16n) & 0xffn); + buffer[offset + 6] = Number((value >> 8n) & 0xffn); + buffer[offset + 7] = Number(value & 0xffn); + } + + return offset + 8; +} + +export function readInt8(buffer: Uint8Array, offset: number): number { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + const val = buffer[offset]; + + if (val <= 0x7f) { + return val; + } else { + return val - 0x100; + } +} + +export function readInt16( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): number { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + const val = buffer[offset] + (buffer[offset + 1] << 8); + return buffer[offset + 1] <= 0x7f ? val : val - 0x10000; + } else { + const val = (buffer[offset] << 8) + buffer[offset + 1]; + return buffer[offset] <= 0x7f ? val : val - 0x10000; + } +} + +export function readInt32( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): number { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + const val = + buffer[offset] + + (buffer[offset + 1] << 8) + + (buffer[offset + 2] << 16) + + ((buffer[offset + 3] << 24) >>> 0); + return buffer[offset + 3] <= 0x7f ? val : val - 0x100000000; + } else { + const val = + ((buffer[offset] << 24) >>> 0) + + (buffer[offset + 1] << 16) + + (buffer[offset + 2] << 8) + + buffer[offset + 3]; + return buffer[offset] <= 0x7f ? val : val - 0x100000000; + } +} + +export function readInt64( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): bigint { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + let num = 0n; + if (littleEndian === "LE") { + num = (num << 8n) + BigInt(buffer[offset + 7]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset]); + + return buffer[offset + 7] <= 0x7f ? num : num - 0x10000000000000000n; + } else { + let num = 0n; + num = (num << 8n) + BigInt(buffer[offset]); + num = (num << 8n) + BigInt(buffer[offset + 1]); + num = (num << 8n) + BigInt(buffer[offset + 2]); + num = (num << 8n) + BigInt(buffer[offset + 3]); + num = (num << 8n) + BigInt(buffer[offset + 4]); + num = (num << 8n) + BigInt(buffer[offset + 5]); + num = (num << 8n) + BigInt(buffer[offset + 6]); + num = (num << 8n) + BigInt(buffer[offset + 7]); + + return buffer[offset] <= 0x7f ? num : num - 0x10000000000000000n; + } +} diff --git a/ts_src/index.ts b/ts_src/index.ts index d69ffbb..50f6924 100644 --- a/ts_src/index.ts +++ b/ts_src/index.ts @@ -37,7 +37,7 @@ export function writeUInt8( buffer: Uint8Array, offset: number, value: number -): void { +): number { if (offset + 1 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -45,6 +45,8 @@ export function writeUInt8( const buf = Buffer.alloc(1); buf.writeUInt8(value, 0); buffer.set(Uint8Array.from(buf), offset); + + return offset + 1; } export function writeUInt16( @@ -52,7 +54,7 @@ export function writeUInt16( offset: number, value: number, littleEndian: endian -): void { +): number { if (offset + 2 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -67,6 +69,8 @@ export function writeUInt16( buf.writeUInt16BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + + return offset + 2; } export function writeUInt32( @@ -74,7 +78,7 @@ export function writeUInt32( offset: number, value: number, littleEndian: endian -): void { +): number { if (offset + 4 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -89,6 +93,8 @@ export function writeUInt32( buf.writeUInt32BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + + return offset + 4; } export function writeUInt64( @@ -96,7 +102,7 @@ export function writeUInt64( offset: number, value: bigint, littleEndian: endian -): void { +): number { if (offset + 8 > buffer.length) { throw new Error("Offset is outside the bounds of Uint8Array"); } @@ -117,6 +123,8 @@ export function writeUInt64( buf.writeBigUInt64BE(value, 0); } buffer.set(Uint8Array.from(buf), offset); + + return offset + 8; } export function readUInt8(buffer: Uint8Array, offset: number): number { @@ -187,3 +195,154 @@ export function readUInt64( return buf.readBigUInt64BE(offset); } } + +export function writeInt8( + buffer: Uint8Array, + offset: number, + value: number +): number { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + const buf = Buffer.alloc(1); + buf.writeInt8(value, 0); + buffer.set(Uint8Array.from(buf), offset); + + return offset + 1; +} + +export function writeInt16( + buffer: Uint8Array, + offset: number, + value: number, + littleEndian: endian +): number { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + const buf = Buffer.alloc(2); + if (littleEndian === "LE") { + buf.writeInt16LE(value, 0); + } else { + buf.writeInt16BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 2; +} + +export function writeInt32( + buffer: Uint8Array, + offset: number, + value: number, + littleEndian: endian +): number { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + const buf = Buffer.alloc(4); + if (littleEndian === "LE") { + buf.writeInt32LE(value, 0); + } else { + buf.writeInt32BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 4; +} + +export function writeInt64( + buffer: Uint8Array, + offset: number, + value: bigint, + littleEndian: endian +): number { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + if (value > 0x7fffffffffffffffn || value < -0x8000000000000000n) { + throw new Error( + `The value of "value" is out of range. It must be >= ${-0x8000000000000000n} and <= ${0x7fffffffffffffffn}. Received ${value}` + ); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + const buf = Buffer.alloc(8); + if (littleEndian === "LE") { + buf.writeBigInt64LE(value, 0); + } else { + buf.writeBigInt64BE(value, 0); + } + buffer.set(Uint8Array.from(buf), offset); + return offset + 8; +} + +export function readInt8(buffer: Uint8Array, offset: number): number { + if (offset + 1 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + const buf = Buffer.from(buffer); + return buf.readInt8(offset); +} + +export function readInt16( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): number { + if (offset + 2 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt16LE(offset); + } else { + return Buffer.from(buffer).readInt16BE(offset); + } +} + +export function readInt32( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): number { + if (offset + 4 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + return Buffer.from(buffer).readInt32LE(offset); + } else { + return Buffer.from(buffer).readInt32BE(offset); + } +} + +export function readInt64( + buffer: Uint8Array, + offset: number, + littleEndian: endian +): bigint { + if (offset + 8 > buffer.length) { + throw new Error("Offset is outside the bounds of Uint8Array"); + } + + littleEndian = littleEndian.toUpperCase() as endian; + + if (littleEndian === "LE") { + return Buffer.from(buffer).readBigInt64LE(offset); + } else { + return Buffer.from(buffer).readBigInt64BE(offset); + } +} diff --git a/ts_src/tests.spec.ts b/ts_src/tests.spec.ts index d92aaf0..b5686a3 100644 --- a/ts_src/tests.spec.ts +++ b/ts_src/tests.spec.ts @@ -411,6 +411,219 @@ describe(`Uint8Array tools`, () => { ); } }); + + it("should be able to writeInt8", () => { + const arr = new Uint8Array(1); + const fixtures = [1, 0x7f, 0x0f, 0x1f, -0x80, -0x01, -0x0f, -0x1f]; + + for (const fixture of fixtures) { + const expected = Buffer.alloc(1); + expected.writeInt8(fixture, 0); + expect(tools.writeInt8(arr, 0, fixture)).toEqual(1); + expect(arr).toEqual(Uint8Array.from(expected)); + } + }); + + it("should be able to readInt8", () => { + const arr = new Uint8Array(1); + const fixtures = [1, 0x7f, 0x0f, 0x1f, -0x80, -0x01, -0x0f, -0x1f]; + + for (const fixture of fixtures) { + tools.writeInt8(arr, 0, fixture); + expect(tools.readInt8(arr, 0)).toEqual(fixture); + } + }); + + it("should be able to writeInt16", () => { + const arr = new Uint8Array(2); + + const fixtures = [ + 1, 0x7fff, 0x00ff, 0x01ff, -0x8000, -0x01, -0x00ff, -0x01ff, + ]; + const expected = Buffer.alloc(2); + + for (const fixture of fixtures) { + expected.writeInt16LE(fixture, 0); + expect(tools.writeInt16(arr, 0, fixture, "LE")).toEqual(2); + expect(arr).toEqual(Uint8Array.from(expected)); + } + + for (const fixture of fixtures) { + expected.writeInt16BE(fixture, 0); + expect(tools.writeInt16(arr, 0, fixture, "BE")).toEqual(2); + expect(arr).toEqual(Uint8Array.from(expected)); + } + }); + + it("should be able to readInt16", () => { + const arr = new Uint8Array(2); + const fixtures = [ + 1, 0x7fff, 0x00ff, 0x01ff, -0x8000, -0x01, -0x00ff, -0x01ff, + ]; + + for (const fixture of fixtures) { + tools.writeInt16(arr, 0, fixture, "LE"); + expect(tools.readInt16(arr, 0, "LE")).toEqual(fixture); + } + + for (const fixture of fixtures) { + tools.writeInt16(arr, 0, fixture, "BE"); + expect(tools.readInt16(arr, 0, "BE")).toEqual(fixture); + } + }); + + it("should be able to writeInt32", () => { + const arr = new Uint8Array(4); + const fixtures = [ + 1, 0x7fffffff, 0x0000ffff, 0x0001ffff, -0x80000000, -0x01, + -0x0000ffff, -0x0001ffff, + ]; + const expected = Buffer.alloc(4); + + for (const fixture of fixtures) { + expected.writeInt32LE(fixture, 0); + expect(tools.writeInt32(arr, 0, fixture, "LE")).toEqual(4); + expect(arr).toEqual(Uint8Array.from(expected)); + } + + for (const fixture of fixtures) { + expected.writeInt32BE(fixture, 0); + expect(tools.writeInt32(arr, 0, fixture, "BE")).toEqual(4); + expect(arr).toEqual(Uint8Array.from(expected)); + } + }); + + it("should be able to readInt32", () => { + const arr = new Uint8Array(4); + const fixtures = [ + 1, 0x7fffffff, 0x0000ffff, 0x0001ffff, -0x80000000, -0x01, + -0x0000ffff, -0x0001ffff, + ]; + + for (const fixture of fixtures) { + tools.writeInt32(arr, 0, fixture, "LE"); + expect(tools.readInt32(arr, 0, "LE")).toEqual(fixture); + } + + for (const fixture of fixtures) { + tools.writeInt32(arr, 0, fixture, "BE"); + expect(tools.readInt32(arr, 0, "BE")).toEqual(fixture); + } + }); + + it("should be able to writeInt64", () => { + const arr = new Uint8Array(8); + + const fixtures = [ + 1n, + 0x7fffffffffffffffn, + 0x00000000ffffffffn, + 0x00000001ffffffffn, + -0x8000000000000000n, + -0x01n, + -0x00000000ffffffffn, + -0x00000001ffffffffn, + ]; + const expected = Buffer.alloc(8); + + for (const fixture of fixtures) { + expected.writeBigInt64LE(fixture, 0); + expect(tools.writeInt64(arr, 0, fixture, "LE")).toEqual(8); + expect(arr).toEqual(Uint8Array.from(expected)); + } + + for (const fixture of fixtures) { + expected.writeBigInt64BE(fixture, 0); + expect(tools.writeInt64(arr, 0, fixture, "BE")).toEqual(8); + expect(arr).toEqual(Uint8Array.from(expected)); + } + }); + + it("should be able to readInt64", () => { + const arr = new Uint8Array(8); + + const fixtures = [ + 1n, + 0x7fffffffffffffffn, + 0x00000000ffffffffn, + 0x00000001ffffffffn, + -0x8000000000000000n, + -0x01n, + -0x00000000ffffffffn, + -0x00000001ffffffffn, + ]; + + for (const fixture of fixtures) { + tools.writeInt64(arr, 0, fixture, "LE"); + expect(tools.readInt64(arr, 0, "LE")).toEqual(fixture); + } + + for (const fixture of fixtures) { + tools.writeInt64(arr, 0, fixture, "BE"); + expect(tools.readInt64(arr, 0, "BE")).toEqual(fixture); + } + }); + + it("signed integer functions should throw if the value is out of range", () => { + const nums = [0, 1, 2, 3]; + + for (let i = 0; i < nums.length; i++) { + const bitLength = (1 << nums[i]) * 8; + const fnName = "writeInt" + bitLength.toString(); + const rawLow = BigInt(-(2n ** BigInt(bitLength - 1))); + const rawHigh = -rawLow - 1n; + const rawHighValue = rawHigh + 1n; + const rawLowValue = rawLow - 1n; + + const low = i === 3 ? rawLow : Number(rawLow); + const high = i === 3 ? rawHigh : Number(rawHigh); + const values = [ + i === 3 ? rawLowValue : Number(rawLowValue), + i === 3 ? rawHighValue : Number(rawHighValue), + ]; + + for (const value of values) { + for (const endian of ["BE", "LE"]) { + expect(() => + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + tools[fnName]( + new Uint8Array(bitLength / 8 + 1), + 0, + value, + endian + ) + ).toThrowError( + new Error( + `The value of "value" is out of range. It must be >= ${low} and <= ${high}. Received ${value}` + ) + ); + } + } + } + }); + + it("signed integer read-write functions should throw an error if the offset is out of bounds", () => { + const operation = ["read", "write"]; + const nums = [0, 1, 2, 3]; + + for (let i = 0; i < operation.length; i++) { + for (let j = 0; j < nums.length; j++) { + const fnName = + operation[i] + "Int" + ((1 << nums[j]) * 8).toString(); + const val = j === 4 ? 1n : 1; + for (const endian of ["BE", "LE"]) { + expect(() => + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + tools[fnName](new Uint8Array(j + 1), val, j + 1, endian) + ).toThrowError( + new Error("Offset is outside the bounds of Uint8Array") + ); + } + } + } + }); }); } });