Imported Upstream version 3.9.5
[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_basic_type_setup (PyGIArgCache *arg_cache)
264 {
265     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
266 }
267
268 static void
269 _arg_cache_to_py_basic_type_setup (PyGIArgCache *arg_cache)
270 {
271     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
272 }
273
274 static void
275 _arg_cache_from_py_void_setup (PyGIArgCache *arg_cache)
276 {
277     arg_cache->from_py_marshaller = _pygi_marshal_from_py_void;
278 }
279
280 static void
281 _arg_cache_to_py_void_setup (PyGIArgCache *arg_cache)
282 {
283     arg_cache->to_py_marshaller = _pygi_marshal_to_py_void;
284 }
285
286 static void
287 _arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache,
288                                GITransfer transfer)
289 {
290     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
291     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
292 }
293
294 static void
295 _arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache,
296                                GITransfer transfer)
297 {
298     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
299     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
300 }
301
302 static gboolean
303 _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
304                                 PyGICallableCache *callable_cache,
305                                 GITypeInfo *type_info,
306                                 GITransfer transfer,
307                                 PyGIDirection direction,
308                                 gssize arg_index)
309 {
310     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
311     seq_cache->array_type = g_type_info_get_array_type (type_info);
312
313     arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
314
315     if (seq_cache->len_arg_index >= 0) {
316         PyGIArgCache *child_cache = 
317             callable_cache->args_cache[seq_cache->len_arg_index];
318
319         if (child_cache == NULL) {
320             child_cache = _arg_cache_alloc ();
321         } else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
322                    child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
323             arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
324             return TRUE;
325         }
326
327         if (seq_cache->len_arg_index < arg_index)
328             child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE;
329         else
330             child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
331
332         child_cache->direction = direction;
333         child_cache->to_py_marshaller = NULL;
334         child_cache->from_py_marshaller = NULL;
335
336         callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
337     }
338
339     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
340
341     return TRUE;
342 }
343
344 static gboolean
345 _arg_cache_to_py_array_setup (PyGIArgCache *arg_cache,
346                               PyGICallableCache *callable_cache,
347                               GITypeInfo *type_info,
348                               GITransfer transfer,
349                               PyGIDirection direction,
350                               gssize arg_index)
351 {
352     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
353     arg_cache->to_py_marshaller = _pygi_marshal_to_py_array;
354     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array;
355
356     seq_cache->array_type = g_type_info_get_array_type (type_info);
357
358     if (seq_cache->len_arg_index >= 0) {
359         PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index];
360         if (seq_cache->len_arg_index < arg_index)
361              callable_cache->n_to_py_child_args++;
362
363         if (child_cache != NULL) {
364             callable_cache->to_py_args =
365                 g_slist_remove (callable_cache->to_py_args, child_cache);
366
367             if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
368                 child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE)
369                 return TRUE;
370         } else {
371             child_cache = _arg_cache_alloc ();
372         }
373
374         child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
375         child_cache->direction = direction;
376         child_cache->to_py_marshaller = NULL;
377         child_cache->from_py_marshaller = NULL;
378
379         callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
380     }
381
382     return TRUE;
383 }
384
385 static void
386 _arg_cache_from_py_glist_setup (PyGIArgCache *arg_cache,
387                                 GITransfer transfer)
388 {
389     arg_cache->from_py_marshaller = _pygi_marshal_from_py_glist;
390     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
391 }
392
393 static void
394 _arg_cache_to_py_glist_setup (PyGIArgCache *arg_cache,
395                               GITransfer transfer)
396 {
397     arg_cache->to_py_marshaller = _pygi_marshal_to_py_glist;
398     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
399 }
400
401 static void
402 _arg_cache_from_py_gslist_setup (PyGIArgCache *arg_cache,
403                                  GITransfer transfer)
404 {
405     arg_cache->from_py_marshaller = _pygi_marshal_from_py_gslist;
406     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
407 }
408
409 static void
410 _arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache,
411                                  GITransfer transfer)
412 {
413     arg_cache->to_py_marshaller = _pygi_marshal_to_py_gslist;
414     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
415 }
416
417 static void
418 _arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache)
419 {
420     arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash;
421     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash;
422 }
423
424 static void
425 _arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache)
426 {
427     arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash;
428     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash;
429 }
430
431 static void
432 _arg_cache_from_py_gerror_setup (PyGIArgCache *arg_cache)
433 {
434     arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror;
435     arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
436 }
437
438 static void
439 _arg_cache_to_py_gerror_setup (PyGIArgCache *arg_cache)
440 {
441     arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror;
442     arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
443 }
444
445 static void
446 _arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache,
447                                           GITransfer transfer)
448 {
449     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
450 }
451
452 static void
453 _arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache,
454                                         GITransfer transfer)
455 {
456     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
457 }
458
459 static void
460 _arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
461                                            GIInterfaceInfo *iface_info,
462                                            GITransfer transfer)
463 {
464     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
465     iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
466     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
467
468     if (iface_cache->g_type == G_TYPE_VALUE)
469         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
470     else if (iface_cache->is_foreign)
471         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
472 }
473
474 static void
475 _arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
476                                          GIInterfaceInfo *iface_info,
477                                          GITransfer transfer)
478 {
479     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
480     iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
481     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
482
483     if (iface_cache->is_foreign)
484         arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
485 }
486
487 static void
488 _arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache,
489                                            GITransfer transfer)
490 {
491     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object;
492     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
493 }
494
495 static void
496 _arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache,
497                                          GITransfer transfer)
498 {
499     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object_cache_adapter;
500     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
501 }
502
503 static void
504 _arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache,
505                                              PyGICallableCache *callable_cache)
506 {
507     PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
508     if (callback_cache->user_data_index >= 0) {
509         PyGIArgCache *user_data_arg_cache = _arg_cache_alloc ();
510         user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
511         user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
512         callable_cache->args_cache[callback_cache->user_data_index] = user_data_arg_cache;
513     }
514
515     if (callback_cache->destroy_notify_index >= 0) {
516         PyGIArgCache *destroy_arg_cache = _arg_cache_alloc ();
517         destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
518         destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
519         callable_cache->args_cache[callback_cache->destroy_notify_index] = destroy_arg_cache;
520     }
521     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
522     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback;
523 }
524
525 static void
526 _arg_cache_to_py_interface_callback_setup (void)
527 {
528     PyErr_Format(PyExc_NotImplementedError,
529                  "Callback returns are not supported");
530 }
531
532 static void
533 _arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache,
534                                          GITransfer transfer)
535 {
536     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
537 }
538
539 static void
540 _arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache,
541                                        GITransfer transfer)
542 {
543     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
544 }
545
546 static void
547 _arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache,
548                                           GITransfer transfer)
549 {
550     arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
551 }
552
553 static void
554 _arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache,
555                                         GITransfer transfer)
556 {
557     arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
558 }
559
560 PyGIArgCache *
561 _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
562                               PyGICallableCache *callable_cache,
563                               GIArgInfo *arg_info,
564                               GITransfer transfer,
565                               PyGIDirection direction,
566                               gssize c_arg_index,
567                               gssize py_arg_index)
568 {
569     PyGIInterfaceCache *iface_cache = NULL;
570     PyGIArgCache *arg_cache = NULL;
571     gssize child_offset = 0;
572     GIInfoType info_type;
573
574     if (callable_cache != NULL)
575         child_offset =
576             (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
577                  callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0;
578
579     info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);
580
581     /* Callbacks are special cased */
582     if (info_type != GI_INFO_TYPE_CALLBACK) {
583         iface_cache = _interface_cache_new (iface_info);
584
585         arg_cache = (PyGIArgCache *)iface_cache;
586         if (arg_cache == NULL)
587             return NULL;
588     }
589
590     switch (info_type) {
591         case GI_INFO_TYPE_UNION:
592             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
593                _arg_cache_from_py_interface_union_setup (arg_cache, transfer);
594
595             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
596                _arg_cache_to_py_interface_union_setup (arg_cache, transfer);
597
598             break;
599         case GI_INFO_TYPE_BOXED:
600         case GI_INFO_TYPE_STRUCT:
601             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
602                _arg_cache_from_py_interface_struct_setup (arg_cache,
603                                                           iface_info,
604                                                           transfer);
605
606             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
607                _arg_cache_to_py_interface_struct_setup (arg_cache,
608                                                         iface_info,
609                                                         transfer);
610             break;
611         case GI_INFO_TYPE_OBJECT:
612         case GI_INFO_TYPE_INTERFACE:
613             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
614                _arg_cache_from_py_interface_object_setup (arg_cache, transfer);
615
616             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
617                _arg_cache_to_py_interface_object_setup (arg_cache, transfer);
618
619             break;
620         case GI_INFO_TYPE_CALLBACK:
621             {
622                 PyGICallbackCache *callback_cache;
623
624                 if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
625                     _arg_cache_to_py_interface_callback_setup ();
626                     return NULL;
627                 }
628
629                 callback_cache =
630                     _callback_cache_new (arg_info,
631                                          iface_info,
632                                          child_offset);
633
634                 arg_cache = (PyGIArgCache *)callback_cache;
635                 if (arg_cache == NULL)
636                     return NULL;
637
638                 if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
639                     _arg_cache_from_py_interface_callback_setup (arg_cache, callable_cache);
640
641                 break;
642             }
643         case GI_INFO_TYPE_ENUM:
644             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
645                _arg_cache_from_py_interface_enum_setup (arg_cache, transfer);
646
647             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
648                _arg_cache_to_py_interface_enum_setup (arg_cache, transfer);
649
650             break;
651         case GI_INFO_TYPE_FLAGS:
652             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
653                _arg_cache_from_py_interface_flags_setup (arg_cache, transfer);
654
655             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
656                _arg_cache_to_py_interface_flags_setup (arg_cache, transfer);
657
658             break;
659         default:
660             g_assert_not_reached ();
661     }
662
663     if (arg_cache != NULL) {
664         arg_cache->direction = direction;
665         arg_cache->transfer = transfer;
666         arg_cache->type_tag = GI_TYPE_TAG_INTERFACE;
667         arg_cache->py_arg_index = py_arg_index;
668         arg_cache->c_arg_index = c_arg_index;
669
670         if (iface_cache != NULL) {
671             g_base_info_ref ( (GIBaseInfo *)iface_info);
672             iface_cache->interface_info = iface_info;
673         }
674     }
675
676     return arg_cache;
677 }
678
679 PyGIArgCache *
680 _arg_cache_new (GITypeInfo *type_info,
681                 PyGICallableCache *callable_cache,
682                 GIArgInfo *arg_info,
683                 GITransfer transfer,
684                 PyGIDirection direction,
685                 gssize c_arg_index,
686                 gssize py_arg_index)
687 {
688     PyGIArgCache *arg_cache = NULL;
689     gssize child_offset = 0;
690     GITypeTag type_tag;
691
692     type_tag = g_type_info_get_tag (type_info);
693
694     if (callable_cache != NULL)
695         child_offset =
696             (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
697                 callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0;
698
699     switch (type_tag) {
700        case GI_TYPE_TAG_VOID:
701            arg_cache = _arg_cache_alloc ();
702            if (arg_cache == NULL)
703                break;
704
705            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
706                _arg_cache_from_py_void_setup (arg_cache);
707
708            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
709                _arg_cache_to_py_void_setup (arg_cache);
710
711            break;
712        case GI_TYPE_TAG_BOOLEAN:
713        case GI_TYPE_TAG_INT8:
714        case GI_TYPE_TAG_UINT8:
715        case GI_TYPE_TAG_INT16:
716        case GI_TYPE_TAG_UINT16:
717        case GI_TYPE_TAG_INT32:
718        case GI_TYPE_TAG_UINT32:
719        case GI_TYPE_TAG_INT64:
720        case GI_TYPE_TAG_UINT64:
721        case GI_TYPE_TAG_FLOAT:
722        case GI_TYPE_TAG_DOUBLE:
723        case GI_TYPE_TAG_UNICHAR:
724        case GI_TYPE_TAG_GTYPE:
725            arg_cache = _arg_cache_alloc ();
726            if (arg_cache == NULL)
727                break;
728
729            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
730                _arg_cache_from_py_basic_type_setup (arg_cache);
731
732            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
733                _arg_cache_to_py_basic_type_setup (arg_cache);
734
735            break;
736        case GI_TYPE_TAG_UTF8:
737        case GI_TYPE_TAG_FILENAME:
738            arg_cache = _arg_cache_alloc ();
739            if (arg_cache == NULL)
740                break;
741
742            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
743                _arg_cache_from_py_utf8_setup (arg_cache, transfer);
744
745            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
746                _arg_cache_to_py_utf8_setup (arg_cache, transfer);
747
748            break;
749        case GI_TYPE_TAG_ARRAY:
750            {
751                PyGISequenceCache *seq_cache =
752                    _sequence_cache_new (type_info,
753                                         direction,
754                                         transfer,
755                                         child_offset);
756
757                arg_cache = (PyGIArgCache *)seq_cache;
758                if (arg_cache == NULL)
759                    break;
760
761                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
762                    _arg_cache_from_py_array_setup (arg_cache,
763                                                    callable_cache,
764                                                    type_info,
765                                                    transfer,
766                                                    direction,
767                                                    c_arg_index);
768
769                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
770                    _arg_cache_to_py_array_setup (arg_cache,
771                                                  callable_cache,
772                                                  type_info,
773                                                  transfer,
774                                                  direction,
775                                                  c_arg_index);
776
777                /* ugly edge case code:
778                 *  
779                 * length can come before the array parameter which means we
780                 * need to update indexes if this happens
781                 */ 
782                if (seq_cache->len_arg_index > -1 &&
783                    callable_cache->args_cache[seq_cache->len_arg_index]->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
784                    gssize i;
785                    PyGIArgCache *child_cache =
786                        callable_cache->args_cache[seq_cache->len_arg_index];
787
788                    child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
789                    py_arg_index -= 1;
790                    callable_cache->n_py_args -= 1;
791
792                    for (i = seq_cache->len_arg_index + 1; 
793                           i < callable_cache->n_args; 
794                             i++) {
795                        PyGIArgCache *update_cache = callable_cache->args_cache[i];
796                        if (update_cache == NULL)
797                            break;
798
799                        update_cache->py_arg_index -= 1;
800                    }
801                }
802
803                break;
804            }
805        case GI_TYPE_TAG_GLIST:
806            {
807                PyGISequenceCache *seq_cache =
808                    _sequence_cache_new (type_info,
809                                         direction,
810                                         transfer,
811                                         child_offset);
812
813                arg_cache = (PyGIArgCache *)seq_cache;
814                if (arg_cache == NULL)
815                    break;
816
817                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
818                    _arg_cache_from_py_glist_setup (arg_cache, transfer);
819
820                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
821                    _arg_cache_to_py_glist_setup (arg_cache, transfer);
822
823
824                break;
825            }
826        case GI_TYPE_TAG_GSLIST:
827            {
828                PyGISequenceCache *seq_cache =
829                    _sequence_cache_new (type_info,
830                                         direction,
831                                         transfer,
832                                         child_offset);
833
834                arg_cache = (PyGIArgCache *)seq_cache;
835                if (arg_cache == NULL)
836                    break;
837
838                if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
839                    _arg_cache_from_py_gslist_setup (arg_cache, transfer);
840
841                if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
842                    _arg_cache_to_py_gslist_setup (arg_cache, transfer);
843
844                break;
845             }
846        case GI_TYPE_TAG_GHASH:
847            arg_cache =
848                (PyGIArgCache *)_hash_cache_new (type_info,
849                                                 direction,
850                                                 transfer);
851
852            if (arg_cache == NULL)
853                    break;
854
855            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
856                _arg_cache_from_py_ghash_setup (arg_cache);
857
858            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
859                _arg_cache_to_py_ghash_setup (arg_cache);
860            }
861
862            break;
863        case GI_TYPE_TAG_INTERFACE:
864            {
865                GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
866                arg_cache = _arg_cache_new_for_interface (interface_info,
867                                                          callable_cache,
868                                                          arg_info,
869                                                          transfer,
870                                                          direction,
871                                                          c_arg_index,
872                                                          py_arg_index);
873
874                g_base_info_unref ( (GIBaseInfo *)interface_info);
875                break;
876            }
877        case GI_TYPE_TAG_ERROR:
878            arg_cache = _arg_cache_alloc ();
879            if (arg_cache == NULL)
880                break;
881
882            if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
883                _arg_cache_from_py_gerror_setup (arg_cache);
884
885            if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
886                _arg_cache_to_py_gerror_setup (arg_cache);
887
888            break;
889     }
890
891     if (arg_cache != NULL) {
892         arg_cache->direction = direction;
893         arg_cache->transfer = transfer;
894         arg_cache->type_tag = type_tag;
895         arg_cache->py_arg_index = py_arg_index;
896         arg_cache->c_arg_index = c_arg_index;
897         arg_cache->is_pointer = g_type_info_is_pointer (type_info);
898         g_base_info_ref ( (GIBaseInfo *) type_info);
899         arg_cache->type_info = type_info;
900     }
901
902     return arg_cache;
903 }
904
905 static void
906 _arg_name_list_generate (PyGICallableCache *callable_cache)
907 {
908     GSList * arg_name_list = NULL;
909     int i;
910
911     if (callable_cache->arg_name_hash == NULL) {
912         callable_cache->arg_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
913     } else {
914         g_hash_table_remove_all (callable_cache->arg_name_hash);
915     }
916
917     for (i=0; i < callable_cache->n_args; i++) {
918         PyGIArgCache *arg_cache = NULL;
919
920         arg_cache = callable_cache->args_cache[i];
921
922         if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD &&
923             arg_cache->meta_type != PYGI_META_ARG_TYPE_CLOSURE &&
924                 (arg_cache->direction == PYGI_DIRECTION_FROM_PYTHON ||
925                  arg_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL)) {
926
927             gpointer arg_name = (gpointer)arg_cache->arg_name;
928
929             arg_name_list = g_slist_prepend (arg_name_list, arg_name);
930             if (arg_name != NULL) {
931                 g_hash_table_insert (callable_cache->arg_name_hash, arg_name, arg_name);
932             }
933         }
934     }
935
936     callable_cache->arg_name_list = g_slist_reverse (arg_name_list);
937 }
938
939 /* Generate the cache for the callable's arguments */
940 static gboolean
941 _args_cache_generate (GICallableInfo *callable_info,
942                       PyGICallableCache *callable_cache)
943 {
944     gssize arg_index = 0;
945     gssize i;
946     GITypeInfo *return_info;
947     GITransfer return_transfer;
948     PyGIArgCache *return_cache;
949     PyGIDirection return_direction;
950
951     /* determine if we are marshalling the return to or from python */
952     if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
953         return_direction = PYGI_DIRECTION_FROM_PYTHON;
954     else
955         return_direction = PYGI_DIRECTION_TO_PYTHON;
956
957     /* cache the return arg */
958     return_info =
959         g_callable_info_get_return_type (callable_info);
960     return_transfer =
961         g_callable_info_get_caller_owns (callable_info);
962     return_cache =
963         _arg_cache_new (return_info,
964                         callable_cache,
965                         NULL,
966                         return_transfer,
967                         return_direction,
968                         -1,
969                         -1);
970     if (return_cache == NULL)
971         return FALSE;
972
973     return_cache->is_skipped = g_callable_info_skip_return (callable_info);
974     callable_cache->return_cache = return_cache;
975     g_base_info_unref (return_info);
976
977     /* first arg is the instance */
978     if (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
979             callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
980         GIInterfaceInfo *interface_info;
981         PyGIArgCache *instance_cache;
982         PyGIDirection instance_direction;
983
984         instance_direction = PYGI_DIRECTION_FROM_PYTHON;
985
986
987         interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
988
989         instance_cache =
990             _arg_cache_new_for_interface (interface_info,
991                                           callable_cache,
992                                           NULL,
993                                           GI_TRANSFER_NOTHING,
994                                           instance_direction,
995                                           arg_index,
996                                           0);
997
998         /* FIXME: marshal interfaces from_py */
999         instance_cache->from_py_marshaller = _pygi_marshal_from_py_interface_instance;
1000         g_base_info_unref ( (GIBaseInfo *)interface_info);
1001
1002         if (instance_cache == NULL)
1003             return FALSE;
1004
1005         callable_cache->args_cache[arg_index] = instance_cache;
1006
1007         arg_index++;
1008         callable_cache->n_from_py_args++;
1009         callable_cache->n_py_args++;
1010     }
1011
1012
1013     for (i=0; arg_index < callable_cache->n_args; arg_index++, i++) {
1014         PyGIArgCache *arg_cache = NULL;
1015         GIArgInfo *arg_info;
1016         GITypeInfo *type_info;
1017         GIDirection gi_direction;
1018         PyGIDirection direction;
1019         GITransfer transfer;
1020         GITypeTag type_tag;
1021         gboolean is_caller_allocates = FALSE;
1022         gssize py_arg_index = -1;
1023
1024         arg_info = g_callable_info_get_arg (callable_info, i);
1025
1026         if (g_arg_info_get_closure (arg_info) == i) {
1027
1028             arg_cache = _arg_cache_alloc ();
1029             callable_cache->args_cache[arg_index] = arg_cache;
1030
1031             arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
1032             arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
1033             arg_cache->meta_type = PYGI_META_ARG_TYPE_CLOSURE;
1034             arg_cache->c_arg_index = i;
1035
1036             callable_cache->n_from_py_args++;
1037
1038             g_base_info_unref ( (GIBaseInfo *)arg_info);
1039
1040             continue;
1041         }
1042
1043         /* For vfuncs and callbacks our marshalling directions
1044            are reversed */
1045         gi_direction = g_arg_info_get_direction (arg_info);
1046         if (gi_direction == GI_DIRECTION_INOUT) {
1047             direction = PYGI_DIRECTION_BIDIRECTIONAL;
1048         } else if (gi_direction == GI_DIRECTION_IN) {
1049             direction = PYGI_DIRECTION_FROM_PYTHON;
1050             if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
1051                 direction = PYGI_DIRECTION_TO_PYTHON;
1052         } else {
1053             direction = PYGI_DIRECTION_TO_PYTHON;
1054             if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
1055                 direction = PYGI_DIRECTION_FROM_PYTHON;
1056         }
1057
1058         transfer = g_arg_info_get_ownership_transfer (arg_info);
1059         type_info = g_arg_info_get_type (arg_info);
1060         type_tag = g_type_info_get_tag (type_info);
1061
1062         if (type_tag == GI_TYPE_TAG_INTERFACE || type_tag == GI_TYPE_TAG_ARRAY)
1063             is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
1064
1065         /* must be an child arg filled in by its owner
1066          * and continue
1067          * fill in it's c_arg_index, add to the in count
1068          */
1069         if (callable_cache->args_cache[arg_index] != NULL) {
1070             arg_cache = callable_cache->args_cache[arg_index];
1071             if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) {
1072                 arg_cache->py_arg_index = callable_cache->n_py_args;
1073                 callable_cache->n_py_args++;
1074             }
1075
1076             if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1077                 arg_cache->c_arg_index = callable_cache->n_from_py_args;
1078                 callable_cache->n_from_py_args++;
1079             }
1080
1081             if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1082                 callable_cache->n_to_py_args++;
1083                 callable_cache->n_to_py_child_args++;
1084             }
1085
1086             arg_cache->type_tag = g_type_info_get_tag (type_info);
1087
1088             g_base_info_unref (type_info);
1089             g_base_info_unref ( (GIBaseInfo *)arg_info);
1090             continue;
1091         }
1092
1093         if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1094             py_arg_index = callable_cache->n_py_args;
1095             callable_cache->n_from_py_args++;
1096             callable_cache->n_py_args++;
1097         }
1098
1099         arg_cache =
1100             _arg_cache_new (type_info,
1101                             callable_cache,
1102                             arg_info,
1103                             transfer,
1104                             direction,
1105                             arg_index,
1106                             py_arg_index);
1107
1108         if (arg_cache == NULL)
1109             goto arg_err;
1110
1111         arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
1112         arg_cache->allow_none = g_arg_info_may_be_null(arg_info);
1113         arg_cache->is_caller_allocates = is_caller_allocates;
1114
1115         if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL) {
1116             callable_cache->n_to_py_args++;
1117
1118             if (arg_cache == NULL)
1119                 goto arg_err;
1120
1121             callable_cache->to_py_args =
1122                 g_slist_append (callable_cache->to_py_args, arg_cache);
1123         }
1124
1125         callable_cache->args_cache[arg_index] = arg_cache;
1126         g_base_info_unref( (GIBaseInfo *)type_info);
1127         g_base_info_unref( (GIBaseInfo *)arg_info);
1128
1129         continue;
1130 arg_err:
1131         g_base_info_unref( (GIBaseInfo *)type_info);
1132         g_base_info_unref( (GIBaseInfo *)arg_info);
1133         return FALSE;
1134     }
1135
1136     _arg_name_list_generate (callable_cache);
1137
1138     return TRUE;
1139 }
1140
1141 PyGICallableCache *
1142 _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback)
1143 {
1144     PyGICallableCache *cache;
1145     GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)callable_info);
1146
1147     cache = g_slice_new0 (PyGICallableCache);
1148
1149     if (cache == NULL)
1150         return NULL;
1151
1152     cache->name = g_base_info_get_name ((GIBaseInfo *)callable_info);
1153
1154     if (g_base_info_is_deprecated (callable_info)) {
1155         const gchar *deprecated = g_base_info_get_attribute (callable_info, "deprecated");
1156         gchar *warning;
1157         if (deprecated != NULL)
1158             warning = g_strdup_printf ("%s.%s is deprecated: %s",
1159                                        g_base_info_get_namespace (callable_info), cache->name,
1160                                        deprecated);
1161         else
1162             warning = g_strdup_printf ("%s.%s is deprecated",
1163                                        g_base_info_get_namespace (callable_info), cache->name);
1164         PyErr_WarnEx(PyExc_DeprecationWarning, warning, 0);
1165         g_free (warning);
1166     }
1167
1168     if (type == GI_INFO_TYPE_FUNCTION) {
1169         GIFunctionInfoFlags flags;
1170
1171         flags = g_function_info_get_flags ( (GIFunctionInfo *)callable_info);
1172
1173         if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
1174             cache->function_type = PYGI_FUNCTION_TYPE_CONSTRUCTOR;
1175         else if (flags & GI_FUNCTION_IS_METHOD)
1176             cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
1177     } else if (type == GI_INFO_TYPE_VFUNC) {
1178         cache->function_type = PYGI_FUNCTION_TYPE_VFUNC;
1179     } else if (type == GI_INFO_TYPE_CALLBACK) {
1180         if (is_ccallback)
1181             cache->function_type = PYGI_FUNCTION_TYPE_CCALLBACK;
1182         else
1183             cache->function_type = PYGI_FUNCTION_TYPE_CALLBACK;
1184     } else {
1185         cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
1186     }
1187
1188     cache->n_args = g_callable_info_get_n_args (callable_info);
1189
1190     /* if we are a method or vfunc make sure the instance parameter is counted */
1191     if (cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
1192             cache->function_type == PYGI_FUNCTION_TYPE_VFUNC)
1193         cache->n_args++;
1194
1195     if (cache->n_args > 0)
1196         cache->args_cache = g_slice_alloc0 (cache->n_args * sizeof (PyGIArgCache *));
1197
1198     if (!_args_cache_generate (callable_info, cache))
1199         goto err;
1200
1201     return cache;
1202 err:
1203     _pygi_callable_cache_free (cache);
1204     return NULL;
1205 }