[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