pygi-marshal-to-py.c 28.9 KB
Newer Older
1
2
3
4
5
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>,  Red Hat, Inc.
 *
6
 *   pygi-marshal-from-py.c: functions for converting C types to PyObject
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 *
 * 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
 */

#include "pygi-private.h"

#include <string.h>
#include <time.h>

29
#include <pyglib.h>
30
31
32
33
34
#include <pygobject.h>
#include <pyglib-python-compat.h>

#include "pygi-cache.h"
#include "pygi-marshal-cleanup.h"
35
#include "pygi-marshal-to-py.h"
36
#include "pygi-argument.h"
37

38
static gboolean
David Malcolm's avatar
David Malcolm committed
39
40
41
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
gi_argument_to_c_long (GIArgument *arg_in,
                       long *c_long_out,
                       GITypeTag type_tag)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          *c_long_out = arg_in->v_int8;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          *c_long_out = arg_in->v_uint8;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          *c_long_out = arg_in->v_int16;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          *c_long_out = arg_in->v_uint16;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          *c_long_out = arg_in->v_int32;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          *c_long_out = arg_in->v_uint32;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          *c_long_out = arg_in->v_int64;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          *c_long_out = arg_in->v_uint64;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal %s to C long",
                        g_type_tag_to_string (type_tag));
          return FALSE;
    }
}

76
static gboolean
David Malcolm's avatar
David Malcolm committed
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
gi_argument_to_gsize (GIArgument *arg_in,
                      gsize      *gsize_out,
                      GITypeTag   type_tag)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          *gsize_out = arg_in->v_int8;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          *gsize_out = arg_in->v_uint8;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          *gsize_out = arg_in->v_int16;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          *gsize_out = arg_in->v_uint16;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          *gsize_out = arg_in->v_int32;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          *gsize_out = arg_in->v_uint32;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          *gsize_out = arg_in->v_int64;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          *gsize_out = arg_in->v_uint64;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal %s to gsize",
                        g_type_tag_to_string (type_tag));
          return FALSE;
    }
}

114
PyObject *
115
116
117
118
_pygi_marshal_to_py_void (PyGIInvokeState   *state,
                          PyGICallableCache *callable_cache,
                          PyGIArgCache      *arg_cache,
                          GIArgument        *arg)
119
120
{
    PyObject *py_obj = NULL;
121
122
123
124
125
126
    if (arg_cache->is_pointer) {
        /* NOTE: This will change to interpret pointers as integer values
         * by using the following:
         * py_obj = PyLong_FromVoidPtr (arg->v_pointer);
         * See: https://bugzilla.gnome.org/show_bug.cgi?id=688081
         */
127
        py_obj = arg->v_pointer;
128
    } else {
129
        py_obj = Py_None;
130
    }
131
132
133
134
135

    Py_XINCREF (py_obj);
    return py_obj;
}

136
137
static PyObject *
_pygi_marshal_to_py_unichar (GIArgument *arg)
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
{
    PyObject *py_obj = NULL;

    /* Preserve the bidirectional mapping between 0 and "" */
    if (arg->v_uint32 == 0) {
        py_obj = PYGLIB_PyUnicode_FromString ("");
    } else if (g_unichar_validate (arg->v_uint32)) {
        gchar utf8[6];
        gint bytes;

        bytes = g_unichar_to_utf8 (arg->v_uint32, utf8);
        py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
    } else {
        /* TODO: Convert the error to an exception. */
        PyErr_Format (PyExc_TypeError,
                      "Invalid unicode codepoint %" G_GUINT32_FORMAT,
                      arg->v_uint32);
    }

    return py_obj;
}

160
161
static PyObject *
_pygi_marshal_to_py_utf8 (GIArgument *arg)
162
163
164
{
    PyObject *py_obj = NULL;
    if (arg->v_string == NULL) {
165
        Py_RETURN_NONE;
166
167
168
169
170
171
     }

    py_obj = PYGLIB_PyUnicode_FromString (arg->v_string);
    return py_obj;
}

172
173
static PyObject *
_pygi_marshal_to_py_filename (GIArgument *arg)
174
{
175
    gchar *string = NULL;
176
177
178
179
    PyObject *py_obj = NULL;
    GError *error = NULL;

    if (arg->v_string == NULL) {
180
        Py_RETURN_NONE;
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    }

    string = g_filename_to_utf8 (arg->v_string, -1, NULL, NULL, &error);
    if (string == NULL) {
        PyErr_SetString (PyExc_Exception, error->message);
        /* TODO: Convert the error to an exception. */
        return NULL;
    }

    py_obj = PYGLIB_PyUnicode_FromString (string);
    g_free (string);

    return py_obj;
}

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

