Zero-dependency utilities for reading/writing binary data in JavaScript.
View full documentation at frankkulak.com/binary-coding.
Notes
- This package is for Node, but is compatible with browserify.
- This package is a replacement for @s4tk/encoding, and is completely backwards compatible with it (some methods are deprecated, but still work, so you just have to swap out imports).
Instead of this:
// Encoding
let offset = 0;
const buffer = Buffer.alloc(size);
buffer.write(header, offset, 4);
offset += 4;
buffer.writeUInt16LE(version, offset);
offset += 2;
// Decoding
let offset = 0;
const header = buffer.toString("utf-8", offset, 4);
offset += 4;
const version = buffer.readUInt16LE(offset);
offset += 2;
Do this:
// Encoding
const encoder = BinaryEncoder.alloc(size);
encoder.chars(header);
encoder.uint16(version);
// Decoding
const decoder = new BinaryDecoder(buffer);
const header = decoder.chars(4);
const version = decoder.uint16();
Quick Facts
- All the primitives you'd expect are supported: bytes, bools, chars, signed/unsigned 8/16/32/64-bit ints, floats, and doubles.
- There are options for easily reading/writing more complex types, like null-terminated strings and bit-masked uints.
- Both little and big endianness are supported, and you can switch between them.
- The encoder/decoder automatically track the offset, but it can be manually set if needed.
- The encoder supports dynamically growing as values are written, if needed.
This package is available on npm:
npm i binary-coding
Both ES modules and CommonJS are supported:
import { BinaryEncoder, BinaryDecoder } from "binary-coding";
const { BinaryEncoder, BinaryDecoder } = require("binary-coding");
To decode data in a buffer, create a BinaryDecoder
:
// by default, it uses little endian - but this can be configured
const decoder = new BinaryDecoder(buffer);
Once you have the decoder, simply call its methods:
const header = decoder.chars(4);
const version = decoder.uint16();
decoder.skip(2); // skip over some unneeded metadata
const numEntries = decoder.uint32();
const entries = decoder.iterate(numEntries, () => {
const hash = decoder.uint64();
const value = decoder.terminatedString();
return { hash, value };
});
There are multiple ways to create a BinaryEncoder
:
- Its constructor.
- The static
alloc()
method. - The static
dynamicallySized()
method.
When performance is critical, it is highly recommended to pre-calculate the total length of the buffer and create the encoder using that size, such as:
const encoder = new BinaryEncoder(Buffer.alloc(size));
Or, for short:
const encoder = BinaryEncoder.alloc(size);
When performance isn't as important as ease of writing code, the encoder can figure its size out as you write to it:
const encoder = BinaryEncoder.dynamicallySized(encoder => {
// write your data here
});
However you choose to create your encoder, you can write data just as simply as reading it:
encoder.chars(header);
encoder.uint16(version);
encoder.null(2); // make the metadata blank
encoder.uint32(entries.length);
entries.forEach(({ hash, value }) => {
encoder.uint64(hash);
encoder.terminatedString(value);
});
Finally, when it's time to get your encoded buffer, just access the buffer property:
const buffer = encoder.buffer;