pygi-cache.c 46.5 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-in.h"
#include "pygi-marshal-out.h"
26
#include "pygi-marshal-cleanup.h"
27
#include "pygi-type.h"
28
#include <girepository.h>
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
PyGIArgCache * _arg_cache_new (GITypeInfo *type_info,
                               PyGICallableCache *callable_cache,
                               GIArgInfo *arg_info,
                               GITransfer transfer,
                               GIDirection direction,
                               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,
                                             GIDirection direction,
                                             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->out_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
    GITypeTag item_type_tag;
154
    GITransfer item_transfer;
155

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

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

168 169
    item_type_info = g_type_info_get_param_type (type_info, 0);

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

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

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

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

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

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

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

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

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

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

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

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

    return hc;
}
237

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

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

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

264
static void
265
_arg_cache_in_void_setup (PyGIArgCache *arg_cache)
266
{
267 268
    arg_cache->in_marshaller = _pygi_marshal_in_void;
}
269

270
static void
271
_arg_cache_out_void_setup (PyGIArgCache *arg_cache)
272 273
{
    arg_cache->out_marshaller = _pygi_marshal_out_void;
274 275
}

276
static void
277
_arg_cache_in_boolean_setup (PyGIArgCache *arg_cache)
278
{
279
    arg_cache->in_marshaller = _pygi_marshal_in_boolean;
280 281
}

282
static void
283
_arg_cache_out_boolean_setup (PyGIArgCache *arg_cache)
284 285 286 287
{
    arg_cache->out_marshaller = _pygi_marshal_out_boolean;
}

288
static void
289
_arg_cache_in_int8_setup (PyGIArgCache *arg_cache)
290
{
291
    arg_cache->in_marshaller = _pygi_marshal_in_int8;
292 293
}

294
static void
295
_arg_cache_out_int8_setup (PyGIArgCache *arg_cache)
296 297 298 299
{
    arg_cache->out_marshaller = _pygi_marshal_out_int8;
}

300
static void
301
_arg_cache_in_uint8_setup (PyGIArgCache *arg_cache)
302
{
303
    arg_cache->in_marshaller = _pygi_marshal_in_uint8;
304 305
}

306
static void
307
_arg_cache_out_uint8_setup (PyGIArgCache *arg_cache)
308 309 310 311
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint8;
}

312
static void
313
_arg_cache_in_int16_setup (PyGIArgCache *arg_cache)
314
{
315
    arg_cache->in_marshaller = _pygi_marshal_in_int16;
316 317
}

318
static void
319
_arg_cache_out_int16_setup (PyGIArgCache *arg_cache)
320 321 322 323
{
    arg_cache->out_marshaller = _pygi_marshal_out_int16;
}

324
static void
325
_arg_cache_in_uint16_setup (PyGIArgCache *arg_cache)
326
{
327
    arg_cache->in_marshaller = _pygi_marshal_in_uint16;
328 329
}

330
static void
331
_arg_cache_out_uint16_setup (PyGIArgCache *arg_cache)
332 333 334 335
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint16;
}

336
static void
337
_arg_cache_in_int32_setup (PyGIArgCache *arg_cache)
338
{
339
    arg_cache->in_marshaller = _pygi_marshal_in_int32;
340 341
}

342
static void
343
_arg_cache_out_int32_setup (PyGIArgCache *arg_cache)
344 345 346 347
{
    arg_cache->out_marshaller = _pygi_marshal_out_int32;
}

348
static void
349
_arg_cache_in_uint32_setup (PyGIArgCache *arg_cache)
350
{
351
    arg_cache->in_marshaller = _pygi_marshal_in_uint32;
352 353
}

354
static void
355
_arg_cache_out_uint32_setup (PyGIArgCache *arg_cache)
356 357 358 359
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint32;
}

360
static void
361
_arg_cache_in_int64_setup (PyGIArgCache *arg_cache)
362
{
363
    arg_cache->in_marshaller = _pygi_marshal_in_int64;
364 365
}

366
static void
367
_arg_cache_out_int64_setup (PyGIArgCache *arg_cache)
368 369 370 371
{
    arg_cache->out_marshaller = _pygi_marshal_out_int64;
}

372
static void
373
_arg_cache_in_uint64_setup (PyGIArgCache *arg_cache)
374
{
375
    arg_cache->in_marshaller = _pygi_marshal_in_uint64;
376 377
}

378
static void
379
_arg_cache_out_uint64_setup (PyGIArgCache *arg_cache)
380 381 382 383
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint64;
}

384
static void
385
_arg_cache_in_float_setup (PyGIArgCache *arg_cache)
386
{
387
    arg_cache->in_marshaller = _pygi_marshal_in_float;
388 389
}

390
static void
391
_arg_cache_out_float_setup (PyGIArgCache *arg_cache)
392 393 394 395
{
    arg_cache->out_marshaller = _pygi_marshal_out_float;
}

