Skip to content

Commit

Permalink
Make skip() return the ByteStream, for chaining. Document the tee() m…
Browse files Browse the repository at this point in the history
…ethod.
  • Loading branch information
codedread committed Jan 4, 2024
1 parent b72e629 commit 208b69a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
26 changes: 21 additions & 5 deletions docs/bitjs.io.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,38 @@ 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);
...
```

### 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)`.
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
```
2 changes: 2 additions & 0 deletions io/bytestream.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -313,6 +314,7 @@ export class ByteStream {
}

this.movePointer_(n);
return this;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions tests/io-bytestream.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 208b69a

Please sign in to comment.