Skip to content

Commit 84d6ba5

Browse files
committed
rq: Support length fields that specify the length of multiple fields.
1 parent cbc31f5 commit 84d6ba5

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

Xlib/protocol/rq.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ class LengthField(Field):
161161
may vary, e.g. List and String8.
162162
163163
Its name should be the same as the name of the field whose size
164-
it stores.
164+
it stores. The other_fields attribute can be used to specify the
165+
names of other fields whose sizes are stored by this field, so
166+
a single length field can set the length of multiple fields.
165167
166168
The lf.get_binary_value() method of LengthFields is not used, instead
167169
a lf.get_binary_length() should be provided.
@@ -172,6 +174,7 @@ class LengthField(Field):
172174

173175
structcode = 'L'
174176
structvalues = 1
177+
other_fields = None
175178

176179
def calc_length(self, length):
177180
"""newlen = lf.calc_length(length)
@@ -202,7 +205,11 @@ def calc_length(self, length):
202205

203206
class LengthOf(LengthField):
204207
def __init__(self, name, size):
205-
self.name = name
208+
if isinstance(name, (list, tuple)):
209+
self.name = name[0]
210+
self.other_fields = name[1:]
211+
else:
212+
self.name = name
206213
self.structcode = unsigned_codes[size]
207214

208215

@@ -1222,12 +1229,16 @@ def parse_binary(self, data, display, rawdict = 0):
12221229
# when treating varfields.
12231230

12241231
elif isinstance(f, LengthField):
1225-
if f.parse_value is None:
1226-
lengths[f.name] = 'val[%d]' % vno
1227-
else:
1228-
lengths[f.name] = ('self.static_fields[%d].'
1229-
'parse_value(val[%d], display)'
1230-
% (fno, vno))
1232+
f_names = [f.name]
1233+
if f.other_fields:
1234+
f_names.extend(f.other_fields)
1235+
for f_name in f_names:
1236+
if f.parse_value is None:
1237+
lengths[f_name] = 'val[%d]' % vno
1238+
else:
1239+
lengths[f_name] = ('self.static_fields[%d].'
1240+
'parse_value(val[%d], display)'
1241+
% (fno, vno))
12311242

12321243
elif isinstance(f, FormatField):
12331244
formats[f.name] = 'val[%d]' % vno

0 commit comments

Comments
 (0)