[Spice-devel,v2,29/43] Read array size

Submitted by Frediano Ziglio on July 8, 2015, 1:54 p.m.

Details

Message ID 1436363656-4266-30-git-send-email-fziglio@redhat.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Frediano Ziglio July 8, 2015, 1:54 p.m.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
 python_modules/dissector.py | 48 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/python_modules/dissector.py b/python_modules/dissector.py
index a7add96..aa71615 100644
--- a/python_modules/dissector.py
+++ b/python_modules/dissector.py
@@ -255,10 +255,53 @@  def write_wireshark_field(writer, container, member, t, tree, size, encoding='EN
     hf_defs.writeln('},')
 
 
+# Note: during parsing, byte_size types have been converted to count during validation
+def read_array_len(writer, prefix, array, dest, scope, is_ptr):
+    if is_ptr:
+        nelements = "%s__array__nelements" % prefix
+    else:
+        nelements = "%s__nelements" % prefix
+    if dest.is_toplevel() and scope.variable_defined(nelements):
+        return nelements # 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
+    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():
+        if element_type.is_fixed_nw_size():
+            if element_type.get_fixed_nw_size() == 1:
+                writer.assign(nelements, "glb->message_end - offset")
+            else:
+                writer.assign(nelements, "(glb->message_end - offset) / (%s)" %(element_type.get_fixed_nw_size()))
+        else:
+            raise NotImplementedError("TODO array[] of dynamic element size not done yet")
+    elif array.is_image_size_length():
+        (bpp, width, rows) = array.size[1:]
+        width_v = dest.read_ref(width)
+        rows_v = dest.read_ref(rows)
+        if bpp == 8:
+            writer.assign(nelements, "((guint32) %s * %s)" % (width_v, rows_v))
+        elif bpp == 1:
+            writer.assign(nelements, "(((guint32) %s + 7U) / 8U ) * %s" % (width_v, rows_v))
+        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]))
+    else:
+        raise NotImplementedError("TODO array size type not handled yet")
+    # TODO compute a better size
+    dest.write_ref(writer, 32, prefix+'.nelements', nelements)
+    return nelements
+
 def write_switch(writer, container, switch, dest, scope):
     pass
 
-def write_array(writer, container, member, array, dest, scope):
+def write_array(writer, container, member, nelements, array, dest, scope):
     assert(container and member)
 
 def write_pointer(writer, container, member, t, dest, scope):
@@ -307,7 +350,8 @@  def write_member(writer, container, member, dest, scope):
     elif t.is_primitive():
         write_member_primitive(writer, container, member, t, dest, scope)
     elif t.is_array():
-        write_array(writer, container, member, t, dest, scope)
+        nelements = read_array_len(writer, member.name, t, dest, scope, False)
+        write_array(writer, container, member, nelements, t, dest, scope)
 
     elif t.is_struct():
         write_struct(writer, member, t, '-1', dest, scope)