[Spice-devel] [PATCH v6 41/42] dissector: Allows to use bytes_count and bytes array length in dissector
Frediano Ziglio
fziglio at redhat.com
Thu Aug 13 06:12:20 PDT 2015
Was not implemented. These attributes allows to specify length of
other fields in bytes. Previously was possibly only to specify
arrays length in number of elements.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
python_modules/dissector.py | 64 +++++++++++++++++++++++++++++----------------
1 file changed, 41 insertions(+), 23 deletions(-)
diff --git a/python_modules/dissector.py b/python_modules/dissector.py
index 76c1de0..fb89e11 100644
--- a/python_modules/dissector.py
+++ b/python_modules/dissector.py
@@ -379,15 +379,15 @@ def read_array_len(writer, prefix, array, dest, scope, is_ptr):
nelements = "%s__array__nelements" % prefix
else:
nelements = "%s__nelements" % prefix
+ nbytes = "%s__nbytes" % prefix
if dest.is_toplevel() and scope.variable_defined(nelements):
- return nelements # Already there for toplevel, need not recalculate
+ return (nelements, None) # Already there for toplevel, need not recalculate
# just reuse variable, there is no problem for cast as we always store in guint32
if array.is_identifier_length():
nelements = dest.read_ref(array.size)
dest.write_ref(writer, dest.ref_size(array.size), prefix + '.nelements', nelements)
- return nelements
+ return (nelements, None)
element_type = array.element_type
- scope.variable_def("guint32", nelements)
if array.is_constant_length():
writer.assign(nelements, array.size)
elif array.is_remaining_length():
@@ -409,12 +409,17 @@ def read_array_len(writer, prefix, array, dest, scope, is_ptr):
else:
writer.assign(nelements, "((%sU * (guint32) %s + 7U) / 8U ) * %s" % (bpp, width_v, rows_v))
elif array.is_bytes_length():
- writer.assign(nelements, dest.read_ref(array.size[2]))
+ scope.variable_def("guint32", nbytes)
+ writer.assign(nbytes, dest.read_ref(array.size[1]))
+ # TODO compute a better size
+ dest.write_ref(writer, 32, prefix+'.nbytes', nbytes)
+ return (None, nbytes)
else:
raise NotImplementedError("TODO array size type not handled yet")
+ scope.variable_def("guint32", nelements)
# TODO compute a better size
dest.write_ref(writer, 32, prefix+'.nelements', nelements)
- return nelements
+ return (nelements, None)
def write_switch(writer, container, switch, dest, scope):
@@ -450,8 +455,8 @@ def write_switch(writer, container, switch, dest, scope):
elif t.is_primitive():
write_member_primitive(writer, container, m, t, WSAttributes(t, m.attributes), dest2, scope)
elif t.is_array():
- nelements = read_array_len(writer, m.name, t, dest, block, False)
- write_array(writer, container, m, nelements, t, dest2, block)
+ (nelements, nbytes) = read_array_len(writer, m.name, t, dest, block, False)
+ write_array(writer, container, m, nelements, nbytes, t, dest2, block)
else:
writer.todo("Can't handle type %s" % m.member_type)
@@ -463,10 +468,10 @@ def write_switch(writer, container, switch, dest, scope):
writer.assign("output", "save_output + %s" % switch.get_fixed_nw_size())
-def write_array_core(writer, container, member, nelements, array, dest, scope):
+def write_array_core(writer, container, member, nelements, nbytes, array, dest, scope):
element_type = array.element_type
- with writer.index() as index, writer.for_loop(index, nelements) as array_scope:
+ def write_item(index):
dest.index = index
if element_type.is_primitive():
write_member_primitive(writer, container, member, element_type, WSAttributes(element_type, array.item_attrs), dest, scope)
@@ -475,7 +480,24 @@ def write_array_core(writer, container, member, nelements, array, dest, scope):
write_struct(writer, member, element_type, index, dest, scope)
dest.index = None
-def write_array(writer, container, member, nelements, array, dest, scope):
+ if nbytes:
+ scope.variable_def('guint32', 'start_offset')
+ scope.variable_def('guint32', 'save_end')
+ writer.assign('start_offset', 'offset')
+ writer.assign('save_end', 'glb->message_end')
+ writer.assign('glb->message_end', '%s + start_offset' % nbytes)
+ with writer.index() as index:
+ writer.assign(index, 0)
+ with writer.while_loop('offset < %s + start_offset' % nbytes) as array_scope:
+ write_item(index)
+ writer.increment(index, 1)
+ dest.write_ref(writer, 32, member.name + '.nelements', index)
+ writer.assign('glb->message_end', 'save_end')
+ else:
+ with writer.index() as index, writer.for_loop(index, nelements) as array_scope:
+ write_item(index)
+
+def write_array(writer, container, member, nelements, nbytes, array, dest, scope):
assert(container and member)
ws = WSAttributes(array, member.attributes)
@@ -485,6 +507,7 @@ def write_array(writer, container, member, nelements, array, dest, scope):
# easy case, binary data
if element_type == ptypes.uint8 or element_type == ptypes.int8:
+ assert nbytes is None, "Wrong length for %s" % member.name
if not ws.has_txts():
write_wireshark_field(writer, container, member, array, ws, tree, dest, nelements, 'ENC_NA')
else:
@@ -498,10 +521,10 @@ def write_array(writer, container, member, nelements, array, dest, scope):
# just the core
if not ws.desc and not ws.name and not ws.has_txts():
- write_array_core(writer, container, member, nelements, array, dest, scope)
+ write_array_core(writer, container, member, nelements, nbytes, array, dest, scope)
else:
with tree_item(writer, scope, ws, array, dest):
- write_array_core(writer, container, member, nelements, array, dest, scope)
+ write_array_core(writer, container, member, nelements, nbytes, array, dest, scope)
def write_ptr_function(writer, target_type, container, member, dest, scope):
@@ -524,7 +547,7 @@ def write_ptr_function(writer, target_type, container, member, dest, scope):
dest = RootDestination(scope)
dest.is_helper = True
if target_type.is_array():
- write_array(writer, None, None, "nelements", target_type, dest, scope)
+ write_array(writer, None, None, "nelements", None, target_type, dest, scope)
else:
write_container_parser(writer, target_type, dest)
@@ -555,8 +578,8 @@ def write_pointer(writer, container, member, t, dest, scope):
writer.variable_def('guint32', 'save_offset = offset')
writer.assign('offset', 'ptr + glb->message_offset')
if t.target_type.is_array():
- nelements = read_array_len(writer, member.name, t.target_type, dest, scope, True)
- write_array(writer, container, member, nelements, t.target_type, dest, scope)
+ (nelements, nbytes) = read_array_len(writer, member.name, t.target_type, dest, scope, True)
+ write_array(writer, container, member, nelements, nbytes, t.target_type, dest, scope)
else:
stmt = write_ptr_function(writer, t.target_type, container, member, dest, scope)
writer.statement(stmt)
@@ -787,12 +810,7 @@ def write_flags(writer, container, member, t, ws, tree, dest):
def write_member_primitive(writer, container, member, t, ws, dest, scope):
assert(t.is_primitive())
- if member.has_attr("bytes_count"):
- raise NotImplementedError("bytes_count not implemented")
- if member.has_attr("bytes_count"):
- dest_var = member.attributes["bytes_count"][0]
- else:
- dest_var = member.name
+ dest_var = member.name
dest.write_ref(writer, t.get_fixed_nw_size() * 8, dest_var, '%s(glb->tvb, offset)' % primitive_read_func(t))
if not ws.has_txts():
@@ -832,8 +850,8 @@ def write_member(writer, container, member, dest, scope):
elif t.is_primitive():
write_member_primitive(writer, container, member, t, WSAttributes(t, member.attributes), dest, scope)
elif t.is_array():
- nelements = read_array_len(writer, member.name, t, dest, scope, False)
- write_array(writer, container, member, nelements, t, dest, scope)
+ (nelements, nbytes) = read_array_len(writer, member.name, t, dest, scope, False)
+ write_array(writer, container, member, nelements, nbytes, t, dest, scope)
elif t.is_struct():
write_struct(writer, member, t, '-1', dest, scope)
--
2.4.3
More information about the Spice-devel
mailing list