[pygobject/invoke-rewrite] add sequence caching and array marshalling w/ item marshalling
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] add sequence caching and array marshalling w/ item marshalling
- Date: Sun, 9 Jan 2011 00:13:53 +0000 (UTC)
commit 5f8f3044dd8085b2e8ce0bf70e9d52f05abf909d
Author: John (J5) Palmieri <johnp redhat com>
Date: Sat Jan 8 19:10:29 2011 -0500
add sequence caching and array marshalling w/ item marshalling
* simplify what we pass into the arg cache generators so we may use them
for geneating marshalling caches for container items, not just arguments
gi/pygi-argument.c | 76 ++++++++++++++++-
gi/pygi-cache.c | 242 ++++++++++++++++++++++------------------------------
gi/pygi-cache.h | 4 +-
3 files changed, 175 insertions(+), 147 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 7d7f003..769bfe1 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2548,9 +2548,79 @@ _pygi_marshal_in_array (PyGIState *state,
PyObject *py_arg,
GIArgument *arg)
{
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
- return FALSE;
+ PyGIMarshalInFunc *in_marshaller;
+ int i;
+ Py_ssize_t length;
+ garray array_ = NULL;
+
+ if (py_arg == Py_None) {
+ arg.v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (!PySequence_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PySequence_Length (py_arg);
+ if (length < 0)
+ return FALSE;
+
+ if (arg_cache->sequence_cache->fixed_size >= 0 &&
+ arg_cache->sequence_cache->fixed_size != length) {
+ PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
+ arg_cache->sequence_cache->fixed_size, length);
+
+ return FALSE;
+ }
+
+ array_ = g_array_sized_new (arg_cache->sequence_cache->is_zero_terminated,
+ FALSE,
+ arg_cache->sequence_cache->item_size,
+ length);
+
+ if (array_ == NULL) {
+ PyErr_NoMemory();
+ return FALSE;
+ }
+
+ if (arg_cache->sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
+ PYGLIB_PyBytes_Check(py_arg)) {
+ memcpy(array->data, PYGLIB_PyBytes_AsString(py_arg), length);
+
+ goto array_success;
+ }
+
+ in_marshaler = arg_cache->sequence_cache->item_cache->in_marshaller;
+ for (i = 0; i < length; i++) {
+ GIArgument item;
+ PyObject *py_item = PySequence_GetItem (py_arg, i);
+ if (py_item == NULL) {
+ int j;
+ if (arg_cache->sequence_cache->item_cache->cleanup != NULL) {
+ PyGICleanupFunc *cleanup = arg_cache->sequence_cache->item_cache->cleanup;
+ for(j = 0; j < i; j++)
+ cleanup(array_->data[j]);
+ }
+
+ g_array_free(array_, TRUE);
+ _PyGI_ERROR_PREFIX ("Item %zd: ", i);
+ return FALSE;
+ }
+ arg_cache->sequence_cache->item_cache->in_marshaller(state,
+ function_cache,
+ item_cache,
+ py_item,
+ &item);
+ g_array_insert_val(array_, i, item);
+ }
+
+array_success:
+
+ arg.v_pointer = array;
+ return TRUE;
}
gboolean
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 8757672..aa75d3d 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -19,6 +19,9 @@
* USA
*/
+boolean _arg_cache_generate_metadata_in(PyGIArgCache *arg_cache,
+ GITypeInfo *type_info,
+ GITypeTag type_tag);
/* cleanup */
static inline void
@@ -95,7 +98,7 @@ _pygi_function_cache_free (PyGIFunctionCache *cache)
/* cache generation */
static inline PyGIFunctionCache *
-_function_cache_init(GIFunctionInfo *function_info)
+_function_cache_new_from_function_info(GIFunctionInfo *function_info)
{
PyGIFunctionCache *fc;
GIFunctionInfoFlags flags;
@@ -110,12 +113,41 @@ _function_cache_init(GIFunctionInfo *function_info)
return fc;
}
+static inline PyGIFunctionCache *
+_sequence_cache_new_from_type_info(GITypeInfo *type_info)
+{
+ PyGISequenceCache *sc;
+ GITypeInfo *item_type_info;
+ GITypeTag *item_type_tag;
+
+ sc = g_slice_new0(PyGISequenceCache);
+
+ sc->fixed_size = -1;
+ sc->len_arg_index = -1;
+ sc->is_zero_terminated = g_type_info_is_zero_terminated(type_info);
+ if (!sc->is_zero_terminated)
+ sc->fixed_size = g_type_info_get_array_fixed_size(type_info);
+ if (sc->fixed_size < 0)
+ sc->len_arg_index = g_type_info_get_array_length (type_info);
+
+ item_type_info = g_type_info_get_param_type (type_info, 0);
+ item_tag_type = g_type_info_get_tag (item_type_info);
+
+ sc->item_cache = g_slice_new0(PyGIArgCache);
+ sc->item_cache->type_tag = item_tag_type;
+
+ _arg_cache_generate_metadata_in(PyGIArgCache sc->item_cache,
+ item_type_info,
+ item_type_tag);
+
+
+ g_base_info_unref ( (GIBaseInfo *) item_type_info);
+}
+
/* process in args */
static inline boolean
-_arg_cache_generate_metadata_in_void(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_void(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_void;
@@ -123,127 +155,98 @@ _arg_cache_generate_metadata_in_void(PyGIArgCache *arg_cache,
}
static inline boolean
-_arg_cache_generate_metadata_in_boolean(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_boolean(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_boolean;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_int8(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_int8(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_int8;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_uint8(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_uint8(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_uint8;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_int16(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_int16(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_int16;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_uint16(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_uint16(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_uint16;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_int32(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_int32(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_int32;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_uint32(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_uint32(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_uint32;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_int64(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_int64(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_int64;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_uint64(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_uint64(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_uint64;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_float(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_float(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_float;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_double(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_double(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_double;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_unichar(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_unichar(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_unichar;
-
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_gtype(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_gtype(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_gtype;
return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_utf8(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_utf8(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_utf8;
if (arg_cache->transfer == GI_TRANSFER_NOTHING)
@@ -253,9 +256,7 @@ _arg_cache_generate_metadata_in_utf8(PyGIArgCache *arg_cache,
}
static inline boolean
-_arg_cache_generate_metadata_in_filename(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_filename(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_filename;
if (arg_cache->transfer == GI_TRANSFER_NOTHING)
@@ -266,19 +267,18 @@ _arg_cache_generate_metadata_in_filename(PyGIArgCache *arg_cache,
static inline boolean
_arg_cache_generate_metadata_in_array(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+ GITypeInfo *type_info)
{
+ GITypeInfo *type_info;
arg_cache->in_marshaler = _pygi_marshal_in_array;
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
- return FALSE;
+ arg_cache->sequence_cache = _sequence_cache_new_from_type_info(type_info);
+
+ /* arg_cache->cleanup = _pygi_cleanup_array; */
+ return TRUE;
}
static inline boolean
-_arg_cache_generate_metadata_in_interface(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_interface(PyGIArgCache *arg_cache)
{
/* TODO: Switch on GI_INFO_TYPE_ to determine caching */
PyErr_Format(PyExc_NotImplementedError,
@@ -288,30 +288,29 @@ _arg_cache_generate_metadata_in_interface(PyGIArgCache *arg_cache,
static inline boolean
_arg_cache_generate_metadata_in_glist(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+ GITypeInfo *type_info)
{
arg_cache->in_marshaler = _pygi_marshal_in_glist;
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
- return FALSE;
+ arg_cache->sequence_cache = _sequence_cache_new_from_type_info(type_info);
+ /* arg_cache->cleanup = */
+
+ return TRUE;
}
static inline boolean
_arg_cache_generate_metadata_in_gslist(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+ GITypeInfo *type_info)
{
arg_cache->in_marshaler = _pygi_marshal_in_gslist;
- PyErr_Format(PyExc_NotImplementedError,
- "Caching for this type is not fully implemented yet");
- return FALSE;
+ arg_cache->sequence_cache = _sequence_cache_new_from_type_info(type_info);
+ /* arg_cache->cleanup = */
+
+ return TRUE;
}
static inline boolean
_arg_cache_generate_metadata_in_ghash(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+ GITypeInfo *type_info)
{
arg_cache->in_marshaler = _pygi_marshal_in_ghash;
PyErr_Format(PyExc_NotImplementedError,
@@ -320,138 +319,94 @@ _arg_cache_generate_metadata_in_ghash(PyGIArgCache *arg_cache,
}
static inline boolean
-_arg_cache_generate_metadata_in_error(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info)
+_arg_cache_generate_metadata_in_error(PyGIArgCache *arg_cache)
{
arg_cache->in_marshaler = _pygi_marshal_in_error;
+ arg_cache->is_aux = TRUE;
PyErr_Format(PyExc_NotImplementedError,
"Caching for this type is not fully implemented yet");
return FALSE;
}
-static inline boolean
+boolean
_arg_cache_generate_metadata_in(PyGIArgCache *arg_cache,
- PyGIFunctionCache *function_cache,
- GIArgInfo *arg_info,
+ GITypeInfo *type_info,
GITypeTag type_tag)
{
gboolean success = True;
- arg_cache->c_arg_index = i + function_cache->is_method;
- arg_cache->py_arg_index =
- function_info->n_in_args + function_cache->is_method;
-
function_info->n_in_args++;
switch (type_tag) {
case GI_TYPE_TAG_VOID:
- success = _arg_cache_generate_metadata_in_void(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_void(arg_cache);
break;
case GI_TYPE_TAG_BOOLEAN:
- success = _arg_cache_generate_metadata_in_boolean(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_boolean(arg_cache);
break;
case GI_TYPE_TAG_INT8:
- success = _arg_cache_generate_metadata_in_int8(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_int8(arg_cache);
break;
case GI_TYPE_TAG_UINT8:
- success = _arg_cache_generate_metadata_in_uint8(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_uint8(arg_cache);
break;
case GI_TYPE_TAG_INT16:
- success = _arg_cache_generate_metadata_in_uint16(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_uint16(arg_cache);
break;
case GI_TYPE_TAG_UINT16:
- success = _arg_cache_generate_metadata_in_uint16(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_uint16(arg_cache);
break;
case GI_TYPE_TAG_INT32:
- success = _arg_cache_generate_metadata_in_int32(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_int32(arg_cache);
break;
case GI_TYPE_TAG_UINT32:
- success = _arg_cache_generate_metadata_in_uint32(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_uint32(arg_cache);
break;
case GI_TYPE_TAG_INT64:
- success = _arg_cache_generate_metadata_in_int64(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_int64(arg_cache);
break;
case GI_TYPE_TAG_UINT64:
- success = _arg_cache_generate_metadata_in_uint64(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_uint64(arg_cache);
break;
case GI_TYPE_TAG_FLOAT:
- success = _arg_cache_generate_metadata_in_float(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_float(arg_cache);
break;
case GI_TYPE_TAG_DOUBLE:
- success = _arg_cache_generate_metadata_in_double(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_double(arg_cache);
break;
case GI_TYPE_TAG_UNICHAR:
- success = _arg_cache_generate_metadata_in_unichar(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_unichar(arg_cache);
break;
case GI_TYPE_TAG_GTYPE:
- success = _arg_cache_generate_metadata_in_gtype(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_gtype(arg_cache);
break;
case GI_TYPE_TAG_UTF8:
- success = _arg_cache_generate_metadata_in_utf8(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_utf8(arg_cache);
break;
case GI_TYPE_TAG_FILENAME:
- success = _arg_cache_generate_metadata_in_filename(arg_cache,
- function_cache,
- arg_info);
+ success = _arg_cache_generate_metadata_in_filename(arg_cache);
break;
case GI_TYPE_TAG_ARRAY:
success = _arg_cache_generate_metadata_in_array(arg_cache,
- function_cache,
- arg_info);
+ type_info);
break;
case GI_TYPE_TAG_INTERFACE:
success = _arg_cache_generate_metadata_in_interface(arg_cache,
- function_cache,
arg_info);
break;
case GI_TYPE_TAG_GLIST:
success = _arg_cache_generate_metadata_in_glist(arg_cache,
- function_cache,
- arg_info);
+ type_info);
break;
case GI_TYPE_TAG_GSLIST:
success = _arg_cache_generate_metadata_in_gslist(arg_cache,
- function_cache,
- arg_info);
+ type_info);
break;
case GI_TYPE_TAG_GHASH:
success = _arg_cache_generate_metadata_in_ghash(arg_cache,
- function_cache,
arg_info);
break;
case GI_TYPE_TAG_ERROR:
success = _arg_cache_generate_metadata_in_error(arg_cache,
- function_cache,
arg_info);
break;
}
@@ -479,14 +434,18 @@ _args_cache_generate(GIFunctionInfo *function_info,
arg_cache = function_cache->args_cache[i] = g_slice_new0(PyGIArgCache);
arg_cache->direction = g_arg_info_get_direction (arg_info);
+ arg_cache->transfer = g_arg_info_get_transfer (arg_info);
type_info = g_base_info_get_type ( (GIBaseInfo *) arg_info);
type_tag = g_type_info_get_tag (type_info);
switch(direction) {
case GI_DIRECTION_IN:
+ arg_cache->c_arg_index = i + function_cache->is_method;
+ arg_cache->py_arg_index =
+ function_info->n_in_args + function_cache->is_method;
+
_arg_cache_generate_metadata_in(arg_cache,
- function_cache,
- arg_info,
+ type_info,
type_tag);
break;
@@ -500,15 +459,16 @@ _args_cache_generate(GIFunctionInfo *function_info,
ac->cleanup = <type cleanup function pointer>
fc->out_args = g_slist_append(fc->out_args, ac);
break;
- }
+ }
}
+ g_base_info_unref( (GIBaseInfo *) type_info);
}
}
PyGIFunctionCache *
_pygi_function_cache_new (GIFunctionInfo *function_info)
{
- PyGIFunction *fc = _init_function_cache(function_info);
+ PyGIFunction *fc = _function_cache_new_from_function_info(function_info);
if (!_args_cache_generate(function_info, fc))
goto err;
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 12cfa02..88a43c8 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -43,12 +43,10 @@ typedef gboolean (*PyGIArgCleanupFunc) (gpointer data);
typedef struct _PyGISequenceCache
{
gssize fixed_size;
- PyGIValidateFunc *item_validate_func;
- PyGIMarshalFunc *item_marshal_func;
gint len_arg_index;
gboolean is_zero_terminated;
gsize item_size;
- GITypeTag item_tag_type;
+ PyGIArgCache *item_cache;
} PyGISequenceCache;
typedef struct _PyGIInterfaceCache
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]