diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2010-06-30 22:19:12 +0200 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2012-03-20 15:25:46 +0100 |
commit | c5d06102b77d20600303ff636b095c82be29f0dc (patch) | |
tree | 082d49656318eb2a331ad5851ae57e0b93d86db7 /python_modules | |
parent | dabdea4fac8de901b4af2c61178097c2d3f5f78d (diff) |
Properly parse and marshall SpiceString
Diffstat (limited to 'python_modules')
-rw-r--r-- | python_modules/demarshal.py | 44 | ||||
-rw-r--r-- | python_modules/marshal.py | 20 | ||||
-rw-r--r-- | python_modules/ptypes.py | 8 |
3 files changed, 61 insertions, 11 deletions
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py index 023c3f6..4d3e79b 100644 --- a/python_modules/demarshal.py +++ b/python_modules/demarshal.py @@ -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) diff --git a/python_modules/marshal.py b/python_modules/marshal.py index da9b0d8..95413fc 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -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]) diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py index b7bcac9..055034e 100644 --- a/python_modules/ptypes.py +++ b/python_modules/ptypes.py @@ -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"): |