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@xxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel
Attachment:
pgpI2xAEA4ToL.pgp
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel