[pygobject/invoke-rewrite] [gi] marshal in hashes
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] [gi] marshal in hashes
- Date: Mon, 17 Jan 2011 17:31:35 +0000 (UTC)
commit cfca2f0a53a5c29f543875ca4cb83a2e18d3bc72
Author: John (J5) Palmieri <johnp redhat com>
Date: Thu Jan 13 21:07:25 2011 -0500
[gi] marshal in hashes
gi/pygi-argument.c | 93 ++++++++++++++++++++++++++++++++++++++-
gi/pygi-cache.c | 122 ++++++++++++++++++++++++++++++++++++---------------
2 files changed, 176 insertions(+), 39 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 948f67f..cb2f06c 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2773,9 +2773,96 @@ _pygi_marshal_in_ghash (PyGIInvokeState *state,
PyObject *py_arg,
GIArgument *arg)
{
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
- return FALSE;
+ PyGIMarshalInFunc key_in_marshaller;
+ PyGIMarshalInFunc value_in_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;
+
+ 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_in_marshaller = hash_cache->key_cache->in_marshaller;
+ value_in_marshaller = hash_cache->value_cache->in_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;
+ 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_in_marshaller(state,
+ function_cache,
+ hash_cache->key_cache,
+ py_key,
+ &key))
+ goto err;
+
+ if (!value_in_marshaller(state,
+ function_cache,
+ hash_cache->value_cache,
+ py_value,
+ &value))
+ goto err;
+
+ g_hash_table_insert(hash_, key.v_pointer, value.v_pointer);
+ 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_;
+ return TRUE;
}
gboolean
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 3ad0995..2a5f44e 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -33,7 +33,21 @@ PyGIArgCache * _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
gint c_arg_index,
gint py_arg_index);
/* cleanup */
-static inline void
+void
+_pygi_arg_cache_free(PyGIArgCache *cache)
+{
+ if (cache == NULL)
+ return;
+
+ if (cache->arg_info != NULL)
+ g_base_info_unref(cache->arg_info);
+ if (cache->destroy_notify)
+ cache->destroy_notify(cache);
+ else
+ g_slice_free(PyGIArgCache, cache);
+}
+
+static void
_interface_cache_free_func (PyGIInterfaceCache *cache)
{
if (cache != NULL) {
@@ -44,43 +58,34 @@ _interface_cache_free_func (PyGIInterfaceCache *cache)
}
}
-static inline void
-_pygi_hash_cache_free (PyGIHashCache *cache)
+static void
+_hash_cache_free_func(PyGIHashCache *cache)
{
- if (cache != NULL)
+ 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)
+_sequence_cache_free_func(PyGISequenceCache *cache)
{
- if (cache != NULL)
+ if (cache != NULL) {
+ _pygi_arg_cache_free(cache->item_cache);
g_slice_free(PyGISequenceCache, cache);
+ }
}
static void
-_callback_cache_free_func (PyGICallbackCache *cache)
+_callback_cache_free_func(PyGICallbackCache *cache)
{
if (cache != NULL)
g_slice_free(PyGICallbackCache, cache);
}
void
-_pygi_arg_cache_free (PyGIArgCache *cache)
-{
- if (cache == NULL)
- return;
-
- if (cache->arg_info != NULL)
- g_base_info_unref(cache->arg_info);
- if (cache->destroy_notify)
- cache->destroy_notify(cache);
- else
- g_slice_free(PyGIArgCache, cache);
-}
-
-void
-_pygi_function_cache_free (PyGIFunctionCache *cache)
+_pygi_function_cache_free(PyGIFunctionCache *cache)
{
int i;
@@ -119,14 +124,13 @@ _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;
+ ((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);
@@ -150,7 +154,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;
+ ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
sc->fixed_size = -1;
sc->len_arg_index = -1;
@@ -175,13 +179,61 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
_pygi_arg_cache_free((PyGIArgCache *)sc);
return NULL;
}
-
+
sc->item_cache->type_tag = item_type_tag;
sc->item_size = _pygi_g_type_tag_size(item_type_tag);
g_base_info_unref( (GIBaseInfo *) item_type_info);
return sc;
}
+static inline PyGIHashCache *
+_hash_cache_new_from_type_info(GITypeInfo *type_info)
+{
+ PyGIHashCache *hc;
+ GITypeInfo *key_type_info;
+ GITypeTag key_type_tag;
+ GITypeInfo *value_type_info;
+ GITypeTag value_type_tag;
+
+ 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);
+ key_type_tag = g_type_info_get_tag (key_type_info);
+ value_type_info = g_type_info_get_param_type (type_info, 1);
+ value_type_tag = g_type_info_get_tag (value_type_info);
+
+ hc->key_cache = _arg_cache_in_new_from_type_info(key_type_info,
+ NULL,
+ key_type_tag,
+ GI_TRANSFER_EVERYTHING,
+ GI_DIRECTION_IN,
+ 0, 0);
+
+ if (hc->key_cache == NULL) {
+ _pygi_arg_cache_free((PyGIArgCache *)hc);
+ return NULL;
+ }
+
+ hc->value_cache = _arg_cache_in_new_from_type_info(value_type_info,
+ NULL,
+ value_type_tag,
+ GI_TRANSFER_EVERYTHING,
+ GI_DIRECTION_IN,
+ 0, 0);
+
+ if (hc->value_cache == NULL) {
+ _pygi_arg_cache_free((PyGIArgCache *)hc);
+ return NULL;
+ }
+
+ hc->key_cache->type_tag = key_type_tag;
+ hc->value_cache->type_tag = value_type_tag;
+
+ g_base_info_unref( (GIBaseInfo *)key_type_info);
+ g_base_info_unref( (GIBaseInfo *)value_type_info);
+
+ return hc;
+}
static inline PyGIArgCache *
_arg_cache_new(void)
@@ -361,10 +413,8 @@ _arg_cache_new_for_in_gslist(GITypeInfo *type_info,
static inline PyGIArgCache *
_arg_cache_new_for_in_ghash(GITypeInfo *type_info)
{
- PyGIArgCache *arg_cache = NULL;
- /*arg_cache->in_marshaller = _pygi_marshal_in_ghash;*/
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
+ PyGIArgCache *arg_cache = (PyGIArgCache *)_hash_cache_new_from_type_info(type_info);
+ arg_cache->in_marshaller = _pygi_marshal_in_ghash;
return arg_cache;
}
@@ -388,7 +438,7 @@ _arg_cache_new_for_in_interface_union(void)
}
-static void
+static void
_g_slice_free_gvalue_func(GValue *value) {
g_slice_free(GValue, value);
}
@@ -922,7 +972,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
/* cache the return arg */
return_info = g_callable_info_get_return_type( (GICallableInfo *)function_info);
return_type_tag = g_type_info_get_tag(return_info);
- return_cache =
+ return_cache =
_arg_cache_out_new_from_type_info(return_info,
function_cache,
return_type_tag,
@@ -957,7 +1007,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
return FALSE;
function_cache->args_cache[arg_index] = instance_cache;
-
+
arg_index++;
function_cache->n_in_args++;
}
@@ -1000,7 +1050,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
if (arg_cache == NULL)
goto arg_err;
-
+
arg_cache->allow_none = g_arg_info_may_be_null (arg_info);
function_cache->in_args =
g_slist_append(function_cache->in_args, arg_cache);
@@ -1008,7 +1058,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
case GI_DIRECTION_OUT:
function_cache->n_out_args++;
- arg_cache =
+ arg_cache =
_arg_cache_out_new_from_type_info(return_info,
function_cache,
type_tag,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]