[pygi] The array field 'length' starts to count from the C arg list, so need to decrement when it's a metho



commit 24fa1224ff00b9da177e0bfaa1e14e1b899e4976
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date:   Wed Nov 25 10:33:56 2009 +0100

    The array field 'length' starts to count from the C arg list, so need to decrement when it's a method
    
    https://bugzilla.gnome.org/show_bug.cgi?id=602640

 gi/pygi-argument.c |   11 ++++++++-
 gi/pygi-argument.h |    3 +-
 gi/pygi-info.c     |   14 ++++++++++-
 tests/libtestgi.c  |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/libtestgi.h  |    4 +++
 tests/test_gi.py   |   15 +++++++++++++
 6 files changed, 103 insertions(+), 4 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 7740d0c..b7edcdf 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -597,7 +597,8 @@ check_number_release:
 GArray *
 _pygi_argument_to_array (GArgument  *arg,
                          GArgument  *args[],
-                         GITypeInfo *type_info)
+                         GITypeInfo *type_info,
+                         gboolean is_method)
 {
     GITypeInfo *item_type_info;
     gboolean is_zero_terminated;
@@ -622,11 +623,19 @@ _pygi_argument_to_array (GArgument  *arg,
             length_arg_pos = g_type_info_get_array_length(type_info);
             g_assert(length_arg_pos >= 0);
 
+            if (is_method) {
+                length_arg_pos--;
+            }
+
+            g_assert (length_arg_pos >= 0);
+
             /* FIXME: Take into account the type of the argument. */
             length = args[length_arg_pos]->v_int;
         }
     }
 
