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