[pygobject/invoke-rewrite] [gi] flesh out interface in marshalling a bit more
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] [gi] flesh out interface in marshalling a bit more
- Date: Tue, 11 Jan 2011 18:50:24 +0000 (UTC)
commit 4fcca8518774ab89607196dfc52037e3da30ac8a
Author: John (J5) Palmieri <johnp redhat com>
Date: Tue Jan 11 13:49:58 2011 -0500
[gi] flesh out interface in marshalling a bit more
gi/pygi-argument.c | 74 +++++++++++++++++++++++++++++++++++++++---------
gi/pygi-cache.c | 79 ++++++++++++++++++++++++++++++++++++++++-----------
gi/pygi-cache.h | 1 +
3 files changed, 123 insertions(+), 31 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 49d41b5..19df4d6 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2718,21 +2718,60 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState *state,
PyObject *py_arg,
GIArgument *arg)
{
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
- return FALSE;
-}
+ PyGIIntefaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
-gboolean
-_pygi_marshal_in_interface_interface (PyGIInvokeState *state,
- PyGIFunctionCache *function_cache,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- GIArgument *arg)
-{
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
- return FALSE;
+ if (py_arg == Py_None) {
+ arg.v_pointer = NULL;
+ return TRUE;
+ }
+
+ 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);
+ return FALSE;
+ }
+
+ closure = pyg_closure_new (py_arg, NULL, NULL);
+ if (closure == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
+ return FALSE;
+ }
+
+ (*argv).v_pointer = closure;
+ } else if (iface_cache->g_type == G_VALUE) {
+ GValue *value;
+ GType object_type;
+
+ 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;
+ }
+
+ value = g_slice_new0 (GValue);
+ g_value_init (value, object_type);
+ if (pyg_value_from_pyobject (value, object) < 0) {
+ g_slice_free (GValue, value);
+ PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
+ return FALSE;
+ }
+
+ (*arg).v_pointer = value;
+
+ } 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)) {
+ PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
+ iface_cache->type_name,
+ iface_cache->py_type->ob_type->tp_name);
+ return FALSE;
+ }
+
+ return TRUE;
}
gboolean
@@ -2759,6 +2798,13 @@ _pygi_marshal_in_interface_object (PyGIInvokeState *state,
return TRUE;
}
+ if (!PyObject_IsInstance (py_arg, ((PyGIInterfaceCache *)arg_cache)->py_type)) {
+ PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
+ ((PyGIInterfaceCache *)arg_cache)->type_name,
+ ((PyGIInterfaceCache *)arg_cache)->py_type->ob_type->tp_name);
+ return FALSE;
+ }
+
(*arg).v_pointer = pygobject_get (py_arg);
if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
g_object_ref ((*arg).v_pointer);
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index af4f704..ff92de9 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -18,8 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
+
+#include "pygi-info.h"
#include "pygi-cache.h"
#include "pygi-argument.h"
+#include "pygi-type.h"
#include <girepository.h>
PyGIArgCache * _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
@@ -36,6 +39,8 @@ _interface_cache_free_func (PyGIInterfaceCache *cache)
if (cache != NULL) {
Py_XDECREF(cache->py_type);
g_slice_free(PyGIInterfaceCache, cache);
+ if (cache->type_name != NULL)
+ g_free(cache->type_name);
}
}
@@ -103,6 +108,7 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
flags = g_function_info_get_flags(function_info);
fc->is_method = flags & GI_FUNCTION_IS_METHOD;
fc->is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;
+
fc->n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info) + (fc->is_method ? 1: 0);
if (fc->n_args > 0)
fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *));
@@ -110,6 +116,29 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
return fc;
}
+
+static inline PyGIInterfaceCache *
+_interface_cache_new_from_interface_info(GIInterfaceInfo *iface_info)
+{
+ PyGIInterfaceCache *ic;
+
+ ic = g_slice_new0(PyGIInterfaceCache);
+ ((PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
+ ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
+ if (ic->g_type != G_TYPE_NONE) {
+ ic->py_type = _pygi_type_get_from_g_type (ic->g_type);
+ } else {
+ /* FIXME: avoid passing GI infos to noncache API */
+ ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
+ }
+
+ if (ic->py_type == NULL)
+ return NULL;
+
+ ic->type_name == _pygi_g_base_info_get_fullname(iface_info);
+ return ic;
+}
+
static inline PyGISequenceCache *
_sequence_cache_new_from_type_info(GITypeInfo *type_info)
{
@@ -118,6 +147,7 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
GITypeTag item_type_tag;
sc = g_slice_new0(PyGISequenceCache);
+ ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
sc->fixed_size = -1;
sc->len_arg_index = -1;
@@ -146,8 +176,6 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
sc->item_cache->type_tag = item_type_tag;
g_base_info_unref( (GIBaseInfo *) item_type_info);
- ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
-
return sc;
}
@@ -355,20 +383,33 @@ _arg_cache_new_for_in_interface_union(void)
return arg_cache;
}
+
+static void
+_g_slice_free_gvalue_func(GValue *value) {
+ g_slice_free(GValue, value);
+}
+
static inline PyGIArgCache *
-_arg_cache_new_for_in_interface_struct(void)
+_arg_cache_new_for_in_interface_struct(GIInterfaceInfo *iface_info,
+ GITransfer transfer)
{
- PyGIArgCache *arg_cache = NULL;
- /*arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;*/
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
+ PyGIInterfaceCache *iface_cache = _interface_cache_new_from_interface_info(iface_info);
+ PyGIArgCache *arg_cache = (PyGIArgCache *)iface_cache);
+ iface_cache->is_foreign = g_struct_info_is_foreign( (GIStructInfo*)iface_info);
+ arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
+ if (iface_cache->g_type == G_TYPE_VALUE)
+ arg_cache->cleanup = _g_slice_free_gvalue_func;
+ if (iface_cache->g_type == G_TYPE_CLOSURE)
+ arg_cache->cleanup = g_closure_unref;
+
return arg_cache;
}
static inline PyGIArgCache *
-_arg_cache_new_for_in_interface_object(GITransfer transfer)
+_arg_cache_new_for_in_interface_object(GIInterfaceInfo *iface_info,
+ GITransfer transfer)
{
- PyGIArgCache *arg_cache = _arg_cache_new();
+ PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
arg_cache->in_marshaller = _pygi_marshal_in_interface_object;
if (transfer == GI_TRANSFER_EVERYTHING)
arg_cache->cleanup = (GDestroyNotify)g_object_unref;
@@ -377,12 +418,11 @@ _arg_cache_new_for_in_interface_object(GITransfer transfer)
}
static inline PyGIArgCache *
-_arg_cache_new_for_in_interface_boxed(void)
+_arg_cache_new_for_in_interface_boxed(GIInterfaceInfo *iface_info,
+ GITransfer transfer)
{
- PyGIArgCache *arg_cache = NULL;
- /*arg_cache->in_marshaller = _pygi_marshal_in_boxed;*/
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
+ PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
+ arg_cache->in_marshaller = _pygi_marshal_in_interface_boxed;
return arg_cache;
}
@@ -436,10 +476,12 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info,
break;
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
- arg_cache = _arg_cache_new_for_in_interface_object(transfer);
+ arg_cache = _arg_cache_new_for_in_interface_object(iface_info,
+ transfer);
break;
case GI_INFO_TYPE_BOXED:
- arg_cache = _arg_cache_new_for_in_interface_boxed();
+ arg_cache = _arg_cache_new_for_in_interface_boxed(iface_info,
+ transfer);
break;
case GI_INFO_TYPE_CALLBACK:
arg_cache = _arg_cache_new_for_in_interface_callback();
@@ -461,6 +503,8 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info,
arg_cache->py_arg_index = py_arg_index;
arg_cache->c_arg_index = c_arg_index;
}
+
+ return arg_cache;
}
@@ -604,7 +648,8 @@ _args_cache_generate(GIFunctionInfo *function_info,
function_cache->n_in_args++;
}
- for (arg_index; arg_index < function_cache->n_args; arg_index++) {
+
+ for (; arg_index < function_cache->n_args; arg_index++) {
PyGIArgCache *arg_cache = NULL;
GIArgInfo *arg_info;
GITypeInfo *type_info;
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 00780db..310839e 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -76,6 +76,7 @@ typedef struct _PyGIInterfaceCache
gboolean is_foreign;
GType g_type;
PyObject *py_type;
+ gchar *type_name;
} PyGIInterfaceCache;
typedef struct _PyGIHashCache
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]