2 This module contains the classes which represent XCB data types.
4 from expr import Field, Expression
9 Abstract base class for all XCB data types.
10 Contains default fields, and some abstract methods.
12 def __init__(self, name):
14 Default structure initializer. Sets up default fields.
17 name is a tuple of strings specifying the full type name.
18 size is the size of the datatype in bytes, or None if variable-sized.
19 nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
20 booleans for identifying subclasses, because I can't figure out isinstance().
30 self.is_container = False
35 def resolve(self, module):
37 Abstract method for resolving a type.
38 This should make sure any referenced types are already declared.
40 raise Exception('abstract resolve method not overridden!')
44 Abstract method for outputting code.
45 These are declared in the language-specific modules, and
46 there must be a dictionary containing them declared when this module is imported!
48 raise Exception('abstract out method not overridden!')
52 Abstract method for determining if the data type is fixed-size.
54 raise Exception('abstract fixed_size method not overridden!')
56 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
58 Default method for making a data type a member of a structure.
59 Extend this if the data type needs to add an additional length field or something.
61 module is the global module object.
62 complex_type is the structure object.
63 see Field for the meaning of the other parameters.
65 new_field = Field(self, field_type, field_name, visible, wire, auto)
67 # We dump the _placeholder_byte if any fields are added.
68 for (idx, field) in enumerate(complex_type.fields):
69 if field == _placeholder_byte:
70 complex_type.fields[idx] = new_field
73 complex_type.fields.append(new_field)
75 class SimpleType(Type):
77 Derived class which represents a cardinal type like CARD32 or char.
78 Any type which is typedef'ed to cardinal will be one of these.
83 def __init__(self, name, size):
84 Type.__init__(self, name)
88 def resolve(self, module):
94 out = __main__.output['simple']
97 # Cardinal datatype globals. See module __init__ method.
98 tcard8 = SimpleType(('uint8_t',), 1)
99 tcard16 = SimpleType(('uint16_t',), 2)
100 tcard32 = SimpleType(('uint32_t',), 4)
101 tint8 = SimpleType(('int8_t',), 1)
102 tint16 = SimpleType(('int16_t',), 2)
103 tint32 = SimpleType(('int32_t',), 4)
104 tchar = SimpleType(('char',), 1)
105 tfloat = SimpleType(('float',), 4)
106 tdouble = SimpleType(('double',), 8)
109 class Enum(SimpleType):
111 Derived class which represents an enum. Fixed-size.
114 values contains a list of (name, value) tuples. value is empty, or a number.
116 def __init__(self, name, elt):
117 SimpleType.__init__(self, name, 4)
119 for item in list(elt):
120 # First check if we're using a default value
121 if len(list(item)) == 0:
122 self.values.append((item.get('name'), ''))
125 # An explicit value or bit was specified.
126 value = list(item)[0]
127 if value.tag == 'value':
128 self.values.append((item.get('name'), value.text))
129 elif value.tag == 'bit':
130 # XXX replace this with a simple number, please.
131 self.values.append((item.get('name'), '(1 << %s)' % value.text))
133 def resolve(self, module):
136 def fixed_size(self):
139 out = __main__.output['enum']
142 class ListType(Type):
144 Derived class which represents a list of some other datatype. Fixed- or variable-sized.
147 member is the datatype of the list elements.
148 parent is the structure type containing the list.
149 expr is an Expression object containing the length information, for variable-sized lists.
151 def __init__(self, elt, member, parent):
152 Type.__init__(self, member.name)
157 if elt.tag == 'list':
159 self.expr = Expression(elts[0] if len(elts) else elt, self)
160 elif elt.tag == 'valueparam':
161 self.expr = Expression(elt, self)
163 self.size = member.size if member.fixed_size() else None
164 self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
166 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
167 if not self.fixed_size():
168 # We need a length field.
169 # Ask our Expression object for it's name, type, and whether it's on the wire.
170 lenfid = self.expr.lenfield_type
171 lenfield_name = self.expr.lenfield_name
172 lenwire = self.expr.lenwire
175 # See if the length field is already in the structure.
176 for field in self.parent.fields:
177 if field.field_name == lenfield_name:
180 # It isn't, so we need to add it to the structure ourself.
182 type = module.get_type(lenfid)
183 lenfield_type = module.get_type_name(lenfid)
184 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
186 # Add ourself to the structure by calling our original method.
187 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
189 def resolve(self, module):
192 self.member.resolve(module)
194 # Find my length field again. We need the actual Field object in the expr.
195 # This is needed because we might have added it ourself above.
196 if not self.fixed_size():
197 for field in self.parent.fields:
198 if field.field_name == self.expr.lenfield_name and field.wire:
199 self.expr.lenfield = field
204 def fixed_size(self):
205 return self.member.fixed_size() and self.expr.fixed_size()
207 class ExprType(Type):
209 Derived class which represents an exprfield. Fixed size.
212 expr is an Expression object containing the value of the field.
214 def __init__(self, elt, member, parent):
215 Type.__init__(self, member.name)
220 self.expr = Expression(list(elt)[0], self)
222 self.size = member.size
225 def resolve(self, module):
228 self.member.resolve(module)
231 def fixed_size(self):
236 Derived class which represents a padding field.
238 def __init__(self, elt):
239 Type.__init__(self, tcard8.name)
242 self.nmemb = 1 if (elt == None) else int(elt.get('bytes'))
244 def resolve(self, module):
247 def fixed_size(self):
251 class ComplexType(Type):
253 Derived class which represents a structure. Base type for all structure types.
256 fields is an array of Field objects describing the structure fields.
258 def __init__(self, name, elt):
259 Type.__init__(self, name)
260 self.is_container = True
266 def resolve(self, module):
271 # Resolve all of our field datatypes.
272 for child in list(self.elt):
273 if child.tag == 'pad':
274 field_name = 'pad' + str(pads)
276 type = PadType(child)
279 elif child.tag == 'field':
280 field_name = child.get('name')
281 fkey = child.get('type')
282 type = module.get_type(fkey)
284 elif child.tag == 'exprfield':
285 field_name = child.get('name')
286 fkey = child.get('type')
287 type = ExprType(child, module.get_type(fkey), self)
289 elif child.tag == 'list':
290 field_name = child.get('name')
291 fkey = child.get('type')
292 type = ListType(child, module.get_type(fkey), self)
294 elif child.tag == 'valueparam':
295 field_name = child.get('value-list-name')
297 type = ListType(child, module.get_type(fkey), self)
303 # Get the full type name for the field
304 field_type = module.get_type_name(fkey)
305 # Add the field to ourself
306 type.make_member_of(module, self, field_type, field_name, visible, True, False)
307 # Recursively resolve the type (could be another structure, list)
310 self.calc_size() # Figure out how big we are
315 for m in self.fields:
318 if m.type.fixed_size():
319 self.size = self.size + m.type.size
324 def fixed_size(self):
325 for m in self.fields:
326 if not m.type.fixed_size():
331 class Struct(ComplexType):
333 Derived class representing a struct data type.
335 out = __main__.output['struct']
338 class Union(ComplexType):
340 Derived class representing a union data type.
342 def __init__(self, name, elt):
343 ComplexType.__init__(self, name, elt)
346 out = __main__.output['union']
349 class Reply(ComplexType):
351 Derived class representing a reply. Only found as a field of Request.
353 def __init__(self, name, elt):
354 ComplexType.__init__(self, name, elt)
357 def resolve(self, module):
360 # Add the automatic protocol fields
361 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
362 self.fields.append(_placeholder_byte)
363 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
364 self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
365 ComplexType.resolve(self, module)
368 class Request(ComplexType):
370 Derived class representing a request.
373 reply contains the reply datatype or None for void requests.
374 opcode contains the request number.
376 def __init__(self, name, elt):
377 ComplexType.__init__(self, name, elt)
379 self.opcode = elt.get('opcode')
381 for child in list(elt):
382 if child.tag == 'reply':
383 self.reply = Reply(name, child)
385 def resolve(self, module):
388 # Add the automatic protocol fields
389 if module.namespace.is_ext:
390 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
391 self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
392 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
393 ComplexType.resolve(self, module)
395 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
396 self.fields.append(_placeholder_byte)
397 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
398 ComplexType.resolve(self, module)
401 self.reply.resolve(module)
403 out = __main__.output['request']
406 class Event(ComplexType):
408 Derived class representing an event data type.
411 opcodes is a dictionary of name -> opcode number, for eventcopies.
413 def __init__(self, name, elt):
414 ComplexType.__init__(self, name, elt)
417 tmp = elt.get('no-sequence-number')
418 self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
420 def add_opcode(self, opcode, name, main):
421 self.opcodes[name] = opcode
425 def resolve(self, module):
429 # Add the automatic protocol fields
430 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
432 self.fields.append(_placeholder_byte)
433 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
434 ComplexType.resolve(self, module)
436 out = __main__.output['event']
439 class Error(ComplexType):
441 Derived class representing an error data type.
444 opcodes is a dictionary of name -> opcode number, for errorcopies.
446 def __init__(self, name, elt):
447 ComplexType.__init__(self, name, elt)
450 def add_opcode(self, opcode, name, main):
451 self.opcodes[name] = opcode
455 def resolve(self, module):
459 # Add the automatic protocol fields
460 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
461 self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
462 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
463 ComplexType.resolve(self, module)
465 out = __main__.output['error']
467 _placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)