[pygobject/invoke-rewrite] [gi] implement out arg handling
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] [gi] implement out arg handling
- Date: Tue, 11 Jan 2011 22:21:01 +0000 (UTC)
commit 3b0eff80d2ee35e0417476f0a170b9e178e3d1ee
Author: John (J5) Palmieri <johnp redhat com>
Date: Tue Jan 11 17:20:43 2011 -0500
[gi] implement out arg handling
gi/pygi-argument.c | 43 +++++++++--------------------------
gi/pygi-cache.c | 22 ++++++++++++++----
gi/pygi-invoke-state-struct.h | 13 ++++++++++
gi/pygi-invoke.c | 50 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 89 insertions(+), 39 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index fda7b1e..a490878 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2856,10 +2856,7 @@ _pygi_marshal_out_int8 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
-
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
+ PyObject *py_obj = PYGLIB_PyLong_FromLong(arg->v_int8);
return py_obj;
}
@@ -2869,10 +2866,8 @@ _pygi_marshal_out_uint8 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PYGLIB_PyLong_FromLong(arg->v_uint8);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2882,10 +2877,8 @@ _pygi_marshal_out_int16 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PYGLIB_PyLong_FromLong(arg->v_int16);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2895,10 +2888,8 @@ _pygi_marshal_out_uint16 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PYGLIB_PyLong_FromLong(arg->v_uint16);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2908,10 +2899,8 @@ _pygi_marshal_out_int32 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PYGLIB_PyLong_FromLong(arg->v_int32);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2921,10 +2910,8 @@ _pygi_marshal_out_uint32 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PyLong_FromLongLong(arg->v_uint32);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2934,10 +2921,8 @@ _pygi_marshal_out_int64 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PyLong_FromLongLong(arg->v_int64);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2947,10 +2932,8 @@ _pygi_marshal_out_uint64 (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PyLong_FromUnsignedLongLong(arg->v_uint64);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
@@ -2960,10 +2943,8 @@ _pygi_marshal_out_float (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
-
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
+ PyObject *py_obj = PyFloat_FromDouble (arg->v_float);
+
return py_obj;
}
@@ -2973,10 +2954,8 @@ _pygi_marshal_out_double (PyGIInvokeState *state,
PyGIArgCache *arg_cache,
GIArgument *arg)
{
- PyObject *py_obj = NULL;
+ PyObject *py_obj = PyFloat_FromDouble (arg->v_double);
- PyErr_Format(PyExc_NotImplementedError,
- "Marshalling for this type is not implemented yet");
return py_obj;
}
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 07ef9d1..168d946 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -914,6 +914,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
PyGIFunctionCache *function_cache)
{
int arg_index = 0;
+ int i;
GITypeInfo *return_info;
GITypeTag return_type_tag;
PyGIArgCache *return_cache;
@@ -961,7 +962,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
}
- for (; arg_index < function_cache->n_args; arg_index++) {
+ for (i=0; arg_index < function_cache->n_args; arg_index++, i++) {
PyGIArgCache *arg_cache = NULL;
GIArgInfo *arg_info;
GITypeInfo *type_info;
@@ -975,7 +976,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
continue;
arg_info =
- g_callable_info_get_arg( (GICallableInfo *) function_info, arg_index);
+ g_callable_info_get_arg( (GICallableInfo *) function_info, i);
direction = g_arg_info_get_direction(arg_info);
transfer = g_arg_info_get_ownership_transfer(arg_info);
@@ -1005,10 +1006,21 @@ _args_cache_generate(GIFunctionInfo *function_info,
case GI_DIRECTION_OUT:
function_cache->n_out_args++;
- PyErr_Format(PyExc_NotImplementedError,
- "Out caching is not fully implemented yet");
+ arg_cache =
+ _arg_cache_out_new_from_type_info(return_info,
+ function_cache,
+ type_tag,
+ transfer,
+ direction,
+ arg_index);
- goto arg_err;
+ if (arg_cache == NULL)
+ goto arg_err;
+
+ function_cache->out_args =
+ g_slist_append(function_cache->out_args, arg_cache);
+
+ break;
case GI_DIRECTION_INOUT:
PyErr_Format(PyExc_NotImplementedError,
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index 1c9bf3e..22ac8ea 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -14,7 +14,20 @@ typedef struct _PyGIInvokeState
GIArgument **args;
GIArgument *in_args;
+
+ /* Out args and out values
+ * In order to pass a parameter and get something back out in C
+ * we need to pass a pointer to the value, e.g.
+ * int *out_integer;
+ *
+ * so while out_args == out_integer, out_value == *out_integer
+ * or in other words out_args = &out_values
+ *
+ * We do all of our processing on out_values but we pass out_args to
+ * the actual function.
+ */
GIArgument *out_args;
+ GIArgument *out_values;
GIArgument return_arg;
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 23f7fa6..1be824c 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -929,6 +929,12 @@ _invoke_state_init_from_function_cache(PyGIInvokeState *state,
return FALSE;
}
+ state->out_values = g_slice_alloc0(cache->n_out_args * sizeof(GIArgument));
+ if (state->out_values == NULL && cache->n_out_args != 0) {
+ PyErr_NoMemory();
+ return FALSE;
+ }
+
state->out_args = g_slice_alloc0(cache->n_out_args * sizeof(GIArgument));
if (state->out_args == NULL && cache->n_out_args != 0) {
PyErr_NoMemory();
@@ -946,6 +952,7 @@ _invoke_state_clear(PyGIInvokeState *state, PyGIFunctionCache *cache)
g_slice_free1(cache->n_args * sizeof(GIArgument *), state->args);
g_slice_free1(cache->n_in_args * sizeof(GIArgument), state->in_args);
g_slice_free1(cache->n_out_args * sizeof(GIArgument), state->out_args);
+ g_slice_free1(cache->n_out_args * sizeof(GIArgument), state->out_values);
}
static inline gboolean
@@ -971,7 +978,8 @@ _invoke_marshal_in_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
in_count++;
break;
case GI_DIRECTION_OUT:
- state->args[i] = &(state->out_args[out_count]);
+ state->out_args[out_count].v_pointer = &state->out_values[out_count];
+ state->args[i] = &state->out_values[out_count];
out_count++;
break;
}
@@ -997,13 +1005,51 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
{
PyObject *py_out = NULL;
PyObject *py_return = NULL;
+ int total_out_args = cache->n_out_args;
+ gboolean has_return = FALSE;
if (cache->return_cache)
py_return = cache->return_cache->out_marshaller(state,
cache,
cache->return_cache,
&state->return_arg);
- return py_return;
+
+ if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
+ total_out_args++;
+ has_return = TRUE;
+ }
+
+ if (cache->n_out_args == 0) {
+ py_out = py_return;
+ } else if (total_out_args == 1) {
+ /* if we get here there is one out arg an no return */
+ PyGIArgCache *arg_cache = (PyGIArgCache *)cache->out_args->data;
+ py_out = arg_cache->out_marshaller(state,
+ cache,
+ arg_cache,
+ &(state->out_values[0]));
+ } else {
+ int arg_index = 0;
+ GSList *cache_item = cache->out_args;
+ /* return a tuple */
+ py_out = PyTuple_New(total_out_args);
+ if (has_return) {
+ PyTuple_SET_ITEM(py_out, arg_index, py_return);
+ arg_index++;
+ }
+
+ for(; arg_index < total_out_args; arg_index++) {
+ PyGIArgCache *arg_cache = (PyGIArgCache *)cache_item->data;
+ PyObject *py_obj = arg_cache->out_marshaller(state,
+ cache,
+ arg_cache,
+ &(state->out_values[arg_index]));
+
+ PyTuple_SET_ITEM(py_out, arg_index, py_obj);
+ cache_item = cache_item->next;
+ }
+ }
+ return py_out;
}
PyObject *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]