Parse and consume binary streams with a neat DSL
npm install raptor-dissolveDissolve
========
This is a fork of https://github.com/deoxxa/dissolve with minor updates.
Parse and consume binary streams with a neat DSL.
Overview
--------
Dissolve allows you to parse packed binary data into numbers, buffers, strings
and more*! With a simple syntax inspired by node-binary
and a solid, minimal implementation, you can be up and running in no time.
(* implementing "more" is left as an exercise to the reader)
If you want to produce binary data, might I suggest concentrate?
Features
--------
* Accurate handling of [u]int{8,16,32} numbers in both signed and unsigned
variants using fast, built-in Buffer
methods
* Fast approximation of [u]int64 numbers in signed and unsigned variants
* Extendable base class for building your own parsers and implementing
custom types
* Tiny (~250 LoC) implementation, allowing for easy debugging
Installation
------------
Available via npm:
> $ npm install dissolve
Or via git:
> $ git clone git://github.com/deoxxa/dissolve.git node_modules/dissolve
Usage
-----
Also see example.js,
example-complex.js
and example-loop.js.
``javascript
#!/usr/bin/env node
var Dissolve = require("./index");
var parser = Dissolve().loop(function(end) {
this.uint8("id").tap(function() {
if (this.vars.id === 0x01) {
this.uint16be("a").uint16be("b");
} else if (this.vars.id === 0x02) {
this.uint32be("x").uint32be("y");
}
}).tap(function() {
this.push(this.vars);
this.vars = {};
});
});
parser.on("readable", function() {
var e;
while (e = parser.read()) {
console.log(e);
}
});
parser.write(new Buffer([0x01, 0x00, 0x02, 0x00, 0x03])); // {id: 1, a: 2, b: 3}
parser.write(new Buffer([0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05])); // {id: 2, x: 4, y: 5}
parser.write(new Buffer([0x01]));
parser.write(new Buffer([0x00, 0x02, 0x00]));
parser.write(new Buffer([0x03])); // {id: 1, a: 2, b: 3}
`
Methods
-------
All parser methods are chainable and return the same parser instance they were
called on.
Tap
---
tap(name, callback)
This method allows you to "tap" into the parser at an arbitrary point. The
callback will be called bound to the parser instance, so you can use parser
methods on this. Any additional parser steps you introduce inside the callbacktap
will be executed before any existing steps that are already scheduled to run
after the call.
If you provide a name parameter, all actions performed in the callback will bename
applied to a child object that will be put into a new property named after. Note that in the callback, even if you provide a name parameter, youvars
can still pretend you were in the outer "scope" because of some prototype
trickery done with the object under the hood. You don't need to worry
about that too much, the examples should make it a bit clearer.
Loop
----
loop(name, callback)
This method is like tap except that the callback is called over and over untilend
signalled to stop. You do this by calling the function that's provided asend
the first argument to your callback. When you call the function, you canend
provide an optional truthy/non-truthy flag to tell Dissolve to ignore the result
of the iteration of the loop where was called. This is useful if you are
reading until a null entry or similar.
If you provide a name parameter, a new array will be placed into a propertyname
named for that parameter, and after each iteration of the loop, any new values
will be appended to the array as an object. As with the stuff on tap,
the examples will make that explanation a lot clearer.
The same semantics for job ordering and "scoping" apply as for tap.
Basic Parsing Methods
---------------------
For each basic parsing method, the name value is the key under which the valuethis.vars
will be attached to .
Buffer/String Methods
---------------------
For these methods, the length parameter tells the parser how many bytes tothis.vars
pull out. If it's a string, it will be assumed that it is the name of a
previously-set entry. If it's a number, it will be used as-is.
* buffer(name, length) - binary slicestring(name, length)
* - utf8 string sliceskip(length)
* - skip length bytes
Numeric Methods
---------------
* int8(name) - signed 8 bit integersint8(name)
* - signed 8 bit integeruint8(name)
* - unsigned 8 bit integerint16(name)
* - signed, little endian 16 bit integerint16le(name)
* - signed, little endian 16 bit integerint16be(name)
* - signed, big endian 16 bit integersint16(name)
* - signed, little endian 16 bit integersint16le(name)
* - signed, little endian 16 bit integersint16be(name)
* - signed, big endian 16 bit integeruint16(name)
* - unsigned, little endian 16 bit integeruint16le(name)
* - unsigned, little endian 16 bit integeruint16be(name)
* - unsigned, big endian 16 bit integerint32(name)
* - signed, little endian 32 bit integerint32le(name)
* - signed, little endian 32 bit integerint32be(name)
* - signed, big endian 32 bit integersint32(name)
* - signed, little endian 32 bit integersint32le(name)
* - signed, little endian 32 bit integersint32be(name)
* - signed, big endian 32 bit integeruint32(name)
* - unsigned, little endian 32 bit integeruint32le(name)
* - unsigned, little endian 32 bit integeruint32be(name)
* - unsigned, big endian 32 bit integerint64(name)
* - signed, little endian 64 bit integerint64le(name)
* - signed, little endian 64 bit integerint64be(name)
* - signed, big endian 64 bit integersint64(name)
* - signed, little endian 64 bit integersint64le(name)
* - signed, little endian 64 bit integersint64be(name)
* - signed, big endian 64 bit integeruint64(name)
* - unsigned, little endian 64 bit integeruint64le(name)
* - unsigned, little endian 64 bit integeruint64be(name)
* - unsigned, big endian 64 bit integerfloatbe(data)
* - big endian 32 bit floatfloatle(data)
* - little endian 32 bit floatdoublebe(data)
* - big endian 64 bit doubledoublele(data)` - little endian 64 bit double
*
License
-------
3-clause BSD. A copy is included with the source.
Contact
-------
* GitHub (deoxxa)
* Twitter (@deoxxa)
* ADN (@deoxxa)
* Email (deoxxa@fknsrs.biz)