2 from .core import read_element_id, read_element_size, read_int, read_uint, read_float, read_string, read_unicode, read_date
5 __all__ = ('EBMLFile', 'MatroskaFile')
13 UNICODE: read_unicode,
14 DATE: lambda stream, size: read_date(stream)
18 class EBMLFileElement(object):
19 def __init__(self, stream, schema, parent=None):
23 self.class_id, self.class_id_len = read_element_id(self.stream)
25 self.element = schema.element_with_class_id(self.class_id)
29 if self.parent is None:
30 if not self.element in self.schema.root_elements():
33 if not self.element in self.schema.child_elements_of_element(self.parent):
35 self.size, self.size_len = read_element_size(self.stream)
36 self.offset = self.stream.tell()
39 def _read_contents(self):
41 if self.element is not None:
42 if self.element.data_type in TYPE_READERS:
43 contents = TYPE_READERS[self.element.data_type](self.stream, self.size)
44 elif self.element.data_type == CONTAINER:
47 while self.size > read_len:
48 sub_el = EBMLFileElement(self.stream, self.schema, self.element)
49 read_len += (sub_el.class_id_len + sub_el.size_len + sub_el.size)
50 contents.append(sub_el)
52 self.stream.seek(self.offset + self.size, 0)
54 self.stream.seek(self.offset + self.size, 0)
55 self.contents = contents
57 def pprint(self, indent=0):
59 'class_name': self.element.class_name or 'Unknown',
60 'class_id': self.class_id,
62 'value': self.contents or None
65 print ('\t' * indent) + foo
67 pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\' />' % sargs)
69 if self.element.data_type == CONTAINER:
70 pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\'>' % sargs)
71 for sub_el in self.contents:
72 sub_el.pprint(indent + 1)
73 pprint_('</%(class_name)s>' % sargs)
75 pprint_('<%(class_name)s id=\'%(class_id)x\' size=\'%(size)i\'>%(value)s</%(class_name)s>' % sargs)
78 return '<%(class_name)s id=%(class_id)x size=%(size)i>' % {
79 'class_name': self.element.class_name or '?',
80 'class_id': self.element.class_id or self.class_id,
85 class EBMLFile(object):
88 def __init__(self, name_or_stream, schema=None):
90 schema = self.default_schema
93 if isinstance(name_or_stream, basestring):
94 self.stream = open(name_or_stream, 'rb')
96 self.stream = name_or_stream
100 def _read_contents(self):
104 self.contents.append(EBMLFileElement(self.stream, self.schema, None))
109 for el in self.contents:
113 class MatroskaFile(EBMLFile):
114 default_schema = Matroska