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
36 def resolve(self, module):
38 Abstract method for resolving a type.
39 This should make sure any referenced types are already declared.
41 raise Exception('abstract resolve method not overridden!')
45 Abstract method for outputting code.
46 These are declared in the language-specific modules, and
47 there must be a dictionary containing them declared when this module is imported!
49 raise Exception('abstract out method not overridden!')
53 Abstract method for determining if the data type is fixed-size.
55 raise Exception('abstract fixed_size method not overridden!')
57 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
59 Default method for making a data type a member of a structure.
60 Extend this if the data type needs to add an additional length field or something.
62 module is the global module object.
63 complex_type is the structure object.
64 see Field for the meaning of the other parameters.
66 new_field = Field(self, field_type, field_name, visible, wire, auto)
68 # We dump the _placeholder_byte if any fields are added.
69 for (idx, field) in enumerate(complex_type.fields):
70 if field == _placeholder_byte:
71 complex_type.fields[idx] = new_field
74 complex_type.fields.append(new_field)
76 class SimpleType(Type):
78 Derived class which represents a cardinal type like CARD32 or char.
79 Any type which is typedef'ed to cardinal will be one of these.
84 def __init__(self, name, size):
85 Type.__init__(self, name)
90 def resolve(self, module):
96 out = __main__.output['simple']
99 # Cardinal datatype globals. See module __init__ method.
100 tcard8 = SimpleType(('uint8_t',), 1)
101 tcard16 = SimpleType(('uint16_t',), 2)
102 tcard32 = SimpleType(('uint32_t',), 4)
103 tint8 = SimpleType(('int8_t',), 1)
104 tint16 = SimpleType(('int16_t',), 2)
105 tint32 = SimpleType(('int32_t',), 4)
106 tchar = SimpleType(('char',), 1)
107 tfloat = SimpleType(('float',), 4)
108 tdouble = SimpleType(('double',), 8)
111 class Enum(SimpleType):
113 Derived class which represents an enum. Fixed-size.
116 values contains a list of (name, value) tuples. value is empty, or a number.
117 bits contains a list of (name, bitnum) tuples. items only appear if specified as a bit. bitnum is a number.
119 def __init__(self, name, elt):
120 SimpleType.__init__(self, name, 4)
123 for item in list(elt):
124 # First check if we're using a default value
125 if len(list(item)) == 0:
126 self.values.append((item.get('name'), ''))
129 # An explicit value or bit was specified.
130 value = list(item)[0]
131 if value.tag == 'value':
132 self.values.append((item.get('name'), value.text))
133 elif value.tag == 'bit':
134 self.values.append((item.get('name'), '%u' % (1 << int(value.text))))
135 self.bits.append((item.get('name'), value.text))
137 def resolve(self, module):
140 def fixed_size(self):
143 out = __main__.output['enum']
146 class ListType(Type):
148 Derived class which represents a list of some other datatype. Fixed- or variable-sized.
151 member is the datatype of the list elements.
152 parent is the structure type containing the list.
153 expr is an Expression object containing the length information, for variable-sized lists.
155 def __init__(self, elt, member, parent):
156 Type.__init__(self, member.name)
161 if elt.tag == 'list':
163 self.expr = Expression(elts[0] if len(elts) else elt, self)
164 elif elt.tag == 'valueparam':
165 self.expr = Expression(elt, self)
167 self.size = member.size if member.fixed_size() else None
168 self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
170 def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
171 if not self.fixed_size():
172 # We need a length field.
173 # Ask our Expression object for it's name, type, and whether it's on the wire.
174 lenfid = self.expr.lenfield_type
175 lenfield_name = self.expr.lenfield_name
176 lenwire = self.expr.lenwire
179 # See if the length field is already in the structure.
180 for field in self.parent.fields:
181 if field.field_name == lenfield_name:
184 # It isn't, so we need to add it to the structure ourself.
186 type = module.get_type(lenfid)
187 lenfield_type = module.get_type_name(lenfid)
188 type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
190 # Add ourself to the structure by calling our original method.
191 Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
193 def resolve(self, module):
196 self.member.resolve(module)
198 # Find my length field again. We need the actual Field object in the expr.
199 # This is needed because we might have added it ourself above.
200 if not self.fixed_size():
201 for field in self.parent.fields:
202 if field.field_name == self.expr.lenfield_name and field.wire:
203 self.expr.lenfield = field
208 def fixed_size(self):
209 return self.member.fixed_size() and self.expr.fixed_size()
211 class ExprType(Type):
213 Derived class which represents an exprfield. Fixed size.
216 expr is an Expression object containing the value of the field.
218 def __init__(self, elt, member, parent):
219 Type.__init__(self, member.name)
224 self.expr = Expression(list(elt)[0], self)
226 self.size = member.size
229 def resolve(self, module):
232 self.member.resolve(module)
235 def fixed_size(self):
238 class SizedPadType(Type):
240 Derived class which represents a padding field of given size.
242 def __init__(self, size):
243 Type.__init__(self, tcard8.name)
246 self.nmemb = int(size)
248 def resolve(self, module):
251 def fixed_size(self):
254 class PadType(SizedPadType):
256 Derived class which represents a padding field of given type.
258 def __init__(self, elt):
259 self.nmemb = "1" if (elt == None) else elt.get('bytes')
260 SizedPadType.__init__(self, self.nmemb)
262 class ComplexType(Type):
264 Derived class which represents a structure. Base type for all structure types.
267 fields is an array of Field objects describing the structure fields.
269 def __init__(self, name, elt):
270 Type.__init__(self, name)
271 self.is_container = True
277 def resolve(self, module):
282 # Resolve all of our field datatypes.
283 for child in list(self.elt):
284 value_mask_pad = None
285 if child.tag == 'pad':
286 field_name = 'pad' + str(pads)
288 type = PadType(child)
291 elif child.tag == 'field':
292 field_name = child.get('name')
293 fkey = child.get('type')
294 type = module.get_type(fkey)
296 elif child.tag == 'exprfield':
297 field_name = child.get('name')
298 fkey = child.get('type')
299 type = ExprType(child, module.get_type(fkey), self)
301 elif child.tag == 'list':
302 field_name = child.get('name')
303 fkey = child.get('type')
304 type = ListType(child, module.get_type(fkey), self)
306 elif child.tag == 'valueparam':
307 field_name = child.get('value-list-name')
309 type = ListType(child, module.get_type(fkey), self)
311 value_mask_pad = child.get('value-mask-pad')
316 # Get the full type name for the field
317 field_type = module.get_type_name(fkey)
318 # Add the field to ourself
319 type.make_member_of(module, self, field_type, field_name, visible, True, False)
320 # Recursively resolve the type (could be another structure, list)
323 # Add a value-mask-pad if necessary
324 if value_mask_pad != None:
325 vmp_field_name = 'pad' + str(pads)
327 vmp_type = SizedPadType(value_mask_pad)
330 vmp_field_type = module.get_type_name(vmp_fkey)
331 vmp_type.make_member_of(module, self, vmp_field_type, vmp_field_name, vmp_visible, True, False)
332 vmp_type.resolve(module)
334 self.calc_size() # Figure out how big we are
339 for m in self.fields:
342 if m.type.fixed_size():
343 self.size = self.size + (m.type.size * m.type.nmemb)
348 def fixed_size(self):
349 for m in self.fields:
350 if not m.type.fixed_size():
355 class Struct(ComplexType):
357 Derived class representing a struct data type.
359 out = __main__.output['struct']
362 class Union(ComplexType):
364 Derived class representing a union data type.
366 def __init__(self, name, elt):
367 ComplexType.__init__(self, name, elt)
370 out = __main__.output['union']
373 class Reply(ComplexType):
375 Derived class representing a reply. Only found as a field of Request.
377 def __init__(self, name, elt):
378 ComplexType.__init__(self, name, elt)
381 def resolve(self, module):
384 # Add the automatic protocol fields
385 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
386 self.fields.append(_placeholder_byte)
387 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
388 self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
389 ComplexType.resolve(self, module)
392 class Request(ComplexType):
394 Derived class representing a request.
397 reply contains the reply datatype or None for void requests.
398 opcode contains the request number.
400 def __init__(self, name, elt):
401 ComplexType.__init__(self, name, elt)
403 self.opcode = elt.get('opcode')
405 for child in list(elt):
406 if child.tag == 'reply':
407 self.reply = Reply(name, child)
409 def resolve(self, module):
412 # Add the automatic protocol fields
413 if module.namespace.is_ext:
414 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
415 self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
416 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
417 ComplexType.resolve(self, module)
419 self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
420 self.fields.append(_placeholder_byte)
421 self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
422 ComplexType.resolve(self, module)
425 self.reply.resolve(module)
427 out = __main__.output['request']
430 class Event(ComplexType):
432 Derived class representing an event data type.
435 opcodes is a dictionary of name -> opcode number, for eventcopies.
437 def __init__(self, name, elt):
438 ComplexType.__init__(self, name, elt)
441 tmp = elt.get('no-sequence-number')
442 self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
444 def add_opcode(self, opcode, name, main):
445 self.opcodes[name] = opcode
449 def resolve(self, module):
453 # Add the automatic protocol fields
454 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
456 self.fields.append(_placeholder_byte)
457 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
458 ComplexType.resolve(self, module)
460 out = __main__.output['event']
463 class Error(ComplexType):
465 Derived class representing an error data type.
468 opcodes is a dictionary of name -> opcode number, for errorcopies.
470 def __init__(self, name, elt):
471 ComplexType.__init__(self, name, elt)
474 def add_opcode(self, opcode, name, main):
475 self.opcodes[name] = opcode
479 def resolve(self, module):
483 # Add the automatic protocol fields
484 self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
485 self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
486 self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
487 ComplexType.resolve(self, module)
489 out = __main__.output['error']
491 _placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)