5c344674a2f5eb4eda6a9392388fff01a9a6d52a
[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-private.h"
27 #include "pygi-marshal-cleanup.h"
28 #include "pygi-basictype.h"
29
30 /* Needed for _pygi_marshal_cleanup_from_py_interface_struct_gvalue hack */
31 #include "pygi-struct-marshal.h"
32
33 /*
34  * GArray to Python
35  */
36
37 static gboolean
38 gi_argument_from_py_ssize_t (GIArgument   *arg_out,
39                              Py_ssize_t    size_in,
40                              GITypeTag     type_tag)
41 {
42     switch (type_tag) {
43     case GI_TYPE_TAG_VOID:
44     case GI_TYPE_TAG_BOOLEAN:
45         goto unhandled_type;
46
47     case GI_TYPE_TAG_INT8:
48         if (size_in >= G_MININT8 && size_in <= G_MAXINT8) {
49             arg_out->v_int8 = size_in;
50             return TRUE;
51         } else {
52             goto overflow;
53         }
54
55     case GI_TYPE_TAG_UINT8:
56         if (size_in >= 0 && size_in <= G_MAXUINT8) {
57             arg_out->v_uint8 = size_in;
58             return TRUE;
59         } else {
60             goto overflow;
61         }
62
63     case GI_TYPE_TAG_INT16:
64         if (size_in >= G_MININT16 && size_in <= G_MAXINT16) {
65             arg_out->v_int16 = size_in;
66             return TRUE;
67         } else {
68             goto overflow;
69         }
70
71     case GI_TYPE_TAG_UINT16:
72         if (size_in >= 0 && size_in <= G_MAXUINT16) {
73             arg_out->v_uint16 = size_in;
74             return TRUE;
75         } else {
76             goto overflow;
77         }
78
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;
83             return TRUE;
84         } else {
85             goto overflow;
86         }
87
88     case GI_TYPE_TAG_UINT32:
89         if (size_in >= 0 && size_in <= G_MAXUINT32) {
90             arg_out->v_uint32 = size_in;
91             return TRUE;
92         } else {
93             goto overflow;
94         }
95
96     case GI_TYPE_TAG_INT64:
97         arg_out->v_int64 = size_in;
98         return TRUE;
99
100     case GI_TYPE_TAG_UINT64:
101         if (size_in >= 0) {
102             arg_out->v_uint64 = size_in;
103             return TRUE;
104         } else {
105             goto overflow;
106         }
107
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:
120     default:
121         goto unhandled_type;
122     }
123
124  overflow:
125     PyErr_Format (PyExc_OverflowError,
126                   "Unable to marshal C Py_ssize_t %zd to %s",
127                   size_in,
128                   g_type_tag_to_string (type_tag));
129     return FALSE;
130
131  unhandled_type:
132     PyErr_Format (PyExc_TypeError,
133                   "Unable to marshal C Py_ssize_t %zd to %s",
134                   size_in,
135                   g_type_tag_to_string (type_tag));
136     return FALSE;
137 }
138
139 static gboolean
140 gi_argument_to_gsize (GIArgument *arg_in,
141                       gsize      *gsize_out,
142                       GITypeTag   type_tag)
143 {
144     switch (type_tag) {
145       case GI_TYPE_TAG_INT8:
146           *gsize_out = arg_in->v_int8;
147           return TRUE;
148       case GI_TYPE_TAG_UINT8:
149           *gsize_out = arg_in->v_uint8;
150           return TRUE;
151       case GI_TYPE_TAG_INT16:
152           *gsize_out = arg_in->v_int16;
153           return TRUE;
154       case GI_TYPE_TAG_UINT16:
155           *gsize_out = arg_in->v_uint16;
156           return TRUE;
157       case GI_TYPE_TAG_INT32:
158           *gsize_out = arg_in->v_int32;
159           return TRUE;
160       case GI_TYPE_TAG_UINT32:
161           *gsize_out = arg_in->v_uint32;
162           return TRUE;
163       case GI_TYPE_TAG_INT64:
164           *gsize_out = arg_in->v_int64;
165           return TRUE;
166       case GI_TYPE_TAG_UINT64:
167           *gsize_out = arg_in->v_uint64;
168           return TRUE;
169       default:
170           PyErr_Format (PyExc_TypeError,
171                         "Unable to marshal %s to gsize",
172                         g_type_tag_to_string (type_tag));
173           return FALSE;
174     }
175 }
176
177 static gboolean
178 _pygi_marshal_from_py_array (PyGIInvokeState   *state,
179                              PyGICallableCache *callable_cache,
180                              PyGIArgCache      *arg_cache,
181                              PyObject          *py_arg,
182                              GIArgument        *arg,
183                              gpointer          *cleanup_data)
184 {
185     PyGIMarshalFromPyFunc from_py_marshaller;
186     int i = 0;
187     int success_count = 0;
188     Py_ssize_t length;
189     gssize item_size;
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;
195
196
197     if (py_arg == Py_None) {
198         arg->v_pointer = NULL;
199         return TRUE;
200     }
201
202     if (!PySequence_Check (py_arg)) {
203         PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
204                       py_arg->ob_type->tp_name);
205         return FALSE;
206     }
207
208     length = PySequence_Length (py_arg);
209     if (length < 0)
210         return FALSE;
211
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);
216
217         return FALSE;
218     }
219
220     item_size = array_cache->item_size;
221     is_ptr_array = (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
222     if (is_ptr_array) {
223         array_ = (GArray *)g_ptr_array_sized_new (length);
224     } else {
225         array_ = g_array_sized_new (array_cache->is_zero_terminated,
226                                     TRUE,
227                                     item_size,
228                                     length);
229     }
230
231     if (array_ == NULL) {
232         PyErr_NoMemory ();
233         return FALSE;
234     }
235
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);
239
240         /* Avoid making a copy if the data
241          * is not transferred to the C function
242          * and cannot not be modified by it.
243          */
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);
248             array_->data = data;
249             cleanup_transfer = GI_TRANSFER_EVERYTHING;
250         } else {
251             memcpy (array_->data, data, length);
252         }
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';
258         }
259         goto array_success;
260     }
261
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);
267         if (py_item == NULL)
268             goto err;
269
270         if (!from_py_marshaller ( state,
271                                   callable_cache,
272                                   sequence_cache->item_cache,
273                                   py_item,
274                                  &item,
275                                  &item_cleanup_data)) {
276             Py_DECREF (py_item);
277             goto err;
278         }
279         Py_DECREF (py_item);
280
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.
289              */
290             PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to "
291                                                 "the items data its cleanup data being different.");
292             goto err;
293         }
294
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
298          */
299         if (is_ptr_array) {
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);
310
311             switch (info_type) {
312                 case GI_INFO_TYPE_UNION:
313                 case GI_INFO_TYPE_STRUCT:
314                 {
315                     PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache;
316                     PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
317
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);
325                         }
326                         /* Manually increment the length because we are manually setting the memory. */
327                         array_->len++;
328
329                     } else {
330                         /* Handles flat arrays of boxed or struct types. */
331                         g_array_insert_vals (array_, i, item.v_pointer, 1);
332                     }
333
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.
337                      */
338                     if (from_py_cleanup)
339                         from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE);
340
341                     break;
342                 }
343                 default:
344                     g_array_insert_val (array_, i, item);
345             }
346         } else {
347             /* default value copy of a simple type */
348             g_array_insert_val (array_, i, item);
349         }
350
351         success_count++;
352         continue;
353 err:
354         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
355             gsize j;
356             PyGIMarshalCleanupFunc cleanup_func =
357                 sequence_cache->item_cache->from_py_cleanup;
358
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);
363                     cleanup_func (state,
364                                   sequence_cache->item_cache,
365                                   py_item,
366                                   is_ptr_array ?
367                                           g_ptr_array_index ((GPtrArray *)array_, j) :
368                                           g_array_index (array_, gpointer, j),
369                                   TRUE);
370                     Py_DECREF (py_item);
371                 }
372             }
373         }
374
375         if (is_ptr_array)
376             g_ptr_array_free ( ( GPtrArray *)array_, TRUE);
377         else
378             g_array_free (array_, TRUE);
379         _PyGI_ERROR_PREFIX ("Item %i: ", i);
380         return FALSE;
381     }
382
383 array_success:
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);
388
389         if (!gi_argument_from_py_ssize_t (&state->args[child_cache->c_arg_index].arg_value,
390                                           length,
391                                           child_cache->type_tag)) {
392             goto err;
393         }
394     }
395
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
399          * it's length again.
400          */
401         arg->v_pointer = array_->data;
402
403         if (cleanup_transfer == GI_TRANSFER_EVERYTHING) {
404             g_array_free (array_, FALSE);
405             *cleanup_data = NULL;
406         } else {
407             *cleanup_data = array_;
408         }
409     } else {
410         arg->v_pointer = array_;
411
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;
424         }
425     }
426
427     return TRUE;
428 }
429
430 static void
431 _pygi_marshal_cleanup_from_py_array (PyGIInvokeState *state,
432                                      PyGIArgCache    *arg_cache,
433                                      PyObject        *py_arg,
434                                      gpointer         data,
435                                      gboolean         was_processed)
436 {
437     if (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;
442
443         if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
444             ptr_array_ = (GPtrArray *) data;
445         } else {
446             array_ = (GArray *) data;
447         }
448
449         /* clean up items first */
450         if (sequence_cache->item_cache->from_py_cleanup != NULL) {
451             gsize i;
452             guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
453             PyGIMarshalCleanupFunc cleanup_func =
454                 sequence_cache->item_cache->from_py_cleanup;
455
456             for (i = 0; i < len; i++) {
457                 gpointer item;
458                 PyObject *py_item = NULL;
459
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 */
467                 else {
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);
475                         continue;
476                     }
477                 }
478
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);
482             }
483         }
484
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
489              */
490             g_array_free (array_, arg_cache->transfer == GI_TRANSFER_NOTHING);
491         } else {
492             if (array_ != NULL)
493                 g_array_unref (array_);
494             else
495                 g_ptr_array_unref (ptr_array_);
496         }
497     }
498 }
499
500 /*
501  * GArray from Python
502  */
503 static PyObject *
504 _pygi_marshal_to_py_array (PyGIInvokeState   *state,
505                            PyGICallableCache *callable_cache,
506                            PyGIArgCache      *arg_cache,
507                            GIArgument        *arg)
508 {
509     GArray *array_;
510     PyObject *py_obj = NULL;
511     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
512     PyGIArgGArray *array_cache = (PyGIArgGArray *)arg_cache;
513     gsize processed_items = 0;
514
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
518       */
519     if (array_cache->array_type == GI_ARRAY_TYPE_C) {
520         gsize len;
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) {
526                 len = 0;
527             } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
528                 len = strlen (arg->v_pointer);
529             } else {
530                 len = g_strv_length ((gchar **)arg->v_pointer);
531             }
532         } else {
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);
536
537             if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) {
538                 return NULL;
539             }
540         }
541
542         array_ = g_array_new (FALSE,
543                               FALSE,
544                               array_cache->item_size);
545         if (array_ == NULL) {
546             PyErr_NoMemory ();
547
548             if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL)
549                 g_free (arg->v_pointer);
550
551             return NULL;
552         }
553
554         if (array_->data != NULL)
555             g_free (array_->data);
556         array_->data = arg->v_pointer;
557         array_->len = len;
558     } else {
559         array_ = arg->v_pointer;
560     }
561
562     if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
563         if (arg->v_pointer == NULL) {
564             py_obj = PYGLIB_PyBytes_FromString ("");
565         } else {
566             py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len);
567         }
568     } else {
569         if (arg->v_pointer == NULL) {
570             py_obj = PyList_New (0);
571         } else {
572             int i;
573
574             gsize item_size;
575             PyGIMarshalToPyFunc item_to_py_marshaller;
576             PyGIArgCache *item_arg_cache;
577
578             py_obj = PyList_New (array_->len);
579             if (py_obj == NULL)
580                 goto err;
581
582
583             item_arg_cache = seq_cache->item_cache;
584             item_to_py_marshaller = item_arg_cache->to_py_marshaller;
585
586             item_size = g_array_get_element_size (array_);
587
588             for (i = 0; i < array_->len; i++) {
589                 GIArgument item_arg = {0};
590                 PyObject *py_item;
591
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).
595                  */
596                 if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
597                     item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
598
599                 } else if (item_arg_cache->is_pointer) {
600                     item_arg.v_pointer = g_array_index (array_, gpointer, i);
601
602                 } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
603                     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
604
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,
614                                         item_size);
615                                 item_arg.v_pointer = _struct;
616                             } else {
617                                 item_arg.v_pointer = array_->data + i * item_size;
618                             }
619                             break;
620                         default:
621                             item_arg.v_pointer = g_array_index (array_, gpointer, i);
622                             break;
623                     }
624                 } else {
625                     memcpy (&item_arg, array_->data + i * item_size, item_size);
626                 }
627
628                 py_item = item_to_py_marshaller ( state,
629                                                 callable_cache,
630                                                 item_arg_cache,
631                                                 &item_arg);
632
633                 if (py_item == NULL) {
634                     Py_CLEAR (py_obj);
635
636                     if (array_cache->array_type == GI_ARRAY_TYPE_C)
637                         g_array_unref (array_);
638
639                     goto err;
640                 }
641                 PyList_SET_ITEM (py_obj, i, py_item);
642                 processed_items++;
643             }
644         }
645     }
646
647     if (array_cache->array_type == GI_ARRAY_TYPE_C)
648         g_array_free (array_, FALSE);
649
650     return py_obj;
651
652 err:
653     if (array_cache->array_type == GI_ARRAY_TYPE_C) {
654         g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
655     } else {
656         /* clean up unprocessed items */
657         if (seq_cache->item_cache->to_py_cleanup != NULL) {
658             int j;
659             PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup;
660             for (j = processed_items; j < array_->len; j++) {
661                 cleanup_func (state,
662                               seq_cache->item_cache,
663                               NULL,
664                               g_array_index (array_, gpointer, j),
665                               FALSE);
666             }
667         }
668
669         if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
670             g_array_free (array_, TRUE);
671     }
672
673     return NULL;
674 }
675
676 static GArray*
677 _wrap_c_array (PyGIInvokeState   *state,
678                PyGIArgGArray     *array_cache,
679                gpointer           data)
680 {
681     GArray *array_;
682     gsize   len = 0;
683
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;
691     }
692
693     array_ = g_array_new (FALSE,
694                           FALSE,
695                           array_cache->item_size);
696
697     if (array_ == NULL)
698         return NULL;
699
700     g_free (array_->data);
701     array_->data = data;
702     array_->len = len;
703
704     return array_;
705 }
706
707 static void
708 _pygi_marshal_cleanup_to_py_array (PyGIInvokeState *state,
709                                    PyGIArgCache    *arg_cache,
710                                    PyObject        *dummy,
711                                    gpointer         data,
712                                    gboolean         was_processed)
713 {
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;
720
721         /* If this isn't a garray create one to help process variable sized
722            array elements */
723         if (array_cache->array_type == GI_ARRAY_TYPE_C) {
724             array_ = _wrap_c_array (state, array_cache, data);
725
726             if (array_ == NULL)
727                 return;
728
729         } else if (array_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
730             ptr_array_ = (GPtrArray *) data;
731         } else {
732             array_ = (GArray *) data;
733         }
734
735         if (sequence_cache->item_cache->to_py_cleanup != NULL) {
736             gsize i;
737             guint len = (array_ != NULL) ? array_->len : ptr_array_->len;
738
739             PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->to_py_cleanup;
740             for (i = 0; i < len; i++) {
741                 cleanup_func (state,
742                               sequence_cache->item_cache,
743                               NULL,
744                               (array_ != NULL) ? g_array_index (array_, gpointer, i) : g_ptr_array_index (ptr_array_, i),
745                               was_processed);
746             }
747         }
748
749         if (array_ != NULL)
750             g_array_free (array_, TRUE);
751         else
752             g_ptr_array_free (ptr_array_, TRUE);
753     }
754 }
755
756 static void
757 _array_cache_free_func (PyGIArgGArray *cache)
758 {
759     if (cache != NULL) {
760         pygi_arg_cache_free (((PyGISequenceCache *)cache)->item_cache);
761         g_slice_free (PyGIArgGArray, cache);
762     }
763 }
764
765 PyGIArgCache*
766 pygi_arg_garray_len_arg_setup (PyGIArgCache *arg_cache,
767                                GITypeInfo *type_info,
768                                PyGICallableCache *callable_cache,
769                                PyGIDirection direction,
770                                gssize arg_index,
771                                gssize *py_arg_index)
772 {
773     PyGIArgGArray *seq_cache = (PyGIArgGArray *)arg_cache;
774
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);
778
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;
782         }
783     }
784
785     if (seq_cache->len_arg_index >= 0) {
786         PyGIArgCache *child_cache = NULL;
787
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 ();
792         } else {
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.
797              */
798             if (direction & PYGI_DIRECTION_TO_PYTHON) {
799                 callable_cache->to_py_args =
800                     g_slist_remove (callable_cache->to_py_args, child_cache);
801             }
802
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
806              */
807             if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
808                 return child_cache;
809         }
810
811         /* There is a length argument for this array, so increment the number
812          * of "to python" child arguments when applicable.
813          */
814         if (direction & PYGI_DIRECTION_TO_PYTHON)
815              callable_cache->n_to_py_child_args++;
816
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;
822
823         /* ugly edge case code:
824          *
825          * When the length comes before the array parameter we need to update
826          * indexes of arguments after the index argument.
827          */
828         if (seq_cache->len_arg_index < arg_index && direction & PYGI_DIRECTION_FROM_PYTHON) {
829             gssize i;
830             (*py_arg_index) -= 1;
831             callable_cache->n_py_args -= 1;
832
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)
837                     break;
838
839                 update_cache->py_arg_index -= 1;
840             }
841         }
842
843         _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache);
844         return child_cache;
845     }
846
847     return NULL;
848 }
849
850 static gboolean
851 pygi_arg_garray_setup (PyGIArgGArray     *sc,
852                        GITypeInfo        *type_info,
853                        GIArgInfo         *arg_info,    /* may be NULL for return arguments */
854                        GITransfer         transfer,
855                        PyGIDirection      direction,
856                        PyGICallableCache *callable_cache)
857 {
858     GITypeInfo *item_type_info;
859     PyGIArgCache *arg_cache = (PyGIArgCache *)sc;
860
861     if (!pygi_arg_sequence_setup ((PyGISequenceCache *)sc,
862                                   type_info,
863                                   arg_info,
864                                   transfer,
865                                   direction,
866                                   callable_cache)) {
867         return FALSE;
868     }
869
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 */
875
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);
879
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;
883     }
884
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;
888     }
889
890     return TRUE;
891 }
892
893 PyGIArgCache *
894 pygi_arg_garray_new_from_info (GITypeInfo *type_info,
895                                GIArgInfo *arg_info,
896                                GITransfer transfer,
897                                PyGIDirection direction,
898                                PyGICallableCache *callable_cache)
899 {
900     PyGIArgGArray *array_cache = g_slice_new0 (PyGIArgGArray);
901     if (array_cache == NULL)
902         return NULL;
903
904     if (!pygi_arg_garray_setup (array_cache,
905                                 type_info,
906                                 arg_info,
907                                 transfer,
908                                 direction,
909                                 callable_cache)) {
910         pygi_arg_cache_free ( (PyGIArgCache *)array_cache);
911         return NULL;
912     }
913
914     return (PyGIArgCache *)array_cache;
915 }