pygi-cache.c 32.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 23
#include <girepository.h>

24
#include "pygi-info.h"
25
#include "pygi-cache.h"
26 27
#include "pygi-marshal-to-py.h"
#include "pygi-marshal-from-py.h"
28
#include "pygi-marshal-cleanup.h"
29
#include "pygi-type.h"
30
#include "pygi-hashtable.h"
31
#include "pygi-basictype.h"
32
#include "pygi-list.h"
33
#include "pygi-array.h"
34
#include "pygi-error.h"
35

36 37

PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
38
                                             GITypeInfo *type_info,
39 40
                                             GIArgInfo *arg_info,
                                             GITransfer transfer,
41
                                             PyGIDirection direction,
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
                                             /* will be removed */
                                             PyGICallableCache *callable_cache);


/* _arg_info_default_value
 * info:
 * arg: (out): GIArgument to fill in with default value.
 *
 * This is currently a place holder API which only supports "allow-none" pointer args.
 * Once defaults are part of the GI API, we can replace this with: g_arg_info_default_value
 * https://bugzilla.gnome.org/show_bug.cgi?id=558620
 *
 * Returns: TRUE if the given argument supports a default value and was filled in.
 */
static gboolean
_arg_info_default_value (GIArgInfo *info, GIArgument *arg)
{
    if (g_arg_info_may_be_null (info)) {
        arg->v_pointer = NULL;
        return TRUE;
    }
    return FALSE;
}

gboolean
pygi_arg_base_setup (PyGIArgCache *arg_cache,
                     GITypeInfo   *type_info,
                     GIArgInfo    *arg_info,  /* may be NULL for return arguments */
                     GITransfer    transfer,
                     PyGIDirection direction)
{
    arg_cache->direction = direction;
    arg_cache->transfer = transfer;
    arg_cache->py_arg_index = -1;
    arg_cache->c_arg_index = -1;

    if (type_info != NULL) {
        arg_cache->is_pointer = g_type_info_is_pointer (type_info);
        arg_cache->type_tag = g_type_info_get_tag (type_info);
        g_base_info_ref ( (GIBaseInfo *) type_info);
        arg_cache->type_info = type_info;
    }

    if (arg_info != NULL) {
        if (!arg_cache->has_default) {
            /* It is possible has_default was set somewhere else */
            arg_cache->has_default = _arg_info_default_value (arg_info,
                                                              &arg_cache->default_value);
        }
        arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
        arg_cache->allow_none = g_arg_info_may_be_null (arg_info);

        if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE || arg_cache->type_tag == GI_TYPE_TAG_ARRAY)
            arg_cache->is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
        else
            arg_cache->is_caller_allocates = FALSE;
    }
    return TRUE;
}


