[pygobject] cache refactoring: Move PyGIHashCache and related marshaling into new file
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] cache refactoring: Move PyGIHashCache and related marshaling into new file
- Date: Mon, 3 Feb 2014 13:55:15 +0000 (UTC)
commit 4a6bf3be49cc5aec7287c41ec02c78d60df1d44c
Author: Simon Feltman <sfeltman src gnome org>
Date: Fri Oct 11 17:39:31 2013 -0700
cache refactoring: Move PyGIHashCache and related marshaling into new file
Re-organize hash table arg cache and its marshaling by moving all
related code fragments into an isolated file where most of it is made
static. pygi-hashtable.h exposes a single function:
pygi_arg_hash_table_new_from_info. This is all the caching system needs to
produce the proper bits for handling hash table marshaling.
https://bugzilla.gnome.org/show_bug.cgi?id=709700
gi/Makefile.am | 4 +-
gi/pygi-cache.c | 103 +-----------
gi/pygi-cache.h | 21 ++-
gi/pygi-hashtable.c | 413 +++++++++++++++++++++++++++++++++++++++++++++
gi/pygi-hashtable.h | 35 ++++
gi/pygi-marshal-cleanup.c | 63 -------
gi/pygi-marshal-cleanup.h | 10 -
gi/pygi-marshal-from-py.c | 125 --------------
gi/pygi-marshal-from-py.h | 6 -
gi/pygi-marshal-to-py.c | 85 ---------
gi/pygi-marshal-to-py.h | 4 -
11 files changed, 471 insertions(+), 398 deletions(-)
---
diff --git a/gi/Makefile.am b/gi/Makefile.am
index fa1ce9a..c2fcd5c 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -102,7 +102,9 @@ _gi_la_SOURCES = \
pygi-marshal-to-py.c \
pygi-marshal-to-py.h \
pygi-marshal-cleanup.c \
- pygi-marshal-cleanup.h
+ pygi-marshal-cleanup.h \
+ pygi-hashtable.c \
+ pygi-hashtable.h
_gi_la_CFLAGS = \
$(extension_cppflags) \
$(GLIB_CFLAGS) \
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index f476501..0c6b94c 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -19,22 +19,16 @@
* USA
*/
+#include <girepository.h>
+
#include "pygi-info.h"
#include "pygi-cache.h"
#include "pygi-marshal-to-py.h"
#include "pygi-marshal-from-py.h"
#include "pygi-marshal-cleanup.h"
#include "pygi-type.h"
-#include <girepository.h>
+#include "pygi-hashtable.h"
-PyGIArgCache * _arg_cache_new (GITypeInfo *type_info,
- GIArgInfo *arg_info,
- GITransfer transfer,
- PyGIDirection direction,
- /* will be removed */
- gssize c_arg_index,
- gssize py_arg_index,
- PyGICallableCache *callable_cache);
PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
GITypeInfo *type_info,
@@ -127,7 +121,7 @@ pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache,
/* cleanup */
-static void
+void
_pygi_arg_cache_free (PyGIArgCache *cache)
{
if (cache == NULL)
@@ -154,15 +148,6 @@ _interface_cache_free_func (PyGIInterfaceCache *cache)
}
}
-static void
-_hash_cache_free_func (PyGIHashCache *cache)
-{
- if (cache != NULL) {
- _pygi_arg_cache_free (cache->key_cache);
- _pygi_arg_cache_free (cache->value_cache);
- g_slice_free (PyGIHashCache, cache);
- }
-}
static void
_sequence_cache_free_func (PyGISequenceCache *cache)
@@ -261,53 +246,6 @@ _sequence_cache_new (GITypeInfo *type_info,
return sc;
}
-static PyGIHashCache *
-_hash_cache_new (GITypeInfo *type_info,
- GIDirection direction,
- GITransfer transfer)
-{
- PyGIHashCache *hc;
- GITypeInfo *key_type_info;
- GITypeInfo *value_type_info;
- GITransfer item_transfer;
-
- hc = g_slice_new0 (PyGIHashCache);
- ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func;
- key_type_info = g_type_info_get_param_type (type_info, 0);
- value_type_info = g_type_info_get_param_type (type_info, 1);
-
- item_transfer =
- transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
-
- hc->key_cache = _arg_cache_new (key_type_info,
- NULL,
- item_transfer,
- direction,
- 0, 0,
- NULL);
-
- if (hc->key_cache == NULL) {
- _pygi_arg_cache_free ( (PyGIArgCache *)hc);
- return NULL;
- }
-
- hc->value_cache = _arg_cache_new (value_type_info,
- NULL,
- item_transfer,
- direction,
- 0, 0,
- NULL);
-
- if (hc->value_cache == NULL) {
- _pygi_arg_cache_free ( (PyGIArgCache *)hc);
- return NULL;
- }
-
- g_base_info_unref( (GIBaseInfo *)key_type_info);
- g_base_info_unref( (GIBaseInfo *)value_type_info);
-
- return hc;
-}
static PyGICallbackCache *
_callback_cache_new (GIArgInfo *arg_info,
@@ -512,20 +450,6 @@ _arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache,
}
static void
-_arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache)
-{
- arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash;
- arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash;
-}
-
-static void
-_arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache)
-{
- arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash;
- arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash;
-}
-
-static void
_arg_cache_from_py_gerror_setup (PyGIArgCache *arg_cache)
{
arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror;
@@ -920,22 +844,11 @@ _arg_cache_new (GITypeInfo *type_info,
break;
}
case GI_TYPE_TAG_GHASH:
- arg_cache =
- (PyGIArgCache *)_hash_cache_new (type_info,
- direction,
- transfer);
-
- if (arg_cache == NULL)
- break;
+ arg_cache = pygi_arg_hash_table_new_from_info (type_info, arg_info, transfer, direction);
+ arg_cache->py_arg_index = py_arg_index;
+ arg_cache->c_arg_index = c_arg_index;
+ return arg_cache;
- if (direction & PYGI_DIRECTION_FROM_PYTHON)
- _arg_cache_from_py_ghash_setup (arg_cache);
-
- if (direction & PYGI_DIRECTION_TO_PYTHON) {
- _arg_cache_to_py_ghash_setup (arg_cache);
- }
-
- break;
case GI_TYPE_TAG_INTERFACE:
{
GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 7a5be37..e1b0649 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -150,13 +150,6 @@ typedef struct _PyGIInterfaceCache
gchar *type_name;
} PyGIInterfaceCache;
-typedef struct _PyGIHashCache
-{
- PyGIArgCache arg_cache;
- PyGIArgCache *key_cache;
- PyGIArgCache *value_cache;
-} PyGIHashCache;
-
typedef struct _PyGICallbackCache
{
PyGIArgCache arg_cache;
@@ -218,8 +211,18 @@ pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache,
PyGIDirection direction,
GIInterfaceInfo *iface_info);
-void _pygi_arg_cache_clear (PyGIArgCache *cache);
-void _pygi_callable_cache_free (PyGICallableCache *cache);
+PyGIArgCache * _arg_cache_new (GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction,
+ /* will be removed */
+ gssize c_arg_index,
+ gssize py_arg_index,
+ PyGICallableCache *callable_cache);
+
+void _pygi_arg_cache_free (PyGIArgCache *cache);
+void _pygi_arg_cache_clear (PyGIArgCache *cache);
+void _pygi_callable_cache_free (PyGICallableCache *cache);
PyGICallableCache *_pygi_callable_cache_new (GICallableInfo *callable_info,
gboolean is_ccallback);
diff --git a/gi/pygi-hashtable.c b/gi/pygi-hashtable.c
new file mode 100644
index 0000000..f8864f0
--- /dev/null
+++ b/gi/pygi-hashtable.c
@@ -0,0 +1,413 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>
+ * Copyright (C) 2014 Simon Feltman <sfeltman gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pygi-hashtable.h"
+#include "pygi-argument.h"
+#include "pygi-private.h"
+
+typedef struct _PyGIHashCache
+{
+ PyGIArgCache arg_cache;
+ PyGIArgCache *key_cache;
+ PyGIArgCache *value_cache;
+} PyGIHashCache;
+
+
+static void
+_hash_cache_free_func (PyGIHashCache *cache)
+{
+ if (cache != NULL) {
+ _pygi_arg_cache_free (cache->key_cache);
+ _pygi_arg_cache_free (cache->value_cache);
+ g_slice_free (PyGIHashCache, cache);
+ }
+}
+
+static gboolean
+_pygi_marshal_from_py_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg,
+ gpointer *cleanup_data)
+{
+ PyGIMarshalFromPyFunc key_from_py_marshaller;
+ PyGIMarshalFromPyFunc value_from_py_marshaller;
+
+ int i;
+ Py_ssize_t length;
+ PyObject *py_keys, *py_values;
+
+ GHashFunc hash_func;
+ GEqualFunc equal_func;
+
+ GHashTable *hash_ = NULL;
+ PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ py_keys = PyMapping_Keys (py_arg);
+ if (py_keys == NULL) {
+ PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PyMapping_Length (py_arg);
+ if (length < 0) {
+ Py_DECREF (py_keys);
+ return FALSE;
+ }
+
+ py_values = PyMapping_Values (py_arg);
+ if (py_values == NULL) {
+ Py_DECREF (py_keys);
+ return FALSE;
+ }
+
+ key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller;
+ value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller;
+
+ switch (hash_cache->key_cache->type_tag) {
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ hash_func = g_str_hash;
+ equal_func = g_str_equal;
+ break;
+ default:
+ hash_func = NULL;
+ equal_func = NULL;
+ }
+
+ hash_ = g_hash_table_new (hash_func, equal_func);
+ if (hash_ == NULL) {
+ PyErr_NoMemory ();
+ Py_DECREF (py_keys);
+ Py_DECREF (py_values);
+ return FALSE;
+ }
+
+ for (i = 0; i < length; i++) {
+ GIArgument key, value;
+ gpointer key_cleanup_data = NULL;
+ gpointer value_cleanup_data = NULL;
+ PyObject *py_key = PyList_GET_ITEM (py_keys, i);
+ PyObject *py_value = PyList_GET_ITEM (py_values, i);
+ if (py_key == NULL || py_value == NULL)
+ goto err;
+
+ if (!key_from_py_marshaller ( state,
+ callable_cache,
+ hash_cache->key_cache,
+ py_key,
+ &key,
+ &key_cleanup_data))
+ goto err;
+
+ if (!value_from_py_marshaller ( state,
+ callable_cache,
+ hash_cache->value_cache,
+ py_value,
+ &value,
+ &value_cleanup_data))
+ goto err;
+
+ g_hash_table_insert (hash_,
+ _pygi_arg_to_hash_pointer (&key, hash_cache->key_cache->type_tag),
+ _pygi_arg_to_hash_pointer (&value, hash_cache->value_cache->type_tag));
+ continue;
+err:
+ /* FIXME: cleanup hash keys and values */
+ Py_XDECREF (py_key);
+ Py_XDECREF (py_value);
+ Py_DECREF (py_keys);
+ Py_DECREF (py_values);
+ g_hash_table_unref (hash_);
+ _PyGI_ERROR_PREFIX ("Item %i: ", i);
+ return FALSE;
+ }
+
+ arg->v_pointer = hash_;
+
+ if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
+ /* Free everything in cleanup. */
+ *cleanup_data = arg->v_pointer;
+ } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
+ /* Make a shallow copy so we can free the elements later in cleanup
+ * because it is possible invoke will free the list before our cleanup. */
+ *cleanup_data = g_hash_table_ref (arg->v_pointer);
+ } else { /* GI_TRANSFER_EVERYTHING */
+ /* No cleanup, everything is given to the callee.
+ * Note that the keys and values will leak for transfer everything because
+ * we do not use g_hash_table_new_full and set key/value_destroy_func. */
+ *cleanup_data = NULL;
+ }
+
+ return TRUE;
+}
+
+static void
+_pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ gpointer data,
+ gboolean was_processed)
+{
+ if (data == NULL)
+ return;
+
+ if (was_processed) {
+ GHashTable *hash_;
+ PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
+
+ hash_ = (GHashTable *)data;
+
+ /* clean up keys and values first */
+ if (hash_cache->key_cache->from_py_cleanup != NULL ||
+ hash_cache->value_cache->from_py_cleanup != NULL) {
+ GHashTableIter hiter;
+ gpointer key;
+ gpointer value;
+
+ PyGIMarshalCleanupFunc key_cleanup_func =
+ hash_cache->key_cache->from_py_cleanup;
+ PyGIMarshalCleanupFunc value_cleanup_func =
+ hash_cache->value_cache->from_py_cleanup;
+
+ g_hash_table_iter_init (&hiter, hash_);
+ while (g_hash_table_iter_next (&hiter, &key, &value)) {
+ if (key != NULL && key_cleanup_func != NULL)
+ key_cleanup_func (state,
+ hash_cache->key_cache,
+ NULL,
+ key,
+ TRUE);
+ if (value != NULL && value_cleanup_func != NULL)
+ value_cleanup_func (state,
+ hash_cache->value_cache,
+ NULL,
+ value,
+ TRUE);
+ }
+ }
+
+ g_hash_table_unref (hash_);
+ }
+}
+
+static PyObject *
+_pygi_marshal_to_py_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ GHashTable *hash_;
+ GHashTableIter hash_table_iter;
+
+ PyGIMarshalToPyFunc key_to_py_marshaller;
+ PyGIMarshalToPyFunc value_to_py_marshaller;
+
+ PyGIArgCache *key_arg_cache;
+ PyGIArgCache *value_arg_cache;
+ PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
+
+ GIArgument key_arg;
+ GIArgument value_arg;
+
+ PyObject *py_obj = NULL;
+
+ hash_ = arg->v_pointer;
+
+ if (hash_ == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ py_obj = PyDict_New ();
+ if (py_obj == NULL)
+ return NULL;
+
+ key_arg_cache = hash_cache->key_cache;
+ key_to_py_marshaller = key_arg_cache->to_py_marshaller;
+
+ value_arg_cache = hash_cache->value_cache;
+ value_to_py_marshaller = value_arg_cache->to_py_marshaller;
+
+ g_hash_table_iter_init (&hash_table_iter, hash_);
+ while (g_hash_table_iter_next (&hash_table_iter,
+ &key_arg.v_pointer,
+ &value_arg.v_pointer)) {
+ PyObject *py_key;
+ PyObject *py_value;
+ int retval;
+
+
+ _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag);
+ py_key = key_to_py_marshaller ( state,
+ callable_cache,
+ key_arg_cache,
+ &key_arg);
+
+ if (py_key == NULL) {
+ Py_CLEAR (py_obj);
+ return NULL;
+ }
+
+ _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag);
+ py_value = value_to_py_marshaller ( state,
+ callable_cache,
+ value_arg_cache,
+ &value_arg);
+
+ if (py_value == NULL) {
+ Py_CLEAR (py_obj);
+ Py_DECREF(py_key);
+ return NULL;
+ }
+
+ retval = PyDict_SetItem (py_obj, py_key, py_value);
+
+ Py_DECREF (py_key);
+ Py_DECREF (py_value);
+
+ if (retval < 0) {
+ Py_CLEAR (py_obj);
+ return NULL;
+ }
+ }
+
+ return py_obj;
+}
+
+static void
+_pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state,
+ PyGIArgCache *arg_cache,
+ PyObject *dummy,
+ gpointer data,
+ gboolean was_processed)
+{
+ if (data == NULL)
+ return;
+
+ /* assume hashtable has boxed key and value */
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->transfer == GI_TRANSFER_CONTAINER)
+ g_hash_table_unref ( (GHashTable *)data);
+}
+
+static void
+_arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache)
+{
+ arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash;
+ arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash;
+}
+
+static void
+_arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache)
+{
+ arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash;
+ arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash;
+}
+
+static gboolean
+pygi_arg_hash_table_setup_from_info (PyGIHashCache *hc,
+ GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction)
+{
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GITransfer item_transfer;
+
+ if (!pygi_arg_base_setup ((PyGIArgCache *)hc, type_info, arg_info, transfer, direction))
+ return FALSE;
+
+ ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func;
+ key_type_info = g_type_info_get_param_type (type_info, 0);
+ value_type_info = g_type_info_get_param_type (type_info, 1);
+
+ item_transfer =
+ transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ hc->key_cache = _arg_cache_new (key_type_info,
+ NULL,
+ item_transfer,
+ direction,
+ 0, 0,
+ NULL);
+
+ if (hc->key_cache == NULL) {
+ return FALSE;
+ }
+
+ hc->value_cache = _arg_cache_new (value_type_info,
+ NULL,
+ item_transfer,
+ direction,
+ 0, 0,
+ NULL);
+
+ if (hc->value_cache == NULL) {
+ return FALSE;
+ }
+
+ g_base_info_unref( (GIBaseInfo *)key_type_info);
+ g_base_info_unref( (GIBaseInfo *)value_type_info);
+
+ if (direction & PYGI_DIRECTION_FROM_PYTHON) {
+ _arg_cache_from_py_ghash_setup ((PyGIArgCache *)hc);
+ }
+
+ if (direction & PYGI_DIRECTION_TO_PYTHON) {
+ _arg_cache_to_py_ghash_setup ((PyGIArgCache *)hc);
+ }
+
+ return TRUE;
+}
+
+PyGIArgCache *
+pygi_arg_hash_table_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction)
+{
+ gboolean res = FALSE;
+ PyGIHashCache *hc = NULL;
+
+ hc = g_slice_new0 (PyGIHashCache);
+ if (hc == NULL)
+ return NULL;
+
+ res = pygi_arg_hash_table_setup_from_info (hc,
+ type_info,
+ arg_info,
+ transfer,
+ direction);
+ if (res) {
+ return (PyGIArgCache *)hc;
+ } else {
+ _pygi_arg_cache_free ((PyGIArgCache *)hc);
+ return NULL;
+ }
+}
diff --git a/gi/pygi-hashtable.h b/gi/pygi-hashtable.h
new file mode 100644
index 0000000..a42aaf0
--- /dev/null
+++ b/gi/pygi-hashtable.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2013 Simon Feltman <sfeltman gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PYGI_HASHTABLE_H__
+#define __PYGI_HASHTABLE_H__
+
+#include <girepository.h>
+#include "pygi-cache.h"
+
+G_BEGIN_DECLS
+
+PyGIArgCache *pygi_arg_hash_table_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info, /* may be null */
+ GITransfer transfer,
+ PyGIDirection direction);
+
+G_END_DECLS
+
+#endif /*__PYGI_HASHTABLE_H__*/
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index 33d0339..38783d9 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -548,66 +548,3 @@ _pygi_marshal_cleanup_to_py_glist (PyGIInvokeState *state,
}
}
-void
-_pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- gpointer data,
- gboolean was_processed)
-{
- if (data == NULL)
- return;
-
- if (was_processed) {
- GHashTable *hash_;
- PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
-
- hash_ = (GHashTable *)data;
-
- /* clean up keys and values first */
- if (hash_cache->key_cache->from_py_cleanup != NULL ||
- hash_cache->value_cache->from_py_cleanup != NULL) {
- GHashTableIter hiter;
- gpointer key;
- gpointer value;
-
- PyGIMarshalCleanupFunc key_cleanup_func =
- hash_cache->key_cache->from_py_cleanup;
- PyGIMarshalCleanupFunc value_cleanup_func =
- hash_cache->value_cache->from_py_cleanup;
-
- g_hash_table_iter_init (&hiter, hash_);
- while (g_hash_table_iter_next (&hiter, &key, &value)) {
- if (key != NULL && key_cleanup_func != NULL)
- key_cleanup_func (state,
- hash_cache->key_cache,
- NULL,
- key,
- TRUE);
- if (value != NULL && value_cleanup_func != NULL)
- value_cleanup_func (state,
- hash_cache->value_cache,
- NULL,
- value,
- TRUE);
- }
- }
-
- g_hash_table_unref (hash_);
- }
-}
-
-void
-_pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *dummy,
- gpointer data,
- gboolean was_processed)
-{
- if (data == NULL)
- return;
-
- /* assume hashtable has boxed key and value */
- if (arg_cache->transfer == GI_TRANSFER_EVERYTHING || arg_cache->transfer == GI_TRANSFER_CONTAINER)
- g_hash_table_unref ( (GHashTable *)data);
-}
diff --git a/gi/pygi-marshal-cleanup.h b/gi/pygi-marshal-cleanup.h
index 3acfbeb..70a91c8 100644
--- a/gi/pygi-marshal-cleanup.h
+++ b/gi/pygi-marshal-cleanup.h
@@ -100,16 +100,6 @@ void _pygi_marshal_cleanup_to_py_glist (PyGIInvokeState *stat
PyObject *dummy,
gpointer data,
gboolean was_processed);
-void _pygi_marshal_cleanup_from_py_ghash (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- gpointer data,
- gboolean was_processed);
-void _pygi_marshal_cleanup_to_py_ghash (PyGIInvokeState *state,
- PyGIArgCache *arg_cache,
- PyObject *dummy,
- gpointer data,
- gboolean was_processed);
G_END_DECLS
#endif /* __PYGI_MARSHAL_CLEANUP_H__ */
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index 41dcf54..e3b8ae8 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -1142,131 +1142,6 @@ err:
return TRUE;
}
-gboolean
-_pygi_marshal_from_py_ghash (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- GIArgument *arg,
- gpointer *cleanup_data)
-{
- PyGIMarshalFromPyFunc key_from_py_marshaller;
- PyGIMarshalFromPyFunc value_from_py_marshaller;
-
- int i;
- Py_ssize_t length;
- PyObject *py_keys, *py_values;
-
- GHashFunc hash_func;
- GEqualFunc equal_func;
-
- GHashTable *hash_ = NULL;
- PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
-
- if (py_arg == Py_None) {
- arg->v_pointer = NULL;
- return TRUE;
- }
-
- py_keys = PyMapping_Keys (py_arg);
- if (py_keys == NULL) {
- PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
- py_arg->ob_type->tp_name);
- return FALSE;
- }
-
- length = PyMapping_Length (py_arg);
- if (length < 0) {
- Py_DECREF (py_keys);
- return FALSE;
- }
-
- py_values = PyMapping_Values (py_arg);
- if (py_values == NULL) {
- Py_DECREF (py_keys);
- return FALSE;
- }
-
- key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller;
- value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller;
-
- switch (hash_cache->key_cache->type_tag) {
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- hash_func = g_str_hash;
- equal_func = g_str_equal;
- break;
- default:
- hash_func = NULL;
- equal_func = NULL;
- }
-
- hash_ = g_hash_table_new (hash_func, equal_func);
- if (hash_ == NULL) {
- PyErr_NoMemory ();
- Py_DECREF (py_keys);
- Py_DECREF (py_values);
- return FALSE;
- }
-
- for (i = 0; i < length; i++) {
- GIArgument key, value;
- gpointer key_cleanup_data = NULL;
- gpointer value_cleanup_data = NULL;
- PyObject *py_key = PyList_GET_ITEM (py_keys, i);
- PyObject *py_value = PyList_GET_ITEM (py_values, i);
- if (py_key == NULL || py_value == NULL)
- goto err;
-
- if (!key_from_py_marshaller ( state,
- callable_cache,
- hash_cache->key_cache,
- py_key,
- &key,
- &key_cleanup_data))
- goto err;
-
- if (!value_from_py_marshaller ( state,
- callable_cache,
- hash_cache->value_cache,
- py_value,
- &value,
- &value_cleanup_data))
- goto err;
-
- g_hash_table_insert (hash_,
- _pygi_arg_to_hash_pointer (&key, hash_cache->key_cache->type_tag),
- _pygi_arg_to_hash_pointer (&value, hash_cache->value_cache->type_tag));
- continue;
-err:
- /* FIXME: cleanup hash keys and values */
- Py_XDECREF (py_key);
- Py_XDECREF (py_value);
- Py_DECREF (py_keys);
- Py_DECREF (py_values);
- g_hash_table_unref (hash_);
- _PyGI_ERROR_PREFIX ("Item %i: ", i);
- return FALSE;
- }
-
- arg->v_pointer = hash_;
-
- if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
- /* Free everything in cleanup. */
- *cleanup_data = arg->v_pointer;
- } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
- /* Make a shallow copy so we can free the elements later in cleanup
- * because it is possible invoke will free the list before our cleanup. */
- *cleanup_data = g_hash_table_ref (arg->v_pointer);
- } else { /* GI_TRANSFER_EVERYTHING */
- /* No cleanup, everything is given to the callee.
- * Note that the keys and values will leak for transfer everything because
- * we do not use g_hash_table_new_full and set key/value_destroy_func. */
- *cleanup_data = NULL;
- }
-
- return TRUE;
-}
gboolean
_pygi_marshal_from_py_gerror (PyGIInvokeState *state,
diff --git a/gi/pygi-marshal-from-py.h b/gi/pygi-marshal-from-py.h
index f8e4699..83d074a 100644
--- a/gi/pygi-marshal-from-py.h
+++ b/gi/pygi-marshal-from-py.h
@@ -57,12 +57,6 @@ gboolean _pygi_marshal_from_py_gslist (PyGIInvokeState *state,
PyObject *py_arg,
GIArgument *arg,
gpointer *cleanup_data);
-gboolean _pygi_marshal_from_py_ghash (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- PyObject *py_arg,
- GIArgument *arg,
- gpointer *cleanup_data);
gboolean _pygi_marshal_from_py_gerror (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
index 9427754..3c7d69e 100644
--- a/gi/pygi-marshal-to-py.c
+++ b/gi/pygi-marshal-to-py.c
@@ -537,91 +537,6 @@ _pygi_marshal_to_py_gslist (PyGIInvokeState *state,
}
PyObject *
-_pygi_marshal_to_py_ghash (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- GIArgument *arg)
-{
- GHashTable *hash_;
- GHashTableIter hash_table_iter;
-
- PyGIMarshalToPyFunc key_to_py_marshaller;
- PyGIMarshalToPyFunc value_to_py_marshaller;
-
- PyGIArgCache *key_arg_cache;
- PyGIArgCache *value_arg_cache;
- PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
-
- GIArgument key_arg;
- GIArgument value_arg;
-
- PyObject *py_obj = NULL;
-
- hash_ = arg->v_pointer;
-
- if (hash_ == NULL) {
- py_obj = Py_None;
- Py_INCREF (py_obj);
- return py_obj;
- }
-
- py_obj = PyDict_New ();
- if (py_obj == NULL)
- return NULL;
-
- key_arg_cache = hash_cache->key_cache;
- key_to_py_marshaller = key_arg_cache->to_py_marshaller;
-
- value_arg_cache = hash_cache->value_cache;
- value_to_py_marshaller = value_arg_cache->to_py_marshaller;
-
- g_hash_table_iter_init (&hash_table_iter, hash_);
- while (g_hash_table_iter_next (&hash_table_iter,
- &key_arg.v_pointer,
- &value_arg.v_pointer)) {
- PyObject *py_key;
- PyObject *py_value;
- int retval;
-
-
- _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag);
- py_key = key_to_py_marshaller ( state,
- callable_cache,
- key_arg_cache,
- &key_arg);
-
- if (py_key == NULL) {
- Py_CLEAR (py_obj);
- return NULL;
- }
-
- _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag);
- py_value = value_to_py_marshaller ( state,
- callable_cache,
- value_arg_cache,
- &value_arg);
-
- if (py_value == NULL) {
- Py_CLEAR (py_obj);
- Py_DECREF(py_key);
- return NULL;
- }
-
- retval = PyDict_SetItem (py_obj, py_key, py_value);
-
- Py_DECREF (py_key);
- Py_DECREF (py_value);
-
- if (retval < 0) {
- Py_CLEAR (py_obj);
- return NULL;
- }
- }
-
- return py_obj;
-}
-
-PyObject *
_pygi_marshal_to_py_gerror (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
diff --git a/gi/pygi-marshal-to-py.h b/gi/pygi-marshal-to-py.h
index 1378630..48f1aa2 100644
--- a/gi/pygi-marshal-to-py.h
+++ b/gi/pygi-marshal-to-py.h
@@ -45,10 +45,6 @@ PyObject *_pygi_marshal_to_py_gslist (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
GIArgument *arg);
-PyObject *_pygi_marshal_to_py_ghash (PyGIInvokeState *state,
- PyGICallableCache *callable_cache,
- PyGIArgCache *arg_cache,
- GIArgument *arg);
PyObject *_pygi_marshal_to_py_gerror (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
PyGIArgCache *arg_cache,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]