1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5 * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 #include <pyglib-python-compat.h>
25 #include "pygi-array.h"
26 #include "pygi-private.h"
27 #include "pygi-marshal-cleanup.h"
28 #include "pygi-basictype.h"
30 /* Needed for _pygi_marshal_cleanup_from_py_interface_struct_gvalue hack */
31 #include "pygi-struct-marshal.h"
38 gi_argument_from_py_ssize_t (GIArgument *arg_out,
43 case GI_TYPE_TAG_VOID:
44 case GI_TYPE_TAG_BOOLEAN:
47 case GI_TYPE_TAG_INT8:
48 if (size_in >= G_MININT8 && size_in <= G_MAXINT8) {
49 arg_out->v_int8 = size_in;
55 case GI_TYPE_TAG_UINT8:
56 if (size_in >= 0 && size_in <= G_MAXUINT8) {
57 arg_out->v_uint8 = size_in;
63 case GI_TYPE_TAG_INT16:
64 if (size_in >= G_MININT16 && size_in <= G_MAXINT16) {
65 arg_out->v_int16 = size_in;
71 case GI_TYPE_TAG_UINT16:
72 if (size_in >= 0 && size_in <= G_MAXUINT16) {
73 arg_out->v_uint16 = size_in;
79 /* Ranges assume two's complement */
80 case GI_TYPE_TAG_INT32:
81 if (size_in >= G_MININT32 && size_in <= G_MAXINT32) {
82 arg_out->v_int32 = size_in;
88 case GI_TYPE_TAG_UINT32:
89 if (size_in >= 0 && size_in <= G_MAXUINT32) {
90 arg_out->v_uint32 = size_in;
96 case GI_TYPE_TAG_INT64:
97 arg_out->v_int64 = size_in;
100 case GI_TYPE_TAG_UINT64:
102 arg_out->v_uint64 = size_in;
108 case GI_TYPE_TAG_FLOAT:
109 case GI_TYPE_TAG_DOUBLE:
110 case GI_TYPE_TAG_GTYPE:
111 case GI_TYPE_TAG_UTF8:
112 case GI_TYPE_TAG_FILENAME:
113 case GI_TYPE_TAG_ARRAY:
114 case GI_TYPE_TAG_INTERFACE:
115 case GI_TYPE_TAG_GLIST:
116 case GI_TYPE_TAG_GSLIST:
117 case GI_TYPE_TAG_GHASH:
118 case GI_TYPE_TAG_ERROR:
119 case GI_TYPE_TAG_UNICHAR:
125 PyErr_Format (PyExc_OverflowError,
126 "Unable to marshal C Py_ssize_t %zd to %s",
128 g_type_tag_to_string (type_tag));
132 PyErr_Format (PyExc_TypeError,
133 "Unable to marshal C Py_ssize_t %zd to %s",
135 g_type_tag_to_string (type_tag));
140 gi_argument_to_gsize (GIArgument *arg_in,
145 case GI_TYPE_TAG_INT8:
146 *gsize_out = arg_in->v_int8;
148 case GI_TYPE_TAG_UINT8:
149 *gsize_out = arg_in->v_uint8;
151 case GI_TYPE_TAG_INT16:
152 *gsize_out = arg_in->v_int16;
154 case GI_TYPE_TAG_UINT16:
155 *gsize_out = arg_in->v_uint16;
157 case GI_TYPE_TAG_INT32:
158 *gsize_out = arg_in->v_int32;
160 case GI_TYPE_TAG_UINT32:
161 *gsize_out = arg_in->v_uint32;
163 case GI_TYPE_TAG_INT64:
164 *gsize_out = arg_in->v_int64;
166 case GI_TYPE_TAG_UINT64:
167 *gsize_out = arg_in->v_uint64;
170 PyErr_Format (PyExc_TypeError,
171 "Unable to marshal %s to gsize",
172 g_type_tag_to_string (type_tag));
178 _pygi_marshal_from_py_array (PyGIInvokeState *state,
179 PyGICallableCache *callable_cache,
180 PyGIArgCache *arg_cache,
183 gpointer *cleanup_data)
185 PyGIMarshalFromPyFunc from_py_marshaller;
187 int success_count = 0;
190 gboolean is_ptr_array;
191 GArray *array_ = NULL;
192 PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
193 PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
194 GITransfer cleanup_transfer = arg_cache->transfer;
197 if (py_arg == Py_None) {
198 arg->v_pointer = NULL;
202 if (!PySequence_Check (py_arg)) {
203 PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
204 py_arg->ob_type->tp_name);
208 length = PySequence_Length (py_arg);
212 if (array_cache->fixed_size >= 0 &&
213 array_cache->fixed_size != length) {
214 PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
215 array_cache->fixed_size, length);
220 item_size = array_cache->item_size;
221 is_ptr_array = (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
223 array_ = (GArray *)g_ptr_array_sized_new (length);
225 array_ = g_array_sized_new (array_cache->is_zero_terminated,
231 if (array_ == NULL) {
236 if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
237 PYGLIB_PyBytes_Check (py_arg)) {
238 gchar *data = PYGLIB_PyBytes_AsString (py_arg);
240 /* Avoid making a copy if the data
241 * is not transferred to the C function
242 * and cannot not be modified by it.
244 if (array_cache->array_type == GI_ARRAY_TYPE_C &&
245 arg_cache->transfer == GI_TRANSFER_NOTHING &&
246 !array_cache->is_zero_terminated) {
247 g_free (array_->data);
249 cleanup_transfer = GI_TRANSFER_EVERYTHING;
251 memcpy (array_->data, data, length);
253 array_->len = length;
254 if (array_cache->is_zero_terminated) {
255 /* If array_ has been created with zero_termination, space for the
256 * terminator is properly allocated, so we're not off-by-one here. */
257 array_->data[length] = '\0';
262 from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
263 for (i = 0, success_count = 0; i < length; i++) {
264 GIArgument item = {0};
265 gpointer item_cleanup_data = NULL;
266 PyObject *py_item = PySequence_GetItem (py_arg, i);
270 if (!from_py_marshaller ( state,
272 sequence_cache->item_cache,
275 &item_cleanup_data)) {
281 if (item_cleanup_data != NULL && item_cleanup_data != item.v_pointer) {
282 /* We only support one level of data discrepancy between an items
283 * data and its cleanup data. This is because we only track a single
284 * extra cleanup data pointer per-argument and cannot track the entire
285 * array of items differing data and cleanup_data.
286 * For example, this would fail if trying to marshal an array of
287 * callback closures marked with SCOPE call type where the cleanup data
288 * is different from the items v_pointer, likewise an array of arrays.
290 PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to "
291 "the items data its cleanup data being different.");
295 /* FIXME: it is much more efficent to have seperate marshaller
296 * for ptr arrays than doing the evaluation
297 * and casting each loop iteration
300 g_ptr_array_add((GPtrArray *)array_, item.v_pointer);
301 } else if (sequence_cache->item_cache->is_pointer) {
302 /* if the item is a pointer, simply copy the pointer */
303 g_assert (item_size == sizeof (item.v_pointer));
304 g_array_insert_val (array_, i, item);
305 } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
306 /* Special case handling of flat arrays of gvalue/boxed/struct */
307 PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache;
308 GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info;
309 GIInfoType info_type = g_base_info_get_type (base_info);
312 case GI_INFO_TYPE_UNION:
313 case GI_INFO_TYPE_STRUCT:
315 PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache;
316 PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
318 if (g_type_is_a (item_iface_cache->g_type, G_TYPE_VALUE)) {
319 /* Special case GValue flat arrays to properly init and copy the contents. */
320 GValue* dest = (GValue*) (array_->data + (i * item_size));
321 if (item.v_pointer != NULL) {
322 memset (dest, 0, item_size);
323 g_value_init (dest, G_VALUE_TYPE ((GValue*) item.v_pointer));
324 g_value_copy ((GValue*) item.v_pointer, dest);
326 /* Manually increment the length because we are manually setting the memory. */
330 /* Handles flat arrays of boxed or struct types. */
331 g_array_insert_vals (array_, i, item.v_pointer, 1);
334 /* Cleanup any memory left by the per-item marshaler because
335 * _pygi_marshal_cleanup_from_py_array will not know about this
336 * due to "item" being a temporarily marshaled value done on the stack.
339 from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE);
344 g_array_insert_val (array_, i, item);
347 /* default value copy of a simple type */
348 g_array_insert_val (array_, i, item);
354 if (sequence_cache->item_cache->from_py_cleanup != NULL) {
356 PyGIMarshalCleanupFunc cleanup_func =
357 sequence_cache->item_cache->from_py_cleanup;
359 /* Only attempt per item cleanup on pointer items */
360 if (sequence_cache->item_cache->is_pointer) {
361 for(j = 0; j < success_count; j++) {
362 PyObject *py_item = PySequence_GetItem (py_arg, j);
364 sequence_cache->item_cache,
367 g_ptr_array_index ((GPtrArray *)array_, j) :
368 g_array_index (array_, gpointer, j),
376 g_ptr_array_free ( ( GPtrArray *)array_, TRUE);
378 g_array_free (array_, TRUE);
379 _PyGI_ERROR_PREFIX ("Item %i: ", i);
384 if (array_cache->len_arg_index >= 0) {
385 /* we have an child arg to handle */
386 PyGIArgCache *child_cache =
387 _pygi_callable_cache_get_arg (callable_cache, array_cache->len_arg_index);
389 if (!gi_argument_from_py_ssize_t (&state->args[child_cache->c_arg_index].arg_value,
391 child_cache->type_tag)) {
396 if (array_cache->array_type == GI_ARRAY_TYPE_C) {
397 /* In the case of GI_ARRAY_C, we give the data directly as the argument
398 * but keep the array_ wrapper as cleanup data so we don't have to find
401 arg->v_pointer = array_->data;
403 if (cleanup_transfer == GI_TRANSFER_EVERYTHING) {
404 g_array_free (array_, FALSE);
405 *cleanup_data = NULL;
407 *cleanup_data = array_;
410 arg->v_pointer = array_;
412 if (cleanup_transfer == GI_TRANSFER_NOTHING) {
413 /* Free everything in cleanup. */
414 *cleanup_data = array_;
415 } else if (cleanup_transfer == GI_TRANSFER_CONTAINER) {
416 /* Make a shallow copy so we can free the elements later in cleanup
417 * because it is possible invoke will free the list before our cleanup. */
418 *cleanup_data = is_ptr_array ?
419 (gpointer)g_ptr_array_ref ((GPtrArray *)array_) :
420 (gpointer)g_array_ref (array_);
421 } else { /* GI_TRANSFER_EVERYTHING */
422 /* No cleanup, everything is given to the callee. */
423 *cleanup_data = NULL;
431 _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
432 PyGIArgCache *arg_cache,
435 gboolean was_processed)
438 GArray *array_ = NULL;
439 GPtrArray *ptr_array_ = NULL;
440 PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
441 PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
443 if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
444 ptr_array_ = (GPtrArray *) data;
446 array_ = (GArray *) data;
449 /* clean up items first */
450 if (sequence_cache->item_cache->from_py_cleanup != NULL) {
452 guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
453 PyGIMarshalCleanupFunc cleanup_func =
454 sequence_cache->item_cache->from_py_cleanup;
456 for (i = 0; i < len; i++) {
458 PyObject *py_item = NULL;
460 /* case 1: GPtrArray */
461 if (ptr_array_ != NULL)
462 item = g_ptr_array_index (ptr_array_, i);
463 /* case 2: C array or GArray with object pointers */
464 else if (sequence_cache->item_cache->is_pointer)
465 item = g_array_index (array_, gpointer, i);
466 /* case 3: C array or GArray with simple types or structs */
468 item = array_->data + i * array_cache->item_size;
469 /* special-case hack: GValue array items do not get slice
470 * allocated in _pygi_marshal_from_py_array(), so we must
471 * not try to deallocate it as a slice and thus
472 * short-circuit cleanup_func. */
473 if (cleanup_func == pygi_arg_gvalue_from_py_cleanup) {
474 g_value_unset ((GValue*) item);
479 py_item = PySequence_GetItem (py_arg, i);
480 cleanup_func (state, sequence_cache->item_cache, py_item, item, TRUE);
481 Py_XDECREF (py_item);
485 /* Only free the array when we didn't transfer ownership */
486 if (array_cache->array_type == GI_ARRAY_TYPE_C) {
487 /* always free the GArray wrapper created in from_py marshaling and
488 * passed back as cleanup_data
490 g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING);
493 g_array_unref (array_);
495 g_ptr_array_unref (ptr_array_);
504 _pygi_marshal_to_py_array (PyGIInvokeState *state,
505 PyGICallableCache *callable_cache,
506 PyGIArgCache *arg_cache,
510 PyObject *py_obj = NULL;
511 PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
512 PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
513 gsize processed_items = 0;
515 /* GArrays make it easier to iterate over arrays
516 * with different element sizes but requires that
517 * we allocate a GArray if the argument was a C array
519 if (array_cache->array_type == GI_ARRAY_TYPE_C) {
521 if (array_cache->fixed_size >= 0) {
522 g_assert(arg->v_pointer != NULL);
523 len = array_cache->fixed_size;
524 } else if (array_cache->is_zero_terminated) {
525 if (arg->v_pointer == NULL) {
527 } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
528 len = strlen (arg->v_pointer);
530 len = g_strv_length ((gchar **)arg->v_pointer);
533 GIArgument *len_arg = &state->args[array_cache->len_arg_index].arg_value;
534 PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache,
535 array_cache->len_arg_index);
537 if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) {
542 array_ = g_array_new (FALSE,
544 array_cache->item_size);
545 if (array_ == NULL) {
548 if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL)
549 g_free (arg->v_pointer);
554 if (array_->data != NULL)
555 g_free (array_->data);
556 array_->data = arg->v_pointer;
559 array_ = arg->v_pointer;
562 if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
563 if (arg->v_pointer == NULL) {
564 py_obj = PYGLIB_PyBytes_FromString ("");
566 py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len);
569 if (arg->v_pointer == NULL) {
570 py_obj = PyList_New (0);
575 PyGIMarshalToPyFunc item_to_py_marshaller;
576 PyGIArgCache *item_arg_cache;
578 py_obj = PyList_New (array_->len);
583 item_arg_cache = seq_cache->item_cache;
584 item_to_py_marshaller = item_arg_cache->to_py_marshaller;
586 item_size = g_array_get_element_size (array_);
588 for (i = 0; i < array_->len; i++) {
589 GIArgument item_arg = {0};
592 /* If we are receiving an array of pointers, simply assign the pointer
593 * and move on, letting the per-item marshaler deal with the
594 * various transfer modes and ref counts (e.g. g_variant_ref_sink).
596 if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
597 item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
599 } else if (item_arg_cache->is_pointer) {
600 item_arg.v_pointer = g_array_index (array_, gpointer, i);
602 } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
603 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
605 /* FIXME: This probably doesn't work with boxed types or gvalues.
606 * See fx. _pygi_marshal_from_py_array() */
607 switch (g_base_info_get_type (iface_cache->interface_info)) {
608 case GI_INFO_TYPE_STRUCT:
609 if (arg_cache->transfer == GI_TRANSFER_EVERYTHING &&
610 !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
611 /* array elements are structs */
612 gpointer *_struct = g_malloc (item_size);
613 memcpy (_struct, array_->data + i * item_size,
615 item_arg.v_pointer = _struct;
617 item_arg.v_pointer = array_->data + i * item_size;
621 item_arg.v_pointer = g_array_index (array_, gpointer, i);
625 memcpy (&item_arg, array_->data + i * item_size, item_size);
628 py_item = item_to_py_marshaller ( state,
633 if (py_item == NULL) {
636 if (array_cache->array_type == GI_ARRAY_TYPE_C)
637 g_array_unref (array_);
641 PyList_SET_ITEM (py_obj, i, py_item);
647 if (array_cache->array_type == GI_ARRAY_TYPE_C)
648 g_array_free (array_, FALSE);
653 if (array_cache->array_type == GI_ARRAY_TYPE_C) {
654 g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
656 /* clean up unprocessed items */
657 if (seq_cache->item_cache->to_py_cleanup != NULL) {
659 PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup;
660 for (j = processed_items; j < array_->len; j++) {
662 seq_cache->item_cache,
664 g_array_index (array_, gpointer, j),
669 if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
670 g_array_free (array_, TRUE);
677 _wrap_c_array (PyGIInvokeState *state,
678 PyGIArgGArray *array_cache,
684 if (array_cache->fixed_size >= 0) {
685 len = array_cache->fixed_size;
686 } else if (array_cache->is_zero_terminated) {
687 len = g_strv_length ((gchar **)data);
688 } else if (array_cache->len_arg_index >= 0) {
689 GIArgument *len_arg = &state->args[array_cache->len_arg_index].arg_value;
690 len = len_arg->v_long;
693 array_ = g_array_new (FALSE,
695 array_cache->item_size);
700 g_free (array_->data);
708 _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
709 PyGIArgCache *arg_cache,
712 gboolean was_processed)
714 if (arg_cache->transfer == GI_TRANSFER_EVERYTHING ||
715 arg_cache->transfer == GI_TRANSFER_CONTAINER) {
716 GArray *array_ = NULL;
717 GPtrArray *ptr_array_ = NULL;
718 PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
719 PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
721 /* If this isn't a garray create one to help process variable sized
723 if (array_cache->array_type == GI_ARRAY_TYPE_C) {
724 array_ = _wrap_c_array (state, array_cache, data);
729 } else if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
730 ptr_array_ = (GPtrArray *) data;
732 array_ = (GArray *) data;
735 if (sequence_cache->item_cache->to_py_cleanup != NULL) {
737 guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
739 PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup;
740 for (i = 0; i < len; i++) {
742 sequence_cache->item_cache,
744 (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i),
750 g_array_free (array_, TRUE);
752 g_ptr_array_free (ptr_array_, TRUE);
757 _array_cache_free_func (PyGIArgGArray *cache)
760 pygi_arg_cache_free (((PyGISequenceCache *)cache)->item_cache);
761 g_slice_free (PyGIArgGArray, cache);
766 pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache,
767 GITypeInfo *type_info,
768 PyGICallableCache *callable_cache,
769 PyGIDirection direction,
771 gssize *py_arg_index)
773 PyGIArgGArray *seq_cache = (PyGIArgGArray *)arg_cache;
775 /* attempt len_arg_index setup for the first time */
776 if (seq_cache->len_arg_index < 0) {
777 seq_cache->len_arg_index = g_type_info_get_array_length (type_info);
779 /* offset by self arg for methods and vfuncs */
780 if (seq_cache->len_arg_index >= 0 && callable_cache != NULL) {
781 seq_cache->len_arg_index += callable_cache->args_offset;
785 if (seq_cache->len_arg_index >= 0) {
786 PyGIArgCache *child_cache = NULL;
788 child_cache = _pygi_callable_cache_get_arg (callable_cache,
789 seq_cache->len_arg_index);
790 if (child_cache == NULL) {
791 child_cache = pygi_arg_cache_alloc ();
793 /* If the "length" arg cache already exists (the length comes before
794 * the array in the argument list), remove it from the to_py_args list
795 * because it does not belong in "to python" return tuple. The length
796 * will implicitly be a part of the returned Python list.
798 if (direction & PYGI_DIRECTION_TO_PYTHON) {
799 callable_cache->to_py_args =
800 g_slist_remove (callable_cache->to_py_args, child_cache);
803 /* This is a case where the arg cache already exists and has been
804 * setup by another array argument sharing the same length argument.
805 * See: gi_marshalling_tests_multi_array_key_value_in
807 if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
811 /* There is a length argument for this array, so increment the number
812 * of "to python" child arguments when applicable.
814 if (direction & PYGI_DIRECTION_TO_PYTHON)
815 callable_cache->n_to_py_child_args++;
817 child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
818 child_cache->direction = direction;
819 child_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
820 child_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
821 child_cache->py_arg_index = -1;
823 /* ugly edge case code:
825 * When the length comes before the array parameter we need to update
826 * indexes of arguments after the index argument.
828 if (seq_cache->len_arg_index < arg_index && direction & PYGI_DIRECTION_FROM_PYTHON) {
830 (*py_arg_index) -= 1;
831 callable_cache->n_py_args -= 1;
833 for (i = seq_cache->len_arg_index + 1;
834 i < _pygi_callable_cache_args_len (callable_cache); i++) {
835 PyGIArgCache *update_cache = _pygi_callable_cache_get_arg (callable_cache, i);
836 if (update_cache == NULL)
839 update_cache->py_arg_index -= 1;
843 _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache);
851 pygi_arg_garray_setup (PyGIArgGArray *sc,
852 GITypeInfo *type_info,
853 GIArgInfo *arg_info, /* may be NULL for return arguments */
855 PyGIDirection direction,
856 PyGICallableCache *callable_cache)
858 GITypeInfo *item_type_info;
859 PyGIArgCache *arg_cache = (PyGIArgCache *)sc;
861 if (!pygi_arg_sequence_setup ((PyGISequenceCache *)sc,
870 ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_array_cache_free_func;
871 sc->array_type = g_type_info_get_array_type (type_info);
872 sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info);
873 sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
874 sc->len_arg_index = -1; /* setup by pygi_arg_garray_len_arg_setup */
876 item_type_info = g_type_info_get_param_type (type_info, 0);
877 sc->item_size = _pygi_g_type_info_size (item_type_info);
878 g_base_info_unref ( (GIBaseInfo *)item_type_info);
880 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
881 arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
882 arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
885 if (direction & PYGI_DIRECTION_TO_PYTHON) {
886 arg_cache->to_py_marshaller = _pygi_marshal_to_py_array;
887 arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array;
894 pygi_arg_garray_new_from_info (GITypeInfo *type_info,
897 PyGIDirection direction,
898 PyGICallableCache *callable_cache)
900 PyGIArgGArray *array_cache = g_slice_new0 (PyGIArgGArray);
901 if (array_cache == NULL)
904 if (!pygi_arg_garray_setup (array_cache,
910 pygi_arg_cache_free ( (PyGIArgCache *)array_cache);
914 return (PyGIArgCache *)array_cache;