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