Looks awesome and conveniently designed! Am I understanding that `/* pseudocode */ el = MyElement.read( 0b111010101 ) && console.log( json.dump(el) );` would do what's expected?
The library has both imperative and declarative mechanisms for reading bits- The BitstreamReader class provides all the read*() methods and the elements provide a way to declare fields (ie "structural"), and use BitstreamReader to accomplish that.
For bitstreamReader.read(), the first parameter is the number of bits to read. So for example:
import { BitstreamReader } from '@astronautlabs/bitstream';
let reader = new BitstreamReader();
reader.addBuffer(Buffer.from([0b11101010, 0b10000000]));
let value = reader.readSync(9);
expect(value).to.equal(0b111010101);
Conversely for writing with BitstreamWriter you can do:
import { BufferedWritable, WritableStream } from '@astronautlabs/bitstream';
let writable = new BufferedWritable();
let writer = new BitstreamWriter(writable);
writer.write(9, 0b111010101);
expect(writable.buffer.length).to.equal(1); // because the last bit isn't a full byte
writer.write(7, 0);
expect(writable.buffer.length).to.equal(2);
expect(Array.from(writable.buffer)).to.eql([0b11101010, 0b10000000]);
Using Bitstream Elements you would do
import { BitstreamElement } from '@astronautlabs/bitstream';
class MyElement extends BitstreamElement {
@Field(9) value : number;
}
expect(MyElement.deserialize(Buffer.from([0b11101010, 0b10000000])).value).to.equal(0b111010101) // with 7 bits left
expect(Array.from(new MyElement().with({ value: 0b111010101 }).serialize())).to.eql([0b11101010, 0b10000000])