/**
 * _pygi_marshal_to_py_basic_type:
 * @arg: The argument to convert to an object.
 * @type_tag: Type tag for @arg
 * @transfer: Transfer annotation
 *
 * Convert the given argument to a Python object. This function
 * is restricted to simple types that only require the GITypeTag
 * and GITransfer. For a more complete conversion routine, use:
 * _pygi_argument_to_object.
 *
 * Returns: A PyObject representing @arg or NULL if it cannot convert
 *          the argument.
 */
PyObject *
_pygi_marshal_to_py_basic_type (GIArgument  *arg,
                                 GITypeTag type_tag,
                                 GITransfer transfer)
{
    switch (type_tag) {
        case GI_TYPE_TAG_BOOLEAN:
            return PyBool_FromLong (arg->v_boolean);

        case GI_TYPE_TAG_INT8:
            return PYGLIB_PyLong_FromLong (arg->v_int8);

        case GI_TYPE_TAG_UINT8:
            return PYGLIB_PyLong_FromLong (arg->v_uint8);

        case GI_TYPE_TAG_INT16:
            return PYGLIB_PyLong_FromLong (arg->v_int16);

        case GI_TYPE_TAG_UINT16:
            return PYGLIB_PyLong_FromLong (arg->v_uint16);

        case GI_TYPE_TAG_INT32:
            return PYGLIB_PyLong_FromLong (arg->v_int32);

        case GI_TYPE_TAG_UINT32:
            return PyLong_FromLongLong (arg->v_uint32);

        case GI_TYPE_TAG_INT64:
            return PyLong_FromLongLong (arg->v_int64);

        case GI_TYPE_TAG_UINT64:
            return PyLong_FromUnsignedLongLong (arg->v_uint64);

        case GI_TYPE_TAG_FLOAT:
            return PyFloat_FromDouble (arg->v_float);

        case GI_TYPE_TAG_DOUBLE:
            return PyFloat_FromDouble (arg->v_double);

        case GI_TYPE_TAG_GTYPE:
            return pyg_type_wrapper_new ( (GType) arg->v_long);

        case GI_TYPE_TAG_UNICHAR:
            return _pygi_marshal_to_py_unichar (arg);

        case GI_TYPE_TAG_UTF8:
            return _pygi_marshal_to_py_utf8 (arg);

        case GI_TYPE_TAG_FILENAME:
            return _pygi_marshal_to_py_filename (arg);

        default:
            return NULL;
    }
    return NULL;
}

PyObject *
_pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState   *state,
                                              PyGICallableCache *callable_cache,
                                              PyGIArgCache      *arg_cache,
                                              GIArgument        *arg)
{
    return _pygi_marshal_to_py_basic_type (arg,
                                            arg_cache->type_tag,
                                            arg_cache->transfer);
}

