Commit cfca2f0a authored by John (J5) Palmieri's avatar John (J5) Palmieri

[gi] marshal in hashes

parent e9166ba5
......@@ -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
......
......@@ -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,
......
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