summaryrefslogtreecommitdiff
path: root/gi/pygi-struct-marshal.c
diff options
context:
space:
mode:
Diffstat (limited to 'gi/pygi-struct-marshal.c')
-rw-r--r--gi/pygi-struct-marshal.c267
1 files changed, 141 insertions, 126 deletions
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 7346eae..9abaaae 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -84,7 +84,7 @@ _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
* GValue from Python
*/
-/* _pygi_marshal_from_py_gvalue:
+/* pygi_arg_gvalue_from_py_marshal:
* py_arg: (in):
* arg: (out):
* transfer:
@@ -92,10 +92,10 @@ _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
* when it is already holding a GValue vs. copying the value.
*/
gboolean
-_pygi_marshal_from_py_gvalue (PyObject *py_arg,
- GIArgument *arg,
- GITransfer transfer,
- gboolean copy_reference) {
+pygi_arg_gvalue_from_py_marshal (PyObject *py_arg,
+ GIArgument *arg,
+ GITransfer transfer,
+ gboolean copy_reference) {
GValue *value;
GType object_type;
@@ -130,11 +130,11 @@ _pygi_marshal_from_py_gvalue (PyObject *py_arg,
}
void
-_pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- gpointer data,
- gboolean was_processed)
+pygi_arg_gvalue_from_py_cleanup (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ gpointer data,
+ gboolean was_processed)
{
/* Note py_arg can be NULL for hash table which is a bug. */
if (was_processed && py_arg != NULL) {
@@ -151,13 +151,13 @@ _pygi_marshal_cleanup_from_py_interface_struct_gvalue (PyGIInvokeState *state,
}
}
-/* _pygi_marshal_from_py_gclosure:
+/* pygi_arg_gclosure_from_py_marshal:
* py_arg: (in):
* arg: (out):
*/
gboolean
-_pygi_marshal_from_py_gclosure(PyObject *py_arg,
- GIArgument *arg)
+pygi_arg_gclosure_from_py_marshal (PyObject *py_arg,
+ GIArgument *arg)
{
GClosure *closure;
GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
@@ -183,21 +183,21 @@ _pygi_marshal_from_py_gclosure(PyObject *py_arg,
return TRUE;
}
-/* _pygi_marshal_from_py_interface_struct:
+/* pygi_arg_struct_from_py_marshal:
*
* Dispatcher to various sub marshalers
*/
gboolean
-_pygi_marshal_from_py_interface_struct (PyObject *py_arg,
- GIArgument *arg,
- const gchar *arg_name,
- GIBaseInfo *interface_info,
- GType g_type,
- PyObject *py_type,
- GITransfer transfer,
- gboolean copy_reference,
- gboolean is_foreign,
- gboolean is_pointer)
+pygi_arg_struct_from_py_marshal (PyObject *py_arg,
+ GIArgument *arg,
+ const gchar *arg_name,
+ GIBaseInfo *interface_info,
+ GType g_type,
+ PyObject *py_type,
+ GITransfer transfer,
+ gboolean copy_reference,
+ gboolean is_foreign,
+ gboolean is_pointer)
{
gboolean is_union = FALSE;
@@ -211,12 +211,12 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg,
*/
if (g_type_is_a (g_type, G_TYPE_CLOSURE)) {
- return _pygi_marshal_from_py_gclosure (py_arg, arg);
+ return pygi_arg_gclosure_from_py_marshal (py_arg, arg);
} else if (g_type_is_a (g_type, G_TYPE_VALUE)) {
- return _pygi_marshal_from_py_gvalue(py_arg,
- arg,
- transfer,
- copy_reference);
+ return pygi_arg_gvalue_from_py_marshal(py_arg,
+ arg,
+ transfer,
+ copy_reference);
} else if (is_foreign) {
PyObject *success;
success = pygi_struct_foreign_convert_to_g_argument (py_arg,
@@ -292,25 +292,25 @@ type_error:
}
static gboolean
-_pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- GIArgument *arg,
- gpointer *cleanup_data)
+arg_struct_from_py_marshal_adapter (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg,
+ gpointer *cleanup_data)
{
PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
- gboolean res = _pygi_marshal_from_py_interface_struct (py_arg,
- arg,
- arg_cache->arg_name,
- iface_cache->interface_info,
- iface_cache->g_type,
- iface_cache->py_type,
- arg_cache->transfer,
- TRUE, /*copy_reference*/
- iface_cache->is_foreign,
- arg_cache->is_pointer);
+ gboolean res = pygi_arg_struct_from_py_marshal (py_arg,
+ arg,
+ arg_cache->arg_name,
+ iface_cache->interface_info,
+ iface_cache->g_type,
+ iface_cache->py_type,
+ arg_cache->transfer,
+ TRUE, /*copy_reference*/
+ iface_cache->is_foreign,
+ arg_cache->is_pointer);
/* Assume struct marshaling is always a pointer and assign cleanup_data
* here rather than passing it further down the chain.
@@ -320,27 +320,28 @@ _pygi_marshal_from_py_interface_struct_cache_adapter (PyGIInvokeState *state,
}
static void
-_pygi_marshal_cleanup_from_py_interface_struct_foreign (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- gpointer data,
- gboolean was_processed)
+arg_foreign_from_py_cleanup (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ gpointer data,
+ gboolean was_processed)
{
- if (state->failed && was_processed)
+ if (state->failed && was_processed) {
pygi_struct_foreign_release (
( (PyGIInterfaceCache *)arg_cache)->interface_info,
data);
+ }
}
PyObject *
-_pygi_marshal_to_py_interface_struct (GIArgument *arg,
- GIInterfaceInfo *interface_info,
- GType g_type,
- PyObject *py_type,
- GITransfer transfer,
- gboolean is_allocated,
- gboolean is_foreign)
+pygi_arg_struct_to_py_marshal (GIArgument *arg,
+ GIInterfaceInfo *interface_info,
+ GType g_type,
+ PyObject *py_type,
+ GITransfer transfer,
+ gboolean is_allocated,
+ gboolean is_foreign)
{
PyObject *py_obj = NULL;
@@ -400,89 +401,107 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg,
}
static PyObject *
-_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- GIArgument *arg)
+arg_struct_to_py_marshal_adapter (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
{
PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
- return _pygi_marshal_to_py_interface_struct (arg,
- iface_cache->interface_info,
- iface_cache->g_type,
- iface_cache->py_type,
- arg_cache->transfer,
- arg_cache->is_caller_allocates,
- iface_cache->is_foreign);
+ return pygi_arg_struct_to_py_marshal (arg,
+ iface_cache->interface_info,
+ iface_cache->g_type,
+ iface_cache->py_type,
+ arg_cache->transfer,
+ arg_cache->is_caller_allocates,
+ iface_cache->is_foreign);
}
static void
-_pygi_marshal_cleanup_to_py_interface_struct_foreign (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *dummy,
- gpointer data,
- gboolean was_processed)
+arg_foreign_to_py_cleanup (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *dummy,
+ gpointer data,
+ gboolean was_processed)
{
- if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+ if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
pygi_struct_foreign_release (
( (PyGIInterfaceCache *)arg_cache)->interface_info,
data);
+ }
}
+static gboolean
+arg_type_class_from_py_marshal (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg,
+ gpointer *cleanup_data)
+{
+ GType gtype = pyg_type_from_object (py_arg);
+
+ if (G_TYPE_IS_CLASSED (gtype)) {
+ arg->v_pointer = g_type_class_ref (gtype);
+ *cleanup_data = arg->v_pointer;
+ return TRUE;
+ } else {
+ PyErr_Format (PyExc_TypeError,
+ "Unable to retrieve a GObject type class from \"%s\".",
+ Py_TYPE(py_arg)->tp_name);
+ return FALSE;
+ }
+}
static void
-_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
- GIInterfaceInfo *iface_info,
- GITransfer transfer)
+arg_type_class_from_py_cleanup (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ gpointer data,
+ gboolean was_processed)
{
- PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
- iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
- arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
-
- if (iface_cache->g_type == G_TYPE_VALUE)
- arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
- else if (iface_cache->is_foreign)
- arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
+ if (was_processed) {
+ g_type_class_unref (data);
+ }
}
static void
-_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
- GIInterfaceInfo *iface_info,
- GITransfer transfer)
+arg_struct_from_py_setup (PyGIArgCache *arg_cache,
+ GIInterfaceInfo *iface_info,
+ GITransfer transfer)
{
PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
- arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
- if (iface_cache->is_foreign)
- arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
-}
+ if (g_struct_info_is_gtype_struct ((GIStructInfo*)iface_info)) {
+ arg_cache->from_py_marshaller = arg_type_class_from_py_marshal;
+ /* Since we always add a ref in the marshalling, only unref the
+ * GTypeClass when we don't transfer ownership. */
+ if (transfer == GI_TRANSFER_NOTHING) {
+ arg_cache->from_py_cleanup = arg_type_class_from_py_cleanup;
+ }
-static gboolean
-pygi_arg_struct_setup_from_info (PyGIArgCache *arg_cache,
- GITypeInfo *type_info,
- GIArgInfo *arg_info,
- GITransfer transfer,
- PyGIDirection direction,
- GIInterfaceInfo *iface_info)
-{
- /* NOTE: usage of pygi_arg_interface_new_from_info already calls
- * pygi_arg_interface_setup so no need to do it here.
- */
+ } else {
+ arg_cache->from_py_marshaller = arg_struct_from_py_marshal_adapter;
- if (direction & PYGI_DIRECTION_FROM_PYTHON) {
- _arg_cache_from_py_interface_struct_setup (arg_cache,
- iface_info,
- transfer);
+ if (iface_cache->g_type == G_TYPE_VALUE)
+ arg_cache->from_py_cleanup = pygi_arg_gvalue_from_py_cleanup;
+ else if (iface_cache->is_foreign)
+ arg_cache->from_py_cleanup = arg_foreign_from_py_cleanup;
}
+}
- if (direction & PYGI_DIRECTION_TO_PYTHON) {
- _arg_cache_to_py_interface_struct_setup (arg_cache,
- iface_info,
- transfer);
- }
+static void
+arg_struct_to_py_setup (PyGIArgCache *arg_cache,
+ GIInterfaceInfo *iface_info,
+ GITransfer transfer)
+{
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
+ arg_cache->to_py_marshaller = arg_struct_to_py_marshal_adapter;
- return TRUE;
+ if (iface_cache->is_foreign)
+ arg_cache->to_py_cleanup = arg_foreign_to_py_cleanup;
}
PyGIArgCache *
@@ -492,7 +511,6 @@ pygi_arg_struct_new_from_info (GITypeInfo *type_info,
PyGIDirection direction,
GIInterfaceInfo *iface_info)
{
- gboolean res = FALSE;
PyGIArgCache *cache = NULL;
cache = pygi_arg_interface_new_from_info (type_info,
@@ -503,16 +521,13 @@ pygi_arg_struct_new_from_info (GITypeInfo *type_info,
if (cache == NULL)
return NULL;
- res = pygi_arg_struct_setup_from_info (cache,
- type_info,
- arg_info,
- transfer,
- direction,
- iface_info);
- if (res) {
- return cache;
- } else {
- pygi_arg_cache_free (cache);
- return NULL;
+ if (direction & PYGI_DIRECTION_FROM_PYTHON) {
+ arg_struct_from_py_setup (cache, iface_info, transfer);
}
+
+ if (direction & PYGI_DIRECTION_TO_PYTHON) {
+ arg_struct_to_py_setup (cache, iface_info, transfer);
+ }
+
+ return cache;
}