279
PyObject *
280
281
282
283
_pygi_marshal_to_py_array (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
284
285
286
287
288
289
290
291
292
293
294
295
296
{
    GArray *array_;
    PyObject *py_obj = NULL;
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
    gsize processed_items = 0;

     /* GArrays make it easier to iterate over arrays
      * with different element sizes but requires that
      * we allocate a GArray if the argument was a C array
      */
    if (seq_cache->array_type == GI_ARRAY_TYPE_C) {
        gsize len;
        if (seq_cache->fixed_size >= 0) {
297
            g_assert(arg->v_pointer != NULL);
298
299
            len = seq_cache->fixed_size;
        } else if (seq_cache->is_zero_terminated) {
300
301
302
            if (arg->v_pointer == NULL) {
                len = 0;
            } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
303
304
305
306
                len = strlen (arg->v_pointer);
            } else {
                len = g_strv_length ((gchar **)arg->v_pointer);
            }
307
308
        } else {
            GIArgument *len_arg = state->args[seq_cache->len_arg_index];
David Malcolm's avatar
David Malcolm committed
309
310
311
312
313
314

            if (!gi_argument_to_gsize (len_arg,
                                       &len,
                                       callable_cache->args_cache[seq_cache->len_arg_index]->type_tag)) {
                return NULL;
            }
315
316
317
318
319
320
321
322
        }

        array_ = g_array_new (FALSE,
                              FALSE,
                              seq_cache->item_size);
        if (array_ == NULL) {
            PyErr_NoMemory ();

323
            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL)
324
325
326
327
                g_free (arg->v_pointer);

            return NULL;
        }
328
329
330

        if (array_->data != NULL) 
            g_free (array_->data);
331
332
        array_->data = arg->v_pointer;
        array_->len = len;
333
334
    } else {
        array_ = arg->v_pointer;
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
    }

    if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
        if (arg->v_pointer == NULL) {
            py_obj = PYGLIB_PyBytes_FromString ("");
        } else {
            py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len);
        }
    } else {
        if (arg->v_pointer == NULL) {
            py_obj = PyList_New (0);
        } else {
            int i;

            gsize item_size;
350
            PyGIMarshalToPyFunc item_to_py_marshaller;
351
352
353
354
355
356
357
358
            PyGIArgCache *item_arg_cache;

            py_obj = PyList_New (array_->len);
            if (py_obj == NULL)
                goto err;


            item_arg_cache = seq_cache->item_cache;
359
            item_to_py_marshaller = item_arg_cache->to_py_marshaller;
360
361
362
363
364
365
366
367
368
369

            item_size = g_array_get_element_size (array_);

            for (i = 0; i < array_->len; i++) {
                GIArgument item_arg;
                PyObject *py_item;

                if (seq_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
                    item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
                } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
370
                    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
371
                    gboolean is_gvariant = iface_cache->g_type == G_TYPE_VARIANT;
372

373
                    // FIXME: This probably doesn't work with boxed types or gvalues. See fx. _pygi_marshal_from_py_array()
374
375
                    switch (g_base_info_get_type (iface_cache->interface_info)) {
                        case GI_INFO_TYPE_STRUCT:
376
377
378
379
380
381
                            if (is_gvariant) {
                              g_assert (item_size == sizeof (gpointer));
                              if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
                                item_arg.v_pointer = g_variant_ref_sink (g_array_index (array_, gpointer, i));
                              else
                                item_arg.v_pointer = g_array_index (array_, gpointer, i);
382
383
                            } else if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && !item_arg_cache->is_pointer &&
                                       !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
384
                                /* array elements are structs */
385
386
387
388
                                gpointer *_struct = g_malloc (item_size);
                                memcpy (_struct, array_->data + i * item_size,
                                        item_size);
                                item_arg.v_pointer = _struct;
389
                            } else if (item_arg_cache->is_pointer)
390
                                /* array elements are pointers to values */
391
392
                                item_arg.v_pointer = g_array_index (array_, gpointer, i);
                            else
393
                                item_arg.v_pointer = array_->data + i * item_size;
394
395
396
397
                            break;
                        default:
                            item_arg.v_pointer = g_array_index (array_, gpointer, i);
                            break;
398
399
400
401
402
                    }
                } else {
                    memcpy (&item_arg, array_->data + i * item_size, item_size);
                }

403
                py_item = item_to_py_marshaller ( state,
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
                                                callable_cache,
                                                item_arg_cache,
                                                &item_arg);

                if (py_item == NULL) {
                    Py_CLEAR (py_obj);

                    if (seq_cache->array_type == GI_ARRAY_TYPE_C)
                        g_array_unref (array_);

                    goto err;
                }
                PyList_SET_ITEM (py_obj, i, py_item);
                processed_items++;
            }
        }
    }

    if (seq_cache->array_type == GI_ARRAY_TYPE_C)
        g_array_free (array_, FALSE);

    return py_obj;

err:
    if (seq_cache->array_type == GI_ARRAY_TYPE_C) {
        g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
    } else {
        /* clean up unprocessed items */
432
        if (seq_cache->item_cache->to_py_cleanup != NULL) {
433
            int j;
434
            PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup;
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
            for (j = processed_items; j < array_->len; j++) {
                cleanup_func (state,
                              seq_cache->item_cache,
                              g_array_index (array_, gpointer, j),
                              FALSE);
            }
        }

        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
            g_array_free (array_, TRUE);
    }

    return NULL;
}

