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