gboolean
pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache,
                          GITypeInfo         *type_info,
                          GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                          GITransfer          transfer,
                          PyGIDirection       direction,
                          GIInterfaceInfo    *iface_info)
{
    if (!pygi_arg_base_setup ((PyGIArgCache *)iface_cache,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
    }

    g_base_info_ref ( (GIBaseInfo *)iface_info);
    iface_cache->interface_info = iface_info;
    iface_cache->arg_cache.type_tag = GI_TYPE_TAG_INTERFACE;

    return TRUE;
}

126

127
/* cleanup */
128
void
129
_pygi_arg_cache_free (PyGIArgCache *cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
130 131 132 133
{
    if (cache == NULL)
        return;

134
    if (cache->type_info != NULL)
135
        g_base_info_unref ( (GIBaseInfo *)cache->type_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
136
    if (cache->destroy_notify)
137
        cache->destroy_notify (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
138
    else
139
        g_slice_free (PyGIArgCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
140 141 142
}

static void
143
_interface_cache_free_func (PyGIInterfaceCache *cache)
144 145
{
    if (cache != NULL) {
146
        Py_XDECREF (cache->py_type);
147
        if (cache->type_name != NULL)
148
            g_free (cache->type_name);
149
        if (cache->interface_info != NULL)
150 151
            g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
        g_slice_free (PyGIInterfaceCache, cache);
152 153 154 155
    }
}


156
static void
157
_sequence_cache_free_func (PyGISequenceCache *cache)
158
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
159
    if (cache != NULL) {
160 161
        _pygi_arg_cache_free (cache->item_cache);
        g_slice_free (PyGISequenceCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
162
    }
163 164
}

165
static void
166
_callback_cache_free_func (PyGICallbackCache *cache)
167
{
168 169
    if (cache != NULL) {
        if (cache->interface_info != NULL)
170
            g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
171

172
        g_slice_free (PyGICallbackCache, cache);
173
    }
174 175 176
}

void
177
_pygi_callable_cache_free (PyGICallableCache *cache)
178
{
179 180 181
    if (cache == NULL)
        return;

182
    g_slist_free (cache->to_py_args);
183 184
    g_slist_free (cache->arg_name_list);
    g_hash_table_destroy (cache->arg_name_hash);
185
    g_ptr_array_unref (cache->args_cache);
186

187
    if (cache->return_cache != NULL)
188
        _pygi_arg_cache_free (cache->return_cache);
189

190
    g_slice_free (PyGICallableCache, cache);
191 192 193 194
}

/* cache generation */

195 196
static PyGIInterfaceCache *
_interface_cache_new (GIInterfaceInfo *iface_info)
197 198
{
    PyGIInterfaceCache *ic;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
199

200 201
    ic = g_slice_new0 (PyGIInterfaceCache);
    ( (PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
202
    ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
203
    ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
204 205 206 207

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

208
    ic->type_name = _pygi_g_base_info_get_fullname (iface_info);
209 210 211
    return ic;
}

212 213 214 215 216 217
gboolean
pygi_arg_sequence_setup (PyGISequenceCache  *sc,
                         GITypeInfo         *type_info,
                         GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                         GITransfer          transfer,
                         PyGIDirection       direction)
218 219
{
    GITypeInfo *item_type_info;
220
    GITransfer item_transfer;
221

222 223 224 225 226 227 228
    if (!pygi_arg_base_setup ((PyGIArgCache *)sc,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
    }
229

230
    sc->arg_cache.destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
231
    item_type_info = g_type_info_get_param_type (type_info, 0);
232 233
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
234

235 236 237 238
    sc->item_cache = _arg_cache_new (item_type_info,
                                     NULL,
                                     item_transfer,
                                     direction,
239 240
                                     0, 0,
                                     NULL);
241

242 243
    g_base_info_unref ( (GIBaseInfo *)item_type_info);

244
    if (sc->item_cache == NULL) {
245 246 247 248 249 250
        return FALSE;
    }

    return TRUE;
}

251 252 253 254
static PyGICallbackCache *
_callback_cache_new (GIArgInfo *arg_info,
                     GIInterfaceInfo *iface_info,
                     gssize child_offset)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
255 256 257
{
   PyGICallbackCache *cc;

258
   cc = g_slice_new0 (PyGICallbackCache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
259 260
   ( (PyGIArgCache *)cc)->destroy_notify = (GDestroyNotify)_callback_cache_free_func;

261
   cc->user_data_index = g_arg_info_get_closure (arg_info);
262
   if (cc->user_data_index != -1)
263
       cc->user_data_index += child_offset;
264
   cc->destroy_notify_index = g_arg_info_get_destroy (arg_info);
265
   if (cc->destroy_notify_index != -1)
266
       cc->destroy_notify_index += child_offset;
267
   cc->scope = g_arg_info_get_scope (arg_info);
268 269
   g_base_info_ref( (GIBaseInfo *)iface_info);
   cc->interface_info = iface_info;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
270 271 272
   return cc;
}

273
PyGIArgCache *
274
_arg_cache_alloc (void)
275
{
276
    return g_slice_new0 (PyGIArgCache);
277
}
278

279
static void
280 281
_arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache,
                                          GITransfer transfer)
282
{
283
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
284 285
}

286
static void
287 288
_arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
289
{
290
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
291 292
}

293
static void
294 295 296
_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                           GIInterfaceInfo *iface_info,
                                           GITransfer transfer)
297
{
298
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
299
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
300
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
301 302

    if (iface_cache->g_type == G_TYPE_VALUE)
303
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
304
    else if (iface_cache->is_foreign)
305
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
306
}
307

308
static void
309 310 311
_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                         GIInterfaceInfo *iface_info,
                                         GITransfer transfer)
312 313
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
314
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
315
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
316 317

    if (iface_cache->is_foreign)
318
        arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
319 320
}

321
static void
322 323
_arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache,
                                           GITransfer transfer)
324
{
325 326
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
327 328
}

329
static void
330 331
_arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache,
                                         GITransfer transfer)
332
{
333
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object_cache_adapter;
334
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
335 336
}

337
static void
338 339
_arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache,
                                             PyGICallableCache *callable_cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
340
{
341
    PyGICallbackCache *callback_cache = (PyGICallbackCache *)arg_cache;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
342
    if (callback_cache->user_data_index >= 0) {
343
        PyGIArgCache *user_data_arg_cache = _arg_cache_alloc ();
344
        user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG;
345
        user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
346
        user_data_arg_cache->has_default = TRUE; /* always allow user data with a NULL default. */
347 348
        _pygi_callable_cache_set_arg (callable_cache, callback_cache->user_data_index,
                                      user_data_arg_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
349
    }
350 351

    if (callback_cache->destroy_notify_index >= 0) {
352
        PyGIArgCache *destroy_arg_cache = _arg_cache_alloc ();
353
        destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
354
        destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON;
355 356
        _pygi_callable_cache_set_arg (callable_cache, callback_cache->destroy_notify_index,
                                      destroy_arg_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
357
    }
358
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback;
359
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback;
360 361
}

362
static void
363
_arg_cache_to_py_interface_callback_setup (void)
364
{
365 366 367
    PyErr_Format(PyExc_NotImplementedError,
                 "Callback returns are not supported");
}
368

369
static void
370 371
_arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache,
                                         GITransfer transfer)
372
{
373
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
374 375
}

376
static void
377 378
_arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache,
                                       GITransfer transfer)
379
{
380
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
381
}
382

383
static void
384 385
_arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache,
                                          GITransfer transfer)
386
{
387
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
388 389
}

390
static void
391 392
_arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
393
{
394
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
395 396
}

397

398
PyGIArgCache *
399 400 401 402 403 404
_arg_cache_new_for_interface (GIInterfaceInfo   *iface_info,
                              GITypeInfo        *type_info,
                              GIArgInfo         *arg_info,
                              GITransfer         transfer,
                              PyGIDirection      direction,
                              PyGICallableCache *callable_cache)
405
{
406
    PyGIArgCache *arg_cache = NULL;
407
    gssize child_offset = 0;
408
    GIInfoType info_type;
409 410 411 412 413

    if (callable_cache != NULL)
        child_offset =
            (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
                 callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) ? 1: 0;
414

415 416
    info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);

417
    /* Callbacks are special cased */
418 419
    if (info_type == GI_INFO_TYPE_CALLBACK) {
        PyGICallbackCache *callback_cache;
420

421 422 423 424 425 426 427 428 429 430 431
        if (direction & PYGI_DIRECTION_TO_PYTHON) {
            _arg_cache_to_py_interface_callback_setup ();
            return NULL;
        }

        callback_cache =
            _callback_cache_new (arg_info,
                                 iface_info,
                                 child_offset);

        arg_cache = (PyGIArgCache *)callback_cache;
432 433
        if (arg_cache == NULL)
            return NULL;
434 435 436 437 438 439 440 441 442 443 444 445

        pygi_arg_base_setup (arg_cache,
                             type_info,
                             arg_info,
                             transfer,
                             direction);

        if (direction & PYGI_DIRECTION_FROM_PYTHON)
            _arg_cache_from_py_interface_callback_setup (arg_cache, callable_cache);

        return arg_cache;

446 447
    }

448 449 450 451
    arg_cache = (PyGIArgCache *)_interface_cache_new (iface_info);
    if (arg_cache == NULL)
        return NULL;

452 453
    switch (info_type) {
        case GI_INFO_TYPE_UNION:
454
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
455
               _arg_cache_from_py_interface_union_setup (arg_cache, transfer);
456

457
            if (direction & PYGI_DIRECTION_TO_PYTHON)
458
               _arg_cache_to_py_interface_union_setup (arg_cache, transfer);
459

460
            break;
461
        case GI_INFO_TYPE_BOXED:
462
        case GI_INFO_TYPE_STRUCT:
463
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
464 465 466 467
               _arg_cache_from_py_interface_struct_setup (arg_cache,
                                                          iface_info,
                                                          transfer);

468
            if (direction & PYGI_DIRECTION_TO_PYTHON)
469 470 471
               _arg_cache_to_py_interface_struct_setup (arg_cache,
                                                        iface_info,
                                                        transfer);
472 473 474
            break;
        case GI_INFO_TYPE_OBJECT:
        case GI_INFO_TYPE_INTERFACE:
475
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
476
               _arg_cache_from_py_interface_object_setup (arg_cache, transfer);
477

478
            if (direction & PYGI_DIRECTION_TO_PYTHON)
479
               _arg_cache_to_py_interface_object_setup (arg_cache, transfer);
480

481 482
            break;
        case GI_INFO_TYPE_ENUM:
483
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
484
               _arg_cache_from_py_interface_enum_setup (arg_cache, transfer);
485

486
            if (direction & PYGI_DIRECTION_TO_PYTHON)
487
               _arg_cache_to_py_interface_enum_setup (arg_cache, transfer);
488

489 490
            break;
        case GI_INFO_TYPE_FLAGS:
491
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
492
               _arg_cache_from_py_interface_flags_setup (arg_cache, transfer);
493

494
            if (direction & PYGI_DIRECTION_TO_PYTHON)
495
               _arg_cache_to_py_interface_flags_setup (arg_cache, transfer);
496

497 498
            break;
        default:
499
            g_assert_not_reached ();
500 501
    }

502 503 504 505 506 507
    pygi_arg_interface_setup ((PyGIInterfaceCache *)arg_cache,
                              type_info,
                              arg_info,
                              transfer,
                              direction,
                              iface_info);
508 509

    return arg_cache;
510 511
}

512
PyGIArgCache *
513
_arg_cache_new (GITypeInfo *type_info,
514
                GIArgInfo *arg_info,     /* may be null */
515
                GITransfer transfer,
516
                PyGIDirection direction,
517
                gssize c_arg_index,
518 519
                gssize py_arg_index,
                PyGICallableCache *callable_cache)
520
{
521
    PyGIArgCache *arg_cache = NULL;
522
    GITypeTag type_tag;
523

524 525
    type_tag = g_type_info_get_tag (type_info);

526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
    switch (type_tag) {
       case GI_TYPE_TAG_VOID:
       case GI_TYPE_TAG_BOOLEAN:
       case GI_TYPE_TAG_INT8:
       case GI_TYPE_TAG_UINT8:
       case GI_TYPE_TAG_INT16:
       case GI_TYPE_TAG_UINT16:
       case GI_TYPE_TAG_INT32:
       case GI_TYPE_TAG_UINT32:
       case GI_TYPE_TAG_INT64:
       case GI_TYPE_TAG_UINT64:
       case GI_TYPE_TAG_FLOAT:
       case GI_TYPE_TAG_DOUBLE:
       case GI_TYPE_TAG_UNICHAR:
       case GI_TYPE_TAG_GTYPE:
       case GI_TYPE_TAG_UTF8:
542
       case GI_TYPE_TAG_FILENAME:
543 544 545 546 547
           arg_cache = pygi_arg_basic_type_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
           break;
548

549 550
       case GI_TYPE_TAG_ARRAY:
           {
551 552 553 554
               arg_cache = pygi_arg_garray_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
555
               if (arg_cache == NULL)
556 557 558 559 560 561 562 563
                   return NULL;

               pygi_arg_garray_len_arg_setup (arg_cache,
                                              type_info,
                                              callable_cache,
                                              direction,
                                              c_arg_index,
                                              &py_arg_index);
564
           }
565 566
           break;

567
       case GI_TYPE_TAG_GLIST:
568 569 570 571 572
           arg_cache = pygi_arg_glist_new_from_info (type_info,
                                                     arg_info,
                                                     transfer,
                                                     direction);
           break;
573

574
       case GI_TYPE_TAG_GSLIST:
575 576 577 578 579 580 581 582
           arg_cache = pygi_arg_gslist_new_from_info (type_info,
                                                      arg_info,
                                                      transfer,
                                                      direction);
           break;

       case GI_TYPE_TAG_GHASH:
           arg_cache = pygi_arg_hash_table_new_from_info (type_info,
583 584 585
                                                          arg_info,
                                                          transfer,
                                                          direction);
586
           break;
587

588
       case GI_TYPE_TAG_INTERFACE:
589
           {
590
               GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
591
               arg_cache = _arg_cache_new_for_interface (interface_info,
592
                                                         type_info,
593 594 595
                                                         arg_info,
                                                         transfer,
                                                         direction,
596
                                                         callable_cache);
597 598

               g_base_info_unref ( (GIBaseInfo *)interface_info);
599
           }
600
           break;
601

602 603 604 605 606
       case GI_TYPE_TAG_ERROR:
           arg_cache = pygi_arg_gerror_new_from_info (type_info,
                                                      arg_info,
                                                      transfer,
                                                      direction);
607 608 609
           break;
    }

610 611 612 613 614 615
    if (arg_cache != NULL) {
        arg_cache->py_arg_index = py_arg_index;
        arg_cache->c_arg_index = c_arg_index;
    }

    return arg_cache;
616 617
}

618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
static PyGIDirection
_pygi_get_direction (PyGICallableCache *callable_cache, GIDirection gi_direction)
{
    /* For vfuncs and callbacks our marshalling directions are reversed */
    if (gi_direction == GI_DIRECTION_INOUT) {
        return PYGI_DIRECTION_BIDIRECTIONAL;
    } else if (gi_direction == GI_DIRECTION_IN) {
        if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
            return PYGI_DIRECTION_TO_PYTHON;
        return PYGI_DIRECTION_FROM_PYTHON;
    } else {
        if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
            return PYGI_DIRECTION_FROM_PYTHON;
        return PYGI_DIRECTION_TO_PYTHON;
    }
}

635 636
/* Generate the cache for the callable's arguments */
static gboolean
637 638
_args_cache_generate (GICallableInfo *callable_info,
                      PyGICallableCache *callable_cache)
639
{
640 641
    gssize arg_index = 0;
    gssize i;
642
    GITypeInfo *return_info;
643
    GITransfer return_transfer;
644
    PyGIArgCache *return_cache;
645 646
    PyGIDirection return_direction;

647 648
    /* Return arguments are always considered out */
    return_direction = _pygi_get_direction (callable_cache, GI_DIRECTION_OUT);
649

650
    /* cache the return arg */
John (J5) Palmieri's avatar
John (J5) Palmieri committed
651
    return_info =
652
        g_callable_info_get_return_type (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
653
    return_transfer =
654
        g_callable_info_get_caller_owns (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
655
    return_cache =
656 657 658
        _arg_cache_new (return_info,
                        NULL,
                        return_transfer,
659
                        return_direction,
660
                        -1,
661 662
                        -1,
                        callable_cache);
663 664
    if (return_cache == NULL)
        return FALSE;
665

666
    return_cache->is_skipped = g_callable_info_skip_return (callable_info);
667 668
    callable_cache->return_cache = return_cache;
    g_base_info_unref (return_info);
669

670
    /* first arg is the instance */
671 672
    if (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
            callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
673 674 675
        GIInterfaceInfo *interface_info;
        PyGIArgCache *instance_cache;

676
        interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
677 678

        instance_cache =
679
            _arg_cache_new_for_interface (interface_info,
680
                                          NULL,
681 682
                                          NULL,
                                          GI_TRANSFER_NOTHING,
683
                                          PYGI_DIRECTION_FROM_PYTHON,
684
                                          callable_cache);
685

686
        g_base_info_unref ( (GIBaseInfo *)interface_info);
687 688 689 690

        if (instance_cache == NULL)
            return FALSE;

691 692 693
        /* Because we are not supplied a GITypeInfo for instance arguments,
         * assume some defaults. */
        instance_cache->is_pointer = TRUE;
694 695
        instance_cache->py_arg_index = 0;
        instance_cache->c_arg_index = 0;
696

697
        _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
698

699
        arg_index++;
700
        callable_cache->n_from_py_args++;
701
        callable_cache->n_py_args++;
702 703
    }

704

705
    for (i=0; arg_index < _pygi_callable_cache_args_len (callable_cache); arg_index++, i++) {
706
        PyGIArgCache *arg_cache = NULL;
707
        GIArgInfo *arg_info;
708
        PyGIDirection direction;
709

710 711 712 713 714
        arg_info = g_callable_info_get_arg (callable_info, i);

        if (g_arg_info_get_closure (arg_info) == i) {

            arg_cache = _arg_cache_alloc ();
715
            _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
716

717 718
            direction = PYGI_DIRECTION_FROM_PYTHON;
            arg_cache->direction = direction;
719 720 721 722 723
            arg_cache->meta_type = PYGI_META_ARG_TYPE_CLOSURE;
            arg_cache->c_arg_index = i;

            callable_cache->n_from_py_args++;

724
        } else {
725
            GITypeInfo *type_info;
726

727 728 729 730 731 732 733 734 735 736 737 738 739 740
            direction = _pygi_get_direction (callable_cache,
                                             g_arg_info_get_direction (arg_info));
            type_info = g_arg_info_get_type (arg_info);

            /* must be an child arg filled in by its owner
             * and continue
             * fill in it's c_arg_index, add to the in count
             */
            arg_cache = _pygi_callable_cache_get_arg (callable_cache, arg_index);
            if (arg_cache != NULL) {
                if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) {
                    arg_cache->py_arg_index = callable_cache->n_py_args;
                    callable_cache->n_py_args++;
                }
741

742 743 744 745
                if (direction & PYGI_DIRECTION_FROM_PYTHON) {
                    arg_cache->c_arg_index = callable_cache->n_from_py_args;
                    callable_cache->n_from_py_args++;
                }
746

747 748 749
                if (direction & PYGI_DIRECTION_TO_PYTHON) {
                    callable_cache->n_to_py_args++;
                }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
750

751
                arg_cache->type_tag = g_type_info_get_tag (type_info);
752

753
            } else {
754 755 756 757
                GITransfer transfer;
                gssize py_arg_index = -1;
                transfer = g_arg_info_get_ownership_transfer (arg_info);

758 759 760 761 762
                if (direction & PYGI_DIRECTION_FROM_PYTHON) {
                    py_arg_index = callable_cache->n_py_args;
                    callable_cache->n_from_py_args++;
                    callable_cache->n_py_args++;
                }
763

764 765 766 767 768 769
                arg_cache =
                    _arg_cache_new (type_info,
                                    arg_info,
                                    transfer,
                                    direction,
                                    arg_index,
770 771
                                    py_arg_index,
                                    callable_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
772

773 774 775 776 777
                if (arg_cache == NULL) {
                    g_base_info_unref( (GIBaseInfo *)type_info);
                    g_base_info_unref( (GIBaseInfo *)arg_info);
                    return FALSE;
                }
778

779 780 781

                if (direction & PYGI_DIRECTION_TO_PYTHON) {
                    callable_cache->n_to_py_args++;
782

783 784 785
                    callable_cache->to_py_args =
                        g_slist_append (callable_cache->to_py_args, arg_cache);
                }
786

787 788
                _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
            }
789

790
            g_base_info_unref (type_info);
791
        }
792

793 794 795
        /* Ensure arguments always have a name when available */
        arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);

796
        g_base_info_unref ( (GIBaseInfo *)arg_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
797

798
    }
799

800 801 802 803 804 805
    if (callable_cache->arg_name_hash == NULL) {
        callable_cache->arg_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
    } else {
        g_hash_table_remove_all (callable_cache->arg_name_hash);
    }
    callable_cache->n_py_required_args = 0;
806 807 808
    callable_cache->user_data_varargs_index = -1;

    gssize last_explicit_arg_index = -1;
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838

    /* Reverse loop through all the arguments to setup arg_name_list/hash
     * and find the number of required arguments */
    for (i=((gssize)_pygi_callable_cache_args_len (callable_cache))-1; i >= 0; i--) {
        PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache, i);

        if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD &&
                arg_cache->meta_type != PYGI_META_ARG_TYPE_CLOSURE &&
                arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {

            /* Setup arg_name_list and arg_name_hash */
            gpointer arg_name = (gpointer)arg_cache->arg_name;
            callable_cache->arg_name_list = g_slist_prepend (callable_cache->arg_name_list,
                                                             arg_name);
            if (arg_name != NULL) {
                g_hash_table_insert (callable_cache->arg_name_hash,
                                     arg_name,
                                     GINT_TO_POINTER(i));
            }

            /* The first tail argument without a default will force all the preceding
             * argument defaults off. This limits support of default args to the
             * tail of an args list.
             */
            if (callable_cache->n_py_required_args > 0) {
                arg_cache->has_default = FALSE;
                callable_cache->n_py_required_args += 1;
            } else if (!arg_cache->has_default) {
                callable_cache->n_py_required_args += 1;
            }
839 840 841 842 843 844 845 846 847 848 849

            if (last_explicit_arg_index == -1) {
                last_explicit_arg_index = i;

                /* If the last "from python" argument in the args list is a child
                 * with pyarg (currently only callback user_data). Set it to eat
                 * variable args in the callable cache.
                 */
                if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG)
                    callable_cache->user_data_varargs_index = i;
            }
850 851
        }
    }