Store SpicePath segment count rather than size

Internally and in the network protocol (for the new version) we
now store the actual number of segments rather than the size of the
full segments array in bytes. This change consists of multiple changes
to handle this:

* Make the qxl parser calculate num_segments
* Make the canvas stroke code handle the new SpicePath layout.
* Fix up is_equal_path in red_worker.c for the new layout
* replace multiple calls to spice_marshall_PathSegment with a single
  spice_marshall_Path call
* Make the byte_size() array size handling do the conversion from
  network size to number of elements when marshalling/demarshalling.
* Update the current spice protocol to send the segment count rather than
  the size
* Update the old spice protocol to use the new byte_size functionallity
  to calculate the size sent and the number of elements recieved
This commit is contained in:
Alexander Larsson 2010-06-29 21:42:59 +02:00 committed by Marc-André Lureau
parent 140cf2aa79
commit e42c910b5c
5 changed files with 37 additions and 16 deletions

View File

@ -604,7 +604,7 @@ def read_array_len(writer, prefix, array, dest, scope, handles_bytes = False):
elif array.is_bytes_length():
if not handles_bytes:
raise NotImplementedError("handling of bytes() not supported here yet")
writer.assign(nelements, dest.get_ref(array.size[1]))
writer.assign(nelements, array.size[1])
else:
raise NotImplementedError("TODO array size type not handled yet")
return nelements
@ -714,10 +714,15 @@ def write_array_parser(writer, nelements, array, dest, scope):
writer.increment("end", nelements)
else:
if is_byte_size:
real_nelements = nelements[:-len("nbytes")] + "nelements"
scope.variable_def("uint8_t *", "array_end")
scope.variable_def("uint32_t", real_nelements)
writer.assign("array_end", "end + %s" % nelements)
writer.assign(real_nelements, 0)
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("end < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope:
if is_byte_size:
writer.increment(real_nelements, 1)
if element_type.is_primitive():
writer.statement("*(%s *)end = consume_%s(&in)" % (element_type.c_type(), element_type.primitive_type()))
writer.increment("end", element_type.sizeof())
@ -725,6 +730,8 @@ def write_array_parser(writer, nelements, array, dest, scope):
dest2 = dest.child_at_end(writer, element_type)
dest2.reuse_scope = array_scope
write_container_parser(writer, element_type, dest2)
if is_byte_size:
writer.assign(dest.get_ref(array.size[2]), real_nelements)
def write_parse_pointer(writer, t, at_end, as_c_ptr, dest, member_name, scope):
target_type = t.target_type
@ -766,7 +773,12 @@ def write_member_parser(writer, container, member, dest, scope):
writer.statement("*(%s *)end = consume_%s(&in)" % (t.c_type(), t.primitive_type()))
writer.increment("end", t.sizeof())
else:
writer.assign(dest.get_ref(member.name), "consume_%s(&in)" % (t.primitive_type()))
if member.has_attr("bytes_count"):
scope.variable_def("uint32_t", member.name);
dest_var = member.name
else:
dest_var = dest.get_ref(member.name)
writer.assign(dest_var, "consume_%s(&in)" % (t.primitive_type()))
#TODO validate e.g. flags and enums
elif t.is_array():
nelements = read_array_len(writer, member.name, t, dest, scope, handles_bytes = True)

View File

@ -165,7 +165,7 @@ def get_array_size(array, container_src):
else:
return "(((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v)
elif array.is_bytes_length():
return container_src.get_ref(array.size[1])
return container_src.get_ref(array.size[2])
else:
raise NotImplementedError("TODO array size type not handled yet")
@ -179,20 +179,18 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope):
nelements = get_array_size(array, container_src)
is_byte_size = array.is_bytes_length()
if is_byte_size:
element = "%s__bytes" % member.name
else:
element = "%s__element" % member.name
element = "%s__element" % member.name
if not at_end:
writer.assign(element, container_src.get_ref(member.name))
if is_byte_size:
scope.variable_def("size_t", "array_end")
writer.assign("array_end", "spice_marshaller_get_size(m) + %s" % nelements)
size_start_var = "%s__size_start" % member.name
scope.variable_def("size_t", size_start_var)
writer.assign(size_start_var, "spice_marshaller_get_size(m)")
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("spice_marshaller_get_size(m) < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope:
with writer.index() as index:
with writer.for_loop(index, nelements) as array_scope:
array_scope.variable_def(element_type.c_type() + " *", element)
if at_end:
writer.assign(element, "(%s *)end" % element_type.c_type())
@ -210,6 +208,12 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope):
if not at_end:
writer.statement("%s++" % element)
if is_byte_size:
size_var = member.container.lookup_member(array.size[1])
size_var_type = size_var.member_type
var = "%s__ref" % array.size[1]
writer.statement("spice_marshaller_set_%s(m, %s, spice_marshaller_get_size(m) - %s)" % (size_var_type.primitive_type(), var, size_start_var))
def write_switch_marshaller(writer, container, switch, src, scope):
var = container.lookup_member(switch.variable)
var_type = var.member_type
@ -289,6 +293,11 @@ def write_member_marshaller(writer, container, member, src, scope):
elif t.is_primitive():
if member.has_attr("zero"):
writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
if member.has_attr("bytes_count"):
var = "%s__ref" % member.name
scope.variable_def("void *", var)
writer.statement("%s = spice_marshaller_add_%s(m, %s)" % (var, t.primitive_type(), 0))
elif member.has_end_attr():
writer.statement("spice_marshaller_add_%s(m, *(%s_t *)end)" % (t.primitive_type(), t.primitive_type()))
writer.increment("end", t.sizeof())

View File

@ -87,7 +87,7 @@ def SPICE_BNF():
attribute = Group(Combine ("@" + identifier) + Optional(lparen + delimitedList(attributeValue) + rparen))
attributes = Group(ZeroOrMore(attribute))
arraySizeSpecImage = Group(image_size_ + lparen + integer + comma + identifier + comma + identifier + rparen)
arraySizeSpecBytes = Group(bytes_ + lparen + identifier + rparen)
arraySizeSpecBytes = Group(bytes_ + lparen + identifier + comma + identifier + rparen)
arraySizeSpecCString = Group(cstring_ + lparen + rparen)
arraySizeSpec = lbrack + Optional(identifier ^ integer ^ arraySizeSpecImage ^ arraySizeSpecBytes ^arraySizeSpecCString, default="") + rbrack
variableDef = Group(typeSpec + Optional("*", default=None) + identifier + Optional(arraySizeSpec, default=None) + attributes - semi) \

View File

@ -404,8 +404,8 @@ struct PathSegment {
} @ctype(SpicePathSeg);
struct Path {
uint32 size;
PathSegment segments[bytes(size)] @end;
uint32 num_segments;
PathSegment segments[num_segments] @end;
};
struct Clip {

View File

@ -374,8 +374,8 @@ struct PathSegment {
} @ctype(SpicePathSeg);
struct Path {
uint32 size;
PathSegment segments[bytes(size)] @end;
uint32 segments_size @bytes_count;
PathSegment segments[bytes(segments_size, num_segments)] @end;
};
struct Clip {