396
static void
397
_arg_cache_in_double_setup (PyGIArgCache *arg_cache)
398
{
399
    arg_cache->in_marshaller = _pygi_marshal_in_double;
400 401
}

402
static void
403
_arg_cache_out_double_setup (PyGIArgCache *arg_cache)
404 405 406 407
{
    arg_cache->out_marshaller = _pygi_marshal_out_double;
}

408
static void
409
_arg_cache_in_unichar_setup (PyGIArgCache *arg_cache)
410
{
411
    arg_cache->in_marshaller = _pygi_marshal_in_unichar;
412 413
}

414
static void
415
_arg_cache_out_unichar_setup (PyGIArgCache *arg_cache)
416 417 418 419
{
    arg_cache->out_marshaller = _pygi_marshal_out_unichar;
}

420
static void
421
_arg_cache_in_gtype_setup (PyGIArgCache *arg_cache)
422
{
423
    arg_cache->in_marshaller = _pygi_marshal_in_gtype;
424 425
}

426
static void
427
_arg_cache_out_gtype_setup (PyGIArgCache *arg_cache)
428 429 430 431
{
    arg_cache->out_marshaller = _pygi_marshal_out_gtype;
}

432
static void
433 434
_arg_cache_in_utf8_setup (PyGIArgCache *arg_cache,
                          GITransfer transfer)
435
{
436
    arg_cache->in_marshaller = _pygi_marshal_in_utf8;
437
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_utf8;
438
}
439

440
static void
441 442
_arg_cache_out_utf8_setup (PyGIArgCache *arg_cache,
                           GITransfer transfer)
443 444
{
    arg_cache->out_marshaller = _pygi_marshal_out_utf8;
445
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_utf8;
446 447
}

448
static void
449 450
_arg_cache_in_filename_setup (PyGIArgCache *arg_cache,
                              GITransfer transfer)
451
{
452
    arg_cache->in_marshaller = _pygi_marshal_in_filename;
453
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_utf8;
454 455
}

456
static void
457 458
_arg_cache_out_filename_setup (PyGIArgCache *arg_cache,
                               GITransfer transfer)
459
{
460
    arg_cache->out_marshaller = _pygi_marshal_out_filename;
461
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_utf8;
462
}
463

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

474
    arg_cache->in_marshaller = _pygi_marshal_in_array;
475

476 477
    if (seq_cache->len_arg_index >= 0 &&
        direction == GI_DIRECTION_IN) {
478
        PyGIArgCache *child_cache = 
479
            callable_cache->args_cache[seq_cache->len_arg_index];
480

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

487 488 489 490
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
        child_cache->in_marshaller = NULL;
        child_cache->out_marshaller = NULL;
491

492
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
493 494
    }

495
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_array;
496 497

    return TRUE;
498 499
}

500
static gboolean
501 502 503 504 505 506
_arg_cache_out_array_setup (PyGIArgCache *arg_cache,
                            PyGICallableCache *callable_cache,
                            GITypeInfo *type_info,
                            GITransfer transfer,
                            GIDirection direction,
                            gssize arg_index)
507
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
508
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
509
    arg_cache->out_marshaller = _pygi_marshal_out_array;
510
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_array;
511

512
    seq_cache->array_type = g_type_info_get_array_type (type_info);
513 514

    if (seq_cache->len_arg_index >= 0) {
515
        PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index];
516
        if (seq_cache->len_arg_index < arg_index)
517
             callable_cache->n_out_child_args++;
518

519 520
        if (child_cache != NULL) {
            if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
521 522
                return TRUE;

523
            callable_cache->out_args = 
524
                g_slist_remove (callable_cache->out_args, child_cache);
525
        } else {
526
            child_cache = _arg_cache_alloc ();
527
        }
528

529 530 531 532
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
        child_cache->in_marshaller = NULL;
        child_cache->out_marshaller = NULL;
533

534
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
535 536 537 538 539
    }

    return TRUE;
}

540
static void
541 542
_arg_cache_in_glist_setup (PyGIArgCache *arg_cache,
                           GITransfer transfer)
543
{
544
    arg_cache->in_marshaller = _pygi_marshal_in_glist;
545
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_glist;
546
}
547

548
static void
549 550
_arg_cache_out_glist_setup (PyGIArgCache *arg_cache,
                            GITransfer transfer)
551 552
{
    arg_cache->out_marshaller = _pygi_marshal_out_glist;
553
    arg_cache->in_cleanup = _pygi_marshal_cleanup_out_glist;
554 555
}

556
static void
557 558
_arg_cache_in_gslist_setup (PyGIArgCache *arg_cache,
                            GITransfer transfer)
559
{
560
    arg_cache->in_marshaller = _pygi_marshal_in_gslist;
561
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_glist;
562
}
563

564
static void
565 566
_arg_cache_out_gslist_setup (PyGIArgCache *arg_cache,
                             GITransfer transfer)
