Imported Upstream version 3.3.1
[platform/upstream/pygobject2.git] / gi / pygi-cache.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  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19  * USA
20  */
21
22 #include "pygi-info.h"
23 #include "pygi-cache.h"
24 #include "pygi-marshal-to-py.h"
25 #include "pygi-marshal-from-py.h"
26 #include "pygi-marshal-cleanup.h"
27 #include "pygi-type.h"
28 #include <girepository.h>
29
30 PyGIArgCache * _arg_cache_new (GITypeInfo *type_info,
31                                PyGICallableCache *callable_cache,
32                                GIArgInfo *arg_info,
33                                GITransfer transfer,
34                                PyGIDirection direction,
35                                gssize c_arg_index,
36                                gssize py_arg_index);
37
38 PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
39                                              PyGICallableCache *callable_cache,
40                                              GIArgInfo *arg_info,
41                                              GITransfer transfer,
42                                              PyGIDirection direction,
43                                              gssize c_arg_index,
44                                              gssize py_arg_index);
45 /* cleanup */
46 void
47 _pygi_arg_cache_free (PyGIArgCache *cache)
48 {
49     if (cache == NULL)
50         return;
51
52     if (cache->type_info != NULL)
53         g_base_info_unref ( (GIBaseInfo *)cache->type_info);
54     if (cache->destroy_notify)
55         cache->destroy_notify (cache);
56     else
57         g_slice_free (PyGIArgCache, cache);
58 }
59
60 static void
61 _interface_cache_free_func (PyGIInterfaceCache *cache)
62 {
63     if (cache != NULL) {
64         Py_XDECREF (cache->py_type);
65         if (cache->type_name != NULL)
66             g_free (cache->type_name);
67         if (cache->interface_info != NULL)
68             g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
69         g_slice_free (PyGIInterfaceCache, cache);
70     }
71 }
72
73 static void
74 _hash_cache_free_func (PyGIHashCache *cache)
75 {
76     if (cache != NULL) {
77         _pygi_arg_cache_free (cache->key_cache);
78         _pygi_arg_cache_free (cache->value_cache);
79         g_slice_free (PyGIHashCache, cache);
80     }
81 }
82
83 static void
84 _sequence_cache_free_func (PyGISequenceCache *cache)
85 {
86     if (cache != NULL) {
87         _pygi_arg_cache_free (cache->item_cache);
88         g_slice_free (PyGISequenceCache, cache);
89     }
90 }
91
92 static void
93 _callback_cache_free_func (PyGICallbackCache *cache)
94 {
95     if (cache != NULL) {
96         if (cache->interface_info != NULL)
97             g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
98
99         g_slice_free (PyGICallbackCache, cache);
100     }
101 }
102
103 void
104 _pygi_callable_cache_free (PyGICallableCache *cache)
105 {
106     gssize i;
107
108     if (cache == NULL)
109         return;
110
111     g_slist_free (cache->to_py_args);
112     g_slist_free (cache->arg_name_list);
113     g_hash_table_destroy (cache->arg_name_hash);
114
115     for (i = 0; i < cache->n_args; i++) {
116         PyGIArgCache *tmp = cache->args_cache[i];
117         _pygi_arg_cache_free (tmp);
118     }
119     if (cache->return_cache != NULL)
120         _pygi_arg_cache_free (cache->return_cache);
121
122     g_slice_free1 (cache->n_args * sizeof (PyGIArgCache *), cache->args_cache);
123     g_slice_free (PyGICallableCache, cache);
124 }
125
126 /* cache generation */
127
128 static PyGIInterfaceCache *
129 _interface_cache_new (GIInterfaceInfo *iface_info)
130 {
131     PyGIInterfaceCache *ic;
132
133     ic = g_slice_new0 (PyGIInterfaceCache);
134     ( (PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
135     ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
136     ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
137
138     if (ic->py_type == NULL)
139         return NULL;
140
141     ic->type_name = _pygi_g_base_info_get_fullname (iface_info);
142     return ic;
143 }
144
145 static PyGISequenceCache *
146 _sequence_cache_new (GITypeInfo *type_info,
147                      GIDirection direction,
148                      GITransfer transfer,
149                      gssize child_offset)
150 {
151     PyGISequenceCache *sc;
152     GITypeInfo *item_type_info;
153     GITransfer item_transfer;
154
155     sc = g_slice_new0 (PyGISequenceCache);
156     ( (PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
157
158     sc->fixed_size = -1;
159     sc->len_arg_index = -1;
160     sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info);
161     if (!sc->is_zero_terminated) {
162         sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
163         if (sc->fixed_size < 0)
164             sc->len_arg_index = g_type_info_get_array_length (type_info);
165             if (sc->len_arg_index >= 0)
166                 sc->len_arg_index += child_offset;
167     }
168
169     item_type_info = g_type_info_get_param_type (type_info, 0);
170
171     item_transfer =
172         transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
173
174     sc->item_cache = _arg_cache_new (item_type_info,
175                                      NULL,
176                                      NULL,
177                                      item_transfer,
178                                      direction,
179                                      0, 0);
180
181     if (sc->item_cache == NULL) {
182         _pygi_arg_cache_free ( (PyGIArgCache *)sc);
183         return NULL;
184     }
185
186     sc->item_size = _pygi_g_type_info_size (item_type_info);
187     g_base_info_unref ( (GIBaseInfo *)item_type_info);
188
189     return sc;
190 }
191 static PyGIHashCache *
192 _hash_cache_new (GITypeInfo *type_info,
193                  GIDirection direction,
194                  GITransfer transfer)
195 {
196     PyGIHashCache *hc;
197     GITypeInfo *key_type_info;
198     GITypeInfo *value_type_info;
199     GITransfer item_transfer;
200
201     hc = g_slice_new0 (PyGIHashCache);
202     ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func;
203     key_type_info = g_type_info_get_param_type (type_info, 0);
204     value_type_info = g_type_info_get_param_type (type_info, 1);
205
206     item_transfer =
207         transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
208
209     hc->key_cache = _arg_cache_new (key_type_info,
210                                     NULL,
211                                     NULL,
212                                     item_transfer,
213                                     direction,
214                                     0, 0);
215
216     if (hc->key_cache == NULL) {
217         _pygi_arg_cache_free ( (PyGIArgCache *)hc);
218         return NULL;
219     }
220
221     hc->value_cache = _arg_cache_new (value_type_info,
222                                       NULL,
223                                       NULL,
224                                       item_transfer,
225                                       direction,
226                                       0, 0);
227
228     if (hc->value_cache == NULL) {
229         _pygi_arg_cache_free ( (PyGIArgCache *)hc);
230         return NULL;
231     }
232
233     g_base_info_unref( (GIBaseInfo *)key_type_info);
234     g_base_info_unref( (GIBaseInfo *)value_type_info);
235
236     return hc;
237 }
238
239 static PyGICallbackCache *
240 _callback_cache_new (GIArgInfo *arg_info,
241                      GIInterfaceInfo *iface_info,
242                      gssize child_offset)
243 {
244    PyGICallbackCache *cc;
245
246    cc = g_slice_new0 (PyGICallbackCache);
247    ( (PyGIArgCache *)cc)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;
248
249    cc->user_data_index = g_arg_info_get_closure (arg_info);
250    if (cc->user_data_index != -1)
251        cc->user_data_index += child_offset;
252    cc->destroy_notify_index = g_arg_info_get_destroy (arg_info);
253    if (cc->destroy_notify_index != -1)
254        cc->destroy_notify_index += child_offset;
255    cc->scope = g_arg_info_get_scope (arg_info);
256    g_base_info_ref( (GIBaseInfo *)iface_info);
257    cc->interface_info = iface_info;
258    return cc;
259 }
260
261 static PyGIArgCache *
262 _arg_cache_alloc (void)
263 {
264     return g_slice_new0 (PyGIArgCache);
265 }
266
267 static void
268 _arg_cache_from_py_void_setup (PyGIArgCache *arg_cache)
269 {
270     arg_cache->from_py_marshaller = _pygi_marshal_from_py_void;
271 }
272
273 static void
274 _arg_cache_to_py_void_setup (PyGIArgCache *arg_cache)
275 {
276     arg_cache->to_py_marshaller = _pygi_marshal_to_py_void;
277 }
278
279 static void
280 _arg_cache_from_py_boolean_setup (PyGIArgCache *arg_cache)
281 {
282     arg_cache->from_py_marshaller = _pygi_marshal_from_py_boolean;
283 }
284
285 static void
286 _arg_cache_to_py_boolean_setup (PyGIArgCache *arg_cache)
287 {
288     arg_cache->to_py_marshaller = _pygi_marshal_to_py_boolean;
289 }
290
291 static void
292 _arg_cache_from_py_int8_setup (PyGIArgCache *arg_cache)
293 {
294     arg_cache->from_py_marshaller = _pygi_marshal_from_py_int8;
295 }
296
297 static void
298 _arg_cache_to_py_int8_setup (PyGIArgCache *arg_cache)
299 {
300     arg_cache->to_py_marshaller = _pygi_marshal_to_py_int8;
301 }
302
303 static void
304 _arg_cache_from_py_uint8_setup (PyGIArgCache *arg_cache)
305 {
306     arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint8;
307 }
308
309 static void
310 _arg_cache_to_py_uint8_setup (PyGIArgCache *arg_cache)
311 {
312     arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint8;
313 }
314
315 static void
316 _arg_cache_from_py_int16_setup (PyGIArgCache *arg_cache)
317 {
318     arg_cache->from_py_marshaller = _pygi_marshal_from_py_int16;
319 }
320
321 static void
322 _arg_cache_to_py_int16_setup (PyGIArgCache *arg_cache)
323 {
324     arg_cache->to_py_marshaller = _pygi_marshal_to_py_int16;
325 }
326
327 static void
328 _arg_cache_from_py_uint16_setup (PyGIArgCache *arg_cache)
329 {
330     arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint16;
331 }
332
333 static void
334 _arg_cache_to_py_uint16_setup (PyGIArgCache *arg_cache)
335 {
336     arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint16;
337 }
338
339 static void
340 _arg_cache_from_py_int32_setup (PyGIArgCache *arg_cache)
341 {
342     arg_cache->from_py_marshaller = _pygi_marshal_from_py_int32;
343 }
344
345 static void
346 _arg_cache_to_py_int32_setup (PyGIArgCache *arg_cache)
347 {
348     arg_cache->to_py_marshaller = _pygi_marshal_to_py_int32;
349 }
350
351 static void
352 _arg_cache_from_py_uint32_setup (PyGIArgCache *arg_cache)
353 {
354     arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint32;
355 }
356
357 static void
358 _arg_cache_to_py_uint32_setup (PyGIArgCache *arg_cache)
359 {
360     arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint32;
361 }
362
363 static void
364 _arg_cache_from_py_int64_setup (PyGIArgCache *arg_cache)
365 {
366     arg_cache->from_py_marshaller = _pygi_marshal_from_py_int64;
367 }
368
369 static void
370 _arg_cache_to_py_int64_setup (PyGIArgCache *arg_cache)
371 {
372     arg_cache->to_py_marshaller = _pygi_marshal_to_py_int64;
373 }
374
375 static void
376 _arg_cache_from_py_uint64_setup (PyGIArgCache *arg_cache)
377 {
378     arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint64;
379 }
380
381 static void
382 _arg_cache_to_py_uint64_setup (PyGIArgCache *arg_cache)
383 {
384     arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint64;
385 }
386
387 static void
388 _arg_cache_from_py_float_setup (PyGIArgCache *arg_cache)
389 {
390     arg_cache->from_py_marshaller = _pygi_marshal_from_py_float;
391 }
392
393 static void
394 _arg_cache_to_py_float_setup (PyGIArgCache *arg_cache)
395 {
396     arg_cache->to_py_marshaller = _pygi_marshal_to_py_float;
397 }
398
399 static void
400 _arg_cache_from_py_double_setup (PyGIArgCache *arg_cache)
401 {
402     arg_cache->from_py_marshaller = _pygi_marshal_from_py_double;
403 }
404
405 static void
406 _arg_cache_to_py_double_setup (PyGIArgCache *arg_cache)
407 {
408     arg_cache->to_py_marshaller = _pygi_marshal_to_py_double;
409 }
410
411 static void
412 _arg_cache_from_py_unichar_setup (PyGIArgCache *arg_cache)
413 {
414     arg_cache->from_py_marshaller = _pygi_marshal_from_py_unichar;
415 }
416
417 static void
418 _arg_cache_to_py_unichar_setup (PyGIArgCache *arg_cache)
419 {
420     arg_cache->to_py_marshaller = _pygi_marshal_to_py_unichar;
421 }
422
423 static void
424 _arg_cache_from_py_gtype_setup (PyGIArgCache *arg_cache)
425 {
426     arg_cache->from_py_marshaller = _pygi_marshal_from_py_gtype;
427 }
428
429 static void
430 _arg_cache_to_py_gtype_setup (PyGIArgCache *arg_cache)
431 {
432     arg_cache->to_py_marshaller = _pygi_marshal_to_py_gtype;
433 }
434
435 static void
436 _arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache,
437                                GITransfer transfer)
438 {
439     arg_cache->from_py_marshaller = _pygi_marshal_from_py_utf8;
440     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
441 }
442
443 static void
444 _arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache,
445                                GITransfer transfer)
446 {
447     arg_cache->to_py_marshaller = _pygi_marshal_to_py_utf8;
448     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
449 }
450
451 static void
452 _arg_cache_from_py_filename_setup (PyGIArgCache *arg_cache,
453                                  GITransfer transfer)
454 {
455     arg_cache->from_py_marshaller = _pygi_marshal_from_py_filename;
456     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
457 }
458
459 static void
460 _arg_cache_to_py_filename_setup (PyGIArgCache *arg_cache,
461                                  GITransfer transfer)
462 {
463     arg_cache->to_py_marshaller = _pygi_marshal_to_py_filename;
464     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
465 }
466
467 static gboolean
468 _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
469                                 PyGICallableCache *callable_cache,
470                                 GITypeInfo *type_info,
471                                 GITransfer transfer,
472                                 PyGIDirection direction,
473                                 gssize arg_index)
474 {
475     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
476     seq_cache->array_type = g_type_info_get_array_type (type_info);
477
478     arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
479
480     if (seq_cache->len_arg_index >= 0) {
481         PyGIArgCache *child_cache = 
482             callable_cache->args_cache[seq_cache->len_arg_index];
483
484         if (child_cache == NULL) {
485             child_cache = _arg_cache_alloc ();
486         } else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
487                    child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
488             return TRUE;
489         }
490
491         if (seq_cache->len_arg_index < arg_index)
492             child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE;
493         else
494             child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
495
496         child_cache->direction = direction;
497         child_cache->to_py_marshaller = NULL;
498         child_cache->from_py_marshaller = NULL;
499
500         callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
501     }
502
503     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
504
505     return TRUE;
506 }
507
508 static gboolean
509 _arg_cache_to_py_array_setup (PyGIArgCache *arg_cache,
510                               PyGICallableCache *callable_cache,
511                               GITypeInfo *type_info,
512                               GITransfer transfer,
513                               PyGIDirection direction,
514                               gssize arg_index)
515 {
516     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
517     arg_cache->to_py_marshaller = _pygi_marshal_to_py_array;
518     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array;
519
520     seq_cache->array_type = g_type_info_get_array_type (type_info);
521
522     if (seq_cache->len_arg_index >= 0) {
523         PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index];
524         if (seq_cache->len_arg_index < arg_index)
525              callable_cache->n_to_py_child_args++;
526
527         if (child_cache != NULL) {
528             callable_cache->to_py_args =
529                 g_slist_remove (callable_cache->to_py_args, child_cache);
530
531             if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
532                 child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE)
533                 return TRUE;
534         } else {
535             child_cache = _arg_cache_alloc ();
536         }
537
538         child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
539         child_cache->direction = direction;
540         child_cache->to_py_marshaller = NULL;
541         child_cache->from_py_marshaller = NULL;
542
543         callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
544     }
545
546     return TRUE;
547 }
548
549 static void
550 _arg_cache_from_py_glist_setup (PyGIArgCache *arg_cache,
551                                 GITransfer transfer)
552 {
553     arg_cache->from_py_marshaller = _pygi_marshal_from_py_glist;
554     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
555 }
556
557 static void
558 _arg_cache_to_py_glist_setup (PyGIArgCache *arg_cache,
559                               GITransfer transfer)
560 {
561     arg_cache->to_py_marshaller = _pygi_marshal_to_py_glist;
562     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
563 }
564
565 static void
566 _arg_cache_from_py_gslist_setup (PyGIArgCache *arg_cache,
567                                  GITransfer transfer)
568 {
569     arg_cache->from_py_marshaller = _pygi_marshal_from_py_gslist;
570     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
571 }
572
573 static void
574 _arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache,
575                                  GITransfer transfer)
576 {
577     arg_cache->to_py_marshaller = _pygi_marshal_to_py_gslist;
578     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
579 }
580
581 static void
582 _arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache)
583 {
584     arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash;
585     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash;
586 }
587
588 static void
589 _arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache)
590 {
591     arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash;
592     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash;
593 }
594
595 static void
596 _arg_cache_from_py_gerror_setup (PyGIArgCache *arg_cache)
597 {
598     arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror;
599     arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
600 }
601
602 static void
603 _arg_cache_to_py_gerror_setup (PyGIArgCache *arg_cache)
604 {
605     arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror;
606     arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
607 }
608
609 static void
610 _arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache,
611                                           GITransfer transfer)
612 {
613     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct;
614 }
615
616 static void
617 _arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache,
618                                         GITransfer transfer)
619 {
620     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct;
621 }
622
623 static void
624 _arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
625                                            GIInterfaceInfo *iface_info,
626                                            GITransfer transfer)
627 {
628     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
629     iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
630     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct;
631
632     if (iface_cache->g_type == G_TYPE_VALUE)
633         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
634     else if (iface_cache->is_foreign)
635         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
636 }
637
638 static void
639 _arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
640                                          GIInterfaceInfo *iface_info,
641                                          GITransfer transfer)
642 {
643     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
644     iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
645     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct;
646
647     if (iface_cache->is_foreign)
648         arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
649 }
650
651 static void
652 _arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache,
653                                            GITransfer transfer)
654 {
655     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object;
656     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
657 }
658
659 static void
660 _arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache,
661                                          GITransfer transfer)
662 {
663     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object;
664     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
665 }
666
667 static void
668 _arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache,
669                                              PyGICallableCache *callable_cache)
670 {
671     PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
672     if (callback_cache->user_data_index >= 0) {
673         PyGIArgCache *user_data_arg_cache = _arg_cache_alloc ();
674         user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
675         user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
676         callable_cache->args_cache[callback_cache->user_data_index] = user_data_arg_cache;
677     }
678
679     if (callback_cache->destroy_notify_index >= 0) {
680         PyGIArgCache *destroy_arg_cache = _arg_cache_alloc ();
681         destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
682         destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
683         callable_cache->args_cache[callback_cache->destroy_notify_index] = destroy_arg_cache;
684     }
685     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
686 }
687
688 static void
689 _arg_cache_to_py_interface_callback_setup (void)
690 {
691     PyErr_Format(PyExc_NotImplementedError,
692                  "Callback returns are not supported");
693 }
694
695 static void
696 _arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache,
697                                          GITransfer transfer)
698 {
699     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
700 }
701
702 static void
703 _arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache,
704                                        GITransfer transfer)
705 {
706     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
707 }
708
709 static void
710 _arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache,
711                                           GITransfer transfer)
712 {
713     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
714 }
715
716 static void
717 _arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache,
718                                         GITransfer transfer)
719 {
720     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
721 }
722
723 PyGIArgCache *
724 _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
725                               PyGICallableCache *callable_cache,
726                               GIArgInfo *arg_info,
727                               GITransfer transfer,
728                               PyGIDirection direction,
729                               gssize c_arg_index,
730                               gssize py_arg_index)
731 {
732     PyGIInterfaceCache *iface_cache = NULL;
733     PyGIArgCache *arg_cache = NULL;
734     gssize child_offset = 0;
735     GIInfoType info_type;
736
737     if (callable_cache != NULL)
738         child_offset =
739             (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
740                  callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0;
741
742     info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);
743
744     /* Callbacks are special cased */
745     if (info_type != GI_INFO_TYPE_CALLBACK) {
746         iface_cache = _interface_cache_new (iface_info);
747
748         arg_cache = (PyGIArgCache *)iface_cache;
749         if (arg_cache == NULL)
750             return NULL;
751     }
752
753     switch (info_type) {
754         case GI_INFO_TYPE_UNION:
755             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
756                _arg_cache_from_py_interface_union_setup (arg_cache, transfer);
757
758             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
759                _arg_cache_to_py_interface_union_setup (arg_cache, transfer);
760
761             break;
762         case GI_INFO_TYPE_STRUCT:
763             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
764                _arg_cache_from_py_interface_struct_setup (arg_cache,
765                                                           iface_info,
766                                                           transfer);
767
768             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
769                _arg_cache_to_py_interface_struct_setup (arg_cache,
770                                                         iface_info,
771                                                         transfer);
772             break;
773         case GI_INFO_TYPE_OBJECT:
774         case GI_INFO_TYPE_INTERFACE:
775             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
776                _arg_cache_from_py_interface_object_setup (arg_cache, transfer);
777
778             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
779                _arg_cache_to_py_interface_object_setup (arg_cache, transfer);
780
781             break;
782         case GI_INFO_TYPE_BOXED:
783             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
784                 _arg_cache_from_py_interface_struct_setup (arg_cache,
785                                                        iface_info,
786                                                        transfer);
787
788             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
789                 _arg_cache_to_py_interface_struct_setup (arg_cache,
790                                                       iface_info,
791                                                       transfer);
792             break;
793         case GI_INFO_TYPE_CALLBACK:
794             {
795                 PyGICallbackCache *callback_cache;
796
797                 if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
798                     _arg_cache_to_py_interface_callback_setup ();
799                     return NULL;
800                 }
801
802                 callback_cache =
803                     _callback_cache_new (arg_info,
804                                          iface_info,
805                                          child_offset);
806
807                 arg_cache = (PyGIArgCache *)callback_cache;
808                 if (arg_cache == NULL)
809                     return NULL;
810
811                 if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
812                     _arg_cache_from_py_interface_callback_setup (arg_cache, callable_cache);
813
814                 break;
815             }
816         case GI_INFO_TYPE_ENUM:
817             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
818                _arg_cache_from_py_interface_enum_setup (arg_cache, transfer);
819
820             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
821                _arg_cache_to_py_interface_enum_setup (arg_cache, transfer);
822
823             break;
824         case GI_INFO_TYPE_FLAGS:
825             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
826                _arg_cache_from_py_interface_flags_setup (arg_cache, transfer);
827
828             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
829                _arg_cache_to_py_interface_flags_setup (arg_cache, transfer);
830
831             break;
832         default:
833             g_assert_not_reached ();
834     }
835
836     if (arg_cache != NULL) {
837         arg_cache->direction = direction;
838         arg_cache->transfer = transfer;
839         arg_cache->type_tag = GI_TYPE_TAG_INTERFACE;
840         arg_cache->py_arg_index = py_arg_index;
841         arg_cache->c_arg_index = c_arg_index;
842
843         if (iface_cache != NULL) {
844             g_base_info_ref ( (GIBaseInfo *)iface_info);
845             iface_cache->interface_info = iface_info;
846         }
847     }
848
849     return arg_cache;
850 }
851
852 PyGIArgCache *
853 _arg_cache_new (GITypeInfo *type_info,
854                 PyGICallableCache *callable_cache,
855                 GIArgInfo *arg_info,
856                 GITransfer transfer,
857                 PyGIDirection direction,
858                 gssize c_arg_index,
859                 gssize py_arg_index)
860 {
861     PyGIArgCache *arg_cache = NULL;
862     gssize child_offset = 0;
863     GITypeTag type_tag;
864
865     type_tag = g_type_info_get_tag (type_info);
866
867     if (callable_cache != NULL)
868         child_offset =
869             (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
870                 callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0;
871
872     switch (type_tag) {
873        case GI_TYPE_TAG_VOID:
874            arg_cache = _arg_cache_alloc ();
875            if (arg_cache == NULL)
876                break;
877
878            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
879                _arg_cache_from_py_void_setup (arg_cache);
880
881            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
882                _arg_cache_to_py_void_setup (arg_cache);
883
884            break;
885        case GI_TYPE_TAG_BOOLEAN:
886            arg_cache = _arg_cache_alloc ();
887            if (arg_cache == NULL)
888                break;
889
890            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
891                _arg_cache_from_py_boolean_setup (arg_cache);
892
893            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
894                _arg_cache_to_py_boolean_setup (arg_cache);
895
896            break;
897        case GI_TYPE_TAG_INT8:
898            arg_cache = _arg_cache_alloc ();
899            if (arg_cache == NULL)
900                break;
901
902            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
903                _arg_cache_from_py_int8_setup (arg_cache);
904
905            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
906                _arg_cache_to_py_int8_setup (arg_cache);
907
908            break;
909        case GI_TYPE_TAG_UINT8:
910            arg_cache = _arg_cache_alloc ();
911            if (arg_cache == NULL)
912                break;
913
914            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
915                _arg_cache_from_py_uint8_setup (arg_cache);
916
917            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
918                _arg_cache_to_py_uint8_setup (arg_cache);
919
920            break;
921        case GI_TYPE_TAG_INT16:
922            arg_cache = _arg_cache_alloc ();
923            if (arg_cache == NULL)
924                break;
925
926            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
927                _arg_cache_from_py_int16_setup (arg_cache);
928
929            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
930                _arg_cache_to_py_int16_setup (arg_cache);
931
932            break;
933        case GI_TYPE_TAG_UINT16:
934            arg_cache = _arg_cache_alloc ();
935            if (arg_cache == NULL)
936                break;
937
938            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
939                _arg_cache_from_py_uint16_setup (arg_cache);
940
941            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
942                _arg_cache_to_py_uint16_setup (arg_cache);
943            break;
944        case GI_TYPE_TAG_INT32:
945            arg_cache = _arg_cache_alloc ();
946            if (arg_cache == NULL)
947                break;
948
949            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
950                _arg_cache_from_py_int32_setup (arg_cache);
951
952            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
953                _arg_cache_to_py_int32_setup (arg_cache);
954
955            break;
956        case GI_TYPE_TAG_UINT32:
957            arg_cache = _arg_cache_alloc ();
958            if (arg_cache == NULL)
959                break;
960
961            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
962                _arg_cache_from_py_uint32_setup (arg_cache);
963
964            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
965                _arg_cache_to_py_uint32_setup (arg_cache);
966
967            break;
968        case GI_TYPE_TAG_INT64:
969            arg_cache = _arg_cache_alloc ();
970            if (arg_cache == NULL)
971                break;
972
973            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
974                _arg_cache_from_py_int64_setup (arg_cache);
975
976            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
977                _arg_cache_to_py_int64_setup (arg_cache);
978
979            break;
980        case GI_TYPE_TAG_UINT64:
981            arg_cache = _arg_cache_alloc ();
982            if (arg_cache == NULL)
983                break;
984
985            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
986                _arg_cache_from_py_uint64_setup (arg_cache);
987
988            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
989                _arg_cache_to_py_uint64_setup (arg_cache);
990
991            break;
992        case GI_TYPE_TAG_FLOAT:
993            arg_cache = _arg_cache_alloc ();
994            if (arg_cache == NULL)
995                break;
996
997            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
998                _arg_cache_from_py_float_setup (arg_cache);
999
1000            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1001                _arg_cache_to_py_float_setup (arg_cache);
1002
1003            break;
1004        case GI_TYPE_TAG_DOUBLE:
1005            arg_cache = _arg_cache_alloc ();
1006            if (arg_cache == NULL)
1007                break;
1008
1009            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1010                _arg_cache_from_py_double_setup (arg_cache);
1011
1012            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1013                _arg_cache_to_py_double_setup (arg_cache);
1014
1015            break;
1016        case GI_TYPE_TAG_UNICHAR:
1017            arg_cache = _arg_cache_alloc ();
1018            if (arg_cache == NULL)
1019                break;
1020
1021            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1022                _arg_cache_from_py_unichar_setup (arg_cache);
1023
1024            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1025                _arg_cache_to_py_unichar_setup (arg_cache);
1026
1027            break;
1028        case GI_TYPE_TAG_GTYPE:
1029            arg_cache = _arg_cache_alloc ();
1030            if (arg_cache == NULL)
1031                break;
1032
1033            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1034                _arg_cache_from_py_gtype_setup (arg_cache);
1035
1036            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1037                _arg_cache_to_py_gtype_setup (arg_cache);
1038
1039            break;
1040        case GI_TYPE_TAG_UTF8:
1041            arg_cache = _arg_cache_alloc ();
1042            if (arg_cache == NULL)
1043                break;
1044
1045            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1046                _arg_cache_from_py_utf8_setup (arg_cache, transfer);
1047
1048            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1049                _arg_cache_to_py_utf8_setup (arg_cache, transfer);
1050
1051            break;
1052        case GI_TYPE_TAG_FILENAME:
1053            arg_cache = _arg_cache_alloc ();
1054            if (arg_cache == NULL)
1055                break;
1056
1057            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1058                _arg_cache_from_py_filename_setup (arg_cache, transfer);
1059
1060            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1061                _arg_cache_to_py_filename_setup (arg_cache, transfer);
1062
1063            break;
1064        case GI_TYPE_TAG_ARRAY:
1065            {
1066                PyGISequenceCache *seq_cache =
1067                    _sequence_cache_new (type_info,
1068                                         direction,
1069                                         transfer,
1070                                         child_offset);
1071
1072                arg_cache = (PyGIArgCache *)seq_cache;
1073                if (arg_cache == NULL)
1074                    break;
1075
1076                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1077                    _arg_cache_from_py_array_setup (arg_cache,
1078                                                    callable_cache,
1079                                                    type_info,
1080                                                    transfer,
1081                                                    direction,
1082                                                    c_arg_index);
1083
1084                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1085                    _arg_cache_to_py_array_setup (arg_cache,
1086                                                  callable_cache,
1087                                                  type_info,
1088                                                  transfer,
1089                                                  direction,
1090                                                  c_arg_index);
1091
1092                /* ugly edge case code:
1093                 *  
1094                 * length can come before the array parameter which means we
1095                 * need to update indexes if this happens
1096                 */ 
1097                if (seq_cache->len_arg_index > -1 &&
1098                    callable_cache->args_cache[seq_cache->len_arg_index]->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
1099                    gssize i;
1100                    PyGIArgCache *child_cache =
1101                        callable_cache->args_cache[seq_cache->len_arg_index];
1102
1103                    child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
1104                    py_arg_index -= 1;
1105                    callable_cache->n_py_args -= 1;
1106
1107                    for (i = seq_cache->len_arg_index + 1; 
1108                           i < callable_cache->n_args; 
1109                             i++) {
1110                        PyGIArgCache *update_cache = callable_cache->args_cache[i];
1111                        if (update_cache == NULL)
1112                            break;
1113
1114                        update_cache->py_arg_index -= 1;
1115                    }
1116                }
1117
1118                break;
1119            }
1120        case GI_TYPE_TAG_GLIST:
1121            {
1122                PyGISequenceCache *seq_cache =
1123                    _sequence_cache_new (type_info,
1124                                         direction,
1125                                         transfer,
1126                                         child_offset);
1127
1128                arg_cache = (PyGIArgCache *)seq_cache;
1129                if (arg_cache == NULL)
1130                    break;
1131
1132                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1133                    _arg_cache_from_py_glist_setup (arg_cache, transfer);
1134
1135                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1136                    _arg_cache_to_py_glist_setup (arg_cache, transfer);
1137
1138
1139                break;
1140            }
1141        case GI_TYPE_TAG_GSLIST:
1142            {
1143                PyGISequenceCache *seq_cache =
1144                    _sequence_cache_new (type_info,
1145                                         direction,
1146                                         transfer,
1147                                         child_offset);
1148
1149                arg_cache = (PyGIArgCache *)seq_cache;
1150                if (arg_cache == NULL)
1151                    break;
1152
1153                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1154                    _arg_cache_from_py_gslist_setup (arg_cache, transfer);
1155
1156                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1157                    _arg_cache_to_py_gslist_setup (arg_cache, transfer);
1158
1159                break;
1160             }
1161        case GI_TYPE_TAG_GHASH:
1162            arg_cache =
1163                (PyGIArgCache *)_hash_cache_new (type_info,
1164                                                 direction,
1165                                                 transfer);
1166
1167            if (arg_cache == NULL)
1168                    break;
1169
1170            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1171                _arg_cache_from_py_ghash_setup (arg_cache);
1172
1173            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1174                _arg_cache_to_py_ghash_setup (arg_cache);
1175            }
1176
1177            break;
1178        case GI_TYPE_TAG_INTERFACE:
1179            {
1180                GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
1181                arg_cache = _arg_cache_new_for_interface (interface_info,
1182                                                          callable_cache,
1183                                                          arg_info,
1184                                                          transfer,
1185                                                          direction,
1186                                                          c_arg_index,
1187                                                          py_arg_index);
1188
1189                g_base_info_unref ( (GIBaseInfo *)interface_info);
1190                break;
1191            }
1192        case GI_TYPE_TAG_ERROR:
1193            arg_cache = _arg_cache_alloc ();
1194            if (arg_cache == NULL)
1195                break;
1196
1197            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1198                _arg_cache_from_py_gerror_setup (arg_cache);
1199
1200            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
1201                _arg_cache_to_py_gerror_setup (arg_cache);
1202
1203            break;
1204     }
1205
1206     if (arg_cache != NULL) {
1207         arg_cache->direction = direction;
1208         arg_cache->transfer = transfer;
1209         arg_cache->type_tag = type_tag;
1210         arg_cache->py_arg_index = py_arg_index;
1211         arg_cache->c_arg_index = c_arg_index;
1212         arg_cache->is_pointer = g_type_info_is_pointer (type_info);
1213         g_base_info_ref ( (GIBaseInfo *) type_info);
1214         arg_cache->type_info = type_info;
1215     }
1216
1217     return arg_cache;
1218 }
1219
1220 static void
1221 _arg_name_list_generate (PyGICallableCache *callable_cache)
1222 {
1223     GSList * arg_name_list = NULL;
1224     int i;
1225
1226     if (callable_cache->arg_name_hash == NULL) {
1227         callable_cache->arg_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
1228     } else {
1229         g_hash_table_remove_all (callable_cache->arg_name_hash);
1230     }
1231
1232     for (i=0; i < callable_cache->n_args; i++) {
1233         PyGIArgCache *arg_cache = NULL;
1234
1235         arg_cache = callable_cache->args_cache[i];
1236
1237         if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD &&
1238             arg_cache->meta_type != PYGI_META_ARG_TYPE_CLOSURE &&
1239                 (arg_cache->direction == PYGI_DIRECTION_FROM_PYTHON ||
1240                  arg_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL)) {
1241
1242             gpointer arg_name = (gpointer)arg_cache->arg_name;
1243
1244             arg_name_list = g_slist_prepend (arg_name_list, arg_name);
1245             if (arg_name != NULL) {
1246                 g_hash_table_insert (callable_cache->arg_name_hash, arg_name, arg_name);
1247             }
1248         }
1249     }
1250
1251     callable_cache->arg_name_list = g_slist_reverse (arg_name_list);
1252 }
1253
1254 /* Generate the cache for the callable's arguments */
1255 static gboolean
1256 _args_cache_generate (GICallableInfo *callable_info,
1257                       PyGICallableCache *callable_cache)
1258 {
1259     gssize arg_index = 0;
1260     gssize i;
1261     GITypeInfo *return_info;
1262     GITransfer return_transfer;
1263     PyGIArgCache *return_cache;
1264     PyGIDirection return_direction;
1265
1266     /* determine if we are marshalling the return to or from python */
1267     if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
1268         return_direction = PYGI_DIRECTION_FROM_PYTHON;
1269     else
1270         return_direction = PYGI_DIRECTION_TO_PYTHON;
1271
1272     /* cache the return arg */
1273     return_info =
1274         g_callable_info_get_return_type (callable_info);
1275     return_transfer =
1276         g_callable_info_get_caller_owns (callable_info);
1277     return_cache =
1278         _arg_cache_new (return_info,
1279                         callable_cache,
1280                         NULL,
1281                         return_transfer,
1282                         return_direction,
1283                         -1,
1284                         -1);
1285
1286     return_cache->is_skipped = g_callable_info_skip_return (callable_info);
1287     callable_cache->return_cache = return_cache;
1288     g_base_info_unref (return_info);
1289
1290     /* first arg is the instance */
1291     if (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
1292             callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
1293         GIInterfaceInfo *interface_info;
1294         PyGIArgCache *instance_cache;
1295         PyGIDirection instance_direction;
1296
1297         instance_direction = PYGI_DIRECTION_FROM_PYTHON;
1298
1299
1300         interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
1301
1302         instance_cache =
1303             _arg_cache_new_for_interface (interface_info,
1304                                           callable_cache,
1305                                           NULL,
1306                                           GI_TRANSFER_NOTHING,
1307                                           instance_direction,
1308                                           arg_index,
1309                                           0);
1310
1311         /* FIXME: marshal interfaces from_py */
1312         instance_cache->from_py_marshaller = _pygi_marshal_from_py_interface_instance;
1313         g_base_info_unref ( (GIBaseInfo *)interface_info);
1314
1315         if (instance_cache == NULL)
1316             return FALSE;
1317
1318         callable_cache->args_cache[arg_index] = instance_cache;
1319
1320         arg_index++;
1321         callable_cache->n_from_py_args++;
1322         callable_cache->n_py_args++;
1323     }
1324
1325
1326     for (i=0; arg_index < callable_cache->n_args; arg_index++, i++) {
1327         PyGIArgCache *arg_cache = NULL;
1328         GIArgInfo *arg_info;
1329         GITypeInfo *type_info;
1330         GIDirection gi_direction;
1331         PyGIDirection direction;
1332         GITransfer transfer;
1333         GITypeTag type_tag;
1334         gboolean is_caller_allocates = FALSE;
1335         gssize py_arg_index = -1;
1336
1337         arg_info = g_callable_info_get_arg (callable_info, i);
1338
1339         if (g_arg_info_get_closure (arg_info) == i) {
1340
1341             arg_cache = _arg_cache_alloc ();
1342             callable_cache->args_cache[arg_index] = arg_cache;
1343
1344             arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
1345             arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
1346             arg_cache->meta_type = PYGI_META_ARG_TYPE_CLOSURE;
1347             arg_cache->c_arg_index = i;
1348
1349             callable_cache->n_from_py_args++;
1350
1351             g_base_info_unref ( (GIBaseInfo *)arg_info);
1352
1353             continue;
1354         }
1355
1356         /* For vfuncs and callbacks our marshalling directions
1357            are reversed */
1358         gi_direction = g_arg_info_get_direction (arg_info);
1359         if (gi_direction == GI_DIRECTION_INOUT) {
1360             direction = PYGI_DIRECTION_BIDIRECTIONAL;
1361         } else if (gi_direction == GI_DIRECTION_IN) {
1362             direction = PYGI_DIRECTION_FROM_PYTHON;
1363             if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
1364                 direction = PYGI_DIRECTION_TO_PYTHON;
1365         } else {
1366             direction = PYGI_DIRECTION_TO_PYTHON;
1367             if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
1368                 direction = PYGI_DIRECTION_FROM_PYTHON;
1369         }
1370
1371         transfer = g_arg_info_get_ownership_transfer (arg_info);
1372         type_info = g_arg_info_get_type (arg_info);
1373         type_tag = g_type_info_get_tag (type_info);
1374
1375         if (type_tag == GI_TYPE_TAG_INTERFACE)
1376             is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
1377
1378         /* must be an child arg filled in by its owner
1379          * and continue
1380          * fill in it's c_arg_index, add to the in count
1381          */
1382         if (callable_cache->args_cache[arg_index] != NULL) {
1383             arg_cache = callable_cache->args_cache[arg_index];
1384             if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) {
1385                 arg_cache->py_arg_index = callable_cache->n_py_args;
1386                 callable_cache->n_py_args++;
1387             }
1388
1389             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1390                 arg_cache->c_arg_index = callable_cache->n_from_py_args;
1391                 callable_cache->n_from_py_args++;
1392             }
1393
1394             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1395                 callable_cache->n_to_py_args++;
1396                 callable_cache->n_to_py_child_args++;
1397             }
1398
1399             g_base_info_unref ( (GIBaseInfo *)arg_info);
1400             continue;
1401         }
1402
1403         if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1404             py_arg_index = callable_cache->n_py_args;
1405             callable_cache->n_from_py_args++;
1406             callable_cache->n_py_args++;
1407         }
1408
1409         arg_cache =
1410             _arg_cache_new (type_info,
1411                             callable_cache,
1412                             arg_info,
1413                             transfer,
1414                             direction,
1415                             arg_index,
1416                             py_arg_index);
1417
1418         if (arg_cache == NULL)
1419             goto arg_err;
1420
1421         arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
1422         arg_cache->allow_none = g_arg_info_may_be_null(arg_info);
1423         arg_cache->is_caller_allocates = is_caller_allocates;
1424
1425         if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1426             callable_cache->n_to_py_args++;
1427
1428             if (arg_cache == NULL)
1429                 goto arg_err;
1430
1431             callable_cache->to_py_args =
1432                 g_slist_append (callable_cache->to_py_args, arg_cache);
1433         }
1434
1435         callable_cache->args_cache[arg_index] = arg_cache;
1436         g_base_info_unref( (GIBaseInfo *)type_info);
1437         g_base_info_unref( (GIBaseInfo *)arg_info);
1438
1439         continue;
1440 arg_err:
1441         g_base_info_unref( (GIBaseInfo *)type_info);
1442         g_base_info_unref( (GIBaseInfo *)arg_info);
1443         return FALSE;
1444     }
1445
1446     _arg_name_list_generate (callable_cache);
1447
1448     return TRUE;
1449 }
1450
1451 PyGICallableCache *
1452 _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback)
1453 {
1454     PyGICallableCache *cache;
1455     GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)callable_info);
1456
1457     cache = g_slice_new0 (PyGICallableCache);
1458
1459     if (cache == NULL)
1460         return NULL;
1461
1462     cache->name = g_base_info_get_name ((GIBaseInfo *)callable_info);
1463
1464     if (type == GI_INFO_TYPE_FUNCTION) {
1465         GIFunctionInfoFlags flags;
1466
1467         flags = g_function_info_get_flags ( (GIFunctionInfo *)callable_info);
1468
1469         if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
1470             cache->function_type = PYGI_FUNCTION_TYPE_CONSTRUCTOR;
1471         else if (flags & GI_FUNCTION_IS_METHOD)
1472             cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
1473     } else if (type == GI_INFO_TYPE_VFUNC) {
1474         cache->function_type = PYGI_FUNCTION_TYPE_VFUNC;
1475     } else if (type == GI_INFO_TYPE_CALLBACK) {
1476         if (is_ccallback)
1477             cache->function_type = PYGI_FUNCTION_TYPE_CCALLBACK;
1478         else
1479             cache->function_type = PYGI_FUNCTION_TYPE_CALLBACK;
1480     } else {
1481         cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
1482     }
1483
1484     cache->n_args = g_callable_info_get_n_args (callable_info);
1485
1486     /* if we are a method or vfunc make sure the instance parameter is counted */
1487     if (cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
1488             cache->function_type == PYGI_FUNCTION_TYPE_VFUNC)
1489         cache->n_args++;
1490
1491     if (cache->n_args > 0)
1492         cache->args_cache = g_slice_alloc0 (cache->n_args * sizeof (PyGIArgCache *));
1493
1494     if (!_args_cache_generate (callable_info, cache))
1495         goto err;
1496
1497     return cache;
1498 err:
1499     _pygi_callable_cache_free (cache);
1500     return NULL;
1501 }