Library

While the command line interface can be used to parse a binary file when the correct types and structure files are provided, it may be useful to have a dedicated interface for specific file types. It could also be that the current library does not provide all functions required for a specific file type. In these cases, direct interfacing to the library is needed.

Basic usage

For both implementations we provide a BinReader and a BinWriter object that are initialised with the input file and the types and structure definitions.

Python

To use the library from our own code, we need to use the following:

#!/usr/bin/env python
import yaml

from bin_parser import BinReader


parser = BinReader(
    open('balance.dat', 'rb').read(),
    yaml.safe_load(open('structure.yml')),
    yaml.safe_load(open('types.yml')))

print('{}\n'.format(parser.parsed['name']))
print('{}\n'.format(parser.parsed['year_of_birth']))
print('{}\n'.format(parser.parsed['balance']))

The BinReader object stores the original data in the data member variable and the parsed data in the parsed member variable.

JavaScript

Similarly, in JavaScript, we use the following:

#!/usr/bin/env node

'use strict';

var fs = require('fs'),
    yaml = require('js-yaml');

var BinParser = require('../../javascript/index');

var parser = new BinParser.BinReader(
  fs.readFileSync('balance.dat'),
  yaml.load(fs.readFileSync('structure.yml')),
  yaml.load(fs.readFileSync('types.yml')),
  {})

console.log(parser.parsed.name);
console.log(parser.parsed.year_of_birth);
console.log(parser.parsed.balance);

Defining new types

See prince for a working example of a reader and a writer in both Python and JavaScript.

Python

Types can be added by subclassing the BinReadFunctions class. Suppose we need a function that inverts all bits in a byte. We first have to make a subclass that implements this function:

from bin_parser import BinReadFunctions

class Invert(BinReadFunctions):
    def inv(self, data):
        return data ^ 0xff

By default, the new type will read one byte and process it with the inv function. In this case there is no need to define the type in types.yml.

Now we can initialise the parser using an instance of the new class:

parser = bin_parser.BinReader(
    open('something.dat', 'rb').read(),
    yaml.safe_load(open('structure.yml')),
    yaml.safe_load(open('types.yml')),
    functions=Invert())

JavaScript

Similarly, in JavaScript, we make a prototype of the BinReadFunctions function.

var Functions = require('../../../javascript/functions');

function Invert() {
  this.inv = function(data) {
    return data ^ 0xff;
  };

  Functions.BinReadFunctions.call(this);
}

Now we can initialise the parser with the prototyped function:

var parser = new BinParser.BinReader(
  fs.readFileSync('something.dat'),
  yaml.load(fs.readFileSync('structure.yml')),
  yaml.load(fs.readFileSync('types.yml')),
  {'functions': new Invert()});