[pygobject/invoke-rewrite] [gi] fix marshalling structs



commit 5f16df31b5a5a9f45f702eee48c3a18899ea3f71
Author: John (J5) Palmieri <johnp redhat com>
Date:   Wed Jan 19 09:13:44 2011 -0500

    [gi] fix marshalling structs

 gi/pygi-argument.c |   47 +++++++++++++++++++++++++++++++++++------------
 gi/pygi-foreign.c  |   18 ++++++++++++------
 gi/pygi-foreign.h  |    8 ++++----
 3 files changed, 51 insertions(+), 22 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index e33d648..e1d2b7c 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -3004,26 +3004,31 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState   *state,
         return TRUE;
     }
 
+    /* FIXME: handle this large if statement in the cache
+     *        and set the correct marshaller
+     */
+
     if (iface_cache->g_type == G_TYPE_CLOSURE) {
         GClosure *closure;
-        if (!PyCallable_Check (py_arg)) {
-            PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
-                          py_arg->ob_type->tp_name);
+        if (!PyCallable_Check(py_arg)) {
+            PyErr_Format(PyExc_TypeError, "Must be callable, not %s",
+                         py_arg->ob_type->tp_name);
             return FALSE;
         }
 
-        closure = pyg_closure_new (py_arg, NULL, NULL);
+        closure = pyg_closure_new(py_arg, NULL, NULL);
         if (closure == NULL) {
-            PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
+            PyErr_SetString(PyExc_RuntimeError, "PyObject conversion to GClosure failed");
             return FALSE;
         }
 
         arg->v_pointer = closure;
+        return TRUE;
     } else if (iface_cache->g_type == G_TYPE_VALUE) {
         GValue *value;
         GType object_type;
 
-        object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
+        object_type = pyg_type_from_object_strict( (PyObject *) py_arg->ob_type, FALSE);
         if (object_type == G_TYPE_INVALID) {
             PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
             return FALSE;
@@ -3031,25 +3036,43 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState   *state,
 
         value = g_slice_new0 (GValue);
         g_value_init (value, object_type);
-        if (pyg_value_from_pyobject (value, py_arg) < 0) {
+        if (pyg_value_from_pyobject(value, py_arg) < 0) {
             g_slice_free (GValue, value);
             PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
             return FALSE;
         }
 
         arg->v_pointer = value;
-
+        return TRUE;
     } else if (iface_cache->is_foreign) {
-         PyErr_Format (PyExc_NotImplementedError, "foreign types not implemented yet");
-
-        return FALSE;
-    } else if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
+        gboolean success;
+        GITypeInfo *type_info = g_arg_info_get_type(arg_cache->arg_info);
+        success = pygi_struct_foreign_convert_to_g_argument(py_arg, 
+                                                            type_info, 
+                                                            arg_cache->transfer, 
+                                                            arg);
+        g_base_info_unref((GIBaseInfo *)type_info);
+
+        return success;
+    } else if (!PyObject_IsInstance(py_arg, iface_cache->py_type)) {
         PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
                       iface_cache->type_name, 
                       iface_cache->py_type->ob_type->tp_name);
         return FALSE;
     }
 
+    if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
+        arg->v_pointer = pyg_boxed_get(py_arg, void);
+        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+            arg->v_pointer = g_boxed_copy(iface_cache->g_type, arg->v_pointer);
+        }
+    } else if (g_type_is_a (iface_cache->g_type, G_TYPE_POINTER) ||
+               iface_cache->g_type  == G_TYPE_NONE) {
+        arg->v_pointer = pyg_pointer_get(py_arg, void);
+    } else {
+        PyErr_Format (PyExc_NotImplementedError, "structure type '%s' is not supported yet", g_type_name(iface_cache->g_type));
+        return FALSE;
+    }
     return TRUE;
 }
 
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index 75d5bb9..fa43005 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -106,23 +106,29 @@ pygi_struct_foreign_lookup (GIBaseInfo *base_info)
     return result;
 }
 
-PyObject *
+gboolean
 pygi_struct_foreign_convert_to_g_argument (PyObject       *value,
                                            GITypeInfo     *type_info,
                                            GITransfer      transfer,
                                            GIArgument      *arg)
 {
+    PyObject *result;
     GIBaseInfo *base_info = g_type_info_get_interface (type_info);
     PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (base_info);
     g_base_info_unref (base_info);
 
-    if (foreign_struct == NULL)
-        return NULL;
+    if (foreign_struct == NULL) {
+        PyErr_Format(PyExc_KeyError, "could not find foreign type %s",
+                     g_base_info_get_name (base_info));
+        return FALSE;
+    }
 
-    if (!foreign_struct->to_func (value, type_info, transfer, arg))
-        return NULL;
+    result = foreign_struct->to_func (value, type_info, transfer, arg);
+    if (result == NULL)
+        return FALSE;
 
-    Py_RETURN_NONE;
+    Py_DECREF(result);
+    return TRUE;
 }
 
 PyObject *
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index b57f892..3e20663 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -30,10 +30,10 @@
 
 #include "pygi.h"
 
-PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject           *value,
-                                                     GITypeInfo         *type_info,
-                                                     GITransfer          transfer,
-                                                     GIArgument          *arg);
+gboolean pygi_struct_foreign_convert_to_g_argument (PyObject           *value,
+                                                    GITypeInfo         *type_info,
+                                                    GITransfer          transfer,
+                                                    GIArgument          *arg);
 PyObject *pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
                                                        GIArgument  *arg);
 PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,



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