[Spice-devel] [PATCH v3 21/51] Add code to handle destination variable
Christophe Fergeau
cfergeau at redhat.com
Thu Jul 23 06:13:18 PDT 2015
On Tue, Jul 21, 2015 at 05:45:51PM +0100, Frediano Ziglio wrote:
> Add some classes to be able to store retrieved data from structure
> and messages.
> The idea is to generate code dynamically when variable are readed.
'are read'
>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
> python_modules/dissector.py | 104 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/python_modules/dissector.py b/python_modules/dissector.py
> index 40e348a..588becd 100644
> --- a/python_modules/dissector.py
> +++ b/python_modules/dissector.py
> @@ -66,6 +66,106 @@ def write_parser_helpers(writer):
> writer.writeln('#endif')
> writer.newline()
>
> +# generate code to declare a variable only when needed
> +# code is generated only when we read the reference
> +class Reference:
> + def __init__(self, writer, name):
> + self.defined = False
> + self.written = False
> + self.name = name
> + # create a subwriter to write code to read variable only once
> + self.writer = writer.get_subwriter()
> +
> + def write(self, size, value, scope):
> + if not size in (8, 16, 32, 64):
> + raise Exception('Unknown size %d for %s' % (size, self.name))
> + assert(not self.defined or (value, size) == (self.value, self.size))
> + if not self.defined:
> + self.value = value
> + self.size = size
> + self.scope = scope
> + self.defined = True
> +
> + def read(self):
> + # variable not yet defined
> + assert(self.defined)
> + if not self.written:
> + assert(not self.scope.variable_defined(self.name))
> + t = { 8: 'guint32', 16: 'guint32', 32: 'guint32', 64: 'guint64' }[self.size]
> + self.scope.variable_def(t, self.name)
> + self.writer.assign(self.name, self.value)
> + self.written = True
> + return self.name
> +
> +class Level:
> + def __init__(self, n=0):
> + self.level = n
> + def __enter__(self):
> + self.level += 1
> + def __exit__(self, exc_type, exc_value, traceback):
> + self.level -= 1
> + def __getattr__(self, name):
> + if not name in {'tree', 'ti'}:
> + raise Exception('Not possible to get name %s' % name)
> + return name if self.level == 0 else name + str(self.level)
> +
> +# represent part of a destination to write to
> +# for instance if we are parsing a structure dest represent that structure output
> +class Destination:
> + def __init__(self, scope):
> + self.refs = {}
> + self.is_helper = False
> + self.reuse_scope = scope
> + self.parent_dest = None
> + self.level = Level()
> +
> + def child_sub(self, member, scope):
> + return SubDestination(self, member, scope)
> +
> + def declare(self, writer):
> + return writer.optional_block(self.reuse_scope)
> +
> + def is_toplevel(self):
> + return self.parent_dest == None and not self.is_helper
> +
> + def read_ref(self, member):
> + return self.get_ref(member).read()
> +
> + def write_ref(self, writer, size, member, value):
> + ref = self.get_ref(member, writer)
> + ref.write(size, value, self.reuse_scope)
> +
> + def ref_size(self, member):
> + return self.get_ref(member).size
> +
> +class RootDestination(Destination):
> + def __init__(self, scope):
> + Destination.__init__(self, scope)
> + self.base_var = "fld"
> +
> + def get_ref(self, member, writer=None):
> + name = (self.base_var + "." + member).replace('.', '__')
> + if name in self.refs:
> + return self.refs[name]
> + if not writer:
> + raise Exception('trying to read a reference to %s' % member)
> + self.refs[name] = ref = Reference(writer, name)
> + return ref
> +
> + def declare(self, writer):
> + return writer.no_block(self.reuse_scope)
> +
> +class SubDestination(Destination):
> + def __init__(self, parent_dest, member, scope):
> + Destination.__init__(self, scope)
> + self.parent_dest = parent_dest
> + self.member = member
> + self.level = parent_dest.level
> +
> + def get_ref(self, member, writer=None):
> + return self.parent_dest.get_ref(self.member + "." + member, writer)
> +
> +
> def write_msg_parser(writer, message, server):
> msg_name = message.c_name()
> function_name = "dissect_spice_%s_%s" % ('server' if server else 'client', msg_name)
> @@ -80,7 +180,9 @@ def write_msg_parser(writer, message, server):
> writer.ifdef(message)
> parent_scope = writer.function(function_name,
> "guint32",
> - "GlobalInfo *glb _U_, proto_tree *tree0 _U_, guint32 offset", True)
> + "GlobalInfo *glb _U_, proto_tree *tree _U_, guint32 offset", True)
> +
> + dest = RootDestination(parent_scope)
>
> writer.statement("return offset")
> writer.end_block()
> --
> 2.1.0
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150723/777fca0f/attachment.sig>
More information about the Spice-devel
mailing list