Imported Upstream version 3.21.91
[platform/upstream/python-gobject.git] / gi / pygi-array.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <Python.h>
22 #include <glib.h>
23 #include <pyglib-python-compat.h>
24
25 #include "pygi-array.h"
26 #include "pygi-info.h"
27 #include "pygi-marshal-cleanup.h"
28 #include "pygi-basictype.h"
29 #include "pygi-util.h"
30
31 /* Needed for _pygi_marshal_cleanup_from_py_interface_struct_gvalue hack */
32 #include "pygi-struct-marshal.h"
33
34 /*
35  * GArray to Python
36  */
37
38 static gboolean
39 gi_argument_from_py_ssize_t (GIArgument   *arg_out,
40                              Py_ssize_t    size_in,
41                              GITypeTag     type_tag)
42 {
43     switch (type_tag) {
44     case GI_TYPE_TAG_VOID:
45     case GI_TYPE_TAG_BOOLEAN:
46         goto unhandled_type;
47
48     case GI_TYPE_TAG_INT8:
49         if (size_in >= G_MININT8 && size_in <= G_MAXINT8) {
50             arg_out->v_int8 = size_in;
51             return TRUE;
52         } else {
53             goto overflow;
54         }
55
56     case GI_TYPE_TAG_UINT8:
57         if (size_in >= 0 && size_in <= G_MAXUINT8) {
58             arg_out->v_uint8 = size_in;
59             return TRUE;
60         } else {
61             goto overflow;
62         }
63
64     case GI_TYPE_TAG_INT16:
65         if (size_in >= G_MININT16 && size_in <= G_MAXINT16) {
66             arg_out->v_int16 = size_in;
67             return TRUE;
68         } else {
69             goto overflow;
70         }
71
72     case GI_TYPE_TAG_UINT16:
73         if (size_in >= 0 && size_in <= G_MAXUINT16) {
74             arg_out->v_uint16 = size_in;
75             return TRUE;
76         } else {
77             goto overflow;
78         }
79
80         /* Ranges assume two's complement */
81     case GI_TYPE_TAG_INT32:
82         if (size_in >= G_MININT32 && size_in <= G_MAXINT32) {
83             arg_out->v_int32 = size_in;
84             return TRUE;
85         } else {
86             goto overflow;
87         }
88
89     case GI_TYPE_TAG_UINT32:
90         if (size_in >= 0 && size_in <= G_MAXUINT32) {
91             arg_out->v_uint32 = size_in;
92             return TRUE;
93         } else {
94             goto overflow;
95         }
96
97     case GI_TYPE_TAG_INT64:
98         arg_out->v_int64 = size_in;
99         return TRUE;
100
101     case GI_TYPE_TAG_UINT64:
102         if (size_in >= 0) {
103             arg_out->v_uint64 = size_in;
104             return TRUE;
105         } else {
106             goto overflow;
107         }
108
109     case GI_TYPE_TAG_FLOAT:
110     case GI_TYPE_TAG_DOUBLE:
111     case GI_TYPE_TAG_GTYPE:
112     case GI_TYPE_TAG_UTF8:
113     case GI_TYPE_TAG_FILENAME:
114     case GI_TYPE_TAG_ARRAY:
115     case GI_TYPE_TAG_INTERFACE:
116     case GI_TYPE_TAG_GLIST:
117     case GI_TYPE_TAG_GSLIST:
118     case GI_TYPE_TAG_GHASH:
119     case GI_TYPE_TAG_ERROR:
120     case GI_TYPE_TAG_UNICHAR:
121     default:
122         goto unhandled_type;
123     }
124
125  overflow:
126     PyErr_Format (PyExc_OverflowError,
127                   "Unable to marshal C Py_ssize_t %zd to %s",
128                   size_in,
129                   g_type_tag_to_string (type_tag));
130     return FALSE;
131
132  unhandled_type:
133     PyErr_Format (PyExc_TypeError,
134                   "Unable to marshal C Py_ssize_t %zd to %s",
135                   size_in,
136                   g_type_tag_to_string (type_tag));
137     return FALSE;
138 }
139
140 static gboolean
141 gi_argument_to_gsize (GIArgument *arg_in,
142                       gsize      *gsize_out,
143                       GITypeTag   type_tag)
144 {
145     switch (type_tag) {
146       case GI_TYPE_TAG_INT8:
147           *gsize_out = arg_in->v_int8;
148           return TRUE;
149       case GI_TYPE_TAG_UINT8:
150           *gsize_out = arg_in->v_uint8;
151           return TRUE;
152       case GI_TYPE_TAG_INT16:
153           *gsize_out = arg_in->v_int16;
154           return TRUE;
155       case GI_TYPE_TAG_UINT16:
156           *gsize_out = arg_in->v_uint16;
157           return TRUE;
158       case GI_TYPE_TAG_INT32:
159           *gsize_out = arg_in->v_int32;
160           return TRUE;
161       case GI_TYPE_TAG_UINT32:
162           *gsize_out = arg_in->v_uint32;
163           return TRUE;
164       case GI_TYPE_TAG_INT64:
165           *gsize_out = arg_in->v_int64;
166           return TRUE;
167       case GI_TYPE_TAG_UINT64:
168           *gsize_out = arg_in->v_uint64;
169           return TRUE;
170       default:
171           PyErr_Format (PyExc_TypeError,
172                         "Unable to marshal %s to gsize",
173                         g_type_tag_to_string (type_tag));
174           return FALSE;
175     }
176 }
177
178 static gboolean
179 _pygi_marshal_from_py_array (PyGIInvokeState   *state,
180                              PyGICallableCache *callable_cache,
181                              PyGIArgCache      *arg_cache,
182                              PyObject          *py_arg,
183                              GIArgument        *arg,
184                              gpointer          *cleanup_data)
185 {
186     PyGIMarshalFromPyFunc from_py_marshaller;
187     int i = 0;
188     int success_count = 0;
189     Py_ssize_t length;
190     gssize item_size;
191     gboolean is_ptr_array;
192     GArray *array_ = NULL;
193     PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
194     PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
195     GITransfer cleanup_transfer = arg_cache->transfer;
196
197
198     if (py_arg == Py_None) {
199         arg->v_pointer = NULL;
200         return TRUE;
201     }
202
203     if (!PySequence_Check (py_arg)) {
204         PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
205                       py_arg->ob_type->tp_name);
206         return FALSE;
207     }
208
209     length = PySequence_Length (py_arg);
210     if (length < 0)
211         return FALSE;
212
213     if (array_cache->fixed_size >= 0 &&
214             array_cache->fixed_size != length) {
215         PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
216                       array_cache->fixed_size, length);
217
218         return FALSE;
219     }
220
221     item_size = array_cache->item_size;
222     is_ptr_array = (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
223     if (is_ptr_array) {
224         array_ = (GArray *)g_ptr_array_sized_new (length);
225     } else {
226         array_ = g_array_sized_new (array_cache->is_zero_terminated,
227                                     TRUE,
228                                     item_size,
229                                     length);
230     }
231
232     if (array_ == NULL) {
233         PyErr_NoMemory ();
234         return FALSE;
235     }
236
237     if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
238         PYGLIB_PyBytes_Check (py_arg)) {
239         gchar *data = PYGLIB_PyBytes_AsString (py_arg);
240
241         /* Avoid making a copy if the data
242          * is not transferred to the C function
243          * and cannot not be modified by it.
244          */
245         if (array_cache->array_type == GI_ARRAY_TYPE_C &&
246             arg_cache->transfer == GI_TRANSFER_NOTHING &&
247             !array_cache->is_zero_terminated) {
248             g_free (array_->data);
249             array_->data = data;
250             cleanup_transfer = GI_TRANSFER_EVERYTHING;
251         } else {
252             memcpy (array_->data, data, length);
253         }
254         array_->len = length;
255         if (array_cache->is_zero_terminated) {
256             /* If array_ has been created with zero_termination, space for the
257              * terminator is properly allocated, so we're not off-by-one here. */
258             array_->data[length] = '\0';
259         }
260         goto array_success;
261     }
262
263     from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
264     for (i = 0, success_count = 0; i < length; i++) {
265         GIArgument item = {0};
266         gpointer item_cleanup_data = NULL;
267         PyObject *py_item = PySequence_GetItem (py_arg, i);
268         if (py_item == NULL)
269             goto err;
270
271         if (!from_py_marshaller ( state,
272                                   callable_cache,
273                                   sequence_cache->item_cache,
274                                   py_item,
275                                  &item,
276                                  &item_cleanup_data)) {
277             Py_DECREF (py_item);
278             goto err;
279         }
280         Py_DECREF (py_item);
281
282         if (item_cleanup_data != NULL && item_cleanup_data != item.v_pointer) {
283             /* We only support one level of data discrepancy between an items
284              * data and its cleanup data. This is because we only track a single
285              * extra cleanup data pointer per-argument and cannot track the entire
286              * array of items differing data and cleanup_data.
287              * For example, this would fail if trying to marshal an array of
288              * callback closures marked with SCOPE call type where the cleanup data
289              * is different from the items v_pointer, likewise an array of arrays.
290              */
291             PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to "
292                                                 "the items data its cleanup data being different.");
293             goto err;
294         }
295
296         /* FIXME: it is much more efficent to have seperate marshaller
297          *        for ptr arrays than doing the evaluation
298          *        and casting each loop iteration
299          */
300         if (is_ptr_array) {
301             g_ptr_array_add((GPtrArray *)array_, item.v_pointer);
302         } else if (sequence_cache->item_cache->is_pointer) {
303             /* if the item is a pointer, simply copy the pointer */
304             g_assert (item_size == sizeof (item.v_pointer));
305             g_array_insert_val (array_, i, item);
306         } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
307             /* Special case handling of flat arrays of gvalue/boxed/struct */
308             PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache;
309             GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info;
310             GIInfoType info_type = g_base_info_get_type (base_info);
311
312             switch (info_type) {
313                 case GI_INFO_TYPE_UNION:
314                 case GI_INFO_TYPE_STRUCT:
315                 {
316                     PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache;
317                     PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
318
319                     if (g_type_is_a (item_iface_cache->g_type, G_TYPE_VALUE)) {
320                         /* Special case GValue flat arrays to properly init and copy the contents. */
321                         GValue* dest = (GValue*) (array_->data + (i * item_size));
322                         if (item.v_pointer != NULL) {
323                             memset (dest, 0, item_size);
324                             g_value_init (dest, G_VALUE_TYPE ((GValue*) item.v_pointer));
325                             g_value_copy ((GValue*) item.v_pointer, dest);
326                         }
327                         /* Manually increment the length because we are manually setting the memory. */
328                         array_->len++;
329
330                     } else {
331                         /* Handles flat arrays of boxed or struct types. */
332                         g_array_insert_vals (array_, i, item.v_pointer, 1);
333                     }
334
335                     /* Cleanup any memory left by the per-item marshaler because
336                      * _pygi_marshal_cleanup_from_py_array will not know about this
337                      * due to "item" being a temporarily marshaled value done on the stack.
338                      */
339                     if (from_py_cleanup)
340                         from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE);
341
342                     break;
343                 }
344                 default:
345                     g_array_insert_val (array_, i, item);
346             }
347         } else {
348             /* default value copy of a simple type */
349             g_array_insert_val (array_, i, item);
350         }
351
352         success_count++;
353         continue;
354 err:
355         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
356             gsize j;
357             PyGIMarshalCleanupFunc cleanup_func =
358                 sequence_cache->item_cache->from_py_cleanup;
359
360             /* Only attempt per item cleanup on pointer items */
361             if (sequence_cache->item_cache->is_pointer) {
362                 for(j = 0; j < success_count; j++) {
363                     PyObject *py_item = PySequence_GetItem (py_arg, j);
364                     cleanup_func (state,
365                                   sequence_cache->item_cache,
366                                   py_item,
367                                   is_ptr_array ?
368                                           g_ptr_array_index ((GPtrArray *)array_, j) :
369                                           g_array_index (array_, gpointer, j),
370                                   TRUE);
371                     Py_DECREF (py_item);
372                 }
373             }
374         }
375
376         if (is_ptr_array)
377             g_ptr_array_free ( ( GPtrArray *)array_, TRUE);
378         else
379             g_array_free (array_, TRUE);
380         _PyGI_ERROR_PREFIX ("Item %i: ", i);
381         return FALSE;
382     }
383
384 array_success:
385     if (array_cache->len_arg_index >= 0) {
386         /* we have an child arg to handle */
387         PyGIArgCache *child_cache =
388             _pygi_callable_cache_get_arg (callable_cache, array_cache->len_arg_index);
389
390         if (!gi_argument_from_py_ssize_t (&state->args[child_cache->c_arg_index].arg_value,
391                                           length,
392                                           child_cache->type_tag)) {
393             goto err;
394         }
395     }
396
397     if (array_cache->array_type == GI_ARRAY_TYPE_C) {
398         /* In the case of GI_ARRAY_C, we give the data directly as the argument
399          * but keep the array_ wrapper as cleanup data so we don't have to find
400          * it's length again.
401          */
402         arg->v_pointer = array_->data;
403
404         if (cleanup_transfer == GI_TRANSFER_EVERYTHING) {
405             g_array_free (array_, FALSE);
406             *cleanup_data = NULL;
407         } else {
408             *cleanup_data = array_;
409         }
410     } else {
411         arg->v_pointer = array_;
412
413         if (cleanup_transfer == GI_TRANSFER_NOTHING) {
414             /* Free everything in cleanup. */
415             *cleanup_data = array_;
416         } else if (cleanup_transfer == GI_TRANSFER_CONTAINER) {
417             /* Make a shallow copy so we can free the elements later in cleanup
418              * because it is possible invoke will free the list before our cleanup. */
419             *cleanup_data = is_ptr_array ?
420                     (gpointer)g_ptr_array_ref ((GPtrArray *)array_) :
421                     (gpointer)g_array_ref (array_);
422         } else { /* GI_TRANSFER_EVERYTHING */
423             /* No cleanup, everything is given to the callee. */
424             *cleanup_data = NULL;
425         }
426     }
427
428     return TRUE;
429 }
430
431 static void
432 _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
433                                      PyGIArgCache    *arg_cache,
434                                      PyObject        *py_arg,
435                                      gpointer         data,
436                                      gboolean         was_processed)
437 {
438     if (was_processed) {
439         GArray *array_ = NULL;
440         GPtrArray *ptr_array_ = NULL;
441         PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
442         PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
443
444         if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
445             ptr_array_ = (GPtrArray *) data;
446         } else {
447             array_ = (GArray *) data;
448         }
449
450         /* clean up items first */
451         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
452             gsize i;
453             guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
454             PyGIMarshalCleanupFunc cleanup_func =
455                 sequence_cache->item_cache->from_py_cleanup;
456
457             for (i = 0; i < len; i++) {
458                 gpointer item;
459                 PyObject *py_item = NULL;
460
461                 /* case 1: GPtrArray */
462                 if (ptr_array_ != NULL)
463                     item = g_ptr_array_index (ptr_array_, i);
464                 /* case 2: C array or GArray with object pointers */
465                 else if (sequence_cache->item_cache->is_pointer)
466                     item = g_array_index (array_, gpointer, i);
467                 /* case 3: C array or GArray with simple types or structs */
468                 else {
469                     item = array_->data + i * array_cache->item_size;
470                     /* special-case hack: GValue array items do not get slice
471                      * allocated in _pygi_marshal_from_py_array(), so we must
472                      * not try to deallocate it as a slice and thus
473                      * short-circuit cleanup_func. */
474                     if (cleanup_func == pygi_arg_gvalue_from_py_cleanup) {
475                         g_value_unset ((GValue*) item);
476                         continue;
477                     }
478                 }
479
480                 py_item = PySequence_GetItem (py_arg, i);
481                 cleanup_func (state, sequence_cache->item_cache, py_item, item, TRUE);
482                 Py_XDECREF (py_item);
483             }
484         }
485
486         /* Only free the array when we didn't transfer ownership */
487         if (array_cache->array_type == GI_ARRAY_TYPE_C) {
488             /* always free the GArray wrapper created in from_py marshaling and
489              * passed back as cleanup_data
490              */
491             g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING);
492         } else {
493             if (array_ != NULL)
494                 g_array_unref (array_);
495             else
496                 g_ptr_array_unref (ptr_array_);
497         }
498     }
499 }
500
501 /*
502  * GArray from Python
503  */
504 static PyObject *
505 _pygi_marshal_to_py_array (PyGIInvokeState   *state,
506                            PyGICallableCache *callable_cache,
507                            PyGIArgCache      *arg_cache,
508                            GIArgument        *arg)
509 {
510     GArray *array_;
511     PyObject *py_obj = NULL;
512     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
513     PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
514     gsize processed_items = 0;
515
516      /* GArrays make it easier to iterate over arrays
517       * with different element sizes but requires that
518       * we allocate a GArray if the argument was a C array
519       */
520     if (array_cache->array_type == GI_ARRAY_TYPE_C) {
521         gsize len;
522         if (array_cache->fixed_size >= 0) {
523             g_assert(arg->v_pointer != NULL);
524             len = array_cache->fixed_size;
525         } else if (array_cache->is_zero_terminated) {
526             if (arg->v_pointer == NULL) {
527                 len = 0;
528             } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
529                 len = strlen (arg->v_pointer);
530             } else {
531                 len = g_strv_length ((gchar **)arg->v_pointer);
532             }
533         } else {
534             GIArgument *len_arg = &state->args[array_cache->len_arg_index].arg_value;
535             PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache,
536                                                                     array_cache->len_arg_index);
537
538             if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) {
539                 return NULL;
540             }
541         }
542
543         array_ = g_array_new (FALSE,
544                               FALSE,
545                               array_cache->item_size);
546         if (array_ == NULL) {
547             PyErr_NoMemory ();
548
549             if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL)
550                 g_free (arg->v_pointer);
551
552             return NULL;
553         }
554
555         if (array_->data != NULL)
556             g_free (array_->data);
557         array_->data = arg->v_pointer;
558         array_->len = len;
559     } else {
560         array_ = arg->v_pointer;
561     }
562
563     if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
564         if (arg->v_pointer == NULL) {
565             py_obj = PYGLIB_PyBytes_FromString ("");
566         } else {
567             py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len);
568         }
569     } else {
570         if (arg->v_pointer == NULL) {
571             py_obj = PyList_New (0);
572         } else {
573             int i;
574
575             gsize item_size;
576             PyGIMarshalToPyFunc item_to_py_marshaller;
577             PyGIArgCache *item_arg_cache;
578
579             py_obj = PyList_New (array_->len);
580             if (py_obj == NULL)
581                 goto err;
582
583
584             item_arg_cache = seq_cache->item_cache;
585             item_to_py_marshaller = item_arg_cache->to_py_marshaller;
586
587             item_size = g_array_get_element_size (array_);
588
589             for (i = 0; i < array_->len; i++) {
590                 GIArgument item_arg = {0};
591                 PyObject *py_item;
592
593                 /* If we are receiving an array of pointers, simply assign the pointer
594                  * and move on, letting the per-item marshaler deal with the
595                  * various transfer modes and ref counts (e.g. g_variant_ref_sink).
596                  */
597                 if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
598                     item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
599
600                 } else if (item_arg_cache->is_pointer) {
601                     item_arg.v_pointer = g_array_index (array_, gpointer, i);
602
603                 } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
604                     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
605
606                     /* FIXME: This probably doesn't work with boxed types or gvalues.
607                      * See fx. _pygi_marshal_from_py_array() */
608                     switch (g_base_info_get_type (iface_cache->interface_info)) {
609                         case GI_INFO_TYPE_STRUCT:
610                             if (arg_cache->transfer == GI_TRANSFER_EVERYTHING &&
611                                        !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
612                                 /* array elements are structs */
613                                 gpointer *_struct = g_malloc (item_size);
614                                 memcpy (_struct, array_->data + i * item_size,
615                                         item_size);
616                                 item_arg.v_pointer = _struct;
617                             } else {
618                                 item_arg.v_pointer = array_->data + i * item_size;
619                             }
620                             break;
621                         default:
622                             item_arg.v_pointer = g_array_index (array_, gpointer, i);
623                             break;
624                     }
625                 } else {
626                     memcpy (&item_arg, array_->data + i * item_size, item_size);
627                 }
628
629                 py_item = item_to_py_marshaller ( state,
630                                                 callable_cache,
631                                                 item_arg_cache,
632                                                 &item_arg);
633
634                 if (py_item == NULL) {
635                     Py_CLEAR (py_obj);
636
637                     if (array_cache->array_type == GI_ARRAY_TYPE_C)
638                         g_array_unref (array_);
639
640                     goto err;
641                 }
642                 PyList_SET_ITEM (py_obj, i, py_item);
643                 processed_items++;
644             }
645         }
646     }
647
648     if (array_cache->array_type == GI_ARRAY_TYPE_C)
649         g_array_free (array_, FALSE);
650
651     return py_obj;
652
653 err:
654     if (array_cache->array_type == GI_ARRAY_TYPE_C) {
655         g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
656     } else {
657         /* clean up unprocessed items */
658         if (seq_cache->item_cache->to_py_cleanup != NULL) {
659             int j;
660             PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup;
661             for (j = processed_items; j < array_->len; j++) {
662                 cleanup_func (state,
663                               seq_cache->item_cache,
664                               NULL,
665                               g_array_index (array_, gpointer, j),
666                               FALSE);
667             }
668         }
669
670         if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
671             g_array_free (array_, TRUE);
672     }
673
674     return NULL;
675 }
676
677 static GArray*
678 _wrap_c_array (PyGIInvokeState   *state,
679                PyGIArgGArray     *array_cache,
680                gpointer           data)
681 {
682     GArray *array_;
683     gsize   len = 0;
684
685     if (array_cache->fixed_size >= 0) {
686         len = array_cache->fixed_size;
687     } else if (array_cache->is_zero_terminated) {
688         len = g_strv_length ((gchar **)data);
689     } else if (array_cache->len_arg_index >= 0) {
690         GIArgument *len_arg = &state->args[array_cache->len_arg_index].arg_value;
691         len = len_arg->v_long;
692     }
693
694     array_ = g_array_new (FALSE,
695                           FALSE,
696                           array_cache->item_size);
697
698     if (array_ == NULL)
699         return NULL;
700
701     g_free (array_->data);
702     array_->data = data;
703     array_->len = len;
704
705     return array_;
706 }
707
708 static void
709 _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
710                                    PyGIArgCache    *arg_cache,
711                                    PyObject        *dummy,
712                                    gpointer         data,
713                                    gboolean         was_processed)
714 {
715     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING ||
716         arg_cache->transfer == GI_TRANSFER_CONTAINER) {
717         GArray *array_ = NULL;
718         GPtrArray *ptr_array_ = NULL;
719         PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
720         PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
721
722         /* If this isn't a garray create one to help process variable sized
723            array elements */
724         if (array_cache->array_type == GI_ARRAY_TYPE_C) {
725             array_ = _wrap_c_array (state, array_cache, data);
726
727             if (array_ == NULL)
728                 return;
729
730         } else if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
731             ptr_array_ = (GPtrArray *) data;
732         } else {
733             array_ = (GArray *) data;
734         }
735
736         if (sequence_cache->item_cache->to_py_cleanup != NULL) {
737             gsize i;
738             guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
739
740             PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup;
741             for (i = 0; i < len; i++) {
742                 cleanup_func (state,
743                               sequence_cache->item_cache,
744                               NULL,
745                               (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i),
746                               was_processed);
747             }
748         }
749
750         if (array_ != NULL)
751             g_array_free (array_, TRUE);
752         else
753             g_ptr_array_free (ptr_array_, TRUE);
754     }
755 }
756
757 static void
758 _array_cache_free_func (PyGIArgGArray *cache)
759 {
760     if (cache != NULL) {
761         pygi_arg_cache_free (((PyGISequenceCache *)cache)->item_cache);
762         g_slice_free (PyGIArgGArray, cache);
763     }
764 }
765
766 PyGIArgCache*
767 pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache,
768                                GITypeInfo *type_info,
769                                PyGICallableCache *callable_cache,
770                                PyGIDirection direction,
771                                gssize arg_index,
772                                gssize *py_arg_index)
773 {
774     PyGIArgGArray *seq_cache = (PyGIArgGArray *)arg_cache;
775
776     /* attempt len_arg_index setup for the first time */
777     if (seq_cache->len_arg_index < 0) {
778         seq_cache->len_arg_index = g_type_info_get_array_length (type_info);
779
780         /* offset by self arg for methods and vfuncs */
781         if (seq_cache->len_arg_index >= 0 && callable_cache != NULL) {
782             seq_cache->len_arg_index += callable_cache->args_offset;
783         }
784     }
785
786     if (seq_cache->len_arg_index >= 0) {
787         PyGIArgCache *child_cache = NULL;
788
789         child_cache = _pygi_callable_cache_get_arg (callable_cache,
790                                                     seq_cache->len_arg_index);
791         if (child_cache == NULL) {
792             child_cache = pygi_arg_cache_alloc ();
793         } else {
794             /* If the "length" arg cache already exists (the length comes before
795              * the array in the argument list), remove it from the to_py_args list
796              * because it does not belong in "to python" return tuple. The length
797              * will implicitly be a part of the returned Python list.
798              */
799             if (direction & PYGI_DIRECTION_TO_PYTHON) {
800                 callable_cache->to_py_args =
801                     g_slist_remove (callable_cache->to_py_args, child_cache);
802             }
803
804             /* This is a case where the arg cache already exists and has been
805              * setup by another array argument sharing the same length argument.
806              * See: gi_marshalling_tests_multi_array_key_value_in
807              */
808             if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
809                 return child_cache;
810         }
811
812         /* There is a length argument for this array, so increment the number
813          * of "to python" child arguments when applicable.
814          */
815         if (direction & PYGI_DIRECTION_TO_PYTHON)
816              callable_cache->n_to_py_child_args++;
817
818         child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
819         child_cache->direction = direction;
820         child_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
821         child_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
822         child_cache->py_arg_index = -1;
823
824         /* ugly edge case code:
825          *
826          * When the length comes before the array parameter we need to update
827          * indexes of arguments after the index argument.
828          */
829         if (seq_cache->len_arg_index < arg_index && direction & PYGI_DIRECTION_FROM_PYTHON) {
830             gssize i;
831             (*py_arg_index) -= 1;
832             callable_cache->n_py_args -= 1;
833
834             for (i = seq_cache->len_arg_index + 1;
835                    i < _pygi_callable_cache_args_len (callable_cache); i++) {
836                 PyGIArgCache *update_cache = _pygi_callable_cache_get_arg (callable_cache, i);
837                 if (update_cache == NULL)
838                     break;
839
840                 update_cache->py_arg_index -= 1;
841             }
842         }
843
844         _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache);
845         return child_cache;
846     }
847
848     return NULL;
849 }
850
851 static gboolean
852 pygi_arg_garray_setup (PyGIArgGArray     *sc,
853                        GITypeInfo        *type_info,
854                        GIArgInfo         *arg_info,    /* may be NULL for return arguments */
855                        GITransfer         transfer,
856                        PyGIDirection      direction,
857                        PyGICallableCache *callable_cache)
858 {
859     GITypeInfo *item_type_info;
860     PyGIArgCache *arg_cache = (PyGIArgCache *)sc;
861
862     if (!pygi_arg_sequence_setup ((PyGISequenceCache *)sc,
863                                   type_info,
864                                   arg_info,
865                                   transfer,
866                                   direction,
867                                   callable_cache)) {
868         return FALSE;
869     }
870
871     ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_array_cache_free_func;
872     sc->array_type = g_type_info_get_array_type (type_info);
873     sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info);
874     sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
875     sc->len_arg_index = -1;  /* setup by pygi_arg_garray_len_arg_setup */
876
877     item_type_info = g_type_info_get_param_type (type_info, 0);
878     sc->item_size = _pygi_g_type_info_size (item_type_info);
879     g_base_info_unref ( (GIBaseInfo *)item_type_info);
880
881     if (direction & PYGI_DIRECTION_FROM_PYTHON) {
882         arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
883         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
884     }
885
886     if (direction & PYGI_DIRECTION_TO_PYTHON) {
887         arg_cache->to_py_marshaller = _pygi_marshal_to_py_array;
888         arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array;
889     }
890
891     return TRUE;
892 }
893
894 PyGIArgCache *
895 pygi_arg_garray_new_from_info (GITypeInfo *type_info,
896                                GIArgInfo *arg_info,
897                                GITransfer transfer,
898                                PyGIDirection direction,
899                                PyGICallableCache *callable_cache)
900 {
901     PyGIArgGArray *array_cache = g_slice_new0 (PyGIArgGArray);
902     if (array_cache == NULL)
903         return NULL;
904
905     if (!pygi_arg_garray_setup (array_cache,
906                                 type_info,
907                                 arg_info,
908                                 transfer,
909                                 direction,
910                                 callable_cache)) {
911         pygi_arg_cache_free ( (PyGIArgCache *)array_cache);
912         return NULL;
913     }
914
915     return (PyGIArgCache *)array_cache;
916 }