Commit 3b0eff80 authored by John (J5) Palmieri's avatar John (J5) Palmieri

[gi] implement out arg handling

parent c5c149be
......@@ -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;
}
......
......@@ -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,
......
......@@ -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;
......
......@@ -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 *
......
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