Skip to content

prideout/flatbin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

flatbin is a tiny BSD-licensed utility that makes it easy to parse ArrayBuffer objects, especially when they have a flatbuffers layout.

Rationale

If you're a WebGL developer, you often want to request binary data from the server, and extract some typed arrays from it, along with some metadata:

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/graphics_data.bin', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
    var arraybuffer = this.response;
    // Hey, this is where I can use flatbin!
};

xhr.send();

Examples

Let's say the first two words in your binary chunk are little-endian 16-bit words, followed by a float. Here's how you can extract 'em:

var reader = new FLATBIN.Reader(this.response),
    width  = reader.uint16(),
    height = reader.uint16();
    coolness = reader.float32();

Suppose the binary starts with a magic 4-byte identifier, followed by uint32 count, followed by that many floats. You want those floats in a typed array that you can pass straight to WebGL. Easy:

var reader = new FLATBIN.Reader(this.response),
    magic  = reader.uint32(),
    floats = reader.vector(Float32Array);

The vector method assumes you're requesting a swath of data that has been prefixed with a uint32 length.

By the way, that was a zero-copy operation! The backing store of the returned typed array is the array buffer that was used to construct Reader.

What if the encoded length value is actually a count of 3-tuples instead of scalars? Easy:

var coordinates  = reader.vector(Float32Array, 3);

How about length-prefixed strings? Also easy:

var firstName = reader.string(),
    lastName  = reader.string();

Strings must be encoded using 8-bit ASCII characters. They have a length prefix and a null-terminator. If you need unicode support, you'll probably want to use a vector of 32-bit unsigned integers instead. Or, you might consider using a more business-like protocol like JSON. :)

Structs

flatbin lets you define simple POD structures:

// Declare a struct type.
reader.registerStruct('Rocket', [
    'id', reader.uint32,
    'velocity', reader.float32,
    'weight', reader.float32
]);

// Extract an instance of the struct.
var myRocket = reader.object('Rocket');
console.info(myRocket.id, myRocket.velocity);

The second argument to registerStruct is a flat list of string-function pairs, not an object literal. We want it to be clear that order is significant.

You can also extract a size-prefixed array of structs:

var rockets  = reader.vector('Rocket');

Structs can be nested:

reader.registerStruct('Rocket', [
    'velocity', reader.float32,
    'engine', reader.object.bind(reader, 'Engine']
]);

Structs cannot contain vectors or strings, which brings us to...

Tables

The object method an be used to parse both struct types and table types. Tables are registered in a similar way, but they're encoded a bit differently:

reader.registerTable('Rocket', [
    'id', reader.uint32,
    'engines', reader.vector.bind(reader, 'Engine')
    'data', reader.vector.bind(reader, Uint16Array, 3),
]);

var myRocket = reader.object('Rocket');
consle.info(myRocket.engines);

See the flatbuffers for more information about how tables are laid out in memory.

About

Tiny JavaScript utility for parsing simple binary files.

Resources

License

Stars

Watchers

Forks

Packages

No packages published