summaryrefslogtreecommitdiff
path: root/python_modules/marshal.py
diff options
context:
space:
mode:
Diffstat (limited to 'python_modules/marshal.py')
-rw-r--r--python_modules/marshal.py420
1 files changed, 0 insertions, 420 deletions
diff --git a/python_modules/marshal.py b/python_modules/marshal.py
deleted file mode 100644
index 1d38d3d..0000000
--- a/python_modules/marshal.py
+++ /dev/null
@@ -1,420 +0,0 @@
-
-from . import ptypes
-from . import codegen
-
-def write_includes(writer):
- writer.header.writeln("#include <spice/protocol.h>")
- writer.header.writeln('#include "common/marshaller.h"')
- writer.header.newline()
- writer.header.writeln("#ifndef _GENERATED_HEADERS_H")
- writer.header.writeln("#define _GENERATED_HEADERS_H")
-
- writer.writeln("#include <string.h>")
- writer.writeln("#include <assert.h>")
- writer.writeln("#include <stdlib.h>")
- writer.writeln("#include <stdio.h>")
- writer.writeln("#include <spice/protocol.h>")
- writer.writeln("#include <spice/macros.h>")
- writer.writeln('#include "common/marshaller.h"')
- writer.newline()
- writer.writeln("#ifdef _MSC_VER")
- writer.writeln("#pragma warning(disable:4101)")
- writer.writeln("#pragma warning(disable:4018)")
- writer.writeln("#endif")
- writer.newline()
-
-class MarshallingSource:
- def __init__(self):
- pass
-
- def child_at_end(self, t):
- return RootMarshallingSource(self, t.c_type(), t.sizeof())
-
- def child_sub(self, containee):
- return SubMarshallingSource(self, containee)
-
- def declare(self, writer):
- return writer.optional_block(self.reuse_scope)
-
- def is_toplevel(self):
- return self.parent_src == None and not self.is_helper
-
-class RootMarshallingSource(MarshallingSource):
- def __init__(self, parent_src, c_type, sizeof, pointer = None):
- self.is_helper = False
- self.reuse_scope = None
- self.parent_src = parent_src
- if parent_src:
- self.base_var = codegen.increment_identifier(parent_src.base_var)
- else:
- self.base_var = "src"
- self.c_type = c_type
- self.sizeof = sizeof
- self.pointer = pointer
- assert pointer != None
-
- def get_self_ref(self):
- return self.base_var
-
- def get_ref(self, member):
- return self.base_var + "->" + member
-
- def declare(self, writer):
- if self.reuse_scope:
- scope = self.reuse_scope
- else:
- writer.begin_block()
- scope = writer.get_subwriter()
-
- scope.variable_def(self.c_type + " *", self.base_var)
- if not self.reuse_scope:
- scope.newline()
-
- writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer))
- writer.newline()
-
- if self.reuse_scope:
- return writer.no_block(self.reuse_scope)
- else:
- return writer.partial_block(scope)
-
-class SubMarshallingSource(MarshallingSource):
- def __init__(self, parent_src, containee):
- self.reuse_scope = None
- self.parent_src = parent_src
- self.base_var = parent_src.base_var
- self.containee = containee
- self.name = containee.name
- self.is_helper = False
-
- def get_self_ref(self):
- if self.containee.has_attr("to_ptr"):
- return "%s" % self.parent_src.get_ref(self.name)
- else:
- return "&%s" % self.parent_src.get_ref(self.name)
-
- def get_ref(self, member):
- if self.containee.has_attr("to_ptr"):
- return self.parent_src.get_ref(self.name) + "->" + member
- else:
- return self.parent_src.get_ref(self.name) + "." + member
-
-def write_marshal_ptr_function(writer, target_type, is_helper=True):
- if target_type.is_array():
- marshal_function = "spice_marshall_array_%s" % target_type.element_type.primitive_type()
- else:
- marshal_function = "spice_marshall_%s" % target_type.name
- if writer.is_generated("marshaller", marshal_function):
- return marshal_function
-
- writer.set_is_generated("marshaller", marshal_function)
-
- names = target_type.get_pointer_names(False)
- names_args = ""
- if len(names) > 0:
- n = [", SpiceMarshaller **%s_out" % name for name in names]
- names_args = "".join(n)
-
- header = writer.header
- if is_helper:
- writer = writer.function_helper()
- writer.header = header
- writer.out_prefix = ""
- if target_type.is_array():
- scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void", "SpiceMarshaller *m, %s_t *ptr, unsigned count" % target_type.element_type.primitive_type() + names_args)
- else:
- scope = writer.function(marshal_function, "void", "SpiceMarshaller *m, %s *ptr" % target_type.c_type() + names_args)
- header.writeln("void " + marshal_function + "(SpiceMarshaller *m, %s *msg" % target_type.c_type() + names_args + ");")
- scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
-
- for n in names:
- writer.assign("*%s_out" % n, "NULL")
-
- writer.newline()
-
- if target_type.is_struct():
- src = RootMarshallingSource(None, target_type.c_type(), target_type.sizeof(), "ptr")
- src.reuse_scope = scope
- write_container_marshaller(writer, target_type, src)
- elif target_type.is_array() and target_type.element_type.is_primitive():
- with writer.index() as index:
- with writer.for_loop(index, "count") as array_scope:
- writer.statement("spice_marshaller_add_%s(m, *ptr++)" % (target_type.element_type.primitive_type()))
- else:
- writer.todo("Unsuppored pointer marshaller type")
-
- writer.end_block()
-
- return marshal_function
-
-def get_array_size(array, container_src):
- if array.is_constant_length():
- return array.size
- elif array.is_identifier_length():
- return container_src.get_ref(array.size)
- elif array.is_remaining_length():
- raise NotImplementedError("remaining size array sizes marshalling not supported")
- elif array.is_image_size_length():
- bpp = array.size[1]
- width = array.size[2]
- rows = array.size[3]
- width_v = container_src.get_ref(width)
- rows_v = container_src.get_ref(rows)
- # TODO: Handle multiplication overflow
- if bpp == 8:
- return "(unsigned) (%s * %s)" % (width_v, rows_v)
- elif bpp == 1:
- return "(unsigned) (((%s + 7) / 8 ) * %s)" % (width_v, rows_v)
- else:
- return "(unsigned) (((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v)
- elif array.is_bytes_length():
- return container_src.get_ref(array.size[2])
- else:
- raise NotImplementedError("TODO array size type not handled yet: %s" % array)
-
-def write_array_marshaller(writer, member, array, container_src, scope):
- element_type = array.element_type
-
- if array.is_remaining_length():
- writer.comment("Remaining data must be appended manually").newline()
- return
-
- nelements = get_array_size(array, container_src)
- is_byte_size = array.is_bytes_length()
-
- element = "%s__element" % member.name
-
- if not scope.variable_defined(element):
- if array.has_attr("ptr_array"):
- stars = " **"
- else:
- stars = " *"
- scope.variable_def(element_type.c_type() + stars, element)
- element_array = element
- if array.has_attr("ptr_array"):
- element = "*" + element
-
- writer.assign(element_array, container_src.get_ref(member.name))
-
- if is_byte_size:
- 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() as index:
- with writer.for_loop(index, nelements) as array_scope:
- if element_type.is_primitive():
- 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)
- src2.reuse_scope = array_scope
- write_container_marshaller(writer, element_type, src2)
- else:
- writer.todo("array element unhandled type").newline()
-
- writer.statement("%s++" % element_array)
-
- 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_pointer_marshaller(writer, member, src):
- t = member.member_type
- ptr_func = write_marshal_ptr_function(writer, t.target_type)
- submarshaller = "spice_marshaller_get_ptr_submarshaller(m, %d)" % (1 if member.get_fixed_nw_size() == 8 else 0)
- if member.has_attr("marshall"):
- rest_args = ""
- if t.target_type.is_array():
- rest_args = ", %s" % get_array_size(t.target_type, src)
- writer.assign("m2", submarshaller)
- if t.has_attr("nonnull"):
- writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args))
- else:
- with writer.if_block("%s != NULL" % src.get_ref(member.name)) as block:
- writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args))
- else:
- writer.assign("*%s_out" % (writer.out_prefix + member.name), submarshaller)
-
-def write_switch_marshaller(writer, container, switch, src, scope):
- var = container.lookup_member(switch.variable)
- var_type = var.member_type
-
- saved_out_prefix = writer.out_prefix
- first = True
- for c in switch.cases:
- check = c.get_check(src.get_ref(switch.variable), var_type)
- m = c.member
- writer.out_prefix = saved_out_prefix
- if m.has_attr("outvar"):
- writer.out_prefix = "%s_%s" % (m.attributes["outvar"][0], writer.out_prefix)
- with writer.if_block(check, not first, False) as block:
- t = m.member_type
- if switch.has_attr("anon"):
- if t.is_struct():
- src2 = src.child_sub(m)
- else:
- src2 = src
- else:
- if t.is_struct():
- src2 = src.child_sub(switch).child_sub(m)
- else:
- src2 = src.child_sub(switch)
- src2.reuse_scope = block
-
- if t.is_struct():
- write_container_marshaller(writer, t, src2)
- elif t.is_pointer():
- write_pointer_marshaller(writer, m, src2)
- elif t.is_primitive():
- if m.has_attr("zero"):
- writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
- else:
- writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src2.get_ref(m.name)))
- #TODO validate e.g. flags and enums
- elif t.is_array():
- write_array_marshaller(writer, m, t, src2, scope)
- else:
- writer.todo("Can't handle type %s" % m.member_type)
-
- if switch.has_attr("fixedsize"):
- remaining = switch.get_fixed_nw_size() - t.get_fixed_nw_size()
- if remaining != 0:
- writer.statement("spice_marshaller_reserve_space(m, %s)" % remaining)
-
- first = False
- if switch.has_attr("fixedsize"):
- with writer.block(" else"):
- writer.statement("spice_marshaller_reserve_space(m, %s)" % switch.get_fixed_nw_size())
-
- writer.newline()
-
-def write_member_marshaller(writer, container, member, src, scope):
- if member.has_attr("outvar"):
- writer.out_prefix = "%s_%s" % (member.attributes["outvar"][0], writer.out_prefix)
- if member.has_attr("virtual"):
- writer.comment("Don't marshall @virtual %s" % member.name).newline()
- return
- if member.has_attr("nomarshal"):
- writer.comment("Don't marshall @nomarshal %s" % member.name).newline()
- return
- if member.is_switch():
- write_switch_marshaller(writer, container, member, src, scope)
- return
-
- t = member.member_type
-
- if t.is_pointer():
- write_pointer_marshaller(writer, member, src)
- 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))
-
- else:
- writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src.get_ref(member.name)))
- elif t.is_array():
- write_array_marshaller(writer, member, t, src, scope)
- elif t.is_struct():
- src2 = src.child_sub(member)
- writer.comment(member.name)
- write_container_marshaller(writer, t, src2)
- else:
- raise NotImplementedError("TODO can't handle parsing of %s" % t)
-
-def write_container_marshaller(writer, container, src):
- saved_out_prefix = writer.out_prefix
- with src.declare(writer) as scope:
- for m in container.members:
- writer.out_prefix = saved_out_prefix
- write_member_marshaller(writer, container, m, src, scope)
-
-def write_message_marshaller(writer, message, is_server, private):
- if message.has_attr("ifdef"):
- writer.ifdef(message.attributes["ifdef"][0])
- writer.out_prefix = ""
- function_name = "spice_marshall_" + message.c_name()
- if writer.is_generated("marshaller", function_name):
- return function_name
- writer.set_is_generated("marshaller", function_name)
-
- names = message.get_pointer_names(False)
- names_args = ""
- if len(names) > 0:
- n = [", SpiceMarshaller **%s_out" % name for name in names]
- names_args = "".join(n)
-
- if not private:
- writer.header.writeln("void " + function_name + "(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");")
-
- scope = writer.function(function_name,
- "static void" if private else "void",
- "SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED %s *msg" % message.c_type() + names_args)
- scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
-
- for n in names:
- writer.assign("*%s_out" % n, "NULL")
-
- # fix warnings about unused variables by not creating body if no members to parse
- if any(x.is_fixed_nw_size() for x in message.members):
- src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg")
- src.reuse_scope = scope
-
- write_container_marshaller(writer, message, src)
-
- writer.end_block()
- if message.has_attr("ifdef"):
- writer.endif(message.attributes["ifdef"][0])
- writer.newline()
- return function_name
-
-def write_protocol_marshaller(writer, proto, is_server, private_marshallers):
- functions = {}
- for c in proto.channels:
- channel = c.channel_type
- if channel.has_attr("ifdef"):
- writer.ifdef(channel.attributes["ifdef"][0])
- writer.header.ifdef(channel.attributes["ifdef"][0])
- if is_server:
- messages = channel.client_messages
- else:
- messages = channel.server_messages
- for m in messages:
- message = m.message_type
- f = write_message_marshaller(writer, message, is_server, private_marshallers)
- if channel.has_attr("ifdef") and f not in functions:
- functions[f] = channel.attributes["ifdef"][0]
- elif message.has_attr("ifdef") and f not in functions:
- functions[f] = message.attributes["ifdef"][0]
- else:
- functions[f] = True
- if channel.has_attr("ifdef"):
- writer.endif(channel.attributes["ifdef"][0])
- writer.header.endif(channel.attributes["ifdef"][0])
-
- if private_marshallers:
- scope = writer.function("spice_message_marshallers_get" + writer.public_prefix,
- "SpiceMessageMarshallers *",
- "void")
- writer.writeln("static SpiceMessageMarshallers marshallers = {NULL};").newline()
- for f in sorted(functions.keys()):
- member = f[len("spice_marshall_"):]
- if not member.startswith("msg"):
- member = "msg_" + member
- if functions[f] != True:
- writer.ifdef(functions[f])
- writer.assign("marshallers.%s" % member, f)
- if functions[f] != True:
- writer.endif(functions[f])
-
- writer.newline()
- writer.statement("return &marshallers")
- writer.end_block()
- writer.newline()
-
-def write_trailer(writer):
- writer.header.writeln("#endif")