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().
28 self.is_simple = False
31 self.is_container = False
35 self.is_switch = False
37 def resolve(self, module):
39 Abstract method for resolving a type.
40 This should make sure any referenced types are already declared.
42 raise Exception('abstract resolve method not overridden!')
46 Abstract method for outputting code.
47 These are declared in the language-specific modules, and
48 there must be a dictionary containing them declared when this module is imported!
50 raise Exception('abstract out method not overridden!')
54 Abstract method for determining if the data type is fixed-size.
56 raise Exception('abstract fixed_size method not overridden!')
58 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
60 Default method for making a data type a member of a structure.
61 Extend this if the data type needs to add an additional length field or something.
63 module is the global module object.
64 complex_type is the structure object.
65 see Field for the meaning of the other parameters.
67 new_field = Field(self, field_type, field_name, visible, wire, auto)
69 # We dump the _placeholder_byte if any fields are added.
70 for (idx, field) in enumerate(complex_type.fields):
71 if field == _placeholder_byte:
72 complex_type.fields[idx] = new_field
75 complex_type.fields.append(new_field)
78 class SimpleType(Type):
80 Derived class which represents a cardinal type like CARD32 or char.
81 Any type which is typedef'ed to cardinal will be one of these.
86 def __init__(self, name, size):
87 Type.__init__(self, name)
92 def resolve(self, module):
98 out = __main__.output['simple']
101 # Cardinal datatype globals. See module __init__ method.
102 tcard8 = SimpleType(('uint8_t',), 1)
103 tcard16 = SimpleType(('uint16_t',), 2)
104 tcard32 = SimpleType(('uint32_t',), 4)
105 tint8 = SimpleType(('int8_t',), 1)
106 tint16 = SimpleType(('int16_t',), 2)
107 tint32 = SimpleType(('int32_t',), 4)
108 tchar = SimpleType(('char',), 1)
109 tfloat = SimpleType(('float',), 4)
110 tdouble = SimpleType(('double',), 8)
113 class Enum(SimpleType):
115 Derived class which represents an enum. Fixed-size.
118 values contains a list of (name, value) tuples. value is empty, or a number.
119 bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number.
121 def __init__(self, name, elt):
122 SimpleType.__init__(self, name, 4)
125 for item in list(elt):
126 # First check if we're using a default value
127 if len(list(item)) == 0:
128 self.values.append((item.get('name'), ''))
131 # An explicit value or bit was specified.
132 value = list(item)[0]
133 if value.tag == 'value':
134 self.values.append((item.get('name'), value.text))
135 elif value.tag == 'bit':
136 self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
137 self.bits.append((item.get('name'), value.text))
139 def resolve(self, module):
142 def fixed_size(self):
145 out = __main__.output['enum']
148 class ListType(Type):
150 Derived class which represents a list of some other datatype. Fixed- or variable-sized.
153 member is the datatype of the list elements.
154 parent is the structure type containing the list.
155 expr is an Expression object containing the length information, for variable-sized lists.
157 def __init__(self, elt, member, *parent):
158 Type.__init__(self, member.name)
161 self.parent = list(parent)
163 if elt.tag == 'list':
165 self.expr = Expression(elts[0] if len(elts) else elt, self)
166 elif elt.tag == 'valueparam':
167 self.expr = Expression(elt, self)
169 self.size = member.size if member.fixed_size() else None
170 self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
172 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
173 if not self.fixed_size():
174 # We need a length field.
175 # Ask our Expression object for it's name, type, and whether it's on the wire.
176 lenfid = self.expr.lenfield_type
177 lenfield_name = self.expr.lenfield_name
178 lenwire = self.expr.lenwire
181 # See if the length field is already in the structure.
182 for parent in self.parent:
183 for field in parent.fields:
184 if field.field_name == lenfield_name:
187 # It isn't, so we need to add it to the structure ourself.
189 type = module.get_type(lenfid)
190 lenfield_type = module.get_type_name(lenfid)
191 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
193 # Add ourself to the structure by calling our original method.
194 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
196 def resolve(self, module):
199 self.member.resolve(module)
200 self.expr.resolve(module, self.parent)
202 # Find my length field again. We need the actual Field object in the expr.
203 # This is needed because we might have added it ourself above.
204 if not self.fixed_size():
205 for parent in self.parent:
206 for field in parent.fields:
207 if field.field_name == self.expr.lenfield_name and field.wire:
208 self.expr.lenfield = field
213 def fixed_size(self):
214 return self.member.fixed_size() and self.expr.fixed_size()
216 class ExprType(Type):
218 Derived class which represents an exprfield. Fixed size.
221 expr is an Expression object containing the value of the field.
223 def __init__(self, elt, member, *parent):
224 Type.__init__(self, member.name)
229 self.expr = Expression(list(elt)[0], self)
231 self.size = member.size
234 def resolve(self, module):
237 self.member.resolve(module)
240 def fixed_size(self):
245 Derived class which represents a padding field.
247 def __init__(self, elt):
248 Type.__init__(self, tcard8.name)
251 self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
253 def resolve(self, module):
256 def fixed_size(self):
260 class ComplexType(Type):
262 Derived class which represents a structure. Base type for all structure types.
265 fields is an array of Field objects describing the structure fields.
267 def __init__(self, name, elt):
268 Type.__init__(self, name)
269 self.is_container = True
274 self.lenfield_parent = [self]
276 def resolve(self, module):
281 # Resolve all of our field datatypes.
282 for child in list(self.elt):
283 if child.tag == 'pad':
284 field_name = 'pad' + str(pads)
286 type = PadType(child)
289 elif child.tag == 'field':
290 field_name = child.get('name')
291 fkey = child.get('type')
292 type = module.get_type(fkey)
294 elif child.tag == 'exprfield':
295 field_name = child.get('name')
296 fkey = child.get('type')
297 type = ExprType(child, module.get_type(fkey), *self.lenfield_parent)
299 elif child.tag == 'list':
300 field_name = child.get('name')
301 fkey = child.get('type')
302 type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
304 elif child.tag == 'valueparam':
305 field_name = child.get('value-list-name')
307 type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
309 elif child.tag == 'switch':
310 field_name = child.get('name')
311 # construct the switch type name from the parent type and the field name
312 field_type = self.name + (field_name,)
313 type = SwitchType(field_type, child, *self.lenfield_parent)
315 type.make_member_of(module, self, field_type, field_name, visible, True, False)
322 # Get the full type name for the field
323 field_type = module.get_type_name(fkey)
324 # Add the field to ourself
325 type.make_member_of(module, self, field_type, field_name, visible, True, False)
326 # Recursively resolve the type (could be another structure, list)
329 self.calc_size() # Figure out how big we are
334 for m in self.fields:
337 if m.type.fixed_size():
338 self.size = self.size + (m.type.size * m.type.nmemb)
343 def fixed_size(self):
344 for m in self.fields:
345 if not m.type.fixed_size():
349 class SwitchType(ComplexType):
351 Derived class which represents a List of Items.
354 bitcases is an array of Bitcase objects describing the list items
357 def __init__(self, name, elt, *parents):
358 ComplexType.__init__(self, name, elt)
359 self.parent = parents
360 # FIXME: switch cannot store lenfields, so it should just delegate the parents
361 self.lenfield_parent = list(parents) + [self]
362 # self.fields contains all possible fields collected from the Bitcase objects,
363 # whereas self.items contains the Bitcase objects themselves
366 self.is_switch = True
368 self.expr = Expression(elts[0] if len(elts) else elt, self)
370 def resolve(self, module):
375 # Resolve all of our field datatypes.
376 for index, child in enumerate(list(self.elt)):
377 if child.tag == 'bitcase':
378 # use self.parent to indicate anchestor,
379 # as switch does not contain named fields itself
380 type = BitcaseType(index, child, *self.parent)
383 # Get the full type name for the field
384 field_type = type.name
386 # add the field to ourself
387 type.make_member_of(module, self, field_type, index, visible, True, False)
389 # recursively resolve the type (could be another structure, list)
392 for new_field in type.fields:
393 # We dump the _placeholder_byte if any fields are added.
394 for (idx, field) in enumerate(self.fields):
395 if field == _placeholder_byte:
396 self.fields[idx] = new_field
399 if False == inserted:
400 self.fields.append(new_field)
402 self.calc_size() # Figure out how big we are
405 # FIXME: really necessary for Switch??
406 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
407 if not self.fixed_size():
408 # We need a length field.
409 # Ask our Expression object for it's name, type, and whether it's on the wire.
410 lenfid = self.expr.lenfield_type
411 lenfield_name = self.expr.lenfield_name
412 lenwire = self.expr.lenwire
415 # See if the length field is already in the structure.
416 for parent in self.parent:
417 for field in parent.fields:
418 if field.field_name == lenfield_name:
421 # It isn't, so we need to add it to the structure ourself.
423 type = module.get_type(lenfid)
424 lenfield_type = module.get_type_name(lenfid)
425 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
427 # Add ourself to the structure by calling our original method.
428 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
430 # size for switch can only be calculated at runtime
434 # note: switch is _always_ of variable size, but we indicate here wether
435 # it contains elements that are variable-sized themselves
436 def fixed_size(self):
438 # for m in self.fields:
439 # if not m.type.fixed_size():
444 class Struct(ComplexType):
446 Derived class representing a struct data type.
448 out = __main__.output['struct']
451 class Union(ComplexType):
453 Derived class representing a union data type.
455 def __init__(self, name, elt):
456 ComplexType.__init__(self, name, elt)
459 out = __main__.output['union']
462 class BitcaseType(ComplexType):
464 Derived class representing a struct data type.
466 def __init__(self, index, elt, *parent):
468 self.expr = Expression(elts[0] if len(elts) else elt, self)
469 ComplexType.__init__(self, ('bitcase%d' % index,), elts[1:])
470 self.lenfield_parent = list(parent) + [self]
471 self.parents = list(parent)
473 def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto):
475 register BitcaseType with the corresponding SwitchType
477 module is the global module object.
478 complex_type is the structure object.
479 see Field for the meaning of the other parameters.
481 new_field = Field(self, field_type, field_name, visible, wire, auto)
483 # We dump the _placeholder_byte if any bitcases are added.
484 for (idx, field) in enumerate(switch_type.bitcases):
485 if field == _placeholder_byte:
486 switch_type.bitcases[idx] = new_field
489 switch_type.bitcases.append(new_field)
491 def resolve(self, module):
495 self.expr.resolve(module, self.parents+[self])
497 # Resolve the bitcase expression
498 ComplexType.resolve(self, module)
501 class Reply(ComplexType):
503 Derived class representing a reply. Only found as a field of Request.
505 def __init__(self, name, elt):
506 ComplexType.__init__(self, name, elt)
509 def resolve(self, module):
512 # Add the automatic protocol fields
513 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
514 self.fields.append(_placeholder_byte)
515 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
516 self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
517 ComplexType.resolve(self, module)
520 class Request(ComplexType):
522 Derived class representing a request.
525 reply contains the reply datatype or None for void requests.
526 opcode contains the request number.
528 def __init__(self, name, elt):
529 ComplexType.__init__(self, name, elt)
531 self.opcode = elt.get('opcode')
533 for child in list(elt):
534 if child.tag == 'reply':
535 self.reply = Reply(name, child)
537 def resolve(self, module):
540 # Add the automatic protocol fields
541 if module.namespace.is_ext:
542 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
543 self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
544 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
545 ComplexType.resolve(self, module)
547 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
548 self.fields.append(_placeholder_byte)
549 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
550 ComplexType.resolve(self, module)
553 self.reply.resolve(module)
555 out = __main__.output['request']
558 class Event(ComplexType):
560 Derived class representing an event data type.
563 opcodes is a dictionary of name -> opcode number, for eventcopies.
565 def __init__(self, name, elt):
566 ComplexType.__init__(self, name, elt)
569 tmp = elt.get('no-sequence-number')
570 self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
572 def add_opcode(self, opcode, name, main):
573 self.opcodes[name] = opcode
577 def resolve(self, module):
581 # Add the automatic protocol fields
582 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
584 self.fields.append(_placeholder_byte)
585 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
586 ComplexType.resolve(self, module)
588 out = __main__.output['event']
591 class Error(ComplexType):
593 Derived class representing an error data type.
596 opcodes is a dictionary of name -> opcode number, for errorcopies.
598 def __init__(self, name, elt):
599 ComplexType.__init__(self, name, elt)
602 def add_opcode(self, opcode, name, main):
603 self.opcodes[name] = opcode
607 def resolve(self, module):
611 # Add the automatic protocol fields
612 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
613 self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
614 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
615 ComplexType.resolve(self, module)
617 out = __main__.output['error']
619 _placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)