calculate lengthless list
Some rework done by Christian Linhart Signed-off-by: Jaya Tiwari <tiwari.jaya18@gmail.com> Signed-off-by: Christian Linhart <chris@demorecorder.com>
This commit is contained in:
parent
7758257567
commit
c03388ff9e
|
@ -471,7 +471,8 @@ def _c_type_setup(self, name, postfix):
|
||||||
field.first_field_after_varsized = first_field_after_varsized
|
field.first_field_after_varsized = first_field_after_varsized
|
||||||
|
|
||||||
if field.type.fixed_size():
|
if field.type.fixed_size():
|
||||||
prev_varsized_offset += field.type.size
|
if field.wire:
|
||||||
|
prev_varsized_offset += field.type.size
|
||||||
# special case: intermixed fixed and variable size fields
|
# special case: intermixed fixed and variable size fields
|
||||||
if prev_varsized_field is not None and not field.type.is_pad and field.wire:
|
if prev_varsized_field is not None and not field.type.is_pad and field.wire:
|
||||||
if not self.is_union:
|
if not self.is_union:
|
||||||
|
@ -649,7 +650,7 @@ def get_expr_fields(self):
|
||||||
get the Fields referenced by switch or list expression
|
get the Fields referenced by switch or list expression
|
||||||
"""
|
"""
|
||||||
def get_expr_field_names(expr):
|
def get_expr_field_names(expr):
|
||||||
if expr.op is None:
|
if expr.op is None or expr.op == 'calculate_len':
|
||||||
if expr.lenfield_name is not None:
|
if expr.lenfield_name is not None:
|
||||||
return [expr.lenfield_name]
|
return [expr.lenfield_name]
|
||||||
else:
|
else:
|
||||||
|
@ -726,15 +727,17 @@ def resolve_expr_fields_list(self, parents):
|
||||||
all_fields = []
|
all_fields = []
|
||||||
expr_fields = get_expr_fields(self)
|
expr_fields = get_expr_fields(self)
|
||||||
unresolved = []
|
unresolved = []
|
||||||
|
dont_resolve_this = ''
|
||||||
for complex_obj in parents:
|
for complex_obj in parents:
|
||||||
for field in complex_obj.fields:
|
for field in complex_obj.fields:
|
||||||
|
if field.type.is_list and field.type.expr.op == 'calculate_len':
|
||||||
|
dont_resolve_this = field.type.expr.lenfield_name
|
||||||
if field.wire:
|
if field.wire:
|
||||||
all_fields.append(field)
|
all_fields.append(field)
|
||||||
|
|
||||||
# try to resolve expr fields
|
# try to resolve expr fields
|
||||||
for e in expr_fields:
|
for e in expr_fields:
|
||||||
if e not in all_fields and e not in unresolved:
|
if e not in all_fields and e not in unresolved and e.field_name != dont_resolve_this:
|
||||||
unresolved.append(e)
|
unresolved.append(e)
|
||||||
|
|
||||||
return unresolved
|
return unresolved
|
||||||
|
@ -775,7 +778,9 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
|
||||||
# _serialize()/_unserialize()/_unpack() function parameters
|
# _serialize()/_unserialize()/_unpack() function parameters
|
||||||
# note: don't use set() for params, it is unsorted
|
# note: don't use set() for params, it is unsorted
|
||||||
params = []
|
params = []
|
||||||
|
parameter = ''
|
||||||
|
if self.is_list:
|
||||||
|
parameter = self.type.expr.lenfield_name
|
||||||
# 1. the parameter for the void * buffer
|
# 1. the parameter for the void * buffer
|
||||||
if 'serialize' == context:
|
if 'serialize' == context:
|
||||||
params.append(('void', '**', buffer_var))
|
params.append(('void', '**', buffer_var))
|
||||||
|
@ -795,7 +800,7 @@ def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
|
||||||
pointerspec = p.c_pointer
|
pointerspec = p.c_pointer
|
||||||
add_param(params, (typespec, pointerspec, p.c_field_name))
|
add_param(params, (typespec, pointerspec, p.c_field_name))
|
||||||
else:
|
else:
|
||||||
if p.visible and not p.wire and not p.auto:
|
if p.visible and not p.wire and not p.auto and p.field_name != parameter:
|
||||||
typespec = p.c_field_type
|
typespec = p.c_field_type
|
||||||
pointerspec = ''
|
pointerspec = ''
|
||||||
add_param(params, (typespec, pointerspec, p.c_field_name))
|
add_param(params, (typespec, pointerspec, p.c_field_name))
|
||||||
|
@ -984,8 +989,10 @@ def _c_serialize_helper_list_field(context, self, field,
|
||||||
unresolved = [x for x in unresolved if x not in field_mapping]
|
unresolved = [x for x in unresolved if x not in field_mapping]
|
||||||
if len(unresolved)>0:
|
if len(unresolved)>0:
|
||||||
raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
|
raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
|
||||||
|
if expr.op == 'calculate_len':
|
||||||
list_length = _c_accessor_get_expr(expr, field_mapping)
|
list_length = field.type.expr.lenfield_name
|
||||||
|
else:
|
||||||
|
list_length = _c_accessor_get_expr(expr, field_mapping)
|
||||||
|
|
||||||
# default: list with fixed size elements
|
# default: list with fixed size elements
|
||||||
length = '%s * sizeof(%s)' % (list_length, field.type.member.c_wiretype)
|
length = '%s * sizeof(%s)' % (list_length, field.type.member.c_wiretype)
|
||||||
|
@ -1723,7 +1730,7 @@ def _c_accessor_get_expr(expr, field_mapping):
|
||||||
return sumvar
|
return sumvar
|
||||||
elif expr.op == 'listelement-ref':
|
elif expr.op == 'listelement-ref':
|
||||||
return '(*xcb_listelement)'
|
return '(*xcb_listelement)'
|
||||||
elif expr.op != None:
|
elif expr.op != None and expr.op != 'calculate_len':
|
||||||
return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) +
|
return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) +
|
||||||
' ' + expr.op + ' ' +
|
' ' + expr.op + ' ' +
|
||||||
_c_accessor_get_expr(expr.rhs, field_mapping) + ')')
|
_c_accessor_get_expr(expr.rhs, field_mapping) + ')')
|
||||||
|
@ -1913,8 +1920,34 @@ def _c_accessors_list(self, field):
|
||||||
_h('%s (const %s *R%s);', field.c_length_name, c_type, add_param_str)
|
_h('%s (const %s *R%s);', field.c_length_name, c_type, add_param_str)
|
||||||
_c('%s (const %s *R%s)', field.c_length_name, c_type, add_param_str)
|
_c('%s (const %s *R%s)', field.c_length_name, c_type, add_param_str)
|
||||||
_c('{')
|
_c('{')
|
||||||
length = _c_accessor_get_expr(field.type.expr, fields)
|
|
||||||
_c(' return %s;', length)
|
def get_length():
|
||||||
|
if field.type.expr.op == 'calculate_len':
|
||||||
|
if field.type.member.fixed_size():
|
||||||
|
if field.prev_varsized_field is None:
|
||||||
|
# the list is directly after the fixed size part of the
|
||||||
|
# request: simply subtract the size of the fixed-size part
|
||||||
|
# from the request size and divide that by the member size
|
||||||
|
return '(((R->length * 4) - sizeof('+ self.c_type + '))/'+'sizeof('+field.type.member.c_wiretype+'))'
|
||||||
|
else:
|
||||||
|
# use the accessor to get the start of the list, then
|
||||||
|
# compute the length of it by subtracting it from
|
||||||
|
# the adress of the first byte after the end of the
|
||||||
|
# request
|
||||||
|
after_end_of_request = '(((char*)R) + R->length * 4)'
|
||||||
|
start_of_list = '%s(R)' % (field.c_accessor_name)
|
||||||
|
bytesize_of_list = '%s - (char*)(%s)' % (after_end_of_request, start_of_list)
|
||||||
|
return '(%s) / sizeof(%s)' % (bytesize_of_list, field.type.member.c_wiretype)
|
||||||
|
else:
|
||||||
|
raise Exception(
|
||||||
|
"lengthless lists with varsized members are not supported. Fieldname '%s'"
|
||||||
|
%
|
||||||
|
(field.c_field_name)
|
||||||
|
);
|
||||||
|
else:
|
||||||
|
return _c_accessor_get_expr(field.type.expr, fields)
|
||||||
|
|
||||||
|
_c(' return %s;', get_length())
|
||||||
_c('}')
|
_c('}')
|
||||||
|
|
||||||
if field.type.member.is_simple:
|
if field.type.member.is_simple:
|
||||||
|
@ -1935,10 +1968,10 @@ def _c_accessors_list(self, field):
|
||||||
param = 'R' if switch_obj is None else 'S'
|
param = 'R' if switch_obj is None else 'S'
|
||||||
if switch_obj is not None:
|
if switch_obj is not None:
|
||||||
_c(' i.data = %s + %s;', fields[field.c_field_name][0],
|
_c(' i.data = %s + %s;', fields[field.c_field_name][0],
|
||||||
_c_accessor_get_expr(field.type.expr, fields))
|
get_length())
|
||||||
elif field.prev_varsized_field == None:
|
elif field.prev_varsized_field == None:
|
||||||
_c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype,
|
_c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype,
|
||||||
_c_accessor_get_expr(field.type.expr, fields))
|
get_length())
|
||||||
else:
|
else:
|
||||||
(prev_varsized_field, align_pad) = get_align_pad(field)
|
(prev_varsized_field, align_pad) = get_align_pad(field)
|
||||||
|
|
||||||
|
@ -1950,7 +1983,7 @@ def _c_accessors_list(self, field):
|
||||||
_c_iterator_get_end(prev_varsized_field, 'R'))
|
_c_iterator_get_end(prev_varsized_field, 'R'))
|
||||||
_c(' i.data = ((%s *) ((char*) prev.data + %s)) + (%s);',
|
_c(' i.data = ((%s *) ((char*) prev.data + %s)) + (%s);',
|
||||||
field.type.c_wiretype, align_pad,
|
field.type.c_wiretype, align_pad,
|
||||||
_c_accessor_get_expr(field.type.expr, fields))
|
get_length())
|
||||||
|
|
||||||
_c(' i.rem = 0;')
|
_c(' i.rem = 0;')
|
||||||
_c(' i.index = (char *) i.data - (char *) %s;', param)
|
_c(' i.index = (char *) i.data - (char *) %s;', param)
|
||||||
|
@ -1961,7 +1994,6 @@ def _c_accessors_list(self, field):
|
||||||
_hc('')
|
_hc('')
|
||||||
_hc('%s', field.c_iterator_type)
|
_hc('%s', field.c_iterator_type)
|
||||||
spacing = ' '*(len(field.c_iterator_name)+2)
|
spacing = ' '*(len(field.c_iterator_name)+2)
|
||||||
add_param_str = additional_params_to_str(spacing)
|
|
||||||
if switch_obj is not None:
|
if switch_obj is not None:
|
||||||
_hc('%s (const %s *R,', field.c_iterator_name, R_obj.c_type)
|
_hc('%s (const %s *R,', field.c_iterator_name, R_obj.c_type)
|
||||||
_h('%sconst %s *S%s);', spacing, S_obj.c_type, add_param_str)
|
_h('%sconst %s *S%s);', spacing, S_obj.c_type, add_param_str)
|
||||||
|
@ -1973,7 +2005,7 @@ def _c_accessors_list(self, field):
|
||||||
_c(' %s i;', field.c_iterator_type)
|
_c(' %s i;', field.c_iterator_type)
|
||||||
|
|
||||||
_c_pre.start()
|
_c_pre.start()
|
||||||
length_expr_str = _c_accessor_get_expr(field.type.expr, fields)
|
length_expr_str = get_length()
|
||||||
|
|
||||||
if switch_obj is not None:
|
if switch_obj is not None:
|
||||||
_c_pre.end()
|
_c_pre.end()
|
||||||
|
@ -2356,11 +2388,16 @@ def _c_request_helper(self, name, void, regular, aux=False, reply_fds=False):
|
||||||
_c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
|
_c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
|
||||||
if field.type.is_list:
|
if field.type.is_list:
|
||||||
if field.type.member.fixed_size():
|
if field.type.member.fixed_size():
|
||||||
_c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count,
|
if field.type.expr.op == 'calculate_len':
|
||||||
_c_accessor_get_expr(field.type.expr, None),
|
lenfield = field.type.expr.lenfield_name
|
||||||
field.type.member.c_wiretype)
|
else:
|
||||||
|
lenfield = _c_accessor_get_expr(field.type.expr, None)
|
||||||
|
|
||||||
|
_c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, lenfield,
|
||||||
|
field.type.member.c_wiretype)
|
||||||
else:
|
else:
|
||||||
list_length = _c_accessor_get_expr(field.type.expr, None)
|
list_length = _c_accessor_get_expr(field.type.expr, None)
|
||||||
|
length = ''
|
||||||
|
|
||||||
_c(" xcb_parts[%d].iov_len = 0;" % count)
|
_c(" xcb_parts[%d].iov_len = 0;" % count)
|
||||||
_c(" xcb_tmp = (char *)%s;", field.c_field_name)
|
_c(" xcb_tmp = (char *)%s;", field.c_field_name)
|
||||||
|
@ -3115,9 +3152,12 @@ def c_request(self, name):
|
||||||
if self.c_need_aux:
|
if self.c_need_aux:
|
||||||
_c_request_helper(self, name, void=True, regular=False, aux=True)
|
_c_request_helper(self, name, void=True, regular=False, aux=True)
|
||||||
_c_request_helper(self, name, void=True, regular=True, aux=True)
|
_c_request_helper(self, name, void=True, regular=True, aux=True)
|
||||||
if config_server_side:
|
for field in self.fields:
|
||||||
_c_accessors(self, name, name)
|
if not field.type.is_pad and field.wire:
|
||||||
|
if _c_field_needs_list_accessor(field):
|
||||||
|
_c_accessors_list(self, field)
|
||||||
|
elif _c_field_needs_field_accessor(field):
|
||||||
|
_c_accessors_field(self, field)
|
||||||
# We generate the manpage afterwards because _c_type_setup has been called.
|
# We generate the manpage afterwards because _c_type_setup has been called.
|
||||||
# TODO: what about aux helpers?
|
# TODO: what about aux helpers?
|
||||||
_man_request(self, name, void=not self.reply, aux=False)
|
_man_request(self, name, void=not self.reply, aux=False)
|
||||||
|
|
Loading…
Reference in New Issue