npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dissolve

v0.3.3

Published

Parse and consume binary streams with a neat DSL

Downloads

1,371

Readme

Dissolve

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.

#!/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 callback will be executed before any existing steps that are already scheduled to run after the tap call.

If you provide a name parameter, all actions performed in the callback will be applied to a child object that will be put into a new property named after name. Note that in the callback, even if you provide a name parameter, you can still pretend you were in the outer "scope" because of some prototype trickery done with the vars 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 until signalled to stop. You do this by calling the end function that's provided as the first argument to your callback. When you call the end function, you can provide an optional truthy/non-truthy flag to tell Dissolve to ignore the result of the iteration of the loop where end 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 property 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 name 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 value will be attached to this.vars.

Buffer/String Methods

For these methods, the length parameter tells the parser how many bytes to pull out. If it's a string, it will be assumed that it is the name of a previously-set this.vars entry. If it's a number, it will be used as-is.

  • buffer(name, length) - binary slice
  • string(name, length) - utf8 string slice

Numeric Methods

  • int8(name) - signed 8 bit integer
  • sint8(name) - signed 8 bit integer
  • uint8(name) - unsigned 8 bit integer
  • int16(name) - signed, little endian 16 bit integer
  • int16le(name) - signed, little endian 16 bit integer
  • int16be(name) - signed, big endian 16 bit integer
  • sint16(name) - signed, little endian 16 bit integer
  • sint16le(name) - signed, little endian 16 bit integer
  • sint16be(name) - signed, big endian 16 bit integer
  • uint16(name) - unsigned, little endian 16 bit integer
  • uint16le(name) - unsigned, little endian 16 bit integer
  • uint16be(name) - unsigned, big endian 16 bit integer
  • int32(name) - signed, little endian 32 bit integer
  • int32le(name) - signed, little endian 32 bit integer
  • int32be(name) - signed, big endian 32 bit integer
  • sint32(name) - signed, little endian 32 bit integer
  • sint32le(name) - signed, little endian 32 bit integer
  • sint32be(name) - signed, big endian 32 bit integer
  • uint32(name) - unsigned, little endian 32 bit integer
  • uint32le(name) - unsigned, little endian 32 bit integer
  • uint32be(name) - unsigned, big endian 32 bit integer
  • int64(name) - signed, little endian 64 bit integer
  • int64le(name) - signed, little endian 64 bit integer
  • int64be(name) - signed, big endian 64 bit integer
  • sint64(name) - signed, little endian 64 bit integer
  • sint64le(name) - signed, little endian 64 bit integer
  • sint64be(name) - signed, big endian 64 bit integer
  • uint64(name) - unsigned, little endian 64 bit integer
  • uint64le(name) - unsigned, little endian 64 bit integer
  • uint64be(name) - unsigned, big endian 64 bit integer
  • floatbe(data) - big endian 32 bit float
  • floatle(data) - little endian 32 bit float
  • doublebe(data) - big endian 64 bit double
  • doublele(data) - little endian 64 bit double

License

3-clause BSD. A copy is included with the source.

Contact