567 568
{
    arg_cache->out_marshaller = _pygi_marshal_out_gslist;
569
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_glist;
570 571
}

572
static void
573
_arg_cache_in_ghash_setup (PyGIArgCache *arg_cache)
574
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
575
    arg_cache->in_marshaller = _pygi_marshal_in_ghash;
576
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_ghash;
577 578
}

579
static void
580
_arg_cache_out_ghash_setup (PyGIArgCache *arg_cache)
581
{
582
    arg_cache->out_marshaller = _pygi_marshal_out_ghash;
583
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_ghash;
584 585
}

586
static void
587
_arg_cache_in_gerror_setup (PyGIArgCache *arg_cache)
588
{
589
    arg_cache->in_marshaller = _pygi_marshal_in_gerror;
590
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
591 592
}

593
static void
594
_arg_cache_out_gerror_setup (PyGIArgCache *arg_cache)
595 596
{
    arg_cache->out_marshaller = _pygi_marshal_out_gerror;
597
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
598 599
}

600
static void
601 602
_arg_cache_in_interface_union_setup (PyGIArgCache *arg_cache,
                                     GITransfer transfer)
603
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
604
    arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
605 606
}

607
static void
608 609
_arg_cache_out_interface_union_setup (PyGIArgCache *arg_cache,
                                      GITransfer transfer)
610 611
{
    arg_cache->out_marshaller = _pygi_marshal_out_interface_struct;
612 613
}

614
static void
615 616 617
_arg_cache_in_interface_struct_setup (PyGIArgCache *arg_cache,
                                      GIInterfaceInfo *iface_info,
                                      GITransfer transfer)
618
{
619
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
620
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
621
    arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
622 623

    if (iface_cache->g_type == G_TYPE_VALUE)
624 625 626
        arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_struct_gvalue;
    else if (iface_cache->is_foreign)
        arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_struct_foreign;
627
}
628

629
static void
630 631 632
_arg_cache_out_interface_struct_setup (PyGIArgCache *arg_cache,
                                       GIInterfaceInfo *iface_info,
                                       GITransfer transfer)
633 634
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
635
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
636
    arg_cache->out_marshaller = _pygi_marshal_out_interface_struct;
637 638 639

    if (iface_cache->is_foreign)
        arg_cache->in_cleanup = _pygi_marshal_cleanup_out_interface_struct_foreign;
640 641
}

642
static void
643 644
_arg_cache_in_interface_object_setup (PyGIArgCache *arg_cache,
                                      GITransfer transfer)
645 646
{
    arg_cache->in_marshaller = _pygi_marshal_in_interface_object;
647
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_object;
648 649
}

650
static void
651 652
_arg_cache_out_interface_object_setup (PyGIArgCache *arg_cache,
                                       GITransfer transfer)
653
{
654
    arg_cache->out_marshaller = _pygi_marshal_out_interface_object;
655
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_interface_object;
656 657
}

658
static void
659 660
_arg_cache_in_interface_callback_setup (PyGIArgCache *arg_cache,
                                        PyGICallableCache *callable_cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
661
{
662
    PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
663
    if (callback_cache->user_data_index >= 0) {
664
        PyGIArgCache *user_data_arg_cache = _arg_cache_alloc ();
665
        user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
666
        callable_cache->args_cache[callback_cache->user_data_index] = user_data_arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
667
    }
668 669

    if (callback_cache->destroy_notify_index >= 0) {
670
        PyGIArgCache *destroy_arg_cache = _arg_cache_alloc ();
671
        destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
672
        callable_cache->args_cache[callback_cache->destroy_notify_index] = destroy_arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
673 674
    }
    arg_cache->in_marshaller = _pygi_marshal_in_interface_callback;
675 676
}

677
static void
678
_arg_cache_out_interface_callback_setup (void)
679
{
680 681 682
    PyErr_Format(PyExc_NotImplementedError,
                 "Callback returns are not supported");
}
683

684
static void
685 686
_arg_cache_in_interface_enum_setup (PyGIArgCache *arg_cache,
                                    GITransfer transfer)
687
{
688
    arg_cache->in_marshaller = _pygi_marshal_in_interface_enum;
689 690
}

691
static void
692 693
_arg_cache_out_interface_enum_setup (PyGIArgCache *arg_cache,
                                     GITransfer transfer)
694
{
695 696
    arg_cache->out_marshaller = _pygi_marshal_out_interface_enum;
}
697

698
static void
699 700
_arg_cache_in_interface_flags_setup (PyGIArgCache *arg_cache,
                                     GITransfer transfer)
701
{
702
    arg_cache->in_marshaller = _pygi_marshal_in_interface_flags;
703 704
}

705
static void
706 707
_arg_cache_out_interface_flags_setup (PyGIArgCache *arg_cache,
                                      GITransfer transfer)
708
{
709 710 711
    arg_cache->out_marshaller = _pygi_marshal_out_interface_flags;
}

712 713 714 715 716 717 718