Commit 4fcca851 authored by John (J5) Palmieri's avatar John (J5) Palmieri
Browse files

[gi] flesh out interface in marshalling a bit more

parent 369a75ba
...@@ -2718,21 +2718,60 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState *state, ...@@ -2718,21 +2718,60 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState *state,
PyObject *py_arg, PyObject *py_arg,
GIArgument *arg) GIArgument *arg)
{ {
PyErr_Format(PyExc_NotImplementedError, PyGIIntefaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
"Marshalling for this type is not implemented yet");
return FALSE;
}
gboolean if (py_arg == Py_None) {
_pygi_marshal_in_interface_interface (PyGIInvokeState *state, arg.v_pointer = NULL;
PyGIFunctionCache *function_cache, return TRUE;
PyGIArgCache *arg_cache, }
PyObject *py_arg,
GIArgument *arg) if (iface_cache->g_type == G_TYPE_CLOSURE) {
{ GClosure *closure;
PyErr_Format(PyExc_NotImplementedError, if (!PyCallable_Check (py_arg)) {
"Marshalling for this type is not implemented yet"); PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
return FALSE; 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 gboolean
...@@ -2759,6 +2798,13 @@ _pygi_marshal_in_interface_object (PyGIInvokeState *state, ...@@ -2759,6 +2798,13 @@ _pygi_marshal_in_interface_object (PyGIInvokeState *state,
return TRUE; 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); (*arg).v_pointer = pygobject_get (py_arg);
if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
g_object_ref ((*arg).v_pointer); g_object_ref ((*arg).v_pointer);
......
...@@ -18,8 +18,11 @@ ...@@ -18,8 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA * USA
*/ */
#include "pygi-info.h"
#include "pygi-cache.h" #include "pygi-cache.h"
#include "pygi-argument.h" #include "pygi-argument.h"
#include "pygi-type.h"
#include <girepository.h> #include <girepository.h>
PyGIArgCache * _arg_cache_in_new_from_type_info (GITypeInfo *type_info, PyGIArgCache * _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
...@@ -36,6 +39,8 @@ _interface_cache_free_func (PyGIInterfaceCache *cache) ...@@ -36,6 +39,8 @@ _interface_cache_free_func (PyGIInterfaceCache *cache)
if (cache != NULL) { if (cache != NULL) {
Py_XDECREF(cache->py_type); Py_XDECREF(cache->py_type);
g_slice_free(PyGIInterfaceCache, cache); 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) ...@@ -103,6 +108,7 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
flags = g_function_info_get_flags(function_info); flags = g_function_info_get_flags(function_info);
fc->is_method = flags & GI_FUNCTION_IS_METHOD; fc->is_method = flags & GI_FUNCTION_IS_METHOD;
fc->is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR; 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); fc->n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info) + (fc->is_method ? 1: 0);
if (fc->n_args > 0) if (fc->n_args > 0)
fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *)); fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *));
...@@ -110,6 +116,29 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info) ...@@ -110,6 +116,29 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
return fc; 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 * static inline PyGISequenceCache *
_sequence_cache_new_from_type_info(GITypeInfo *type_info) _sequence_cache_new_from_type_info(GITypeInfo *type_info)
{ {
...@@ -118,6 +147,7 @@ _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; GITypeTag item_type_tag;
sc = g_slice_new0(PyGISequenceCache); sc = g_slice_new0(PyGISequenceCache);
((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
sc->fixed_size = -1; sc->fixed_size = -1;
sc->len_arg_index = -1; sc->len_arg_index = -1;
...@@ -146,8 +176,6 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info) ...@@ -146,8 +176,6 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
sc->item_cache->type_tag = item_type_tag; sc->item_cache->type_tag = item_type_tag;
g_base_info_unref( (GIBaseInfo *) item_type_info); g_base_info_unref( (GIBaseInfo *) item_type_info);
((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
return sc; return sc;
} }
...@@ -355,20 +383,33 @@ _arg_cache_new_for_in_interface_union(void) ...@@ -355,20 +383,33 @@ _arg_cache_new_for_in_interface_union(void)
return arg_cache; return arg_cache;
} }
static void
_g_slice_free_gvalue_func(GValue *value) {
g_slice_free(GValue, value);
}
static inline PyGIArgCache * 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; PyGIInterfaceCache *iface_cache = _interface_cache_new_from_interface_info(iface_info);
/*arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;*/ PyGIArgCache *arg_cache = (PyGIArgCache *)iface_cache);
PyErr_Format(PyExc_NotImplementedError, iface_cache->is_foreign = g_struct_info_is_foreign( (GIStructInfo*)iface_info);
"Caching for this type is not fully implemented yet"); 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; return arg_cache;
} }
static inline PyGIArgCache * 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; arg_cache->in_marshaller = _pygi_marshal_in_interface_object;
if (transfer == GI_TRANSFER_EVERYTHING) if (transfer == GI_TRANSFER_EVERYTHING)
arg_cache->cleanup = (GDestroyNotify)g_object_unref; arg_cache->cleanup = (GDestroyNotify)g_object_unref;
...@@ -377,12 +418,11 @@ _arg_cache_new_for_in_interface_object(GITransfer transfer) ...@@ -377,12 +418,11 @@ _arg_cache_new_for_in_interface_object(GITransfer transfer)
} }
static inline PyGIArgCache * 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; PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
/*arg_cache->in_marshaller = _pygi_marshal_in_boxed;*/ arg_cache->in_marshaller = _pygi_marshal_in_interface_boxed;
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return arg_cache; return arg_cache;
} }
...@@ -436,10 +476,12 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info, ...@@ -436,10 +476,12 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info,
break; break;
case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE: 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; break;
case GI_INFO_TYPE_BOXED: 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; break;
case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_CALLBACK:
arg_cache = _arg_cache_new_for_in_interface_callback(); arg_cache = _arg_cache_new_for_in_interface_callback();
...@@ -461,6 +503,8 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info, ...@@ -461,6 +503,8 @@ _arg_cache_in_new_from_interface_info (GIInterfaceInfo *iface_info,
arg_cache->py_arg_index = py_arg_index; arg_cache->py_arg_index = py_arg_index;
arg_cache->c_arg_index = c_arg_index; arg_cache->c_arg_index = c_arg_index;
} }
return arg_cache;
} }
...@@ -604,7 +648,8 @@ _args_cache_generate(GIFunctionInfo *function_info, ...@@ -604,7 +648,8 @@ _args_cache_generate(GIFunctionInfo *function_info,
function_cache->n_in_args++; 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; PyGIArgCache *arg_cache = NULL;
GIArgInfo *arg_info; GIArgInfo *arg_info;
GITypeInfo *type_info; GITypeInfo *type_info;
......
...@@ -76,6 +76,7 @@ typedef struct _PyGIInterfaceCache ...@@ -76,6 +76,7 @@ typedef struct _PyGIInterfaceCache
gboolean is_foreign; gboolean is_foreign;
GType g_type; GType g_type;
PyObject *py_type; PyObject *py_type;
gchar *type_name;
} PyGIInterfaceCache; } PyGIInterfaceCache;
typedef struct _PyGIHashCache typedef struct _PyGIHashCache
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment