pygi-cache.c 45.2 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
    for (i = 0; i < cache->n_args; i++) {
        PyGIArgCache *tmp = cache->args_cache[i];
114
        _pygi_arg_cache_free (tmp);
115
    }
116
    if (cache->return_cache != NULL)
117
        _pygi_arg_cache_free (cache->return_cache);
118

119 120
    g_slice_free1 (cache->n_args * sizeof (PyGIArgCache *), cache->args_cache);
    g_slice_free (PyGICallableCache, cache);
121 122 123 124
}

/* cache generation */

125 126
static PyGIInterfaceCache *
_interface_cache_new (GIInterfaceInfo *iface_info)
127 128
{
    PyGIInterfaceCache *ic;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
129

130 131
    ic = g_slice_new0 (PyGIInterfaceCache);
    ( (PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
132
    ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
133
    ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
134 135 136 137

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

138
    ic->type_name = _pygi_g_base_info_get_fullname (iface_info);
139 140 141
    return ic;
}

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

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

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

165 166
    item_type_info = g_type_info_get_param_type (type_info, 0);

167 168
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
169

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

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

182 183
    sc->item_size = _pygi_g_type_info_size (item_type_info);
    g_base_info_unref ( (GIBaseInfo *)item_type_info);
184

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

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

202 203
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
204

205 206 207 208 209 210
    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
211 212

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

217 218 219 220 221 222
    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
223 224

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

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

    return hc;
}
234

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

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

255 256
static PyGIArgCache *
_arg_cache_alloc (void)
257
{
258
    return g_slice_new0 (PyGIArgCache);
259
}
260

261
static void
262
_arg_cache_in_void_setup (PyGIArgCache *arg_cache)
263
{
264 265
    arg_cache->in_marshaller = _pygi_marshal_in_void;
}
266

267
static void
268
_arg_cache_out_void_setup (PyGIArgCache *arg_cache)
269 270
{
    arg_cache->out_marshaller = _pygi_marshal_out_void;
271 272
}

273
static void
274
_arg_cache_in_boolean_setup (PyGIArgCache *arg_cache)
275
{
276
    arg_cache->in_marshaller = _pygi_marshal_in_boolean;
277 278
}

279
static void
280
_arg_cache_out_boolean_setup (PyGIArgCache *arg_cache)
281 282 283 284
{
    arg_cache->out_marshaller = _pygi_marshal_out_boolean;
}

285
static void
286
_arg_cache_in_int8_setup (PyGIArgCache *arg_cache)
287
{
288
    arg_cache->in_marshaller = _pygi_marshal_in_int8;
289 290
}

291
static void
292
_arg_cache_out_int8_setup (PyGIArgCache *arg_cache)
293 294 295 296
{
    arg_cache->out_marshaller = _pygi_marshal_out_int8;
}

297
static void
298
_arg_cache_in_uint8_setup (PyGIArgCache *arg_cache)
299
{
300
    arg_cache->in_marshaller = _pygi_marshal_in_uint8;
301 302
}

303
static void
304
_arg_cache_out_uint8_setup (PyGIArgCache *arg_cache)
305 306 307 308
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint8;
}

309
static void
310
_arg_cache_in_int16_setup (PyGIArgCache *arg_cache)
311
{
312
    arg_cache->in_marshaller = _pygi_marshal_in_int16;
313 314
}

315
static void
316
_arg_cache_out_int16_setup (PyGIArgCache *arg_cache)
317 318 319 320
{
    arg_cache->out_marshaller = _pygi_marshal_out_int16;
}

321
static void
322
_arg_cache_in_uint16_setup (PyGIArgCache *arg_cache)
323
{
324
    arg_cache->in_marshaller = _pygi_marshal_in_uint16;
325 326
}

327
static void
328
_arg_cache_out_uint16_setup (PyGIArgCache *arg_cache)
329 330 331 332
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint16;
}

333
static void
334
_arg_cache_in_int32_setup (PyGIArgCache *arg_cache)
335
{
336
    arg_cache->in_marshaller = _pygi_marshal_in_int32;
337 338
}

339
static void
340
_arg_cache_out_int32_setup (PyGIArgCache *arg_cache)
341 342 343 344
{
    arg_cache->out_marshaller = _pygi_marshal_out_int32;
}

345
static void
346
_arg_cache_in_uint32_setup (PyGIArgCache *arg_cache)
347
{
348
    arg_cache->in_marshaller = _pygi_marshal_in_uint32;
349 350
}

351
static void
352
_arg_cache_out_uint32_setup (PyGIArgCache *arg_cache)
353 354 355 356
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint32;
}

357
static void
358
_arg_cache_in_int64_setup (PyGIArgCache *arg_cache)
359
{
360
    arg_cache->in_marshaller = _pygi_marshal_in_int64;
361 362
}

363
static void
364
_arg_cache_out_int64_setup (PyGIArgCache *arg_cache)
365 366 367 368
{
    arg_cache->out_marshaller = _pygi_marshal_out_int64;
}

369
static void
370
_arg_cache_in_uint64_setup (PyGIArgCache *arg_cache)
371
{
372
    arg_cache->in_marshaller = _pygi_marshal_in_uint64;
373 374
}

375
static void
376
_arg_cache_out_uint64_setup (PyGIArgCache *arg_cache)
377 378 379 380
{
    arg_cache->out_marshaller = _pygi_marshal_out_uint64;
}

381
static void
382
_arg_cache_in_float_setup (PyGIArgCache *arg_cache)
383
{
384
    arg_cache->in_marshaller = _pygi_marshal_in_float;
385 386
}

