Commit 77d76df5 authored by John (J5) Palmieri's avatar John (J5) Palmieri
Browse files

[gi] allow caching and marshalling of ghash out

parent bd66af67
......@@ -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;
}
......
......@@ -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;
......
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