2 This module contains helper classes for structure fields and length expressions.
6 Represents a field of a structure.
8 type is the datatype object for the field.
9 field_type is the name of the type (string tuple)
10 field_name is the name of the structure field.
11 visible is true iff the field should be in the request API.
12 wire is true iff the field should be in the request structure.
13 auto is true iff the field is on the wire but not in the request API (e.g. opcode)
15 def __init__(self, type, field_type, field_name, visible, wire, auto):
17 self.field_type = field_type
18 self.field_name = field_name
19 self.visible = visible
24 class Expression(object):
26 Represents a mathematical expression for a list length or exprfield.
29 op is the operation (text +,*,/,<<,~) or None.
30 lhs and rhs are the sub-Expressions if op is set.
31 lenfield_name is the name of the length field, or None for request lists.
32 lenfield is the Field object for the length field, or None.
33 bitfield is True if the length field is a bitmask instead of a number.
34 nmemb is the fixed size (value)of the expression, or None
36 def __init__(self, elt, parent):
41 self.lenfield_name = None
42 self.lenfield_type = None
43 self.lenfield_parent = None
53 # List going into a request, which has no length field (inferred by server)
54 self.lenfield_name = elt.get('name') + '_len'
55 self.lenfield_type = 'CARD32'
57 elif elt.tag == 'fieldref':
58 # Standard list with a fieldref
59 self.lenfield_name = elt.text
61 elif elt.tag == 'valueparam':
62 # Value-mask. The length bitmask is described by attributes.
63 self.lenfield_name = elt.get('value-mask-name')
64 self.lenfield_type = elt.get('value-mask-type')
69 # Op field. Need to recurse.
70 self.op = elt.get('op')
71 self.lhs = Expression(list(elt)[0], parent)
72 self.rhs = Expression(list(elt)[1], parent)
74 # Hopefully we don't have two separate length fields...
75 self.lenfield_name = self.lhs.lenfield_name
76 if self.lenfield_name == None:
77 self.lenfield_name = self.rhs.lenfield_name
79 elif elt.tag == 'unop':
80 # Op field. Need to recurse.
81 self.op = elt.get('op')
82 self.rhs = Expression(list(elt)[0], parent)
84 self.lenfield_name = self.rhs.lenfield_name
86 elif elt.tag == 'value':
88 self.nmemb = int(elt.text, 0)
90 elif elt.tag == 'popcount':
92 self.rhs = Expression(list(elt)[0], parent)
93 self.lenfield_name = self.rhs.lenfield_name
94 # xcb_popcount returns 'int' - handle the type in the language-specific part
96 elif elt.tag == 'enumref':
98 self.lenfield_name = (elt.get('ref'), elt.text)
100 elif elt.tag == 'sumof':
102 self.lenfield_name = elt.get('ref')
106 raise Exception("undefined tag '%s'" % elt.tag)
108 def fixed_size(self):
109 return self.nmemb != None
111 def resolve(self, module, parents):
112 if self.op == 'enumref':
113 self.lenfield_type = module.get_type(self.lenfield_name[0])
114 self.lenfield_name = self.lenfield_name[1]
115 elif self.op == 'sumof':
116 # need to find the field with lenfield_name
117 for p in reversed(parents):
118 fields = dict([(f.field_name, f) for f in p.fields])
119 if self.lenfield_name in fields.keys():
121 # switch is the anchestor
122 self.lenfield_parent = p.parents[-1]
124 self.lenfield_parent = p
125 self.lenfield_type = fields[self.lenfield_name].field_type