diff --git a/packages/util/src/FlexibleBuffer.ts b/packages/util/src/FlexibleBuffer.ts index 9c47ed0d..afa13b5d 100644 --- a/packages/util/src/FlexibleBuffer.ts +++ b/packages/util/src/FlexibleBuffer.ts @@ -1,42 +1,40 @@ +type IBufferRawData = number[] + interface IBufferJson { type: string - data: number[] + data: IBufferRawData } interface IFlexibleBuffer { readonly length: number - push(value: ArrayLike): this + push(value: ArrayLike): void toBuffer(): Buffer - toArray(): number[] + toArray(): IBufferRawData clear(): void toJSON(): IBufferJson } export abstract class FlexibleBuffer implements IFlexibleBuffer { static auto(size?: number | null): FlexibleBuffer { - return typeof size === "number" + return typeof size === "number" && !isNaN(size) ? new BufferFlexibleBuffer(size) : new ArrayFlexibleBuffer(); } - static flexible(): FlexibleBuffer { - return new ArrayFlexibleBuffer(); - } + static flexible(): FlexibleBuffer { return new ArrayFlexibleBuffer(); } - static fixed(size: number): FlexibleBuffer { - return new BufferFlexibleBuffer(size); - } + static fixed(size: number): FlexibleBuffer { return new BufferFlexibleBuffer(size); } abstract readonly length: number - abstract push(value: ArrayLike): this + abstract push(value: ArrayLike): void abstract toBuffer(): Buffer - abstract toArray(): number[] + abstract toArray(): IBufferRawData abstract clear(): void abstract toJSON(): IBufferJson } class BufferFlexibleBuffer extends FlexibleBuffer { - constructor(size: number) { + constructor(readonly size: number) { super(); this._buffer = Buffer.alloc(size); } @@ -48,18 +46,17 @@ class BufferFlexibleBuffer extends FlexibleBuffer { return this._index; } - push(value: ArrayLike): this { + push(value: ArrayLike) { this._buffer.set(value, this._index); this._index += value.length; - return this; } toBuffer(): Buffer { return this._buffer; } - toArray(): number[] { - return Array.from(this._buffer); + toArray(): IBufferRawData { + return this.toJSON().data; } clear(): void { @@ -73,29 +70,28 @@ class BufferFlexibleBuffer extends FlexibleBuffer { } class ArrayFlexibleBuffer extends FlexibleBuffer { - private readonly _buffer: any[] = []; + private readonly _array: Uint8Array[] = []; private _length = 0; get length(): number { return this._length; } - push(value: ArrayLike): this { - this._buffer.push(value); + push(value: ArrayLike): void { + this._array.push(new Uint8Array(value)); this._length += value.length; - return this; } toBuffer(): Buffer { - return Buffer.concat(this._buffer); + return Buffer.concat(this._array, this._length); } - toArray(): number[] { - return this._buffer; + toArray(): IBufferRawData { + return this.toJSON().data; } clear(): void { - this._buffer.length = 0; + this._array.length = 0; this._length = 0; } diff --git a/packages/util/src/test/FlexibleBuffer.test.ts b/packages/util/src/test/FlexibleBuffer.test.ts index 002bd6a0..3b9dbd5a 100644 --- a/packages/util/src/test/FlexibleBuffer.test.ts +++ b/packages/util/src/test/FlexibleBuffer.test.ts @@ -2,21 +2,46 @@ import assert from "assert"; import test, { suite } from "node:test"; import { FlexibleBuffer } from "../FlexibleBuffer"; -const array = [1, 2, 3]; +const _array = [65, 66, 67]; suite("Array FlexibleBuffer", () => { - const buffer = FlexibleBuffer.flexible(); + const flexibleBuffer = FlexibleBuffer.flexible(); test("Allow push oversized", () => { - buffer.push(array); - assert.strictEqual(buffer.length, array.length); + flexibleBuffer.push(_array); + assert.strictEqual(flexibleBuffer.length, _array.length); + }); + + test("Transform to buffer", () => { + assert.doesNotThrow(() => { + const buffer = flexibleBuffer.toBuffer(); + + assert.strictEqual(buffer.length, _array.length); + + for (let i = 0; i < buffer.length; i++) { + assert.strictEqual(buffer[i], _array[i]); + } + }); }); }); suite("Buffer FlexibleBuffer", () => { - const buffer = FlexibleBuffer.fixed(1); + const fixedBuffer = FlexibleBuffer.fixed(3); + + test("Allow pushing a list with a size within the limit", () => { + assert.doesNotThrow(() => fixedBuffer.push(_array)); + assert.strictEqual(fixedBuffer.length, _array.length); + }); test("Deny push oversized", () => { - assert.throws(() => buffer.push(array)); + assert.throws(() => fixedBuffer.push(_array)); + }); + + test("Transform to array", () => { + assert.doesNotThrow(() => { + const array = fixedBuffer.toArray(); + assert.strictEqual(array.length, _array.length); + assert.deepStrictEqual(array, _array); + }); }); });