/usr/share/pyshared/hachoir_parser/parser.py is in python-hachoir-parser 1.3.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | import hachoir_core.config as config
from hachoir_core.field import Parser as GenericParser
from hachoir_core.error import HACHOIR_ERRORS, HachoirError, error
from hachoir_core.tools import makeUnicode
from hachoir_core.i18n import _
from inspect import getmro
class ValidateError(HachoirError):
pass
class HachoirParser(object):
"""
A parser is the root of all other fields. It create first level of fields
and have special attributes and methods:
- tags: dictionnary with keys:
- "file_ext": classical file extensions (string or tuple of strings) ;
- "mime": MIME type(s) (string or tuple of strings) ;
- "description": String describing the parser.
- endian: Byte order (L{BIG_ENDIAN} or L{LITTLE_ENDIAN}) of input data ;
- stream: Data input stream (set in L{__init__()}).
Default values:
- size: Field set size will be size of input stream ;
- mime_type: First MIME type of tags["mime"] (if it does exist,
None otherwise).
"""
_autofix = False
def __init__(self, stream, **args):
validate = args.pop("validate", False)
self._mime_type = None
while validate:
nbits = self.getParserTags()["min_size"]
if stream.sizeGe(nbits):
res = self.validate()
if res is True:
break
res = makeUnicode(res)
else:
res = _("stream is smaller than %s.%s bytes" % divmod(nbits, 8))
raise ValidateError(res or _("no reason given"))
self._autofix = True
#--- Methods that can be overridden -------------------------------------
def createDescription(self):
"""
Create an Unicode description
"""
return self.PARSER_TAGS["description"]
def createMimeType(self):
"""
Create MIME type (string), eg. "image/png"
If it returns None, "application/octet-stream" is used.
"""
if "mime" in self.PARSER_TAGS:
return self.PARSER_TAGS["mime"][0]
return None
def validate(self):
"""
Check that the parser is able to parse the stream. Valid results:
- True: stream looks valid ;
- False: stream is invalid ;
- str: string describing the error.
"""
raise NotImplementedError()
#--- Getter methods -----------------------------------------------------
def _getDescription(self):
if self._description is None:
try:
self._description = self.createDescription()
if isinstance(self._description, str):
self._description = makeUnicode(self._description)
except HACHOIR_ERRORS, err:
error("Error getting description of %s: %s" \
% (self.path, unicode(err)))
self._description = self.PARSER_TAGS["description"]
return self._description
description = property(_getDescription,
doc="Description of the parser")
def _getMimeType(self):
if not self._mime_type:
try:
self._mime_type = self.createMimeType()
except HACHOIR_ERRORS, err:
self.error("Error when creating MIME type: %s" % unicode(err))
if not self._mime_type \
and self.createMimeType != Parser.createMimeType:
self._mime_type = Parser.createMimeType(self)
if not self._mime_type:
self._mime_type = u"application/octet-stream"
return self._mime_type
mime_type = property(_getMimeType)
def createContentSize(self):
return None
def _getContentSize(self):
if not hasattr(self, "_content_size"):
try:
self._content_size = self.createContentSize()
except HACHOIR_ERRORS, err:
error("Unable to compute %s content size: %s" % (self.__class__.__name__, err))
self._content_size = None
return self._content_size
content_size = property(_getContentSize)
def createFilenameSuffix(self):
"""
Create filename suffix: "." + first value of self.PARSER_TAGS["file_ext"],
or None if self.PARSER_TAGS["file_ext"] doesn't exist.
"""
file_ext = self.getParserTags().get("file_ext")
if isinstance(file_ext, (tuple, list)):
file_ext = file_ext[0]
return file_ext and '.' + file_ext
def _getFilenameSuffix(self):
if not hasattr(self, "_filename_suffix"):
self._filename_extension = self.createFilenameSuffix()
return self._filename_extension
filename_suffix = property(_getFilenameSuffix)
@classmethod
def getParserTags(cls):
tags = {}
for cls in reversed(getmro(cls)):
if hasattr(cls, "PARSER_TAGS"):
tags.update(cls.PARSER_TAGS)
return tags
@classmethod
def print_(cls, out, verbose):
tags = cls.getParserTags()
print >>out, "- %s: %s" % (tags["id"], tags["description"])
if verbose:
if "mime" in tags:
print >>out, " MIME type: %s" % (", ".join(tags["mime"]))
if "file_ext" in tags:
file_ext = ", ".join(
".%s" % file_ext for file_ext in tags["file_ext"])
print >>out, " File extension: %s" % file_ext
autofix = property(lambda self: self._autofix and config.autofix)
class Parser(HachoirParser, GenericParser):
def __init__(self, stream, **args):
GenericParser.__init__(self, stream)
HachoirParser.__init__(self, stream, **args)
|