From 208b69a65d2ef2164b939ceeaaf4193e7d55c68e Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Thu, 4 Jan 2024 22:39:25 +0900 Subject: [PATCH] Make skip() return the ByteStream, for chaining. Document the tee() method. --- docs/bitjs.io.md | 26 +++++++++++++++++++++----- io/bytestream.js | 2 ++ tests/io-bytestream.spec.js | 6 ++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/bitjs.io.md b/docs/bitjs.io.md index 4da06cf..cd76c87 100644 --- a/docs/bitjs.io.md +++ b/docs/bitjs.io.md @@ -42,16 +42,17 @@ interpreting 2 bytes in the stream as a number is done by calling `someByteStrea default, the byte stream is considered Little Endian, but can be changed at any point using `someByteStream.setBigEndian()` and toggled back with `someByteStream.setLittleEndian()`. -By default, numbers are unsigned, but `peekSignedNumber(n)` and `readSignedNumber(n)` exist for signed numbers. +By default, numbers are unsigned, but `peekSignedNumber(n)` and `readSignedNumber(n)` exist for +signed numbers. ```javascript const byteStream = new ByteStream(someArrayBuffer); byteStream.setBigEndian(); - byteStream.readNumber(2); // skip two bytes. + byteStream.skip(2); // skip two bytes. // Interpret next 2 bytes as the string length. const strLen = byteStream.readNumber(2); // Read in bytes as an ASCII string. - const someString = byteStream.readNumber(strLen); + const someString = byteStream.readString(strLen); // Interpret next byte as an int8 (0xFF would be -1). const someVal = byteStream.readSignedNumber(1); ... @@ -59,5 +60,20 @@ By default, numbers are unsigned, but `peekSignedNumber(n)` and `readSignedNumbe ### Appending to the Stream -If you get more bytes (for example, from an asynchronous process), you can add them to the end of the -byte stream by using `someByteStream.push(nextBytesAsAnArrayBuffer)`. \ No newline at end of file +If you get more bytes (for example, from an asynchronous process), you can add them to the end of +the byte stream by using `someByteStream.push(nextBytesAsAnArrayBuffer)`. + +### Forking / Teeing the stream. + +If you have a need to seek ahead to a different section of the stream of bytes, and want to later +return to where you left off, you should use `tee()` method to make a copy of the ByteStream. This +will let you seek to the appropriate spot to grab some bytes. + +```javascript + const byteStream = new ByteStream(someArrayBuffer); + const strLen = byteStream.readNumber(4); // Bytes 0-3. + const strOffset = byteStream.readNumber(4); // Bytes 4-7. + // Grab bytes at that offset... + const description = byteStream.tee().skip(offset).readString(strLen); + const someOtherVal = byteStream.readNumber(4); // Bytes 8-11 +``` \ No newline at end of file diff --git a/io/bytestream.js b/io/bytestream.js index 54c16cb..b7b4e29 100644 --- a/io/bytestream.js +++ b/io/bytestream.js @@ -297,6 +297,7 @@ export class ByteStream { /** * Skips n bytes in the stream. * @param {number} n The number of bytes to skip. Must be a positive integer. + * @returns {ByteStream} Returns this ByteStream for chaining. */ skip(n) { const num = parseInt(n, 10); @@ -313,6 +314,7 @@ export class ByteStream { } this.movePointer_(n); + return this; } /** diff --git a/tests/io-bytestream.spec.js b/tests/io-bytestream.spec.js index 6d74f7f..658ca40 100644 --- a/tests/io-bytestream.spec.js +++ b/tests/io-bytestream.spec.js @@ -219,6 +219,11 @@ describe('bitjs.io.ByteStream', () => { expect(stream.readNumber(1)).equals(3); }); + it('returns itself', () => { + const retVal = stream.skip(2); + expect(stream === retVal).equals(true); + }); + it('skip(0) has no effect', () => { stream.skip(0); expect(stream.getNumBytesRead()).equals(0); @@ -256,6 +261,7 @@ describe('bitjs.io.ByteStream', () => { stream.push(anotherArray.buffer); const teed = stream.tee(); + expect(teed !== stream).equals(true); teed.readBytes(5); expect(stream.getNumBytesLeft()).equals(8); expect(teed.getNumBytesLeft()).equals(3);