pygi-marshal-to-py.c 28.7 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
    if (arg_cache->is_pointer) {
121
        return PyLong_FromVoidPtr (arg->v_pointer);
122
    }
123
    Py_RETURN_NONE;
124
125
}

126
127
static PyObject *
_pygi_marshal_to_py_unichar (GIArgument *arg)
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{
    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;
}

150
151
static PyObject *
_pygi_marshal_to_py_utf8 (GIArgument *arg)
152
153
154
{
    PyObject *py_obj = NULL;
    if (arg->v_string == NULL) {
155
        Py_RETURN_NONE;
156
157
158
159
160
161
     }

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

162
163
static PyObject *
_pygi_marshal_to_py_filename (GIArgument *arg)
164
{
165
    gchar *string = NULL;
166
167
168
169
    PyObject *py_obj = NULL;
    GError *error = NULL;

    if (arg->v_string == NULL) {
170
        Py_RETURN_NONE;
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
    }

    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;
}

186
187
188
189
190
191
192
193
194
195
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

/**
 * _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);
}

269
PyObject *
270
271
272
273
_pygi_marshal_to_py_array (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
274
275
276
277
278
279
280
281
282
283
284
285
286
{
    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) {
287
            g_assert(arg->v_pointer != NULL);
288
289
            len = seq_cache->fixed_size;
        } else if (seq_cache->is_zero_terminated) {
290
291
292
            if (arg->v_pointer == NULL) {
                len = 0;
            } else if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
293
294
295
296
                len = strlen (arg->v_pointer);
            } else {
                len = g_strv_length ((gchar **)arg->v_pointer);
            }
297
298
        } else {
            GIArgument *len_arg = state->args[seq_cache->len_arg_index];
David Malcolm's avatar
David Malcolm committed
299
300
301
302
303
304

            if (!gi_argument_to_gsize (len_arg,
                                       &len,
                                       callable_cache->args_cache[seq_cache->len_arg_index]->type_tag)) {
                return NULL;
            }
305
306
307
308
309
310
311
312
        }

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

313
            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && arg->v_pointer != NULL)
314
315
316
317
                g_free (arg->v_pointer);

            return NULL;
        }
318
319
320

        if (array_->data != NULL) 
            g_free (array_->data);
321
322
        array_->data = arg->v_pointer;
        array_->len = len;
323
324
    } else {
        array_ = arg->v_pointer;
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
    }

    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;
340
            PyGIMarshalToPyFunc item_to_py_marshaller;
341
342
343
344
345
346
347
348
            PyGIArgCache *item_arg_cache;

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


            item_arg_cache = seq_cache->item_cache;
349
            item_to_py_marshaller = item_arg_cache->to_py_marshaller;
350
351
352
353
354
355
356
357
358
359

            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) {
360
                    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
361
                    gboolean is_gvariant = iface_cache->g_type == G_TYPE_VARIANT;
362

363
                    // FIXME: This probably doesn't work with boxed types or gvalues. See fx. _pygi_marshal_from_py_array()
364
365
                    switch (g_base_info_get_type (iface_cache->interface_info)) {
                        case GI_INFO_TYPE_STRUCT:
366
367
368
369
370
371
                            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);
372
373
                            } else if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && !item_arg_cache->is_pointer &&
                                       !g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
374
                                /* array elements are structs */
375
376
377
378
                                gpointer *_struct = g_malloc (item_size);
                                memcpy (_struct, array_->data + i * item_size,
                                        item_size);
                                item_arg.v_pointer = _struct;
379
                            } else if (item_arg_cache->is_pointer)
380
                                /* array elements are pointers to values */
381
382
                                item_arg.v_pointer = g_array_index (array_, gpointer, i);
                            else
383
                                item_arg.v_pointer = array_->data + i * item_size;
384
385
386
387
                            break;
                        default:
                            item_arg.v_pointer = g_array_index (array_, gpointer, i);
                            break;
388
389
390
391
392
                    }
                } else {
                    memcpy (&item_arg, array_->data + i * item_size, item_size);
                }

