pygi-cache.c 50.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */
21 22

#include "pygi-info.h"
23
#include "pygi-cache.h"
24 25
#include "pygi-marshal-to-py.h"
#include "pygi-marshal-from-py.h"
26
#include "pygi-marshal-cleanup.h"
27
#include "pygi-type.h"
28
#include <girepository.h>
29

30 31 32 33
PyGIArgCache * _arg_cache_new (GITypeInfo *type_info,
                               PyGICallableCache *callable_cache,
                               GIArgInfo *arg_info,
                               GITransfer transfer,
34
                               PyGIDirection direction,
35 36 37 38 39 40 41
                               gssize c_arg_index,
                               gssize py_arg_index);

PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
                                             PyGICallableCache *callable_cache,
                                             GIArgInfo *arg_info,
                                             GITransfer transfer,
42
                                             PyGIDirection direction,
43 44
                                             gssize c_arg_index,
                                             gssize py_arg_index);
45
/* cleanup */
John (J5) Palmieri's avatar
John (J5) Palmieri committed
46
void
47
_pygi_arg_cache_free (PyGIArgCache *cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
48 49 50 51
{
    if (cache == NULL)
        return;

52
    if (cache->type_info != NULL)
53
        g_base_info_unref ( (GIBaseInfo *)cache->type_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
54
    if (cache->destroy_notify)
55
        cache->destroy_notify (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
56
    else
57
        g_slice_free (PyGIArgCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
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 69
            g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
        g_slice_free (PyGIInterfaceCache, cache);
70 71 72
    }
}

John (J5) Palmieri's avatar
John (J5) Palmieri committed
73
static void
74
_hash_cache_free_func (PyGIHashCache *cache)
75
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
76
    if (cache != NULL) {
77 78 79
        _pygi_arg_cache_free (cache->key_cache);
        _pygi_arg_cache_free (cache->value_cache);
        g_slice_free (PyGIHashCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
80
    }
81 82
}

83
static void
84
_sequence_cache_free_func (PyGISequenceCache *cache)
85
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
86
    if (cache != NULL) {
87 88
        _pygi_arg_cache_free (cache->item_cache);
        g_slice_free (PyGISequenceCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
89
    }
90 91
}

92
static void
93
_callback_cache_free_func (PyGICallbackCache *cache)
94
{
95 96
    if (cache != NULL) {
        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 109 110
    if (cache == NULL)
        return;

111
    g_slist_free (cache->to_py_args);
112 113 114
    g_slist_free (cache->arg_name_list);
    g_hash_table_destroy (cache->arg_name_hash);

115 116
    for (i = 0; i < cache->n_args; i++) {
        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 123
    g_slice_free1 (cache->n_args * sizeof (PyGIArgCache *), cache->args_cache);
    g_slice_free (PyGICallableCache, cache);
124 125 126 127
}

/* cache generation */

128 129
static PyGIInterfaceCache *
_interface_cache_new (GIInterfaceInfo *iface_info)
130 131
{
    PyGIInterfaceCache *ic;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
132

133 134
    ic = g_slice_new0 (PyGIInterfaceCache);
    ( (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 139 140

    if (ic->py_type == NULL)
        return NULL;

141
    ic->type_name = _pygi_g_base_info_get_fullname (iface_info);
142 143 144
    return ic;
}

145 146 147 148 149
static PyGISequenceCache *
_sequence_cache_new (GITypeInfo *type_info,
                     GIDirection direction,
                     GITransfer transfer,
                     gssize child_offset)
150 151 152
{
    PyGISequenceCache *sc;
    GITypeInfo *item_type_info;
153
    GITransfer item_transfer;
154

155 156
    sc = g_slice_new0 (PyGISequenceCache);
    ( (PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
157 158 159

    sc->fixed_size = -1;
    sc->len_arg_index = -1;
160
    sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info);
161
    if (!sc->is_zero_terminated) {
162
        sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
163
        if (sc->fixed_size < 0)
164
            sc->len_arg_index = g_type_info_get_array_length (type_info) + child_offset;
165
    }
166

167 168
    item_type_info = g_type_info_get_param_type (type_info, 0);

169 170
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
171

172 173 174 175 176 177
    sc->item_cache = _arg_cache_new (item_type_info,
                                     NULL,
                                     NULL,
                                     item_transfer,
                                     direction,
                                     0, 0);
178

179
    if (sc->item_cache == NULL) {
180
        _pygi_arg_cache_free ( (PyGIArgCache *)sc);
181 182
        return NULL;
    }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
183

184 185
    sc->item_size = _pygi_g_type_info_size (item_type_info);
    g_base_info_unref ( (GIBaseInfo *)item_type_info);
186

187
    return sc;
188
}
189 190 191 192
static PyGIHashCache *
_hash_cache_new (GITypeInfo *type_info,
                 GIDirection direction,
                 GITransfer transfer)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
193 194 195 196
{
    PyGIHashCache *hc;
    GITypeInfo *key_type_info;
    GITypeInfo *value_type_info;
197
    GITransfer item_transfer;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
198

199 200
    hc = g_slice_new0 (PyGIHashCache);
    ( (PyGIArgCache *)hc)->destroy_notify = (GDestroyNotify)_hash_cache_free_func;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
201 202 203
    key_type_info = g_type_info_get_param_type (type_info, 0);
    value_type_info = g_type_info_get_param_type (type_info, 1);

204 205
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
206

207 208 209 210 211 212
    hc->key_cache = _arg_cache_new (key_type_info,
                                    NULL,
                                    NULL,
                                    item_transfer,
                                    direction,
                                    0, 0);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
213 214

    if (hc->key_cache == NULL) {
215
        _pygi_arg_cache_free ( (PyGIArgCache *)hc);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
216 217 218
        return NULL;
    }

219 220 221 222 223 224
    hc->value_cache = _arg_cache_new (value_type_info,
                                      NULL,
                                      NULL,
                                      item_transfer,
                                      direction,
                                      0, 0);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
225 226

    if (hc->value_cache == NULL) {
227
        _pygi_arg_cache_free ( (PyGIArgCache *)hc);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
228 229 230 231 232 233 234 235
        return NULL;
    }

    g_base_info_unref( (GIBaseInfo *)key_type_info);
    g_base_info_unref( (GIBaseInfo *)value_type_info);

    return hc;
}
236

237 238 239 240
static PyGICallbackCache *
_callback_cache_new (GIArgInfo *arg_info,
                     GIInterfaceInfo *iface_info,
                     gssize child_offset)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
241 242 243
{
   PyGICallbackCache *cc;

244
   cc = g_slice_new0 (PyGICallbackCache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
245 246
   ( (PyGIArgCache *)cc)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;

247
   cc->user_data_index = g_arg_info_get_closure (arg_info);
248
   if (cc->user_data_index != -1)
249
       cc->user_data_index += child_offset;
250
   cc->destroy_notify_index = g_arg_info_get_destroy (arg_info);
251
   if (cc->destroy_notify_index != -1)
252
       cc->destroy_notify_index += child_offset;
253
   cc->scope = g_arg_info_get_scope (arg_info);
254 255
   g_base_info_ref( (GIBaseInfo *)iface_info);
   cc->interface_info = iface_info;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
256 257 258
   return cc;
}

259 260
static PyGIArgCache *
_arg_cache_alloc (void)
261
{
262
    return g_slice_new0 (PyGIArgCache);
263
}
264

265
static void
266
_arg_cache_from_py_void_setup (PyGIArgCache *arg_cache)
267
{
268
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_void;
269
}
270

271
static void
272
_arg_cache_to_py_void_setup (PyGIArgCache *arg_cache)
273
{
274
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_void;
275 276
}

277
static void
278
_arg_cache_from_py_boolean_setup (PyGIArgCache *arg_cache)
279
{
280
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_boolean;
281 282
}

283
static void
284
_arg_cache_to_py_boolean_setup (PyGIArgCache *arg_cache)
285
{
286
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_boolean;
287 288
}

289
static void
290
_arg_cache_from_py_int8_setup (PyGIArgCache *arg_cache)
291
{
292
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_int8;
293 294
}

295
static void
296
_arg_cache_to_py_int8_setup (PyGIArgCache *arg_cache)
297
{
298
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_int8;
299 300
}

301
static void
302
_arg_cache_from_py_uint8_setup (PyGIArgCache *arg_cache)
303
{
304
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint8;
305 306
}

307
static void
308
_arg_cache_to_py_uint8_setup (PyGIArgCache *arg_cache)
309
{
310
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint8;
311 312
}

313
static void
314
_arg_cache_from_py_int16_setup (PyGIArgCache *arg_cache)
315
{
316
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_int16;
317 318
}

319
static void
320
_arg_cache_to_py_int16_setup (PyGIArgCache *arg_cache)
321
{
322
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_int16;
323 324
}

325
static void
326
_arg_cache_from_py_uint16_setup (PyGIArgCache *arg_cache)
327
{
328
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint16;
329 330
}

331
static void
332
_arg_cache_to_py_uint16_setup (PyGIArgCache *arg_cache)
333
{
334
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint16;
335 336
}

337
static void
338
_arg_cache_from_py_int32_setup (PyGIArgCache *arg_cache)
339
{
340
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_int32;
341 342
}

343
static void
344
_arg_cache_to_py_int32_setup (PyGIArgCache *arg_cache)
345
{
346
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_int32;
347 348
}

349
static void
350
_arg_cache_from_py_uint32_setup (PyGIArgCache *arg_cache)
351
{
352
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint32;
353 354
}

355
static void
356
_arg_cache_to_py_uint32_setup (PyGIArgCache *arg_cache)
357
{
358
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint32;
359 360
}

361
static void
362
_arg_cache_from_py_int64_setup (PyGIArgCache *arg_cache)
363
{
364
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_int64;
365 366
}

367
static void
368
_arg_cache_to_py_int64_setup (PyGIArgCache *arg_cache)
369
{
370
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_int64;
371 372
}

373
static void
374
_arg_cache_from_py_uint64_setup (PyGIArgCache *arg_cache)
375
{
376
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_uint64;
377 378
}

379
static void
380
_arg_cache_to_py_uint64_setup (PyGIArgCache *arg_cache)
381
{
382
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_uint64;
383 384
}

385
static void
386
_arg_cache_from_py_float_setup (PyGIArgCache *arg_cache)
387
{
388
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_float;
389 390
}

391
static void
392
_arg_cache_to_py_float_setup (PyGIArgCache *arg_cache)
393
{
394
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_float;
395 396
}

397
static void
398
_arg_cache_from_py_double_setup (PyGIArgCache *arg_cache)
399
{
400
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_double;
401 402
}

403
static void
404
_arg_cache_to_py_double_setup (PyGIArgCache *arg_cache)
405
{
406
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_double;
407 408
}

409
static void
410
_arg_cache_from_py_unichar_setup (PyGIArgCache *arg_cache)
411
{
412
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_unichar;
413 414
}

415
static void
416
_arg_cache_to_py_unichar_setup (PyGIArgCache *arg_cache)
417
{
418
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_unichar;
419 420
}

421
static void
422
_arg_cache_from_py_gtype_setup (PyGIArgCache *arg_cache)
423
{
424
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_gtype;
425 426
}

427
static void
428
_arg_cache_to_py_gtype_setup (PyGIArgCache *arg_cache)
429
{
430
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_gtype;
431 432
}

433
static void
434 435
_arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache,
                               GITransfer transfer)
436
{
437 438
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_utf8;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
439
}
440

441
static void
442 443
_arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache,
                               GITransfer transfer)
444
{
445 446
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_utf8;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
447 448
}

449
static void
450 451
_arg_cache_from_py_filename_setup (PyGIArgCache *arg_cache,
                                 GITransfer transfer)
452
{
453 454
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_filename;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
455 456
}

457
static void
458 459
_arg_cache_to_py_filename_setup (PyGIArgCache *arg_cache,
                                 GITransfer transfer)
460
{
461 462
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_filename;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
463
}
464

465
static gboolean
466 467 468 469
_arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
                                PyGICallableCache *callable_cache,
                                GITypeInfo *type_info,
                                GITransfer transfer,
470 471
                                PyGIDirection direction,
                                gssize arg_index)
472
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
473
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
474
    seq_cache->array_type = g_type_info_get_array_type (type_info);
475

476
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
477

478
    if (seq_cache->len_arg_index >= 0) {
479
        PyGIArgCache *child_cache = 
480
            callable_cache->args_cache[seq_cache->len_arg_index];
481

482
        if (child_cache == NULL) {
483
            child_cache = _arg_cache_alloc ();
484 485
        } else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
                   child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
486 487 488
            return TRUE;
        }

489 490 491 492 493
        if (seq_cache->len_arg_index < arg_index)
            child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE;
        else
            child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;

494
        child_cache->direction = direction;
495 496
        child_cache->to_py_marshaller = NULL;
        child_cache->from_py_marshaller = NULL;
497

498
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
499 500
    }

501
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
502 503

    return TRUE;
504 505
}

506
static gboolean
507 508 509 510 511 512
_arg_cache_to_py_array_setup (PyGIArgCache *arg_cache,
                              PyGICallableCache *callable_cache,
                              GITypeInfo *type_info,
                              GITransfer transfer,
                              PyGIDirection direction,
                              gssize arg_index)
513
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
514
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
515 516
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_array;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_array;
517

518
    seq_cache->array_type = g_type_info_get_array_type (type_info);
519 520

    if (seq_cache->len_arg_index >= 0) {
521
        PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index];
522
        if (seq_cache->len_arg_index < arg_index)
523
             callable_cache->n_to_py_child_args++;
524

525
        if (child_cache != NULL) {
526 527
            callable_cache->to_py_args =
                g_slist_remove (callable_cache->to_py_args, child_cache);
528 529 530 531

            if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
                child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE)
                return TRUE;
532
        } else {
533
            child_cache = _arg_cache_alloc ();
534
        }
535

536 537
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
538 539
        child_cache->to_py_marshaller = NULL;
        child_cache->from_py_marshaller = NULL;
540

541
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
542 543 544 545 546
    }

    return TRUE;
}

547
static void
548 549
_arg_cache_from_py_glist_setup (PyGIArgCache *arg_cache,
                                GITransfer transfer)
550
{
551 552
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_glist;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
553
}
554

555
static void
556 557
_arg_cache_to_py_glist_setup (PyGIArgCache *arg_cache,
                              GITransfer transfer)
558
{
559 560
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_glist;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
561 562
}

563
static void
564 565
_arg_cache_from_py_gslist_setup (PyGIArgCache *arg_cache,
                                 GITransfer transfer)
566
{
567 568
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_gslist;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_glist;
569
}
570

571
static void
572 573
_arg_cache_to_py_gslist_setup (PyGIArgCache *arg_cache,
                                 GITransfer transfer)
574
{
575 576
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_gslist;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_glist;
577 578
}

579
static void
580
_arg_cache_from_py_ghash_setup (PyGIArgCache *arg_cache)
581
{
582 583
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_ghash;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_ghash;
584 585
}

586
static void
587
_arg_cache_to_py_ghash_setup (PyGIArgCache *arg_cache)
588
{
589 590
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_ghash;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_ghash;
591 592
}

593
static void
594
_arg_cache_from_py_gerror_setup (PyGIArgCache *arg_cache)
595
{
596
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror;
597
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
598 599
}

600
static void
601
_arg_cache_to_py_gerror_setup (PyGIArgCache *arg_cache)
602
{
603
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror;
604
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
605 606
}

607
static void
608 609
_arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache,
                                          GITransfer transfer)
