Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@sugarlabs.org>2009-05-27 13:15:37 (GMT)
committer Tomeu Vizoso <tomeu@sugarlabs.org>2009-05-27 13:15:37 (GMT)
commit3e8b17d45811241258ebc8d34818c9a2bce54160 (patch)
tree860497047be3c757ad04eb42a3a68273c8ddbfcd
parentd994df7718644fc0b7669a6e9aebebc10447e1c9 (diff)
Add initial support for arrays as out arguments
-rw-r--r--bank/bank-argument.c56
-rw-r--r--bank/bank-info.c29
-rw-r--r--bank/bank.h1
-rw-r--r--everything_unittest.py6
4 files changed, 88 insertions, 4 deletions
diff --git a/bank/bank-argument.c b/bank/bank-argument.c
index 0e64b79..ae2371b 100644
--- a/bank/bank-argument.c
+++ b/bank/bank-argument.c
@@ -169,6 +169,53 @@ glist_to_pyobject(GITypeTag list_tag, GITypeInfo *type_info, GList *list, GSList
}
PyObject *
+pyarray_to_pyobject(gpointer array, int length, GITypeInfo *type_info)
+{
+ PyObject *py_list;
+ PyObject *child_obj;
+ GITypeInfo *element_type = g_type_info_get_param_type (type_info, 0);
+ GITypeTag type_tag = g_type_info_get_tag(element_type);
+ gsize size;
+ char buf[256];
+ int i;
+
+ if (array == NULL)
+ return Py_None;
+
+ // FIXME: Doesn't seem right to have this here:
+ switch (type_tag) {
+ case GI_TYPE_TAG_INT:
+ size = sizeof(int);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ size = sizeof(gpointer);
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "Unimplemented type: %s\n", g_type_tag_to_string(type_tag));
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+
+ if ((py_list = PyList_New(0)) == NULL) {
+ return NULL;
+ }
+
+ for( i = 0; i < length; i++ ) {
+ gpointer current_element = array + i * size;
+
+ child_obj = pyg_argument_to_pyobject(current_element, element_type);
+ if (child_obj == NULL) {
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
+ }
+
+ return py_list;
+}
+
+PyObject *
pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
{
GITypeTag type_tag;
@@ -312,8 +359,9 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
}
break;
case GI_TYPE_TAG_ARRAY:
- obj = Py_None;
- break;
+ g_warning("pyg_argument_to_pyobject: use pyarray_to_pyobject instead for arrays");
+ obj = Py_None;
+ break;
default:
g_print("<GArg->PyO> GITypeTag %s is unhandled\n",
g_type_tag_to_string(type_tag));
@@ -321,7 +369,9 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
break;
}
- Py_INCREF(obj);
+ if (obj != NULL)
+ Py_INCREF(obj);
+
return obj;
}
diff --git a/bank/bank-info.c b/bank/bank-info.c
index f60f616..0aaee0c 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -582,7 +582,34 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
g_assert(next_rval < n_return_values);
g_assert(out_args_pos < expected_out_argc);
- PyObject *obj = pyg_argument_to_pyobject(out_args[out_args_pos].v_pointer, arg_type_info);
+ PyObject *obj;
+ GITypeTag type_tag = g_type_info_get_tag(arg_type_info);
+
+ if (type_tag == GI_TYPE_TAG_ARRAY) {
+ GArgument *arg = out_args[out_args_pos].v_pointer;
+ gint length_arg_index = g_type_info_get_array_length(arg_type_info);
+ GArgument *length_arg;
+
+ if (is_method)
+ length_arg_index--;
+
+ if (length_arg_index == -1) {
+ PyErr_SetString(PyExc_NotImplementedError, "Need a field to specify the array length");
+ return NULL;
+ }
+
+ length_arg = out_args[length_arg_index].v_pointer;
+
+ printf("index %d pointer %p\n", length_arg_index, length_arg);fflush(stdout);
+
+ if (length_arg == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to get the length of the array");
+ return NULL;
+ }
+
+ obj = pyarray_to_pyobject(arg->v_pointer, length_arg->v_int, arg_type_info);
+ } else
+ obj = pyg_argument_to_pyobject(out_args[out_args_pos].v_pointer, arg_type_info);
if (obj == NULL) {
return NULL;
}
diff --git a/bank/bank.h b/bank/bank.h
index b8f0181..d960483 100644
--- a/bank/bank.h
+++ b/bank/bank.h
@@ -76,4 +76,5 @@ GArgument pyg_argument_from_pyobject(PyObject *object,
GITypeInfo *info);
PyObject* pyg_argument_to_pyobject(GArgument *arg,
GITypeInfo *info);
+PyObject* pyarray_to_pyobject(gpointer array, int length, GITypeInfo *info);
diff --git a/everything_unittest.py b/everything_unittest.py
index fd245f0..6dc67a6 100644
--- a/everything_unittest.py
+++ b/everything_unittest.py
@@ -277,5 +277,11 @@ class TestGIEverything(unittest.TestCase):
s = TestSubclass()
self.assertEquals(s.do_matrix('matrix'), 42)
+ def testArrayOut(self):
+ b, n_ints, ints = Everything.test_array_int_full_out2()
+ self.assertEquals(b, True)
+ self.assertEquals(n_ints, 5)
+ self.assertEquals(ints, [1, 2, 3, 4, 5])
+
if __name__ == '__main__':
unittest.main()