pygi-cache.c 51.4 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 165 166
            sc->len_arg_index = g_type_info_get_array_length (type_info);
            if (sc->len_arg_index >= 0)
                sc->len_arg_index += child_offset;
167
    }
168

169 170
    item_type_info = g_type_info_get_param_type (type_info, 0);

171 172
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
173

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

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

186 187
    sc->item_size = _pygi_g_type_info_size (item_type_info);
    g_base_info_unref ( (GIBaseInfo *)item_type_info);
188

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

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

206 207
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
208

209 210 211 212 213 214
    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
215 216

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

221 222 223 224 225 226
    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
227 228

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

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

    return hc;
}
238

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

478
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
479

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

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

491 492 493 494 495
        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;

496
        child_cache->direction = direction;
497 498
        child_cache->to_py_marshaller = NULL;
        child_cache->from_py_marshaller = NULL;
499

500
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
501 502
    }

503
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array;
504 505

    return TRUE;
506 507
}

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

520
    seq_cache->array_type = g_type_info_get_array_type (type_info);
521 522

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

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

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

538 539
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
540 541
        child_cache->to_py_marshaller = NULL;
        child_cache->from_py_marshaller = NULL;
542

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

    return TRUE;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (iface_cache->is_foreign)
648
        arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
649 650
}

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

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

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

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