mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-protocol
synced 2025-12-26 22:55:30 +00:00
Properly parse and marshall SpiceString
This commit is contained in:
parent
8ec1247dbe
commit
6228ae633e
@ -125,7 +125,7 @@ def write_validate_switch_member(writer, container, switch_member, scope, parent
|
||||
item.subprefix = item.prefix + "_" + m.name
|
||||
item.non_null = c.member.has_attr("nonnull")
|
||||
sub_want_extra_size = want_extra_size
|
||||
if sub_want_extra_size and not m.contains_extra_size():
|
||||
if sub_want_extra_size and not m.contains_extra_size() and not m.is_extra_size():
|
||||
writer.assign(item.extra_size(), 0)
|
||||
sub_want_extra_size = False
|
||||
|
||||
@ -309,10 +309,13 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
|
||||
|
||||
if element_type.is_fixed_sizeof() and want_mem_size and not is_byte_size:
|
||||
# TODO: Overflow check the multiplication
|
||||
writer.assign(mem_size, "%s * %s" % (element_type.sizeof(), nelements))
|
||||
if array.ptr_array:
|
||||
writer.assign(mem_size, "sizeof(void *) + SPICE_ALIGN(%s * %s, 4)" % (element_type.sizeof(), nelements))
|
||||
else:
|
||||
writer.assign(mem_size, "%s * %s" % (element_type.sizeof(), nelements))
|
||||
want_mem_size = False
|
||||
|
||||
if not element_type.contains_extra_size() and want_extra_size:
|
||||
if not element_type.contains_extra_size() and not array.is_extra_size() and want_extra_size:
|
||||
writer.assign(extra_size, 0)
|
||||
want_extra_size = False
|
||||
|
||||
@ -329,14 +332,24 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
|
||||
|
||||
element_nw_size = element_item.nw_size()
|
||||
element_mem_size = element_item.mem_size()
|
||||
element_extra_size = element_item.extra_size()
|
||||
scope.variable_def("uint32_t", element_nw_size)
|
||||
scope.variable_def("uint32_t", element_mem_size)
|
||||
want_is_extra_size = False
|
||||
want_element_mem_size = want_mem_size
|
||||
if want_extra_size:
|
||||
if array.is_extra_size():
|
||||
want_is_extra_size = True
|
||||
want_extra_size = False
|
||||
want_element_mem_size = True
|
||||
else:
|
||||
scope.variable_def("uint32_t", element_extra_size)
|
||||
|
||||
if want_nw_size:
|
||||
writer.assign(nw_size, 0)
|
||||
if want_mem_size:
|
||||
writer.assign(mem_size, 0)
|
||||
if want_extra_size:
|
||||
if want_extra_size or want_is_extra_size:
|
||||
writer.assign(extra_size, 0)
|
||||
|
||||
want_element_nw_size = want_nw_size
|
||||
@ -352,13 +365,19 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
|
||||
with writer.index(no_block = is_byte_size) as index:
|
||||
with writer.while_loop("%s < %s" % (start2, start2_end) ) if is_byte_size else writer.for_loop(index, nelements) as scope:
|
||||
write_validate_item(writer, container, element_item, scope, parent_scope, start2,
|
||||
want_element_nw_size, want_mem_size, want_extra_size)
|
||||
want_element_nw_size, want_element_mem_size, want_extra_size)
|
||||
|
||||
if want_nw_size:
|
||||
writer.increment(nw_size, element_nw_size)
|
||||
if want_mem_size:
|
||||
writer.increment(mem_size, element_mem_size)
|
||||
if want_extra_size:
|
||||
if not array.is_extra_size():
|
||||
writer.increment(mem_size, element_mem_size)
|
||||
if want_is_extra_size:
|
||||
if array.ptr_array:
|
||||
writer.increment(extra_size, "sizeof(void *) + SPICE_ALIGN(%s, 4)" % element_mem_size)
|
||||
else:
|
||||
writer.increment(extra_size, "%s + %s" % (element_mem_size, element_extra_size))
|
||||
elif want_extra_size:
|
||||
writer.increment(extra_size, element_extra_size)
|
||||
|
||||
writer.increment(start2, start_increment)
|
||||
@ -722,8 +741,16 @@ def write_array_parser(writer, nelements, array, dest, scope):
|
||||
scope.variable_def("uint32_t", real_nelements)
|
||||
writer.assign("array_end", "end + %s" % nelements)
|
||||
writer.assign(real_nelements, 0)
|
||||
if array.ptr_array:
|
||||
scope.variable_def("void **", "ptr_array")
|
||||
scope.variable_def("int", "ptr_array_index")
|
||||
writer.assign("ptr_array_index", 0)
|
||||
writer.assign("ptr_array", "(void **)end")
|
||||
writer.increment("end", "sizeof(void *) * %s" % nelements)
|
||||
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 array.ptr_array:
|
||||
writer.statement("ptr_array[ptr_array_index++] = end")
|
||||
if is_byte_size:
|
||||
writer.increment(real_nelements, 1)
|
||||
if element_type.is_primitive():
|
||||
@ -733,6 +760,9 @@ 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 array.ptr_array:
|
||||
writer.comment("Align ptr_array element to 4 bytes").newline()
|
||||
writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
|
||||
if is_byte_size:
|
||||
writer.assign(dest.get_ref(array.size[2]), real_nelements)
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@ class RootMarshallingSource(MarshallingSource):
|
||||
self.c_type = c_type
|
||||
self.sizeof = sizeof
|
||||
self.pointer = pointer # None == at "end"
|
||||
self.update_end = False
|
||||
|
||||
def get_self_ref(self):
|
||||
return self.base_var
|
||||
@ -70,6 +71,8 @@ class RootMarshallingSource(MarshallingSource):
|
||||
|
||||
if self.pointer:
|
||||
writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer))
|
||||
if self.update_end:
|
||||
writer.assign("end", "((uint8_t *)%s) + %s" % (self.base_var, self.sizeof))
|
||||
else:
|
||||
writer.assign(self.base_var, "(%s *)end" % self.c_type)
|
||||
writer.increment("end", "%s" % self.sizeof)
|
||||
@ -182,8 +185,18 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope):
|
||||
|
||||
element = "%s__element" % member.name
|
||||
|
||||
if not scope.variable_defined(element):
|
||||
if array.ptr_array:
|
||||
stars = " **"
|
||||
else:
|
||||
stars = " *"
|
||||
scope.variable_def(element_type.c_type() + stars, element)
|
||||
element_array = element
|
||||
if array.ptr_array:
|
||||
element = "*" + element
|
||||
|
||||
if not at_end:
|
||||
writer.assign(element, container_src.get_ref(member.name))
|
||||
writer.assign(element_array, container_src.get_ref(member.name))
|
||||
|
||||
if is_byte_size:
|
||||
size_start_var = "%s__size_start" % member.name
|
||||
@ -192,7 +205,6 @@ def write_array_marshaller(writer, at_end, member, array, container_src, 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())
|
||||
writer.increment("end", element_type.sizeof())
|
||||
@ -201,13 +213,15 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope):
|
||||
writer.statement("spice_marshaller_add_%s(m, *%s)" % (element_type.primitive_type(), element))
|
||||
elif element_type.is_struct():
|
||||
src2 = RootMarshallingSource(container_src, element_type.c_type(), element_type.sizeof(), element)
|
||||
if array.is_extra_size():
|
||||
src2.update_end = True
|
||||
src2.reuse_scope = array_scope
|
||||
write_container_marshaller(writer, element_type, src2)
|
||||
else:
|
||||
writer.todo("array element unhandled type").newline()
|
||||
|
||||
if not at_end:
|
||||
writer.statement("%s++" % element)
|
||||
writer.statement("%s++" % element_array)
|
||||
|
||||
if is_byte_size:
|
||||
size_var = member.container.lookup_member(array.size[1])
|
||||
|
||||
@ -353,6 +353,7 @@ class ArrayType(Type):
|
||||
|
||||
self.element_type = element_type
|
||||
self.size = size
|
||||
self.ptr_array = False
|
||||
|
||||
def __str__(self):
|
||||
if self.size == None:
|
||||
@ -414,6 +415,9 @@ class ArrayType(Type):
|
||||
return []
|
||||
raise Exception, "Pointer names in arrays not supported"
|
||||
|
||||
def is_extra_size(self):
|
||||
return self.ptr_array
|
||||
|
||||
def contains_extra_size(self):
|
||||
return self.element_type.contains_extra_size()
|
||||
|
||||
@ -512,6 +516,8 @@ class Member(Containee):
|
||||
self.member_type.register()
|
||||
if self.has_attr("ptr32") and self.member_type.is_pointer():
|
||||
self.member_type.set_ptr_size(4)
|
||||
if self.has_attr("ptr_array") and self.member_type.is_array():
|
||||
self.member_type.ptr_array = True
|
||||
return self
|
||||
|
||||
def is_primitive(self):
|
||||
@ -523,7 +529,7 @@ class Member(Containee):
|
||||
return self.member_type.is_fixed_sizeof()
|
||||
|
||||
def is_extra_size(self):
|
||||
return self.has_end_attr()
|
||||
return self.has_end_attr() or self.member_type.is_extra_size()
|
||||
|
||||
def is_fixed_nw_size(self):
|
||||
if self.has_attr("virtual"):
|
||||
|
||||
10
spice.proto
10
spice.proto
@ -564,12 +564,12 @@ struct String {
|
||||
string_flags flags; /* Special: Only one of a1/a4/a8 set */
|
||||
switch (flags) {
|
||||
case RASTER_A1:
|
||||
RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
case RASTER_A4:
|
||||
RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
case RASTER_A8:
|
||||
RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
} u @end @nomarshal;
|
||||
RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
} u @anon;
|
||||
};
|
||||
|
||||
channel DisplayChannel : BaseChannel {
|
||||
@ -727,7 +727,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Text {
|
||||
String *str;
|
||||
String *str @marshall @nonnull;
|
||||
Rect back_area;
|
||||
Brush fore_brush @outvar(fore_brush);
|
||||
Brush back_brush @outvar(back_brush);
|
||||
|
||||
@ -522,12 +522,12 @@ struct String {
|
||||
string_flags flags; /* Special: Only one of a1/a4/a8 set */
|
||||
switch (flags) {
|
||||
case RASTER_A1:
|
||||
RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
case RASTER_A4:
|
||||
RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
case RASTER_A8:
|
||||
RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph);
|
||||
} u @end @nomarshal;
|
||||
RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
|
||||
} u @anon;
|
||||
};
|
||||
|
||||
channel DisplayChannel : BaseChannel {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user