387
static void
388
_arg_cache_out_float_setup (PyGIArgCache *arg_cache)
389 390 391 392
{
    arg_cache->out_marshaller = _pygi_marshal_out_float;
}

393
static void
394
_arg_cache_in_double_setup (PyGIArgCache *arg_cache)
395
{
396
    arg_cache->in_marshaller = _pygi_marshal_in_double;
397 398
}

399
static void
400
_arg_cache_out_double_setup (PyGIArgCache *arg_cache)
401 402 403 404
{
    arg_cache->out_marshaller = _pygi_marshal_out_double;
}

405
static void
406
_arg_cache_in_unichar_setup (PyGIArgCache *arg_cache)
407
{
408
    arg_cache->in_marshaller = _pygi_marshal_in_unichar;
409 410
}

411
static void
412
_arg_cache_out_unichar_setup (PyGIArgCache *arg_cache)
413 414 415 416
{
    arg_cache->out_marshaller = _pygi_marshal_out_unichar;
}

417
static void
418
_arg_cache_in_gtype_setup (PyGIArgCache *arg_cache)
419
{
420
    arg_cache->in_marshaller = _pygi_marshal_in_gtype;
421 422
}

423
static void
424
_arg_cache_out_gtype_setup (PyGIArgCache *arg_cache)
425 426 427 428
{
    arg_cache->out_marshaller = _pygi_marshal_out_gtype;
}

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

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

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

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

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

471
    arg_cache->in_marshaller = _pygi_marshal_in_array;
472

473 474
    if (seq_cache->len_arg_index >= 0 &&
        direction == GI_DIRECTION_IN) {
475
        PyGIArgCache *child_cache = 
476
            callable_cache->args_cache[seq_cache->len_arg_index];
477

478
        if (child_cache == NULL) {
479
            child_cache = _arg_cache_alloc ();
480
        } else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD) {
481 482 483
            return TRUE;
        }

484 485 486 487
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
        child_cache->in_marshaller = NULL;
        child_cache->out_marshaller = NULL;
488

489
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
490 491
    }

492
    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_array;
493 494

    return TRUE;
495 496
}

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

509
    seq_cache->array_type = g_type_info_get_array_type (type_info);
510 511

    if (seq_cache->len_arg_index >= 0) {
512
        PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index];
513
        if (seq_cache->len_arg_index < arg_index)
514
             callable_cache->n_out_child_args++;
515

516 517
        if (child_cache != NULL) {
            if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
518 519
                return TRUE;

520
            callable_cache->out_args = 
521
                g_slist_remove (callable_cache->out_args, child_cache);
522
        } else {
523
            child_cache = _arg_cache_alloc ();
524
        }
525

526 527 528 529
        child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
        child_cache->direction = direction;
        child_cache->in_marshaller = NULL;
        child_cache->out_marshaller = NULL;
530

531
        callable_cache->args_cache[seq_cache->len_arg_index] = child_cache;
532 533 534 535 536
    }

    return TRUE;
}

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

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

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

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

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

576
static void
577
_arg_cache_out_ghash_setup (PyGIArgCache *arg_cache)
578
{
579
    arg_cache->out_marshaller = _pygi_marshal_out_ghash;
580
    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_ghash;
581 582
}

583
static void
584
_arg_cache_in_gerror_setup (PyGIArgCache *arg_cache)
585
{
586
    arg_cache->in_marshaller = _pygi_marshal_in_gerror;
587
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
588 589
}

590
static void
591
_arg_cache_out_gerror_setup (PyGIArgCache *arg_cache)
592 593
{
    arg_cache->out_marshaller = _pygi_marshal_out_gerror;
594
    arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
595 596
}

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

604
static void
605 606
_arg_cache_out_interface_union_setup (PyGIArgCache *arg_cache,
                                      GITransfer transfer)
607 608
{
    arg_cache->out_marshaller = _pygi_marshal_out_interface_struct;
609 610
}

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

    if (iface_cache->g_type == G_TYPE_VALUE)
621 622 623
        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;
624
}
625

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

    if (iface_cache->is_foreign)
        arg_cache->in_cleanup = _pygi_marshal_cleanup_out_interface_struct_foreign;
637 638
}

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

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

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

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

674
static void
675
_arg_cache_out_interface_callback_setup (void)
676
{
677 678 679
    PyErr_Format(PyExc_NotImplementedError,
                 "Callback returns are not supported");
}
680

681
static void
682 683
_arg_cache_in_interface_enum_setup (PyGIArgCache *arg_cache,
                                    GITransfer transfer)
684
{
685
    arg_cache->in_marshaller = _pygi_marshal_in_interface_enum;
686 687
}

688
static void
689 690
_arg_cache_out_interface_enum_setup (PyGIArgCache *arg_cache,
                                     GITransfer transfer)
691
{
692 693
    arg_cache->out_marshaller = _pygi_marshal_out_interface_enum;
}
694

695
static void
696 697
_arg_cache_in_interface_flags_setup (PyGIArgCache *arg_cache,
                                     GITransfer transfer)
698
{
699
    arg_cache->in_marshaller = _pygi_marshal_in_interface_flags;
700 701
}

702
static void
703 704
_arg_cache_out_interface_flags_setup (PyGIArgCache *arg_cache,
                                      GITransfer transfer)
705
{
706 707 708
    arg_cache->out_marshaller = _pygi_marshal_out_interface_flags;
}

709 710 711 712 713 714 715 716
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)