PyObject *
451
452
453
454
_pygi_marshal_to_py_glist (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
455
456
457
458
459
{
    GList *list_;
    gsize length;
    gsize i;

460
    PyGIMarshalToPyFunc item_to_py_marshaller;
461
462
463
464
465
466
467
468
469
470
471
472
473
    PyGIArgCache *item_arg_cache;
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;

    PyObject *py_obj = NULL;

    list_ = arg->v_pointer;
    length = g_list_length (list_);

    py_obj = PyList_New (length);
    if (py_obj == NULL)
        return NULL;

    item_arg_cache = seq_cache->item_cache;
474
    item_to_py_marshaller = item_arg_cache->to_py_marshaller;
475
476
477
478
479
480

    for (i = 0; list_ != NULL; list_ = g_list_next (list_), i++) {
        GIArgument item_arg;
        PyObject *py_item;

        item_arg.v_pointer = list_->data;
481
482
483
484
485
        _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
        py_item = item_to_py_marshaller (state,
                                         callable_cache,
                                         item_arg_cache,
                                         &item_arg);
486
487
488
489
490
491
492
493
494
495
496
497
498
499

        if (py_item == NULL) {
            Py_CLEAR (py_obj);
            _PyGI_ERROR_PREFIX ("Item %zu: ", i);
            return NULL;
        }

        PyList_SET_ITEM (py_obj, i, py_item);
    }

    return py_obj;
}

PyObject *
500
501
502
503
_pygi_marshal_to_py_gslist (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
                            PyGIArgCache      *arg_cache,
                            GIArgument        *arg)
504
505
506
507
508
{
    GSList *list_;
    gsize length;
    gsize i;

509
    PyGIMarshalToPyFunc item_to_py_marshaller;
510
511
512
513
514
515
516
517
518
519
520
521
522
    PyGIArgCache *item_arg_cache;
    PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;

    PyObject *py_obj = NULL;

    list_ = arg->v_pointer;
    length = g_slist_length (list_);

    py_obj = PyList_New (length);
    if (py_obj == NULL)
        return NULL;

    item_arg_cache = seq_cache->item_cache;
523
    item_to_py_marshaller = item_arg_cache->to_py_marshaller;
524
525
526
527
528
529

    for (i = 0; list_ != NULL; list_ = g_slist_next (list_), i++) {
        GIArgument item_arg;
        PyObject *py_item;

        item_arg.v_pointer = list_->data;
530
531
        _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
        py_item = item_to_py_marshaller (state,
532
533
                                        callable_cache,
                                        item_arg_cache,
534
                                        &item_arg);
535
536
537
538
539
540
541
542
543
544
545
546
547
548

        if (py_item == NULL) {
            Py_CLEAR (py_obj);
            _PyGI_ERROR_PREFIX ("Item %zu: ", i);
            return NULL;
        }

        PyList_SET_ITEM (py_obj, i, py_item);
    }

    return py_obj;
}

PyObject *
549
550
551
552
_pygi_marshal_to_py_ghash (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
553
554
555
556
{
    GHashTable *hash_;
    GHashTableIter hash_table_iter;

557
558
    PyGIMarshalToPyFunc key_to_py_marshaller;
    PyGIMarshalToPyFunc value_to_py_marshaller;
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

    PyGIArgCache *key_arg_cache;
    PyGIArgCache *value_arg_cache;
    PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;

    GIArgument key_arg;
    GIArgument value_arg;

    PyObject *py_obj = NULL;

    hash_ = arg->v_pointer;

    if (hash_ == NULL) {
        py_obj = Py_None;
        Py_INCREF (py_obj);
        return py_obj;
    }

    py_obj = PyDict_New ();
    if (py_obj == NULL)
        return NULL;

    key_arg_cache = hash_cache->key_cache;
582
    key_to_py_marshaller = key_arg_cache->to_py_marshaller;
583
584

    value_arg_cache = hash_cache->value_cache;
585
    value_to_py_marshaller = value_arg_cache->to_py_marshaller;
586
587
588
589
590
591
592
593
594

    g_hash_table_iter_init (&hash_table_iter, hash_);
    while (g_hash_table_iter_next (&hash_table_iter,
                                   &key_arg.v_pointer,
                                   &value_arg.v_pointer)) {
        PyObject *py_key;
        PyObject *py_value;
        int retval;

595
596

        _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag);
597
        py_key = key_to_py_marshaller ( state,
598
599
600
601
602
603
604
605
606
                                      callable_cache,
                                      key_arg_cache,
                                     &key_arg);

        if (py_key == NULL) {
            Py_CLEAR (py_obj);
            return NULL;
        }

607
        _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag);
608
        py_value = value_to_py_marshaller ( state,
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
                                          callable_cache,
                                          value_arg_cache,
                                         &value_arg);

        if (py_value == NULL) {
            Py_CLEAR (py_obj);
            Py_DECREF(py_key);
            return NULL;
        }

        retval = PyDict_SetItem (py_obj, py_key, py_value);

        Py_DECREF (py_key);
        Py_DECREF (py_value);

        if (retval < 0) {
            Py_CLEAR (py_obj);
            return NULL;
        }
    }

    return py_obj;
}

