[pygi] Structs in arrays are not marshalled correctly



commit ac80e64c9f7d257865aa820753e52d56cf2871c8
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date:   Fri Nov 27 12:06:59 2009 +0000

    Structs in arrays are not marshalled correctly
    
    https://bugzilla.gnome.org/show_bug.cgi?id=602709

 gi/pygi-argument.c |   29 ++++++++++++++++++++++++-----
 tests/libtestgi.c  |   23 ++++++++++++++++++++++-
 tests/libtestgi.h  |    7 +++++--
 tests/test_gi.py   |    8 ++++++++
 4 files changed, 59 insertions(+), 8 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 7f66b1f..8411b62 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1480,8 +1480,9 @@ _pygi_argument_to_object (GArgument  *arg,
         {
             GArray *array;
             GITypeInfo *item_type_info;
+            GITypeTag item_type_tag;
             GITransfer item_transfer;
-            gsize i;
+            gsize i, item_size;
 
             array = arg->v_pointer;
 
@@ -1493,13 +1494,31 @@ _pygi_argument_to_object (GArgument  *arg,
             item_type_info = g_type_info_get_param_type(type_info, 0);
             g_assert(item_type_info != NULL);
 
+            item_type_tag = g_type_info_get_tag(item_type_info);
             item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+            item_size = g_array_get_element_size(array);
 
             for(i = 0; i < array->len; i++) {
                 GArgument item;
                 PyObject *py_item;
+                gboolean is_struct = FALSE;
+
+                if (item_type_tag == GI_TYPE_TAG_INTERFACE) {
+                    GIBaseInfo *iface_info = g_type_info_get_interface(item_type_info);
+                    switch (g_base_info_get_type(iface_info)) {
+                        case GI_INFO_TYPE_STRUCT:
+                        case GI_INFO_TYPE_BOXED:
+                            is_struct = TRUE;
+                    }
+                    g_base_info_unref((GIBaseInfo *)iface_info);
+                }
+
+                if (is_struct) {
+                    item.v_pointer = &_g_array_index(array, GArgument, i);
+                } else {
+                    memcpy(&item, &_g_array_index(array, GArgument, i), item_size);
+                }
 
-                item = _g_array_index(array, GArgument, i);
                 py_item = _pygi_argument_to_object(&item, item_type_info, item_transfer);
                 if (py_item == NULL) {
                     Py_CLEAR(object);
@@ -1789,9 +1808,9 @@ _pygi_argument_release (GArgument   *arg,
 
                 /* Free the items */
                 for (i = 0; i < array->len; i++) {
-                    GArgument item;
-                    item = _g_array_index(array, GArgument, i);
-                    _pygi_argument_release(&item, item_type_info, item_transfer, direction);
+                    GArgument *item;
+                    item = &_g_array_index(array, GArgument, i);
+                    _pygi_argument_release(item, item_type_info, item_transfer, direction);
                 }
 
                 g_base_info_unref((GIBaseInfo *)item_type_info);
diff --git a/tests/libtestgi.c b/tests/libtestgi.c
index 3677fca..87f95ae 100644
--- a/tests/libtestgi.c
+++ b/tests/libtestgi.c
@@ -1781,6 +1781,28 @@ test_gi_array_fixed_out (gint **ints)
 }
 
 /**
+ * test_gi_array_fixed_out_struct:
+ * @structs: (out) (array fixed-size=2) (transfer none):
+ */
+void
+test_gi_array_fixed_out_struct (TestGISimpleStruct **structs)
+{
+    static TestGISimpleStruct *values;
+
+    if (values == NULL) {
+        values = g_new(TestGISimpleStruct, 2);
+
+        values[0].long_ = 7;
+        values[0].int8 = 6;
+
+        values[1].long_ = 6;
+        values[1].int8 = 7;
+    }
+
+    *structs = values;
+}
+
+/**
  * test_gi_array_fixed_inout:
  * @ints: (inout) (array fixed-size=4) (transfer none):
  */
@@ -1858,7 +1880,6 @@ test_gi_array_inout (gint **ints, gint *length)
     *ints = values;
 }
 
-
 /**
  * test_gi_array_zero_terminated_return:
  * Returns: (array zero-terminated=1) (transfer none):
diff --git a/tests/libtestgi.h b/tests/libtestgi.h
index 685dcff..1ec4777 100644
--- a/tests/libtestgi.h
+++ b/tests/libtestgi.h
@@ -7,6 +7,7 @@
 #ifndef __TEST_GI_H__
 #define __TEST_GI_H__
 
+typedef struct _TestGISimpleStruct TestGISimpleStruct;
 
 /* Constants */
 
@@ -345,6 +346,8 @@ void test_gi_array_fixed_short_in (const gshort *shorts);
 
 void test_gi_array_fixed_out (gint **ints);
 
+void test_gi_array_fixed_out_struct (TestGISimpleStruct **structs);
+
 void test_gi_array_fixed_inout (gint **ints);
 
 /* Variable-size */
@@ -499,10 +502,10 @@ void test_gi_flags_inout (TestGIFlags *flags_);
 
 /* Structure */
 
-typedef struct {
+struct _TestGISimpleStruct {
     glong long_;
     gint8 int8;
-} TestGISimpleStruct;
+};
 
 typedef struct {
     TestGISimpleStruct simple_struct;
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 1b0cadb..e8654b6 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -823,6 +823,14 @@ class TestArray(unittest.TestCase):
         self.assertEquals((-2, -1, 0, 1, 2), TestGI.array_inout(Sequence((-1, 0, 1, 2))))
 
 
+    def test_array_fixed_out_struct(self):
+        struct1, struct2 = TestGI.array_fixed_out_struct()
+
+        self.assertEquals(7, struct1.long_)
+        self.assertEquals(6, struct1.int8)
+        self.assertEquals(6, struct2.long_)
+        self.assertEquals(7, struct2.int8)
+
     def test_array_zero_terminated_return(self):
         self.assertEquals(('0', '1', '2'), TestGI.array_zero_terminated_return())
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]