[pygobject/invoke-rewrite] [gi] allow caching and marshalling of ghash out
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] [gi] allow caching and marshalling of ghash out
- Date: Sun, 30 Jan 2011 23:21:48 +0000 (UTC)
commit 77d76df59606e470808085e977fb199cc76e8251
Author: John (J5) Palmieri <johnp redhat com>
Date: Sun Jan 30 18:21:24 2011 -0500
[gi] allow caching and marshalling of ghash out
gi/pygi-argument.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++---
gi/pygi-cache.c | 27 ++++++---
2 files changed, 162 insertions(+), 20 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 0dc277d..e426e63 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -3559,16 +3559,18 @@ _pygi_marshal_out_array (PyGIInvokeState *state,
item_size = g_array_get_element_size(array_);
for (i = 0; i < array_->len; i++) {
GIArgument item_arg;
+ PyObject *py_item;
+
if (is_struct) {
item_arg.v_pointer = &_g_array_index(array_, GIArgument, i);
} else {
memcpy (&item_arg, &_g_array_index (array_, GIArgument, i), item_size);
}
- PyObject *py_item = item_out_marshaller(state,
- function_cache,
- item_arg_cache,
- &item_arg);
+ py_item = item_out_marshaller(state,
+ function_cache,
+ item_arg_cache,
+ &item_arg);
if (py_item == NULL) {
Py_CLEAR(py_obj);
@@ -3595,10 +3597,45 @@ _pygi_marshal_out_glist (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
+ GList *list_;
+ gsize length;
+ gsize i;
+
+ PyGIMarshalOutFunc item_out_marshaller;
+ PyGIArgCache *item_arg_cache;
+ PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+
PyObject *py_obj = NULL;
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
+ list_ = arg->v_pointer;
+ length = g_list_length(list_);
+
+ py_obj = PyList_New(length);
+ if (py_obj == NULL)
+ return NULL;
+
+ item_arg_cache = seq_cache->item_cache;
+ item_out_marshaller = item_arg_cache->out_marshaller;
+
+ for (i = 0; list_ != NULL; list_ = g_list_next (list_), i++) {
+ GIArgument item_arg;
+ PyObject *py_item;
+
+ item_arg.v_pointer = list_->data;
+ py_item = item_out_marshaller(state,
+ function_cache,
+ item_arg_cache,
+ &item_arg);
+
+ if (py_item == NULL) {
+ Py_CLEAR (py_obj);
+ _PyGI_ERROR_PREFIX ("Item %zu: ", i);
+ return NULL;
+ }
+
+ PyList_SET_ITEM (py_obj, i, py_item);
+ }
+
return py_obj;
}
@@ -3608,10 +3645,45 @@ _pygi_marshal_out_gslist (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
+ GSList *list_;
+ gsize length;
+ gsize i;
+
+ PyGIMarshalOutFunc item_out_marshaller;
+ PyGIArgCache *item_arg_cache;
+ PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+
PyObject *py_obj = NULL;
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
+ list_ = arg->v_pointer;
+ length = g_slist_length(list_);
+
+ py_obj = PyList_New(length);
+ if (py_obj == NULL)
+ return NULL;
+
+ item_arg_cache = seq_cache->item_cache;
+ item_out_marshaller = item_arg_cache->out_marshaller;
+
+ for (i = 0; list_ != NULL; list_ = g_slist_next (list_), i++) {
+ GIArgument item_arg;
+ PyObject *py_item;
+
+ item_arg.v_pointer = list_->data;
+ py_item = item_out_marshaller(state,
+ function_cache,
+ item_arg_cache,
+ &item_arg);
+
+ if (py_item == NULL) {
+ Py_CLEAR (py_obj);
+ _PyGI_ERROR_PREFIX ("Item %zu: ", i);
+ return NULL;
+ }
+
+ PyList_SET_ITEM (py_obj, i, py_item);
+ }
+
return py_obj;
}
@@ -3621,10 +3693,73 @@ _pygi_marshal_out_ghash (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
+ GHashTable *hash_;
+ GHashTableIter hash_table_iter;
+
+ PyGIMarshalOutFunc key_out_marshaller;
+ PyGIMarshalOutFunc value_out_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;
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
+ hash_ = arg->v_pointer;
+
+ py_obj = PyDict_New();
+ if (py_obj == NULL)
+ return NULL;
+
+ key_arg_cache = hash_cache->key_cache;
+ key_out_marshaller = key_arg_cache->out_marshaller;
+
+ value_arg_cache = hash_cache->value_cache;
+ value_out_marshaller = value_arg_cache->out_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;
+
+ py_key = key_out_marshaller(state,
+ function_cache,
+ key_arg_cache,
+ &key_arg);
+
+ if (py_key == NULL) {
+ Py_CLEAR (py_obj);
+ return NULL;
+ }
+
+ py_value = value_out_marshaller(state,
+ function_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;
}
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 93dd9cd..387944a 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -207,13 +207,16 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info,
return sc;
}
static inline PyGIHashCache *
-_hash_cache_new_from_type_info(GITypeInfo *type_info)
+_hash_cache_new_from_type_info(GITypeInfo *type_info,
+ GIDirection direction,
+ GITransfer transfer)
{
PyGIHashCache *hc;
GITypeInfo *key_type_info;
GITypeTag key_type_tag;
GITypeInfo *value_type_info;
GITypeTag value_type_tag;
+ GITransfer item_transfer;
hc = g_slice_new0(PyGIHashCache);
((PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func;
@@ -222,12 +225,17 @@ _hash_cache_new_from_type_info(GITypeInfo *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);
+ item_transfer = GI_TRANSFER_NOTHING;
+ if (transfer == GI_TRANSFER_EVERYTHING ||
+ transfer == GI_TRANSFER_CONTAINER)
+ item_transfer = GI_TRANSFER_EVERYTHING;
+
hc->key_cache = _arg_cache_new_from_type_info(key_type_info,
NULL,
NULL,
key_type_tag,
- GI_TRANSFER_EVERYTHING,
- GI_DIRECTION_IN,
+ item_transfer,
+ direction,
FALSE,
0, 0);
@@ -240,8 +248,8 @@ _hash_cache_new_from_type_info(GITypeInfo *type_info)
NULL,
NULL,
value_type_tag,
- GI_TRANSFER_EVERYTHING,
- GI_DIRECTION_IN,
+ item_transfer,
+ direction,
FALSE,
0, 0);
@@ -586,8 +594,7 @@ _arg_cache_in_ghash_setup(PyGIArgCache *arg_cache)
static inline void
_arg_cache_out_ghash_setup(PyGIArgCache *arg_cache)
{
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for Out GHash is not fully implemented yet");
+ arg_cache->out_marshaller = _pygi_marshal_out_ghash;
}
static inline void
@@ -1126,7 +1133,9 @@ _arg_cache_new_from_type_info (GITypeInfo *type_info,
}
case GI_TYPE_TAG_GHASH:
arg_cache =
- (PyGIArgCache *)_hash_cache_new_from_type_info(type_info);
+ (PyGIArgCache *)_hash_cache_new_from_type_info(type_info,
+ direction,
+ transfer);
if (arg_cache == NULL)
break;
@@ -1136,8 +1145,6 @@ _arg_cache_new_from_type_info (GITypeInfo *type_info,
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
_arg_cache_out_ghash_setup(arg_cache);
- _pygi_arg_cache_free(arg_cache);
- arg_cache = NULL;
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]