610
{
611
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct;
612 613
}

614
static void
615 616
_arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
617
{
618
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct;
619 620
}

621
static void
622 623 624
_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                           GIInterfaceInfo *iface_info,
                                           GITransfer transfer)
625
{
626
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
627
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
628
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct;
629 630

    if (iface_cache->g_type == G_TYPE_VALUE)
631
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
632
    else if (iface_cache->is_foreign)
633
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
634
}
635

636
static void
637 638 639
_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                         GIInterfaceInfo *iface_info,
                                         GITransfer transfer)
640 641
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
642
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
643
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct;
644 645

    if (iface_cache->is_foreign)
646
        arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
647 648
}

649
static void
650 651
_arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache,
                                           GITransfer transfer)
652
{
653 654
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
655 656
}

657
static void
658 659
_arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache,
                                         GITransfer transfer)
660
{
661 662
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object;
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
663 664
}

665
static void
666 667
_arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache,
                                             PyGICallableCache *callable_cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
668
{
669
    PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
670
    if (callback_cache->user_data_index >= 0) {
671
        PyGIArgCache *user_data_arg_cache = _arg_cache_alloc ();
672
        user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
673
        user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
674
        callable_cache->args_cache[callback_cache->user_data_index] = user_data_arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
675
    }
676 677

    if (callback_cache->destroy_notify_index >= 0) {
678
        PyGIArgCache *destroy_arg_cache = _arg_cache_alloc ();
679
        destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
680
        destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
681
        callable_cache->args_cache[callback_cache->destroy_notify_index] = destroy_arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
682
    }
683
    arg_cache->from_py_marshaller = _pygi_marshal_from_