+++ /dev/null
-from .schema import *
-from .core import *
-
-
-__all__ = ('EBMLFile', 'MatroskaFile')
-
-
-TYPE_READERS = {
- INT: read_signed_integer,
- UINT: read_unsigned_integer,
- FLOAT: read_float,
- STRING: read_string,
- UNICODE: read_unicode_string,
- DATE: read_date
-}
-
-
-class EBMLFileElement(object):
- def __init__(self, stream, schema, parent=None):
- self.stream = stream
- self.schema = schema
- self.parent = parent
- self.class_id, self.class_id_len = read_element_id(self.stream)
- try:
- self.element = schema.element_with_class_id(self.class_id)
- except:
- self.element = None
- else:
- if self.parent is None:
- if not self.element in self.schema.root_elements():
- self.element = None
- else:
- if not self.element in self.schema.child_elements_of_element(self.parent):
- self.element = None
- self.size, self.size_len = read_element_size(self.stream)
- self.offset = self.stream.tell()
- self._read_contents()
-
- def _read_contents(self):
- contents = None
- if self.element is not None:
- if self.element.data_type in TYPE_READERS:
- contents = TYPE_READERS[self.element.data_type](self.stream, self.size)
- elif self.element.data_type == CONTAINER:
- read_len = 0
- contents = []
- while self.size > read_len:
- sub_el = EBMLFileElement(self.stream, self.schema, self.element)
- read_len += (sub_el.class_id_len + sub_el.size_len + sub_el.size)
- contents.append(sub_el)
- else:
- self.stream.seek(self.offset + self.size, 0)
- else:
- self.stream.seek(self.offset + self.size, 0)
- self.contents = contents
-
- def pprint(self, indent=0):
- sargs = {
- 'class_name': self.element.class_name or 'Unknown',
- 'class_id': self.class_id,
- 'size': self.size,
- 'value': self.contents or None
- }
- def pprint_(foo):
- print ('\t' * indent) + foo
- if not self.contents:
- pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\' />' % sargs)
- else:
- if self.element.data_type == CONTAINER:
- pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\'>' % sargs)
- for sub_el in self.contents:
- sub_el.pprint(indent + 1)
- pprint_('</%(class_name)s>' % sargs)
- else:
- pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\'>%(value)s</%(class_name)s>' % sargs)
-
- def __repr__(self):
- return '<%(class_name)s id=%(class_id)x size=%(size)i>' % {
- 'class_name': self.element.class_name or '?',
- 'class_id': self.element.class_id or self.class_id,
- 'size': self.size
- }
-
-
-class EBMLFile(object):
- default_schema = EBML
-
- def __init__(self, name_or_stream, schema=None):
- if schema is None:
- schema = self.default_schema
- self.schema = schema
-
- if isinstance(name_or_stream, basestring):
- self.stream = open(name_or_stream, 'rb')
- else:
- self.stream = name_or_stream
-
- self._read_contents()
-
- def _read_contents(self):
- self.contents = []
- while True:
- try:
- self.contents.append(EBMLFileElement(self.stream, self.schema, None))
- except:
- break
-
- def pprint(self):
- for el in self.contents:
- el.pprint()
-
-
-class MatroskaFile(EBMLFile):
- default_schema = Matroska
\ No newline at end of file