Source code for pfp

#!/usr/bin/env python

import os
import six
import sys

import py010parser.c_parser

import pfp.interp
from pfp.bitwrap import BitwrappedStream
import pfp.fuzz


pfp.fuzz.init()


__version__ = "{{VERSION}}"

PARSER = py010parser.c_parser.CParser()


[docs]def parse( data=None, template=None, data_file=None, template_file=None, interp=None, debug=False, predefines=True, int3=True, keep_successful=False, printf=True, ): """Parse the data stream using the supplied template. The data stream WILL NOT be automatically closed. :data: Input data, can be either a string or a file-like object (StringIO, file, etc) :template: template contents (str) :data_file: PATH to the data to be used as the input stream :template_file: template file path :interp: the interpretor to be used (a default one will be created if ``None``) :debug: if debug information should be printed while interpreting the template (false) :predefines: if built-in type information should be inserted (true) :int3: if debugger breaks are allowed while interpreting the template (true) :keep_successful: return any succesfully parsed data instead of raising an error. If an error occurred and ``keep_successful`` is True, then ``_pfp__error`` will be contain the exception object :printf: if ``False``, all calls to ``Printf`` (:any:`pfp.native.compat_interface.Printf`) will be noops. (default=``True``) :returns: pfp DOM """ if data is None and data_file is None: raise Exception("No input data was specified") if data is not None and data_file is not None: raise Exception("Only one input data may be specified") if isinstance(data, six.string_types): data = six.StringIO(data) if data_file is not None: data = open(os.path.expanduser(data_file), "rb") if template is None and template_file is None: raise Exception("No template specified!") if template is not None and template_file is not None: raise Exception("Only one template may be specified!") orig_filename = "string" if template_file is not None: orig_filename = template_file try: with open(os.path.expanduser(template_file), "r") as f: template = f.read() except Exception as e: raise Exception( "Could not open template file '{}'".format(template_file) ) # the user may specify their own instance of PfpInterp to be # used if interp is None: interp = pfp.interp.PfpInterp(debug=debug, parser=PARSER, int3=int3) # so we can consume single bits at a time data = BitwrappedStream(data) dom = interp.parse( data, template, predefines=predefines, orig_filename=orig_filename, keep_successful=keep_successful, printf=printf, ) # close the data stream if a data_file was specified if data_file is not None: data.close() return dom
[docs]def create_interp(template_file=None, template=None): """Create an Interp instance with the template preloaded :template: template contents (str) :template_file: template file path :returns: Interp """ if template is None and template_file is None: raise Exception("No template specified!") if template is not None and template_file is not None: raise Exception("Only one template may be specified!") orig_filename = "string" if template_file is not None: orig_filename = template_file try: with open(os.path.expanduser(template_file), "r") as f: template = f.read() except Exception as e: raise Exception( "Could not open template file '{}'".format(template_file) ) interp = pfp.interp.PfpInterp(parser=PARSER) interp.load_template(template) return interp