BitSparrow

BitSparrow.io

Efficient cross-platform data

Encode

var Encoder = require('bitsparrow').Encoder;

var buffer = new Encoder()
                 .uint8(20)
                 .string('Hello World!')
                 .float32(42.1337)
                 .end();

console.log(buffer);
// -> [0x14, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
//     0x6f, 0x72, 0x6c, 0x64, 0x21, 0x42, 0x28, 0x88, 0xe9]

Note: BitSparrow will automatically use Buffer type within Node.js or Uint8Array when used in a web browser.

Decode

extern crate bitsparrow;
use bitsparrow::Decoder;

fn main() {
    // Same buffer we got from JavaScript
    let buffer = &[0x14, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
                   0x6f, 0x72, 0x6c, 0x64, 0x21, 0x42, 0x28, 0x88, 0xe9];

    let mut decoder = Decoder::new(buffer);
    println!("{}", decoder.uint8().unwrap()); // 20
    println!("{}", decoder.string().unwrap()); // Hello World!
    println!("{}", decoder.float32().unwrap()); // ~42.1337
}

Profit!

Representing same data in JSON would read [20,"Hello World!",42.1337] and be 27 bytes long. Encoding that in MessagePack cuts it down to 24 bytes. Static typed record in BitSparrow is only 18 bytes and encodes faster. Even upgrading float32 to float64 keeps BitSparrow ahead with 22 bytes.

Strings don't compress well though, how about booleans? JSON array of [true,true,false,false,true] is 28 bytes, MessagePack cuts it down to 6. Since BitSparrow doesn't mark types on data, it can pack those 5 booleans on a single byte, and still have room for 3 more.

Types

Endianness

To keep things compatible between platforms, when encoding to binary data all types described below are saved as big-endian.

uint8, uint16, uint32, uint64

Unsigned 8, 16, 32 and 64 bit integers.

int8, int16, int32, int64

Signed 8, 16, 32 and 64 bit integers.

float32, float64

Single and double precision IEEE 754 floating point numbers.

bool

Simple true or false boolean. BitSparrow can stack up to 8 bools on a single byte when pushed to the buffer in a row.

size

Adaptive unsigned integer type that takes more volume the larger the value. Number of leading 1 bits determines how many bytes this type takes.

Usable volume Binary representation
7 bits 0
14 bits 10
21 bits 110
28 bits 1110
35 bits 11110
42 bits 111110
49 bits 1111110
56 bits 11111110
64 bits 11111111

bytes

Variable-length byte buffer. Each bytes type is internally prefixed by a size matching it's length, ensuring minimal overhead.

string

Variable-length UTF-8 encoded string of characters. Analog to the bytes type, string is prefixed by a size matching it's length in bytes.

Supported languages

JavaScript

Rust

Didn't find your language?

If you implement BitSparrow in another language, contact me on GitHub to add it to the list here!