393
                py_item = item_to_py_marshaller ( state,
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
                                                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 */
422
        if (seq_cache->item_cache->to_py_cleanup != NULL) {
423
            int j;
424
            PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->to_py_cleanup;
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
            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 *
441
442
443
444
_pygi_marshal_to_py_glist (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
445
446
447
448
449
{
    GList *list_;
    gsize length;
    gsize i;

450
    PyGIMarshalToPyFunc item_to_py_marshaller;
451
452
453
454
455
456
457
458
459
460
461
462
463
    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;
464
    item_to_py_marshaller = item_arg_cache->to_py_marshaller;
465
466
467
468
469
470

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

        item_arg.v_pointer = list_->data;
471
472
473
474
475
        _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);
476
477
478
479
480
481
482
483
484
485
486
487
488
489

        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 *
490
491
492
493
_pygi_marshal_to_py_gslist (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
                            PyGIArgCache      *arg_cache,
                            GIArgument        *arg)
494
495
496
497
498
{
    GSList *list_;
    gsize length;
    gsize i;

499
    PyGIMarshalToPyFunc item_to_py_marshaller;
500
501
502
503
504
505
506
507
508
509
510
511
512
    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;
513
    item_to_py_marshaller = item_arg_cache->to_py_marshaller;
514
515
516
517
518
519

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

        item_arg.v_pointer = list_->data;
520
521
        _pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
        py_item = item_to_py_marshaller (state,
522
523
                                        callable_cache,
                                        item_arg_cache,
524
                                        &item_arg);
525
526
527
528
529
530
531
532
533
534
535
536
537
538

        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 *
539
540
541
542
_pygi_marshal_to_py_ghash (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
                           PyGIArgCache      *arg_cache,
                           GIArgument        *arg)
543
544
545
546
{
    GHashTable *hash_;
    GHashTableIter hash_table_iter;

547
548
    PyGIMarshalToPyFunc key_to_py_marshaller;
    PyGIMarshalToPyFunc value_to_py_marshaller;
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

    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;
572
    key_to_py_marshaller = key_arg_cache->to_py_marshaller;
573
574

    value_arg_cache = hash_cache->value_cache;
575
    value_to_py_marshaller = value_arg_cache->to_py_marshaller;
576
577
578
579
580
581
582
583
584

    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;

585
586

        _pygi_hash_pointer_to_arg (&key_arg, hash_cache->key_cache->type_tag);
587
        py_key = key_to_py_marshaller ( state,
588
589
590
591
592
593
594
595
596
                                      callable_cache,
                                      key_arg_cache,
                                     &key_arg);

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

597
        _pygi_hash_pointer_to_arg (&value_arg, hash_cache->value_cache->type_tag);
598
        py_value = value_to_py_marshaller ( state,
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
                                          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 *
624
625
626
627
_pygi_marshal_to_py_gerror (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
                            PyGIArgCache      *arg_cache,
                            GIArgument        *arg)
628
{
629
    GError *error = arg->v_pointer;
630
631
    PyObject *py_obj = NULL;

632
633
634
635
636
637
638
639
640
641
642
    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;
    }
643
644
645
}

PyObject *
646
647
648
649
_pygi_marshal_to_py_interface_callback (PyGIInvokeState   *state,
                                        PyGICallableCache *callable_cache,
                                        PyGIArgCache      *arg_cache,
                                        GIArgument        *arg)
650
651
652
653
{
    PyObject *py_obj = NULL;

    PyErr_Format (PyExc_NotImplementedError,
654
                  "Marshalling a callback to PyObject is not supported");
655
656
657
658
    return py_obj;
}

PyObject *
659
660
661
662
_pygi_marshal_to_py_interface_enum (PyGIInvokeState   *state,
                                    PyGICallableCache *callable_cache,
                                    PyGIArgCache      *arg_cache,
                                    GIArgument        *arg)
663
664
665
{
    PyObject *py_obj = NULL;
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
David Malcolm's avatar
David Malcolm committed
666
667
668
669
670
671
672
673
674
675
    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;
    }
676
677

    if (iface_cache->g_type == G_TYPE_NONE) {
David Malcolm's avatar
David Malcolm committed
678
        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
679
    } else {
David Malcolm's avatar
David Malcolm committed
680
        py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
681
    }
682
    g_base_info_unref (interface);
683
684
685
686
    return py_obj;
}

PyObject *
687
688
689
690
_pygi_marshal_to_py_interface_flags (PyGIInvokeState   *state,
                                     PyGICallableCache *callable_cache,
                                     PyGIArgCache      *arg_cache,
                                     GIArgument        *arg)
691
692
693
{
    PyObject *py_obj = NULL;
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
David Malcolm's avatar
David Malcolm committed
694
695
696
697
698
699
700
701
    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))) {
702
        g_base_info_unref (interface);
David Malcolm's avatar
David Malcolm committed
703
704
        return NULL;
    }
705

706
    g_base_info_unref (interface);
707
708
709
710
711
712
713
714
715
716
    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
717
        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
718
719
720
721
722
            Py_DECREF (py_args);
            Py_DECREF (py_type);
            return NULL;
        }

David Malcolm's avatar
David Malcolm committed
723
        py_obj = PyObject_CallFunction (py_type, "l", c_long);
724
725
726
727

        Py_DECREF (py_args);
        Py_DECREF (py_type);
    } else {
David Malcolm's avatar
David Malcolm committed
728
        py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
729
730
731
732
733
734
    }

    return py_obj;
}

PyObject *
735
736
737
738
_pygi_marshal_to_py_interface_struct_cache_adapter (PyGIInvokeState   *state,
                                                    PyGICallableCache *callable_cache,
                                                    PyGIArgCache      *arg_cache,
                                                    GIArgument        *arg)
739
740
741
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;

742
743
744
745
746
747
748
    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);
749
750
751
}

PyObject *
752
753
754
755
_pygi_marshal_to_py_interface_interface (PyGIInvokeState   *state,
                                         PyGICallableCache *callable_cache,
                                         PyGIArgCache      *arg_cache,
                                         GIArgument        *arg)
756
757
758
759
760
761
762
763
764
{
    PyObject *py_obj = NULL;

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

PyObject *
765
766
767
768
_pygi_marshal_to_py_interface_boxed (PyGIInvokeState   *state,
                                     PyGICallableCache *callable_cache,
                                     PyGIArgCache      *arg_cache,
                                     GIArgument        *arg)
769
770
771
772
773
774
775
776
777
{
    PyObject *py_obj = NULL;

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

PyObject *
778
779
780
781
_pygi_marshal_to_py_interface_object_cache_adapter (PyGIInvokeState   *state,
                                                    PyGICallableCache *callable_cache,
                                                    PyGIArgCache      *arg_cache,
                                                    GIArgument        *arg)
782
{
783
    return _pygi_marshal_to_py_object(arg, arg_cache->transfer);
784
785
786
}

PyObject *
787
788
789
790
_pygi_marshal_to_py_interface_union  (PyGIInvokeState   *state,
                                      PyGICallableCache *callable_cache,
                                      PyGIArgCache      *arg_cache,
                                      GIArgument        *arg)
791
792
793
794
795
796
797
{
    PyObject *py_obj = NULL;

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

PyObject *
800
_pygi_marshal_to_py_object (GIArgument *arg, GITransfer transfer) {
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
    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;
}
820
821

PyObject *
822
823
824
825
826
827
828
_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)
829
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
{
    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;
}