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()});