[Xcb] [PATCH] XCB-XML: Proposal for alignment padding

Evgeny M. Zubok evgeny.zubok at tochka.ru
Mon Nov 8 08:39:36 PST 2010


Julien Cristau <jcristau at debian.org>
writes:

>> After examining a full set of X Protocol extensions which are
>> available in XCB I conclude that the following form is suitable to
>> cover different padding schemas:
>> 
>> <pad align="integer">expression</pad>
>> 

> I don't get why you need the expression here.  What you seem to want is
> 'the next field is aligned on a "integer" boundary', which doesn't
> require a reference to the preceding field(s), unless I'm missing
> something?

This is usually the case with the last pad in structure. The last pad
expression in requests and replies can be omited by code generator and
can be interpreted as 4-byte alignment from all previous
fields. However, the X Window System specification defines padding as
function pad(E), where E is expression.

Look at the example 3. If we compute padding only from preceding list
'string', we'll get incorrect pad size for structure SYSTEMCOUNTER
(sync.xml):

4    COUNTER    counter
8    INT64      resolution
2    n          length of name in bytes
n    STRING8    name
p               pad, p=pad(n+2)

If the 'name' would have length 1, then pad without expression will be 3
bytes. It should be equal to pad(1+2)=1 byte. Although the same result
we will get if compute padding from total size of structure (bacause
first two fields already have a total size that multiple of 4). Below
the one iteration step on the LISTofSYSTEMCOUNTERs from
xorg/lib/libXext/src/XSync.c:

pNextWireSysCounter = (xSyncSystemCounter *)
  (((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
		     pWireSysCounter->name_length + 3) & ~3));

As we can see, the padding is calculated not from the size of list
'name' but from the sum of previous fields and the list size.



Also look at the example 4: This is ListComponents request from xkb.xml:

The spec states:

p        unused, p=pad(6+m+k+t+c+s+g)

The lists from this request follow one after another without padding
between them. If all lists would have the length 1, then
pad(6+1+1+1+1+1+1)=0. In the present C-implementation, the last padding
is always calculated from the previous list length (xcb_part[7] is
calculated from xcb_part[6] length)

xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;

If such schema will be applied to the request below we will get pad(1)=3
instead 0.

<request name="ListComponents" opcode="22">
  <field name="deviceSpec" type="DeviceSpec" />
  <field name="maxNames" type="CARD16" />
  <field name="keymapsSpecLen" type="CARD8" />
  <list name="keymapsSpec" type="STRING8">
    <fieldref>keymapsSpecLen</fieldref>
  </list>
  <field name="keycodesSpecLen" type="CARD8" />
    <list name="keycodesSpec" type="STRING8">
    <fieldref>keycodesSpecLen</fieldref>
  </list>
  <field name="typesSpecLen" type="CARD8" />
  <list name="typesSpec" type="STRING8">
    <fieldref>typesSpecLen</fieldref>
  </list>
  <field name="compatMapSpecLen" type="CARD8" />
  <list name="compatMapSpec" type="STRING8">
    <fieldref>compatMapSpecLen</fieldref>
  </list>
  <field name="symbolsSpecLen" type="CARD8" />
  <list name="symbolsSpec" type="STRING8">
    <fieldref>symbolsSpecLen</fieldref>
  </list>
  <field name="geometrySpecLen" type="CARD8" />
  <list name="geometrySpec" type="STRING8">
    <fieldref>geometrySpecLen</fieldref>
  </list>
  <pad align="4">
    <op op="+"><sizeof>keymapsSpec</sizeof>
    <op op="+"><sizeof>keycodesSpec</sizeof>
    <op op="+"><sizeof>typesSpec</sizeof>
    <op op="+"><sizeof>compatMapSpec</sizeof>
    <op op="+"><sizeof>symbolsSpec</sizeof>
    <op op="+"><sizeof>geometrySpec</sizeof>
    <value>6</value>
    </op></op></op></op></op></op>
  </pad>
  <reply>
    ...
  </reply>
</request>


If we will drop the expression from <pad> then we should constanly
calculate current total legth of request and insert
p=pad(total_length_at_this_place). IMHO, It's better to express padding
as it is described in specification. Then we don't need constantly
calculate the total length of all fields from structure and could only
include those lengths which are referenced by expression inside
<pad>. Anyway, the implementation details can be chosen by implementor
of code generator.

BTW, my first version of this proposal included both a simplified form
<pad align="4" /> with exact interpretation as yours ("pad from total
length of structure at this place") and <pad> with expression.



More information about the Xcb mailing list