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