Implemented a basic form of schema representation.
[~jspiros/python-ebml.git] / ebml / schema / base.py
1 __all__ = ('INT', 'UINT', 'FLOAT', 'STRING', 'UNICODE', 'DATE', 'BINARY', 'CONTAINER', 'Element', 'EBML')
2
3
4 INT, UINT, FLOAT, STRING, UNICODE, DATE, BINARY, CONTAINER = range(0, 8)
5
6
7 SCHEMA_TYPES = {
8         'int': INT,
9         'uint': UINT,
10         'float': FLOAT,
11         'string': STRING,
12         'date': DATE,
13         'binary': BINARY
14 }
15
16
17 class Element(object):
18         class_id = None
19         class_name = 'Unknown'
20         class_parents = ()
21         class_global = False
22         class_root = False
23         data_type = BINARY
24
25
26 class EBMLElement(Element):
27         class_id = 0x1A45DFA3
28         class_name = 'EBML'
29         class_root = True
30         data_type = CONTAINER
31
32
33 class EBMLVersionElement(Element):
34         class_id = 0x4286
35         class_name = 'EBMLVersion'
36         class_parents = (EBMLElement,)
37         data_type = UINT
38
39
40 class EBMLReadVersionElement(Element):
41         class_id = 0x42F7
42         class_name = 'EBMLReadVersion'
43         class_parents = (EBMLElement,)
44         data_type = UINT
45
46
47 class EBMLMaxIDLengthElement(Element):
48         class_id = 0x42F2
49         class_name = 'EBMLMaxIDLength'
50         class_parents = (EBMLElement,)
51         data_type = UINT
52
53
54 class EBMLMaxSizeLengthElement(Element):
55         class_id = 0x42F3
56         class_name = 'EBMLMaxSizeLength'
57         class_parents = (EBMLElement,)
58         data_type = UINT
59
60
61 class DocTypeElement(Element):
62         class_id = 0x4282
63         class_name = 'DocType'
64         class_parents = (EBMLElement,)
65         data_type = STRING
66
67
68 class DocTypeVersionElement(Element):
69         class_id = 0x4287
70         class_name = 'DocTypeVersion'
71         class_parents = (EBMLElement,)
72         data_type = UINT
73
74
75 class DocTypeReadVersionElement(Element):
76         class_id = 0x4285
77         class_name = 'DocTypeReadVersion'
78         class_parents = (EBMLElement,)
79         data_type = UINT
80
81
82 class CRC32Element(Element):
83         class_id = 0xBF
84         class_name = 'CRC-32'
85         class_global = True
86         data_type = BINARY
87
88
89 class VoidElement(Element):
90         class_id = 0xEC
91         class_name = 'Void'
92         class_global = True
93         data_type = BINARY
94
95
96 class SignatureSlotElement(Element):
97         class_id = 0x1B538667
98         class_name = 'SignatureSlot'
99         class_global = True
100         data_type = CONTAINER
101
102
103 class SignatureAlgoElement(Element):
104         class_id = 0x7E8A
105         class_name = 'SignatureAlgo'
106         class_parents = (SignatureSlotElement,)
107         data_type = UINT
108
109
110 class SignatureHashElement(Element):
111         class_id = 0x7E9A
112         class_name = 'SignatureHash'
113         class_parents = (SignatureSlotElement,)
114         data_type = UINT
115
116
117 class SignaturePublicKeyElement(Element):
118         class_id = 0x7EA5
119         class_name = 'SignaturePublicKey'
120         class_parents = (SignatureSlotElement,)
121         data_type = BINARY
122
123
124 class SignatureElement(Element):
125         class_id = 0x7EB5
126         class_name = 'Signature'
127         class_parents = (SignatureSlotElement,)
128         data_type = BINARY
129
130
131 class SignatureElementsElement(Element):
132         class_id = 0x7E5B
133         class_name = 'SignatureElements'
134         class_parents = (SignatureSlotElement,)
135         data_type = CONTAINER
136
137
138 class SignatureElementListElement(Element):
139         class_id = 0x7E7B
140         class_name = 'SignatureElementList'
141         class_parents = (SignatureElementsElement,)
142         data_type = CONTAINER
143
144
145 class SignedElementElement(Element):
146         class_id = 0x6532
147         class_name = 'SignedElement'
148         class_parents = (SignatureElementListElement,)
149         data_type = BINARY
150
151
152 class Schema(object):
153         doc_type = None
154         version = None
155         elements_by_class_id = None
156         
157         @classmethod
158         def element_with_class_id(cls, class_id):
159                 if cls.elements_by_class_id is None:
160                         cls.elements_by_class_id = {}
161                         for element in cls.elements:
162                                 cls.elements_by_class_id[element.class_id] = element
163                 return cls.elements_by_class_id[class_id]
164         
165         @classmethod
166         def global_elements(cls):
167                 return [element for element in cls.elements if element.class_global]
168         
169         @classmethod
170         def root_elements(cls):
171                 return [element for element in cls.elements if element.class_root]
172         
173         @classmethod
174         def child_elements_of_element(cls, parent):
175                 children = [element for element in cls.elements if parent in element.class_parents]
176                 children += cls.global_elements()
177                 if 'self' in parent.class_parents and parent not in children:
178                         children.append(parent)
179                 return children
180
181
182 class EBML(Schema):
183         elements = (
184                 EBMLElement,
185                 EBMLVersionElement,
186                 EBMLReadVersionElement,
187                 EBMLMaxIDLengthElement,
188                 EBMLMaxSizeLengthElement,
189                 DocTypeElement,
190                 DocTypeVersionElement,
191                 DocTypeReadVersionElement,
192                 CRC32Element,
193                 VoidElement,
194                 SignatureSlotElement,
195                 SignatureAlgoElement,
196                 SignatureHashElement,
197                 SignaturePublicKeyElement,
198                 SignatureElement,
199                 SignatureElementsElement,
200                 SignatureElementListElement,
201                 SignedElementElement
202         )