From 89ae8f3b80e2f2594323da0e4c0f6f4d5c0243fa Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 7 Oct 2025 19:58:25 +0200 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20.slice()=20and?= =?UTF-8?q?=20.cut()=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Reader.ts | 52 ++++++++++++++++++++++++++++++++----- src/Slice.ts | 3 +++ src/StreamingOctetReader.ts | 6 +++++ src/StreamingReader.ts | 30 +++++++++++++++++++++ src/Writer.ts | 2 +- src/types.ts | 21 +++++++++++++++ 6 files changed, 107 insertions(+), 7 deletions(-) diff --git a/src/Reader.ts b/src/Reader.ts index ec93156..ab91c3b 100644 --- a/src/Reader.ts +++ b/src/Reader.ts @@ -2,9 +2,12 @@ import {decodeUtf8} from './utf8/decodeUtf8'; import type {IReader, IReaderResettable} from './types'; export class Reader implements IReader, IReaderResettable { - public uint8: Uint8Array = new Uint8Array([]); - public view: DataView = new DataView(this.uint8.buffer); - public x = 0; + constructor( + public uint8: Uint8Array = new Uint8Array([]), + public view: DataView = new DataView(uint8.buffer as ArrayBuffer, uint8.byteOffset, uint8.length), + public x: number = 0, + public end: number = uint8.length, + ) {} public reset(uint8: Uint8Array): void { this.x = 0; @@ -12,6 +15,10 @@ export class Reader implements IReader, IReaderResettable { this.view = new DataView(uint8.buffer as ArrayBuffer, uint8.byteOffset, uint8.length); } + public size(): number { + return this.end - this.x; + } + /** * Get current byte value without advancing the cursor. */ @@ -30,13 +37,46 @@ export class Reader implements IReader, IReaderResettable { this.x += length; } - public buf(size: number): Uint8Array { - const end = this.x + size; - const bin = this.uint8.subarray(this.x, end); + public buf(size: number = this.size()): Uint8Array { + const x = this.x; + const end = x + size; + const bin = this.uint8.subarray(x, end); this.x = end; return bin; } + /** + * Creates a new {@link Reader} that references the same underlying memory + * buffer. But with independent cursor and end. + * + * Preferred over {@link buf} since it also provides a DataView and is much + * faster to allocate a new {@link Slice} than a new {@link Uint8Array}. + * + * @param start Start offset relative to the current cursor position. + * @param end End offset relative to the current cursor position. + * @returns A new {@link Reader} instance. + */ + public slice(start: number = 0, end?: number): Reader { + const x = this.x; + const actualStart = x + start; + const actualEnd = typeof end === 'number' ? (x + end) : this.end; + return new Reader(this.uint8, this.view, actualStart, actualEnd); + } + + /** + * Similar to {@link slice} but also advances the cursor. Returns a new + * {@link Reader} that references the same underlying memory buffer, starting + * from the current cursor position. + * + * @param size Number of bytes to cut from the current position. + * @returns A new {@link Reader} instance. + */ + public cut(size: number = this.size()): Reader { + const slice = this.slice(0, size); + this.skip(size); + return slice; + } + public u8(): number { return this.uint8[this.x++]; // return this.view.getUint8(this.x++); diff --git a/src/Slice.ts b/src/Slice.ts index c0287b8..d174e63 100644 --- a/src/Slice.ts +++ b/src/Slice.ts @@ -1,3 +1,6 @@ +/** + * @deprecated Use {@link Reader} instead. + */ export class Slice { constructor( public readonly uint8: Uint8Array, diff --git a/src/StreamingOctetReader.ts b/src/StreamingOctetReader.ts index 5370e7b..3ebe073 100644 --- a/src/StreamingOctetReader.ts +++ b/src/StreamingOctetReader.ts @@ -1,5 +1,11 @@ const fromCharCode = String.fromCharCode; +/** + * A streaming reader which internally manages multiple chunks of + * Uint8Array instances. For performance it does not merge the chunks into + * a single Uint8Array instance. Instead it keeps track of the chunks and + * reads across chunk boundaries as needed. + */ export class StreamingOctetReader { protected readonly chunks: Uint8Array[] = []; diff --git a/src/StreamingReader.ts b/src/StreamingReader.ts index 34caac1..f2fcb93 100644 --- a/src/StreamingReader.ts +++ b/src/StreamingReader.ts @@ -1,6 +1,7 @@ import {Writer} from './Writer'; import {decodeUtf8} from './utf8/decodeUtf8'; import type {IReader, IReaderResettable} from './types'; +import {Reader} from './Reader'; export class StreamingReader implements IReader, IReaderResettable { protected readonly writer: Writer; @@ -94,6 +95,35 @@ export class StreamingReader implements IReader, IReaderResettable { return bin; } + /** + * Creates a new {@link Reader} that references the same underlying memory + * buffer. But with independent cursor and end. + * + * @param start Start offset relative to the current cursor position. + * @param end End offset relative to the current cursor position. + * @returns A new {@link Reader} instance. + */ + public slice(start: number = 0, end?: number): Reader { + const x = this.x; + const actualStart = x + start; + const actualEnd = typeof end === 'number' ? (x + end) : (this.size() + x - start); + return new Reader(this.uint8, this.view, actualStart, actualEnd); + } + + /** + * Similar to {@link slice} but also advances the cursor. Returns a new + * {@link Reader} that references the same underlying memory buffer, starting + * from the current cursor position. + * + * @param size Number of bytes to cut from the current position. + * @returns A new {@link Reader} instance. + */ + public cut(size: number = this.size()): Reader { + const slice = this.slice(0, size); + this.skip(size); + return slice; + } + public u8(): number { this.assertSize(1); return this.view.getUint8(this.x++); diff --git a/src/Writer.ts b/src/Writer.ts index 8b96de2..956abec 100644 --- a/src/Writer.ts +++ b/src/Writer.ts @@ -12,7 +12,7 @@ const from = hasBuffer ? Buffer.from : null; const textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null; /** - * Encoder class provides an efficient way to encode binary data. It grows the + * Writer class provides an efficient way to encode binary data. It grows the * internal memory buffer automatically as more space is required. It is useful * in cases when it is not known in advance the size of memory needed. */ diff --git a/src/types.ts b/src/types.ts index 2345713..f580fd0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ +import {Reader} from './Reader'; import type {Slice} from './Slice'; export interface IWriter { @@ -70,6 +71,26 @@ export interface IWriterGrowable { } export interface IReaderBase { + /** + * Creates a new {@link IReaderBase} that references the same underlying memory + * buffer. But with independent cursor and end. + * + * @param start Start offset relative to the current cursor position. + * @param end End offset relative to the current cursor position. + * @returns A new {@link IReaderBase} instance. + */ + slice(start?: number, end?: number): IReaderBase; + + /** + * Similar to {@link slice} but also advances the cursor. Returns a new + * {@link IReaderBase} that references the same underlying memory buffer, starting + * from the current cursor position. + * + * @param size Number of bytes to cut from the current position. + * @returns A new {@link IReaderBase} instance. + */ + cut(size?: number): IReaderBase; + /** Get current byte value without advancing the cursor. */ peek(): number; From 9bc1e87bb8208c09010158dfcc828691202244c0 Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 7 Oct 2025 20:12:09 +0200 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20make=20.buf()=20para?= =?UTF-8?q?meter=20optional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StreamingReader.ts | 2 +- src/__tests__/Reader.slice-cut.spec.ts | 298 +++++++++++++++++++++++++ src/types.ts | 6 +- 3 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 src/__tests__/Reader.slice-cut.spec.ts diff --git a/src/StreamingReader.ts b/src/StreamingReader.ts index f2fcb93..9428291 100644 --- a/src/StreamingReader.ts +++ b/src/StreamingReader.ts @@ -87,7 +87,7 @@ export class StreamingReader implements IReader, IReaderResettable { this.x += length; } - public buf(size: number): Uint8Array { + public buf(size: number = this.size()): Uint8Array { this.assertSize(size); const end = this.x + size; const bin = this.uint8.subarray(this.x, end); diff --git a/src/__tests__/Reader.slice-cut.spec.ts b/src/__tests__/Reader.slice-cut.spec.ts new file mode 100644 index 0000000..847e8da --- /dev/null +++ b/src/__tests__/Reader.slice-cut.spec.ts @@ -0,0 +1,298 @@ +import {Reader} from '../Reader'; + +describe('Reader.slice() and Reader.cut() methods', () => { + describe('slice()', () => { + test('creates a new Reader with independent cursor', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); + const slice = reader.slice(); + // slice starts at the same absolute position as reader + expect(slice.x).toBe(0); + expect(slice.u8()).toBe(1); + expect(slice.x).toBe(1); + // original reader's cursor should not be affected + expect(reader.x).toBe(0); + expect(reader.u8()).toBe(1); + expect(reader.x).toBe(1); + }); + + test('slice with no arguments returns full remaining buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + reader.skip(2); // advance to position 2 + const slice = reader.slice(); + // slice starts at reader's current position and goes to end + expect(slice.x).toBe(2); + expect(slice.end).toBe(5); + expect(slice.size()).toBe(3); + expect(slice.buf()).toEqual(new Uint8Array([3, 4, 5])); + }); + + test('slice with start offset', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const slice = reader.slice(2); + expect(slice.x).toBe(2); + expect(slice.buf()).toEqual(new Uint8Array([3, 4, 5, 6, 7, 8])); + }); + + test('slice with start and end offsets', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const slice = reader.slice(2, 5); + expect(slice.x).toBe(2); + expect(slice.size()).toBe(3); + expect(slice.buf()).toEqual(new Uint8Array([3, 4, 5])); + }); + + test('slice after advancing cursor', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + reader.skip(2); // position is now at index 2 (value 3) + const slice = reader.slice(1, 3); + // slice should start at reader.x + 1 = 3, end at reader.x + 3 = 5 + expect(slice.x).toBe(3); + expect(slice.size()).toBe(2); + expect(slice.buf()).toEqual(new Uint8Array([4, 5])); + }); + + test('slice does not advance original reader cursor', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + const slice = reader.slice(1, 3); + slice.u8(); + expect(reader.x).toBe(0); + }); + + test('slice shares underlying buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + const slice = reader.slice(); + // Both should reference the same underlying Uint8Array + expect(slice.uint8).toBe(reader.uint8); + expect(slice.view).toBe(reader.view); + }); + + test('multiple slices are independent', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const slice1 = reader.slice(0, 4); + const slice2 = reader.slice(4, 8); + expect(slice1.u8()).toBe(1); + expect(slice2.u8()).toBe(5); + expect(slice1.u8()).toBe(2); + expect(slice2.u8()).toBe(6); + }); + + test('slice with size() for bounds', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + reader.skip(1); + const slice = reader.slice(); + expect(slice.x).toBe(1); + expect(slice.size()).toBe(4); + expect(slice.u8()).toBe(2); + }); + }); + + describe('cut()', () => { + test('creates slice and advances cursor', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + const cut = reader.cut(3); + // cut should contain first 3 bytes, starting at position 0 + expect(cut.x).toBe(0); + expect(cut.end).toBe(3); + expect(cut.size()).toBe(3); + expect(cut.u8()).toBe(1); + expect(cut.u8()).toBe(2); + expect(cut.u8()).toBe(3); + // original reader cursor should advance by 3 + expect(reader.x).toBe(3); + expect(reader.u8()).toBe(4); + }); + + test('cut with no arguments cuts entire remaining buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + reader.skip(2); + const cut = reader.cut(); + expect(cut.x).toBe(2); + expect(cut.size()).toBe(3); + expect(cut.u8()).toBe(3); + expect(cut.u8()).toBe(4); + expect(cut.u8()).toBe(5); + // original reader should be at the end + expect(reader.x).toBe(5); + expect(reader.size()).toBe(0); + }); + + test('multiple cuts partition the buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const cut1 = reader.cut(2); + const cut2 = reader.cut(3); + const cut3 = reader.cut(3); + + expect(cut1.x).toBe(0); + expect(cut1.u8()).toBe(1); + expect(cut1.u8()).toBe(2); + + expect(cut2.x).toBe(2); + expect(cut2.u8()).toBe(3); + expect(cut2.u8()).toBe(4); + expect(cut2.u8()).toBe(5); + + expect(cut3.x).toBe(5); + expect(cut3.u8()).toBe(6); + expect(cut3.u8()).toBe(7); + expect(cut3.u8()).toBe(8); + + expect(reader.x).toBe(8); + expect(reader.size()).toBe(0); + }); + + test('cut returns independent Reader instance', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + const cut = reader.cut(2); + cut.u8(); // advance cut cursor + expect(reader.x).toBe(2); + expect(cut.x).toBe(1); + expect(reader.buf()).toEqual(new Uint8Array([3, 4, 5])); + }); + + test('cut shares underlying buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5])); + const cut = reader.cut(3); + // Both should reference the same underlying Uint8Array + expect(cut.uint8).toBe(reader.uint8); + expect(cut.view).toBe(reader.view); + }); + + test('cut can be used to parse structured data', () => { + const reader = new Reader(new Uint8Array([3, 1, 2, 3, 2, 4, 5])); + // Simulate a binary format with length-prefixed chunks + // [length: 3][data: 1,2,3][length: 2][data: 4,5] + + const len1 = reader.u8(); + const chunk1 = reader.cut(len1); + + const len2 = reader.u8(); + const chunk2 = reader.cut(len2); + + expect(chunk1.x).toBe(1); + expect(chunk1.size()).toBe(3); + expect(chunk1.u8()).toBe(1); + expect(chunk1.u8()).toBe(2); + expect(chunk1.u8()).toBe(3); + + expect(chunk2.x).toBe(5); + expect(chunk2.size()).toBe(2); + expect(chunk2.u8()).toBe(4); + expect(chunk2.u8()).toBe(5); + + expect(reader.x).toBe(7); + expect(reader.size()).toBe(0); + }); + + test('cut with size zero', () => { + const reader = new Reader(new Uint8Array([1, 2, 3])); + const cut = reader.cut(0); + expect(cut.size()).toBe(0); + expect(reader.x).toBe(0); + expect(reader.u8()).toBe(1); + }); + }); + + describe('slice() and cut() integration', () => { + test('slice then cut', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const slice = reader.slice(2, 6); // [3, 4, 5, 6] + const cut = slice.cut(2); // [3, 4] + + expect(cut.u8()).toBe(3); + expect(cut.u8()).toBe(4); + expect(slice.u8()).toBe(5); + expect(slice.u8()).toBe(6); + + // original reader should be unaffected + expect(reader.x).toBe(0); + }); + + test('cut then slice', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + const cut = reader.cut(4); + const slice = cut.slice(1, 3); + + expect(slice.u8()).toBe(2); + expect(slice.u8()).toBe(3); + + expect(reader.x).toBe(4); + expect(reader.u8()).toBe(5); + }); + + test('nested cuts', () => { + const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6])); + const outer = reader.cut(6); + const inner1 = outer.cut(2); + const inner2 = outer.cut(2); + const inner3 = outer.cut(2); + + expect(inner1.u8()).toBe(1); + expect(inner1.u8()).toBe(2); + + expect(inner2.u8()).toBe(3); + expect(inner2.u8()).toBe(4); + + expect(inner3.u8()).toBe(5); + expect(inner3.u8()).toBe(6); + }); + }); + + describe('DataView access in slices and cuts', () => { + test('slice can use DataView methods', () => { + const reader = new Reader(new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06])); + const slice = reader.slice(0, 4); + expect(slice.u16()).toBe(0x0102); + expect(slice.u16()).toBe(0x0304); + }); + + test('cut can use DataView methods', () => { + const reader = new Reader(new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06])); + const cut = reader.cut(4); + expect(cut.u16()).toBe(0x0102); + expect(cut.u16()).toBe(0x0304); + expect(reader.u16()).toBe(0x0506); + }); + + test('slice with u32 reads', () => { + const buffer = new Uint8Array(8); + const view = new DataView(buffer.buffer); + view.setUint32(0, 0x12345678); + view.setUint32(4, 0x9ABCDEF0); + const reader = new Reader(buffer); + const slice = reader.slice(0, 8); + expect(slice.u32()).toBe(0x12345678); + expect(slice.u32()).toBe(0x9ABCDEF0); + }); + }); + + describe('edge cases', () => { + test('slice at the end of buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3])); + reader.skip(3); + const slice = reader.slice(); + expect(slice.x).toBe(3); + expect(slice.size()).toBe(0); + }); + + test('cut at the end of buffer', () => { + const reader = new Reader(new Uint8Array([1, 2, 3])); + reader.skip(3); + const cut = reader.cut(); + expect(cut.x).toBe(3); + expect(cut.size()).toBe(0); + expect(reader.size()).toBe(0); + }); + + test('empty reader slice', () => { + const reader = new Reader(new Uint8Array([])); + const slice = reader.slice(); + expect(slice.size()).toBe(0); + }); + + test('empty reader cut', () => { + const reader = new Reader(new Uint8Array([])); + const cut = reader.cut(); + expect(cut.size()).toBe(0); + }); + }); +}); diff --git a/src/types.ts b/src/types.ts index f580fd0..9f50107 100644 --- a/src/types.ts +++ b/src/types.ts @@ -106,8 +106,12 @@ export interface IReaderBase { /** * Create a new Uint8Array view of provided length starting at * the current cursor position. + * + * If size is not provided, it will return a view of all remaining bytes. + * + * @param size Length of the returned Uint8Array. */ - buf(size: number): Uint8Array; + buf(size?: number): Uint8Array; u8(): number; i8(): number; From b80a5280da0d5d8203d1b6af93ea206b85e7ce95 Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 7 Oct 2025 20:12:40 +0200 Subject: [PATCH 3/3] =?UTF-8?q?style:=20=F0=9F=92=84=20run=20Prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Reader.ts | 4 +-- src/StreamingReader.ts | 2 +- src/__tests__/Reader.slice-cut.spec.ts | 34 +++++++++++++------------- src/types.ts | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Reader.ts b/src/Reader.ts index ab91c3b..697a524 100644 --- a/src/Reader.ts +++ b/src/Reader.ts @@ -48,7 +48,7 @@ export class Reader implements IReader, IReaderResettable { /** * Creates a new {@link Reader} that references the same underlying memory * buffer. But with independent cursor and end. - * + * * Preferred over {@link buf} since it also provides a DataView and is much * faster to allocate a new {@link Slice} than a new {@link Uint8Array}. * @@ -59,7 +59,7 @@ export class Reader implements IReader, IReaderResettable { public slice(start: number = 0, end?: number): Reader { const x = this.x; const actualStart = x + start; - const actualEnd = typeof end === 'number' ? (x + end) : this.end; + const actualEnd = typeof end === 'number' ? x + end : this.end; return new Reader(this.uint8, this.view, actualStart, actualEnd); } diff --git a/src/StreamingReader.ts b/src/StreamingReader.ts index 9428291..28292e3 100644 --- a/src/StreamingReader.ts +++ b/src/StreamingReader.ts @@ -106,7 +106,7 @@ export class StreamingReader implements IReader, IReaderResettable { public slice(start: number = 0, end?: number): Reader { const x = this.x; const actualStart = x + start; - const actualEnd = typeof end === 'number' ? (x + end) : (this.size() + x - start); + const actualEnd = typeof end === 'number' ? x + end : this.size() + x - start; return new Reader(this.uint8, this.view, actualStart, actualEnd); } diff --git a/src/__tests__/Reader.slice-cut.spec.ts b/src/__tests__/Reader.slice-cut.spec.ts index 847e8da..f6268b4 100644 --- a/src/__tests__/Reader.slice-cut.spec.ts +++ b/src/__tests__/Reader.slice-cut.spec.ts @@ -125,17 +125,17 @@ describe('Reader.slice() and Reader.cut() methods', () => { expect(cut1.x).toBe(0); expect(cut1.u8()).toBe(1); expect(cut1.u8()).toBe(2); - + expect(cut2.x).toBe(2); expect(cut2.u8()).toBe(3); expect(cut2.u8()).toBe(4); expect(cut2.u8()).toBe(5); - + expect(cut3.x).toBe(5); expect(cut3.u8()).toBe(6); expect(cut3.u8()).toBe(7); expect(cut3.u8()).toBe(8); - + expect(reader.x).toBe(8); expect(reader.size()).toBe(0); }); @@ -161,24 +161,24 @@ describe('Reader.slice() and Reader.cut() methods', () => { const reader = new Reader(new Uint8Array([3, 1, 2, 3, 2, 4, 5])); // Simulate a binary format with length-prefixed chunks // [length: 3][data: 1,2,3][length: 2][data: 4,5] - + const len1 = reader.u8(); const chunk1 = reader.cut(len1); - + const len2 = reader.u8(); const chunk2 = reader.cut(len2); - + expect(chunk1.x).toBe(1); expect(chunk1.size()).toBe(3); expect(chunk1.u8()).toBe(1); expect(chunk1.u8()).toBe(2); expect(chunk1.u8()).toBe(3); - + expect(chunk2.x).toBe(5); expect(chunk2.size()).toBe(2); expect(chunk2.u8()).toBe(4); expect(chunk2.u8()).toBe(5); - + expect(reader.x).toBe(7); expect(reader.size()).toBe(0); }); @@ -197,12 +197,12 @@ describe('Reader.slice() and Reader.cut() methods', () => { const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); const slice = reader.slice(2, 6); // [3, 4, 5, 6] const cut = slice.cut(2); // [3, 4] - + expect(cut.u8()).toBe(3); expect(cut.u8()).toBe(4); expect(slice.u8()).toBe(5); expect(slice.u8()).toBe(6); - + // original reader should be unaffected expect(reader.x).toBe(0); }); @@ -211,10 +211,10 @@ describe('Reader.slice() and Reader.cut() methods', () => { const reader = new Reader(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); const cut = reader.cut(4); const slice = cut.slice(1, 3); - + expect(slice.u8()).toBe(2); expect(slice.u8()).toBe(3); - + expect(reader.x).toBe(4); expect(reader.u8()).toBe(5); }); @@ -225,13 +225,13 @@ describe('Reader.slice() and Reader.cut() methods', () => { const inner1 = outer.cut(2); const inner2 = outer.cut(2); const inner3 = outer.cut(2); - + expect(inner1.u8()).toBe(1); expect(inner1.u8()).toBe(2); - + expect(inner2.u8()).toBe(3); expect(inner2.u8()).toBe(4); - + expect(inner3.u8()).toBe(5); expect(inner3.u8()).toBe(6); }); @@ -257,11 +257,11 @@ describe('Reader.slice() and Reader.cut() methods', () => { const buffer = new Uint8Array(8); const view = new DataView(buffer.buffer); view.setUint32(0, 0x12345678); - view.setUint32(4, 0x9ABCDEF0); + view.setUint32(4, 0x9abcdef0); const reader = new Reader(buffer); const slice = reader.slice(0, 8); expect(slice.u32()).toBe(0x12345678); - expect(slice.u32()).toBe(0x9ABCDEF0); + expect(slice.u32()).toBe(0x9abcdef0); }); }); diff --git a/src/types.ts b/src/types.ts index 9f50107..d891134 100644 --- a/src/types.ts +++ b/src/types.ts @@ -106,7 +106,7 @@ export interface IReaderBase { /** * Create a new Uint8Array view of provided length starting at * the current cursor position. - * + * * If size is not provided, it will return a view of all remaining bytes. * * @param size Length of the returned Uint8Array.