+    g_assert (length >= 0);
+
     g_array = g_array_new(is_zero_terminated, FALSE, item_size);
 
     g_array->data = arg->v_pointer;
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
index 59458fc..eef61a2 100644
--- a/gi/pygi-argument.h
+++ b/gi/pygi-argument.h
@@ -42,7 +42,8 @@ gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
 
 GArray* _pygi_argument_to_array (GArgument  *arg,
                                  GArgument  *args[],
-                                 GITypeInfo *type_info);
+                                 GITypeInfo *type_info,
+                                 gboolean    is_method);
 
 GArgument _pygi_argument_from_object (PyObject   *object,
                                       GITypeInfo *type_info,
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 11751a9..6e2b938 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -584,6 +584,10 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
                 gint length_arg_pos;
 
                 length_arg_pos = g_type_info_get_array_length(arg_type_infos[i]);
+
+                if (is_method)
+                    length_arg_pos--; // length_arg_pos refers to C args
+
                 if (length_arg_pos < 0) {
                     break;
                 }
@@ -615,6 +619,10 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
     if (return_type_tag == GI_TYPE_TAG_ARRAY) {
         gint length_arg_pos;
         length_arg_pos = g_type_info_get_array_length(return_type_info);
+
+        if (is_method)
+            length_arg_pos--; // length_arg_pos refers to C args
+
         if (length_arg_pos >= 0) {
             g_assert(length_arg_pos < n_args);
             args_is_auxiliary[length_arg_pos] = TRUE;
@@ -894,6 +902,8 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
                     array = args[i]->v_pointer;
 
                     length_arg_pos = g_type_info_get_array_length(arg_type_infos[i]);
+                    if (is_method)
+                        length_arg_pos--; // length_arg_pos refers to C args
                     if (length_arg_pos >= 0) {
                         /* Set the auxiliary argument holding the length. */
                         args[length_arg_pos]->v_size = array->len;
@@ -1031,7 +1041,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
 
         if (return_type_tag == GI_TYPE_TAG_ARRAY) {
             /* Create a #GArray. */
-            return_arg.v_pointer = _pygi_argument_to_array(&return_arg, args, return_type_info);
+            return_arg.v_pointer = _pygi_argument_to_array(&return_arg, args, return_type_info, is_method);
         }
 
         transfer = g_callable_info_get_caller_owns((GICallableInfo *)self->info);
@@ -1100,7 +1110,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
             if (type_tag == GI_TYPE_TAG_ARRAY
                     && (direction != GI_DIRECTION_IN || transfer == GI_TRANSFER_NOTHING)) {
                 /* Create a #GArray. */
-                args[i]->v_pointer = _pygi_argument_to_array(args[i], args, arg_type_infos[i]);
+                args[i]->v_pointer = _pygi_argument_to_array(args[i], args, arg_type_infos[i], is_method);
             }
 
             if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) {
diff --git a/tests/libtestgi.c b/tests/libtestgi.c
index ac18095..d712b19 100644
--- a/tests/libtestgi.c
+++ b/tests/libtestgi.c
@@ -3245,6 +3245,66 @@ test_gi_object_new (gint int_)
     return g_object_new (TESTGI_TYPE_OBJECT, "int", int_, NULL);
 }
 
+/**
+ * test_gi_object_method_array_in:
+ * @ints: (array length=length):
+ */
+void
+test_gi_object_method_array_in (TestGIObject *object, const gint *ints, gint length)
+{
+    g_assert(length == 4);
+    g_assert(ints[0] == -1);
+    g_assert(ints[1] == 0);
+    g_assert(ints[2] == 1);
+    g_assert(ints[3] == 2);
+}
+
+/**
+ * test_gi_object_method_array_out:
+ * @ints: (out) (array length=length) (transfer none):
+ */
+void
+test_gi_object_method_array_out (TestGIObject *object, gint **ints, gint *length)
+{
+    static gint values[] = {-1, 0, 1, 2};
+
+    *length = 4;
+    *ints = values;
+}
+
+/**
+ * test_gi_object_method_array_inout:
+ * @ints: (inout) (array length=length) (transfer none):
+ * @length: (inout):
+ */
+void
+test_gi_object_method_array_inout (TestGIObject *object, gint **ints, gint *length)
+{
+    static gint values[] = {-2, -1, 0, 1, 2};
+
+    g_assert(*length == 4);
+    g_assert((*ints)[0] == -1);
+    g_assert((*ints)[1] == 0);
+    g_assert((*ints)[2] == 1);
+    g_assert((*ints)[3] == 2);
+
+    *length = 5;
+    *ints = values;
+}
+
+/**
+ * test_gi_object_method_array_return:
+ * Returns: (array length=length):
+ */
+const gint *
+test_gi_object_method_array_return (TestGIObject *object, gint *length)
+{
+    static gint ints[] = {-1, 0, 1, 2};
+
+    *length = 4;
+    return ints;
+}
+
 
 /**
  * test_gi__object_none_return:
diff --git a/tests/libtestgi.h b/tests/libtestgi.h
index cbf6f9b..db12fd3 100644
--- a/tests/libtestgi.h
+++ b/tests/libtestgi.h
@@ -596,6 +596,10 @@ void test_gi_object_method (TestGIObject *object);
 void test_gi_object_overridden_method (TestGIObject *object);
 TestGIObject *test_gi_object_new (gint int_);
 
+void test_gi_object_method_array_in (TestGIObject *object, const gint *ints, gint length);
+void test_gi_object_method_array_out (TestGIObject *object, gint **ints, gint *length);
+void test_gi_object_method_array_inout (TestGIObject *object, gint **ints, gint *length);
+const gint *test_gi_object_method_array_return (TestGIObject *object, gint *length);
 
 TestGIObject *test_gi__object_none_return (void);
 TestGIObject *test_gi__object_full_return (void);
diff --git a/tests/test_gi.py b/tests/test_gi.py
index d776c27..d0bc36e 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -822,6 +822,21 @@ class TestArray(unittest.TestCase):
     def test_array_inout(self):
         self.assertEquals((-2, -1, 0, 1, 2), TestGI.array_inout(Sequence((-1, 0, 1, 2))))
 
+    def test_method_array_in(self):
+        object_ = TestGI.Object()
+        object_.method_array_in(Sequence((-1, 0, 1, 2)))
+
+    def test_method_array_out(self):
+        object_ = TestGI.Object()
+        self.assertEquals((-1, 0, 1, 2), object_.method_array_out())
+
+    def test_method_array_inout(self):
+        object_ = TestGI.Object()
+        self.assertEquals((-2, -1, 0, 1, 2), object_.method_array_inout(Sequence((-1, 0, 1, 2))))
+
+    def test_method_array_return(self):
+        object_ = TestGI.Object()
+        self.assertEquals((-1, 0, 1, 2), object_.method_array_return())
 
     def test_array_fixed_out_struct(self):
         struct1, struct2 = TestGI.array_fixed_out_struct()



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