PyObject *
634
635
636
637
_pygi_marshal_to_py_gerror (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
                            PyGIArgCache      *arg_cache,
                            GIArgument        *arg)
638
{
639
    GError *error = arg->v_pointer;
640
641
    PyObject *py_obj = NULL;

642
643
644
645
646
647
648
649
650
651
652
    py_obj = pyglib_error_marshal(&error);

    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) {
        g_error_free (error);
    }

    if (py_obj != NULL) {
        return py_obj;
    } else {
        Py_RETURN_NONE;
    }
653
654
655
}

PyObject *
656
657
658
659
_pygi_marshal_to_py_interface_callback (PyGIInvokeState   *state,
                                        PyGICallableCache *callable_cache,
                                        PyGIArgCache      *arg_cache,
                                        GIArgument        *arg)
660
661
662
663
{
    PyObject *py_obj = NULL;

    PyErr_Format (PyExc_NotImplementedError,
664
                  "Marshalling a callback to PyObject is not supported");
665
666
667
668
    return py_obj;
}

PyObject *
669
670
671
672
_pygi_marshal_to_py_interface_enum (PyGIInvokeState   *state,
                                    PyGICallableCache *callable_cache,
                                    PyGIArgCache      *arg_cache,
                                    GIArgument        *arg)
673
674
675
{
    PyObject *py_obj = NULL;
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
David Malcolm's avatar
David Malcolm committed
676
677
678
679
680
681
682
683
684
685
    GIBaseInfo *interface;
    long c_long;

    interface = g_type_info_get_interface (arg_cache->type_info);
    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);

    if (!gi_argument_to_c_long(arg, &c_long,
                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
        return NULL;
    }
686
687

    if (iface_cache->g_type == G_TYPE_NONE) {
David Malcolm's avatar
David Malcolm committed
688
        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
689
    } else {
David Malcolm's avatar
David Malcolm committed
690
        py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
691
    }
692
    g_base_info_unref (interface);
693
694
695
696
    return py_obj;
}

PyObject *
697
698
699
700
_pygi_marshal_to_py_interface_flags (PyGIInvokeState   *state,
                                     PyGICallableCache *callable_cache,
                                     PyGIArgCache      *arg_cache,
                                     GIArgument        *arg)
701
702
703
{
    PyObject *py_obj = NULL;
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
David Malcolm's avatar
David Malcolm committed
704
705
706
707
708
709
710
711
    GIBaseInfo *interface;
    long c_long;

    interface = g_type_info_get_interface (arg_cache->type_info);
    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);

    if (!gi_argument_to_c_long(arg, &c_long,
                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
712
        g_base_info_unref (interface);
David Malcolm's avatar
David Malcolm committed
713
714
        return NULL;
    }
715

716
    g_base_info_unref (interface);
717
718
719
720
721
722
723
724
725
726
    if (iface_cache->g_type == G_TYPE_NONE) {
        /* An enum with a GType of None is an enum without GType */

        PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info);
        PyObject *py_args = NULL;

        if (!py_type)
            return NULL;

        py_args = PyTuple_New (1);
David Malcolm's avatar
David Malcolm committed
727
        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
728
729
730
731
732
            Py_DECREF (py_args);
            Py_DECREF (py_type);
            return NULL;
        }

David Malcolm's avatar
David Malcolm committed
733
        py_obj = PyObject_CallFunction (py_type, "l", c_long);
734
735
736
737

        Py_DECREF (py_args);
        Py_DECREF (py_type);
    } else {
David Malcolm's avatar
David Malcolm committed
738
        py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
739
740
741
742
743
744
    }

    return py_obj;
}

PyObject *
745
746
747
748
_pygi_marshal_to_py_interface_struct (PyGIInvokeState   *state,
                                      PyGICallableCache *callable_cache,
                                      PyGIArgCache      *arg_cache,
                                      GIArgument        *arg)
749
750
751
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;

752
753
754
755
756
757
758
    return pygi_marshal_to_py_interface_struct (arg,
                                                iface_cache->interface_info,
                                                iface_cache->g_type,
                                                iface_cache->py_type,
                                                arg_cache->transfer,
                                                arg_cache->is_caller_allocates,
                                                iface_cache->is_foreign);
759
760
761
}

