2 This module contains the classes which represent XCB data types.
4 from xcbgen.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
36 self.is_bitcase = False
38 def resolve(self, module):
40 Abstract method for resolving a type.
41 This should make sure any referenced types are already declared.
43 raise Exception('abstract resolve method not overridden!')
47 Abstract method for outputting code.
48 These are declared in the language-specific modules, and
49 there must be a dictionary containing them declared when this module is imported!
51 raise Exception('abstract out method not overridden!')
55 Abstract method for determining if the data type is fixed-size.
57 raise Exception('abstract fixed_size method not overridden!')
59 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
61 Default method for making a data type a member of a structure.
62 Extend this if the data type needs to add an additional length field or something.
64 module is the global module object.
65 complex_type is the structure object.
66 see Field for the meaning of the other parameters.
68 new_field = Field(self, field_type, field_name, visible, wire, auto)
70 # We dump the _placeholder_byte if any fields are added.
71 for (idx, field) in enumerate(complex_type.fields):
72 if field == _placeholder_byte:
73 complex_type.fields[idx] = new_field
76 complex_type.fields.append(new_field)
79 class SimpleType(Type):
81 Derived class which represents a cardinal type like CARD32 or char.
82 Any type which is typedef'ed to cardinal will be one of these.
87 def __init__(self, name, size):
88 Type.__init__(self, name)
93 def resolve(self, module):
99 out = __main__.output['simple']
102 # Cardinal datatype globals. See module __init__ method.
103 tcard8 = SimpleType(('uint8_t',), 1)
104 tcard16 = SimpleType(('uint16_t',), 2)
105 tcard32 = SimpleType(('uint32_t',), 4)
106 tint8 = SimpleType(('int8_t',), 1)
107 tint16 = SimpleType(('int16_t',), 2)
108 tint32 = SimpleType(('int32_t',), 4)
109 tchar = SimpleType(('char',), 1)
110 tfloat = SimpleType(('float',), 4)
111 tdouble = SimpleType(('double',), 8)
114 class Enum(SimpleType):
116 Derived class which represents an enum. Fixed-size.
119 values contains a list of (name, value) tuples. value is empty, or a number.
120 bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number.
122 def __init__(self, name, elt):
123 SimpleType.__init__(self, name, 4)
126 for item in list(elt):
127 # First check if we're using a default value
128 if len(list(item)) == 0:
129 self.values.append((item.get('name'), ''))
132 # An explicit value or bit was specified.
133 value = list(item)[0]
134 if value.tag == 'value':
135 self.values.append((item.get('name'), value.text))
136 elif value.tag == 'bit':
137 self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
138 self.bits.append((item.get('name'), value.text))
140 def resolve(self, module):
143 def fixed_size(self):
146 out = __main__.output['enum']
149 class ListType(Type):
151 Derived class which represents a list of some other datatype. Fixed- or variable-sized.
154 member is the datatype of the list elements.
155 parent is the structure type containing the list.
156 expr is an Expression object containing the length information, for variable-sized lists.
158 def __init__(self, elt, member, *parent):
159 Type.__init__(self, member.name)
162 self.parents = list(parent)
164 if elt.tag == 'list':
166 self.expr = Expression(elts[0] if len(elts) else elt, self)
167 elif elt.tag == 'valueparam':
168 self.expr = Expression(elt, self)
170 self.size = member.size if member.fixed_size() else None
171 self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
173 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
174 if not self.fixed_size():
175 # We need a length field.
176 # Ask our Expression object for it's name, type, and whether it's on the wire.
177 lenfid = self.expr.lenfield_type
178 lenfield_name = self.expr.lenfield_name
179 lenwire = self.expr.lenwire
182 # See if the length field is already in the structure.
183 for parent in self.parents:
184 for field in parent.fields:
185 if field.field_name == lenfield_name:
188 # It isn't, so we need to add it to the structure ourself.
190 type = module.get_type(lenfid)
191 lenfield_type = module.get_type_name(lenfid)
192 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
194 # Add ourself to the structure by calling our original method.
195 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
197 def resolve(self, module):
200 self.member.resolve(module)
201 self.expr.resolve(module, self.parents)
203 # Find my length field again. We need the actual Field object in the expr.
204 # This is needed because we might have added it ourself above.
205 if not self.fixed_size():
206 for parent in self.parents:
207 for field in parent.fields:
208 if field.field_name == self.expr.lenfield_name and field.wire:
209 self.expr.lenfield = field
214 def fixed_size(self):
215 return self.member.fixed_size() and self.expr.fixed_size()
217 class ExprType(Type):
219 Derived class which represents an exprfield. Fixed size.
222 expr is an Expression object containing the value of the field.
224 def __init__(self, elt, member, *parents):
225 Type.__init__(self, member.name)
228 self.parents = parents
230 self.expr = Expression(list(elt)[0], self)
232 self.size = member.size
235 def resolve(self, module):
238 self.member.resolve(module)
241 def fixed_size(self):
246 Derived class which represents a padding field.
248 def __init__(self, elt):
249 Type.__init__(self, tcard8.name)
252 self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
254 def resolve(self, module):
257 def fixed_size(self):
261 class ComplexType(Type):
263 Derived class which represents a structure. Base type for all structure types.
266 fields is an array of Field objects describing the structure fields.
268 def __init__(self, name, elt):
269 Type.__init__(self, name)
270 self.is_container = True
275 self.lenfield_parent = [self]
277 def resolve(self, module):
282 # Resolve all of our field datatypes.
283 for child in list(self.elt):
284 if child.tag == 'pad':
285 field_name = 'pad' + str(pads)
287 type = PadType(child)
290 elif child.tag == 'field':
291 field_name = child.get('name')
292 fkey = child.get('type')
293 type = module.get_type(fkey)
295 elif child.tag == 'exprfield':
296 field_name = child.get('name')
297 fkey = child.get('type')
298 type = ExprType(child, module.get_type(fkey), *self.lenfield_parent)
300 elif child.tag == 'list':
301 field_name = child.get('name')
302 fkey = child.get('type')
303 type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
305 elif child.tag == 'valueparam':
306 field_name = child.get('value-list-name')
308 type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
310 elif child.tag == 'switch':
311 field_name = child.get('name')
312 # construct the switch type name from the parent type and the field name
313 field_type = self.name + (field_name,)
314 type = SwitchType(field_type, child, *self.lenfield_parent)
316 type.make_member_of(module, self, field_type, field_name, visible, True, False)
323 # Get the full type name for the field
324 field_type = module.get_type_name(fkey)
325 # Add the field to ourself
326 type.make_member_of(module, self, field_type, field_name, visible, True, False)
327 # Recursively resolve the type (could be another structure, list)
330 self.calc_size() # Figure out how big we are
335 for m in self.fields:
338 if m.type.fixed_size():
339 self.size = self.size + (m.type.size * m.type.nmemb)
344 def fixed_size(self):
345 for m in self.fields:
346 if not m.type.fixed_size():
350 class SwitchType(ComplexType):
352 Derived class which represents a List of Items.
355 bitcases is an array of Bitcase objects describing the list items
358 def __init__(self, name, elt, *parents):
359 ComplexType.__init__(self, name, elt)
360 self.parents = parents
361 # FIXME: switch cannot store lenfields, so it should just delegate the parents
362 self.lenfield_parent = list(parents) + [self]
363 # self.fields contains all possible fields collected from the Bitcase objects,
364 # whereas self.items contains the Bitcase objects themselves
367 self.is_switch = True
369 self.expr = Expression(elts[0] if len(elts) else elt, self)
371 def resolve(self, module):
376 parents = list(self.parents) + [self]
378 # Resolve all of our field datatypes.
379 for index, child in enumerate(list(self.elt)):
380 if child.tag == 'bitcase':
381 field_name = child.get('name')
382 if field_name is None:
383 field_type = self.name + ('bitcase%d' % index,)
385 field_type = self.name + (field_name,)
387 # use self.parent to indicate anchestor,
388 # as switch does not contain named fields itself
389 type = BitcaseType(index, field_type, child, *parents)
390 # construct the switch type name from the parent type and the field name
391 if field_name is None:
392 type.has_name = False
393 # Get the full type name for the field
394 field_type = type.name
397 # add the field to ourself
398 type.make_member_of(module, self, field_type, field_name, visible, True, False)
400 # recursively resolve the type (could be another structure, list)
403 for new_field in type.fields:
404 # We dump the _placeholder_byte if any fields are added.
405 for (idx, field) in enumerate(self.fields):
406 if field == _placeholder_byte:
407 self.fields[idx] = new_field
410 if False == inserted:
411 self.fields.append(new_field)
413 self.calc_size() # Figure out how big we are
416 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
417 if not self.fixed_size():
418 # We need a length field.
419 # Ask our Expression object for it's name, type, and whether it's on the wire.
420 lenfid = self.expr.lenfield_type
421 lenfield_name = self.expr.lenfield_name
422 lenwire = self.expr.lenwire
425 # See if the length field is already in the structure.
426 for parent in self.parents:
427 for field in parent.fields:
428 if field.field_name == lenfield_name:
431 # It isn't, so we need to add it to the structure ourself.
433 type = module.get_type(lenfid)
434 lenfield_type = module.get_type_name(lenfid)
435 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
437 # Add ourself to the structure by calling our original method.
438 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
440 # size for switch can only be calculated at runtime
444 # note: switch is _always_ of variable size, but we indicate here wether
445 # it contains elements that are variable-sized themselves
446 def fixed_size(self):
448 # for m in self.fields:
449 # if not m.type.fixed_size():
454 class Struct(ComplexType):
456 Derived class representing a struct data type.
458 out = __main__.output['struct']
461 class Union(ComplexType):
463 Derived class representing a union data type.
465 def __init__(self, name, elt):
466 ComplexType.__init__(self, name, elt)
469 out = __main__.output['union']
472 class BitcaseType(ComplexType):
474 Derived class representing a struct data type.
476 def __init__(self, index, name, elt, *parent):
478 self.expr = Expression(elts[0] if len(elts) else elt, self)
479 ComplexType.__init__(self, name, elts[1:])
482 self.lenfield_parent = list(parent) + [self]
483 self.parents = list(parent)
484 self.is_bitcase = True
486 def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto):
488 register BitcaseType with the corresponding SwitchType
490 module is the global module object.
491 complex_type is the structure object.
492 see Field for the meaning of the other parameters.
494 new_field = Field(self, field_type, field_name, visible, wire, auto)
496 # We dump the _placeholder_byte if any bitcases are added.
497 for (idx, field) in enumerate(switch_type.bitcases):
498 if field == _placeholder_byte:
499 switch_type.bitcases[idx] = new_field
502 switch_type.bitcases.append(new_field)
504 def resolve(self, module):
508 self.expr.resolve(module, self.parents+[self])
510 # Resolve the bitcase expression
511 ComplexType.resolve(self, module)
514 class Reply(ComplexType):
516 Derived class representing a reply. Only found as a field of Request.
518 def __init__(self, name, elt):
519 ComplexType.__init__(self, name, elt)
522 def resolve(self, module):
525 # Add the automatic protocol fields
526 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
527 self.fields.append(_placeholder_byte)
528 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
529 self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
530 ComplexType.resolve(self, module)
533 class Request(ComplexType):
535 Derived class representing a request.
538 reply contains the reply datatype or None for void requests.
539 opcode contains the request number.
541 def __init__(self, name, elt):
542 ComplexType.__init__(self, name, elt)
544 self.opcode = elt.get('opcode')
546 for child in list(elt):
547 if child.tag == 'reply':
548 self.reply = Reply(name, child)
550 def resolve(self, module):
553 # Add the automatic protocol fields
554 if module.namespace.is_ext:
555 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
556 self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
557 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
558 ComplexType.resolve(self, module)
560 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
561 self.fields.append(_placeholder_byte)
562 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
563 ComplexType.resolve(self, module)
566 self.reply.resolve(module)
568 out = __main__.output['request']
571 class Event(ComplexType):
573 Derived class representing an event data type.
576 opcodes is a dictionary of name -> opcode number, for eventcopies.
578 def __init__(self, name, elt):
579 ComplexType.__init__(self, name, elt)
582 tmp = elt.get('no-sequence-number')
583 self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
585 def add_opcode(self, opcode, name, main):
586 self.opcodes[name] = opcode
590 def resolve(self, module):
594 # Add the automatic protocol fields
595 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
597 self.fields.append(_placeholder_byte)
598 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
599 ComplexType.resolve(self, module)
601 out = __main__.output['event']
604 class Error(ComplexType):
606 Derived class representing an error data type.
609 opcodes is a dictionary of name -> opcode number, for errorcopies.
611 def __init__(self, name, elt):
612 ComplexType.__init__(self, name, elt)
615 def add_opcode(self, opcode, name, main):
616 self.opcodes[name] = opcode
620 def resolve(self, module):
624 # Add the automatic protocol fields
625 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
626 self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
627 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
628 ComplexType.resolve(self, module)
630 out = __main__.output['error']
632 _placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)