diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c index b885ba0..2eff676 100644 --- a/gi/pygi-argument.c +++ b/gi/pygi-argument.c @@ -31,6 +31,44 @@ #include #include +static gboolean +gi_argument_to_gssize (GIArgument *arg_in, + GITypeTag type_tag, + gssize *gssize_out) +{ + switch (type_tag) { + case GI_TYPE_TAG_INT8: + *gssize_out = arg_in->v_int8; + return TRUE; + case GI_TYPE_TAG_UINT8: + *gssize_out = arg_in->v_uint8; + return TRUE; + case GI_TYPE_TAG_INT16: + *gssize_out = arg_in->v_int16; + return TRUE; + case GI_TYPE_TAG_UINT16: + *gssize_out = arg_in->v_uint16; + return TRUE; + case GI_TYPE_TAG_INT32: + *gssize_out = arg_in->v_int32; + return TRUE; + case GI_TYPE_TAG_UINT32: + *gssize_out = arg_in->v_uint32; + return TRUE; + case GI_TYPE_TAG_INT64: + *gssize_out = arg_in->v_int64; + return TRUE; + case GI_TYPE_TAG_UINT64: + *gssize_out = arg_in->v_uint64; + return TRUE; + default: + PyErr_Format (PyExc_TypeError, + "Unable to marshal %s to gssize", + g_type_tag_to_string(type_tag)); + return FALSE; + } +} + void _pygi_hash_pointer_to_arg (GIArgument *arg, GITypeTag type_tag) @@ -708,6 +746,7 @@ check_number_release: * @arg: The argument to convert * @args: Arguments to method invocation, possibly contaning the array length. * Set to NULL if this is not for a method call + * @callable_info: Info on the callable, if this a method call; otherwise NULL * @type_info: The type info for @arg * @out_free_array: A return location for a gboolean that indicates whether * or not the wrapped GArray should be freed @@ -725,6 +764,7 @@ check_number_release: GArray * _pygi_argument_to_array (GIArgument *arg, GIArgument *args[], + GICallableInfo *callable_info, GITypeInfo *type_info, gboolean *out_free_array) { @@ -762,12 +802,19 @@ _pygi_argument_to_array (GIArgument *arg, return g_array; } gint length_arg_pos; + GIArgInfo *length_arg_info; + GITypeInfo *length_type_info; length_arg_pos = g_type_info_get_array_length (type_info); g_assert (length_arg_pos >= 0); - - /* FIXME: Take into account the type of the length argument */ - length = args[length_arg_pos]->v_int; + g_assert (callable_info); + length_arg_info = g_callable_info_get_arg(callable_info, length_arg_pos); + length_type_info = g_arg_info_get_type(length_arg_info); + if (!gi_argument_to_gssize (args[length_arg_pos], + g_type_info_get_tag(length_type_info), + &length)) { + return NULL; + } } } diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h index 1b9ef1d..1785f8f 100644 --- a/gi/pygi-argument.h +++ b/gi/pygi-argument.h @@ -50,6 +50,7 @@ gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info, GArray* _pygi_argument_to_array (GIArgument *arg, GIArgument *args[], + GICallableInfo *callable_info, GITypeInfo *type_info, gboolean *out_free_array); diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index 824d620..59721af 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -351,6 +351,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args, if (g_type_info_get_tag (arg_type) == GI_TYPE_TAG_ARRAY) arg->v_pointer = _pygi_argument_to_array (arg, args, + callable_info, arg_type, &free_array); value = _pygi_argument_to_object (arg, arg_type, transfer); diff --git a/gi/pygi-info.c b/gi/pygi-info.c index 9f92cd3..3ca5c8f 100644 --- a/gi/pygi-info.c +++ b/gi/pygi-info.c @@ -1157,7 +1157,7 @@ _wrap_g_constant_info_get_value (PyGIBaseInfo *self) type_info = g_constant_info_get_type ( (GIConstantInfo *) self->info); if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ARRAY) { - value.v_pointer = _pygi_argument_to_array (&value, NULL, + value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL, type_info, &free_array); } @@ -1290,7 +1290,7 @@ _wrap_g_field_info_get_value (PyGIBaseInfo *self, } if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) { - value.v_pointer = _pygi_argument_to_array (&value, NULL, + value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL, field_type_info, &free_array); } diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c index 4e9dcb5..83f9a41 100644 --- a/gi/pygi-signal-closure.c +++ b/gi/pygi-signal-closure.c @@ -154,7 +154,7 @@ pygi_signal_closure_marshal(GClosure *closure, arg = _pygi_argument_from_g_value(¶m_values[i], &type_info); if (g_type_info_get_tag (&type_info) == GI_TYPE_TAG_ARRAY) { - arg.v_pointer = _pygi_argument_to_array (&arg, NULL, + arg.v_pointer = _pygi_argument_to_array (&arg, NULL, NULL, &type_info, &free_array); }