diff --git a/packages/typed-binary/src/io/bufferReaderWriter.test.ts b/packages/typed-binary/src/io/bufferReaderWriter.test.ts index 1ab7f07..cb5f24c 100644 --- a/packages/typed-binary/src/io/bufferReaderWriter.test.ts +++ b/packages/typed-binary/src/io/bufferReaderWriter.test.ts @@ -76,6 +76,21 @@ describe('BufferWriter', () => { expect(reader.readUint32()).to.eq(8); expect(reader.readUint32()).to.eq(4_294_967_295); }); + + it('respects view length when writing slice (#35)', () => { + // Create a 512 byte ArrayBuffer. + const srcBuffer = new ArrayBuffer(512); + + // Create a 100 byte Uint8Array view into the ArrayBuffer at offset 10. + const srcView = new Uint8Array(srcBuffer, 10, 100); + + // Write the Uint8Array into a BufferWriter. + const dstBuffer = new ArrayBuffer(512); + const output = new BufferWriter(dstBuffer); + expect(output.currentByteOffset).toEqual(0); + output.writeSlice(srcView); + expect(output.currentByteOffset).toEqual(100); + }); }); describe('BufferReader', () => { diff --git a/packages/typed-binary/src/io/bufferWriter.ts b/packages/typed-binary/src/io/bufferWriter.ts index 379ef34..9ee50c1 100644 --- a/packages/typed-binary/src/io/bufferWriter.ts +++ b/packages/typed-binary/src/io/bufferWriter.ts @@ -57,7 +57,13 @@ export class BufferWriter extends BufferIOBase implements ISerialOutput { writeSlice(bufferView: ArrayLike & ArrayBufferView): void { const unwrapped = unwrapBuffer(bufferView); - const srcU8 = new Uint8Array(unwrapped.buffer, unwrapped.byteOffset); + + const srcU8 = new Uint8Array( + unwrapped.buffer, + unwrapped.byteOffset, + unwrapped.byteLength, + ); + for (const srcByte of srcU8) { this.uint8View[this.byteOffset++] = srcByte; } diff --git a/packages/typed-binary/src/io/unwrapBuffer.ts b/packages/typed-binary/src/io/unwrapBuffer.ts index 1ad374c..1557d16 100644 --- a/packages/typed-binary/src/io/unwrapBuffer.ts +++ b/packages/typed-binary/src/io/unwrapBuffer.ts @@ -1,7 +1,15 @@ +interface UnwrapBufferResult { + buffer: ArrayBufferLike; + byteOffset: number; + byteLength: number; +} + /** * Removes up to one layer of view over a buffer. */ -export function unwrapBuffer(buffer: ArrayBufferLike | ArrayBufferView) { +export function unwrapBuffer( + buffer: ArrayBufferLike | ArrayBufferView, +): UnwrapBufferResult { let byteOffset = 0; let innerBuffer = buffer; @@ -11,5 +19,5 @@ export function unwrapBuffer(buffer: ArrayBufferLike | ArrayBufferView) { innerBuffer = innerBuffer.buffer; } - return { buffer: innerBuffer, byteOffset }; + return { buffer: innerBuffer, byteOffset, byteLength: buffer.byteLength }; }