[Xcb] [PATCH proto 1/2] Add sizeof tag to struct

Daniel Martin consume.noise at gmail.com
Sun Dec 23 06:29:23 PST 2012


If a struct provides all necessary informations to calculate it's
size, i.e. an explicit length field, this sizeof tag makes it possible
to reference to the length field with an expression (known from lists).
This makes further iterations over these structs very easy, as we don't
have to sum up all field lengths, lists and may add padding.

structs with such a length field can be found in the XInput extension.
For example the device classes (xXIButtonInfo, xXIKeyInfo, ...):
  http://cgit.freedesktop.org/xorg/proto/inputproto/tree/XI2proto.h#n136

Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
 doc/xml-xcb.txt  | 12 +++++++++++-
 src/xcb.xsd      |  7 +++++++
 xcbgen/xtypes.py | 25 +++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/doc/xml-xcb.txt b/doc/xml-xcb.txt
index 15121be..91ffdeb 100644
--- a/doc/xml-xcb.txt
+++ b/doc/xml-xcb.txt
@@ -61,7 +61,10 @@ Top-Level Elements
   root node.  Note that types from xproto are automatically available, without
   explicitly importing them.
 
-<struct name="identifier" [packed="true"]>structure contents</struct>
+<struct name="identifier" [packed="true"]>
+  structure contents
+  [<sizeof>expression</sizeof>]
+</struct>
 
   This element represents a data structure.  The name attribute gives the name
   of the structure.  The content represents the fields of the structure, and
@@ -72,6 +75,13 @@ Top-Level Elements
   part of the data structure is not a multiple of 4 and it mustn't be
   aligned to the next 4byte boundary.
 
+  If the optional sizeof element is present it provides a simple way to
+  compute the struct size at runtime. This is usefull if the struct itself
+  contains a length field referencing the whole struct. With that given it's
+  not necessary to sum up all fields, lists and pads of the struct.
+  DO NOT use it the work around alignmend issues. Use the packed attribute
+  for that.
+
 <union name="identifier">structure contents</union>
 
   This element represents a union of data types, which can hold one value of
diff --git a/src/xcb.xsd b/src/xcb.xsd
index bcad558..98111be 100644
--- a/src/xcb.xsd
+++ b/src/xcb.xsd
@@ -188,6 +188,12 @@ authorization from the authors.
     </xsd:choice>
   </xsd:group>
 
+  <xsd:element name="sizeof">
+    <xsd:complexType>
+      <xsd:group ref="expression" minOccurs="1" maxOccurs="1" />
+    </xsd:complexType>
+  </xsd:element>
+
   <!-- Type for a structure -->
   <xsd:complexType name="struct">
     <xsd:sequence>
@@ -195,6 +201,7 @@ authorization from the authors.
       <xsd:choice minOccurs="0" maxOccurs="1">
         <xsd:element ref="switch" />
       </xsd:choice>
+      <xsd:element ref="sizeof" minOccurs="0" maxOccurs="1" />
     </xsd:sequence>
     <xsd:attribute name="name" type="xsd:string" use="required" />
     <xsd:attribute name="packed" type="xsd:boolean" use="optional" />
diff --git a/xcbgen/xtypes.py b/xcbgen/xtypes.py
index e6d15c8..a799d2e 100644
--- a/xcbgen/xtypes.py
+++ b/xcbgen/xtypes.py
@@ -464,6 +464,31 @@ class Struct(ComplexType):
     def __init__(self, name, elt):
         ComplexType.__init__(self, name, elt)
         self.packed = elt.get('packed')
+        self.sizeof_expr = None
+
+        for child in list(elt):
+            if child.tag == 'sizeof':
+                self.sizeof_expr = Expression(child[0], self)
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+
+        ComplexType.resolve(self, module)
+        if self.sizeof_expr != None:
+            self.sizeof_expr.resolve(module, self)
+
+    def calc_size(self):
+        if self.sizeof_expr != None:
+            pass
+        else:
+            ComplexType.calc_size(self)
+
+    def fixed_size(self):
+        if self.sizeof_expr != None:
+            return False
+        else:
+            return ComplexType.fixed_size(self)
 
     out = __main__.output['struct']
 
-- 
1.8.0.2



More information about the Xcb mailing list