PyObject *
762
763
764
765
_pygi_marshal_to_py_interface_interface (PyGIInvokeState   *state,
                                         PyGICallableCache *callable_cache,
                                         PyGIArgCache      *arg_cache,
                                         GIArgument        *arg)
766
767
768
769
770
771
772
773
774
{
    PyObject *py_obj = NULL;

    PyErr_Format (PyExc_NotImplementedError,
                  "Marshalling for this type is not implemented yet");
    return py_obj;
}

PyObject *
775
776
777
778
_pygi_marshal_to_py_interface_boxed (PyGIInvokeState   *state,
                                     PyGICallableCache *callable_cache,
                                     PyGIArgCache      *arg_cache,
                                     GIArgument        *arg)
779
780
781
782
783
784
785
786
787
{
    PyObject *py_obj = NULL;

    PyErr_Format (PyExc_NotImplementedError,
                  "Marshalling for this type is not implemented yet");
    return py_obj;
}

PyObject *
788
789
790
791
_pygi_marshal_to_py_interface_object (PyGIInvokeState   *state,
                                      PyGICallableCache *callable_cache,
                                      PyGIArgCache      *arg_cache,
                                      GIArgument        *arg)
792
{
793
    return pygi_marshal_to_py_object(arg, arg_cache->transfer);
794
795
796
}

PyObject *
797
798
799
800
_pygi_marshal_to_py_interface_union  (PyGIInvokeState   *state,
                                      PyGICallableCache *callable_cache,
                                      PyGIArgCache      *arg_cache,
                                      GIArgument        *arg)
801
802
803
804
805
806
807
{
    PyObject *py_obj = NULL;

    PyErr_Format (PyExc_NotImplementedError,
                  "Marshalling for this type is not implemented yet");
    return py_obj;
}
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829

PyObject *
pygi_marshal_to_py_object (GIArgument *arg, GITransfer transfer) {
    PyObject *pyobj;

    if (arg->v_pointer == NULL) {
        pyobj = Py_None;
        Py_INCREF (pyobj);

    } else if (G_IS_PARAM_SPEC(arg->v_pointer)) {
        pyobj = pyg_param_spec_new (arg->v_pointer);
        if (transfer == GI_TRANSFER_EVERYTHING)
            g_param_spec_unref (arg->v_pointer);

    } else {
         pyobj = pygobject_new_full (arg->v_pointer,
                                     /*steal=*/ transfer == GI_TRANSFER_EVERYTHING,
                                     /*type=*/  NULL);
    }

    return pyobj;
}
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891

PyObject *
pygi_marshal_to_py_interface_struct (GIArgument *arg,
                                     GIInterfaceInfo *interface_info,
                                     GType g_type,
                                     PyObject *py_type,
                                     GITransfer transfer,
                                     gboolean is_allocated,
                                     gboolean is_foreign)
{
    PyObject *py_obj = NULL;

    if (arg->v_pointer == NULL) {
        Py_RETURN_NONE;
    }

    if (g_type_is_a (g_type, G_TYPE_VALUE)) {
        py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
    } else if (is_foreign) {
        py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
                                                              arg->v_pointer);
    } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
        if (py_type) {
            py_obj = _pygi_boxed_new ((PyTypeObject *) py_type,
                                      arg->v_pointer,
                                      transfer == GI_TRANSFER_EVERYTHING || is_allocated,
                                      is_allocated ?
                                              g_struct_info_get_size(interface_info) : 0);
        }
    } else if (g_type_is_a (g_type, G_TYPE_POINTER)) {
        if (py_type == NULL ||
                !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) {
            g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
            py_obj = pyg_pointer_new (g_type, arg->v_pointer);
        } else {
            py_obj = _pygi_struct_new ( (PyTypeObject *) py_type,
                                       arg->v_pointer,
                                       transfer == GI_TRANSFER_EVERYTHING);
        }
    } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) {
        /* Note we do not use transfer for the structs free_on_dealloc because
         * GLib.Variant overrides __del__ to call "g_variant_unref". */
        if (py_type) {
            g_variant_ref_sink (arg->v_pointer);
            py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
                                       arg->v_pointer,
                                       FALSE);
        }
    } else if (g_type == G_TYPE_NONE) {
        if (py_type) {
            py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
                                       arg->v_pointer,
                                       transfer == GI_TRANSFER_EVERYTHING);
        }
    } else {
        PyErr_Format (PyExc_NotImplementedError,
                      "structure type '%s' is not supported yet",
                      g_type_name (g_type));
    }

    return py_obj;
}