[Spice-devel] [PATCH 14/33] Generate scheleton for messages and channels
Frediano Ziglio
fziglio at redhat.com
Wed Jul 1 10:10:06 PDT 2015
Messages are not generated as stub.
Code partially from demarshaller.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
python_modules/dissector.py | 138 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 137 insertions(+), 1 deletion(-)
diff --git a/python_modules/dissector.py b/python_modules/dissector.py
index 67d0fa7..9971140 100644
--- a/python_modules/dissector.py
+++ b/python_modules/dissector.py
@@ -1,4 +1,5 @@
+from . import ptypes
from . import codegen
import types
@@ -53,6 +54,124 @@ def write_parser_helpers(writer):
writer.writeln('#endif')
writer.newline()
+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)
+ if writer.is_generated("msg_parser", function_name):
+ return function_name
+ writer.set_is_generated("msg_parser", function_name)
+
+ msg_type = message.c_type()
+ msg_sizeof = message.sizeof()
+
+ writer.newline()
+ writer.ifdef(message)
+ parent_scope = writer.function(function_name,
+ "guint32",
+ "GlobalInfo *glb _U_, proto_tree *tree0 _U_, guint32 offset", True)
+
+ writer.statement("return offset")
+ writer.end_block()
+
+ writer.endif(message)
+
+ return function_name
+
+def write_channel_parser(writer, channel, server):
+ writer.newline()
+ ids = {}
+ if server:
+ messages = channel.server_messages
+ else:
+ messages = channel.client_messages
+ for m in messages:
+ ids[m.value] = m
+
+ ranges = []
+ ids2 = ids.copy()
+ while len(ids2) > 0:
+ end = start = min(ids2.keys())
+ while end in ids2:
+ del ids2[end]
+ end = end + 1
+
+ ranges.append( (start, end) )
+
+ if server:
+ function_name = "dissect_spice_data_server_%s" % channel.name
+ else:
+ function_name = "dissect_spice_data_client_%s" % channel.name
+ writer.newline()
+ writer.ifdef(channel)
+ scope = writer.function(function_name,
+ "guint32",
+ "guint16 message_type, GlobalInfo *glb _U_, proto_tree *tree _U_, guint32 offset", True)
+
+ helpers = writer.function_helper()
+
+ d = 0
+ for r in ranges:
+ d = d + 1
+ writer.write("static const parse_msg_func_t funcs%d[%d] = " % (d, r[1] - r[0]))
+ writer.begin_block()
+ for i in range(r[0], r[1]):
+ func = write_msg_parser(helpers, ids[i].message_type, server)
+ writer.write(func)
+ if i != r[1] -1:
+ writer.write(",")
+ writer.newline()
+
+ writer.end_block(semicolon = True)
+
+ d = 0
+ for r in ranges:
+ d = d + 1
+ with writer.if_block("message_type >= %d && message_type < %d" % (r[0], r[1]), d > 1, False):
+ writer.statement("return funcs%d[message_type-%d](glb, tree, offset)" % (d, r[0]))
+ writer.newline()
+
+ writer.statement('expert_add_info_format(glb->pinfo, glb->msgtype_item, &ei_spice_unknown_message, "Unknown display server message - cannot dissect")')
+ writer.statement("return offset")
+ writer.end_block()
+ writer.endif(channel)
+
+ return function_name
+
+def write_get_channel_parser(writer, channel_parsers, max_channel, is_server):
+ writer.newline()
+ function_name = "spice_%s%s_channel_get_dissect" % ('server' if is_server else 'client', writer.public_prefix)
+
+ writer.function(function_name, "spice_dissect_func_t", "guint8 channel")
+
+ writer.write("static const spice_dissect_func_t channels[%d] = " % (max_channel+1))
+ writer.begin_block()
+ channel = None
+ for i in range(0, max_channel + 1):
+ if i in channel_parsers:
+ channel = channel_parsers[i][0]
+ writer.ifdef(channel)
+ writer.write(channel_parsers[i][1])
+ else:
+ writer.write("NULL")
+
+ if i != max_channel:
+ writer.write(",")
+ writer.newline()
+ if channel and channel.has_attr("ifdef"):
+ writer.ifdef_else(channel)
+ writer.write("NULL")
+ if i != max_channel:
+ writer.write(",")
+ writer.newline()
+ writer.endif(channel)
+ writer.end_block(semicolon = True)
+
+ with writer.if_block("channel < %d" % (max_channel + 1)):
+ writer.statement("return channels[channel]")
+
+ writer.statement("return NULL")
+ writer.end_block()
+
def write_protocol_definitions(writer):
global hf_defs
@@ -114,8 +233,25 @@ def write_protocol_parser(writer, proto):
writer.newline()
hf_writer = writer.get_subwriter()
+ # put everything else after
+ defs_writer = writer
+ writer = writer.get_subwriter()
+
# put fields definition at last
- write_protocol_definitions(writer)
+ write_protocol_definitions(defs_writer)
+
+ # scan all, looks for items and tree
+ # list add items and tree
+ # write all structure functions (get size + tree)
+ for is_server in (True, False):
+ max_channel = 0
+ parsers = {}
+ for channel in proto.channels:
+ max_channel = max(max_channel, channel.value)
+
+ parsers[channel.value] = (channel.channel_type, write_channel_parser(writer, channel.channel_type, is_server))
+
+ write_get_channel_parser(writer, parsers, max_channel, is_server)
def write_includes(writer):
writer.newline()
--
2.1.0
More information about the Spice-devel
mailing list