pygi-marshal-from-py.c 64.5 KB
Newer Older
1
2
3
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
4
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>,  Red Hat, Inc.
5
 *
6
 *   pygi-marshal-from-py.c: Functions to convert PyObjects to C types.
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 *
 * 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>
#include <pygobject.h>
#include <pyglib-python-compat.h>

#include "pygi-cache.h"
32
#include "pygi-marshal-cleanup.h"
33
#include "pygi-marshal-from-py.h"
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#ifdef _WIN32
#ifdef _MSC_VER
#include <math.h>

#ifndef NAN
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
#define NAN (*(const float *) __nan)
#endif

#ifndef INFINITY
#define INFINITY HUGE_VAL
#endif

#endif
#endif

51
static gboolean
David Malcolm's avatar
David Malcolm committed
52
53
54
55
56
57
58
gi_argument_from_py_ssize_t (GIArgument   *arg_out,
                             Py_ssize_t    size_in,
                             GITypeTag     type_tag)                             
{
    switch (type_tag) {
    case GI_TYPE_TAG_VOID:
    case GI_TYPE_TAG_BOOLEAN:
59
60
        goto unhandled_type;

David Malcolm's avatar
David Malcolm committed
61
    case GI_TYPE_TAG_INT8:
62
63
64
65
66
67
68
        if (size_in >= G_MININT8 && size_in <= G_MAXINT8) {
            arg_out->v_int8 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }

David Malcolm's avatar
David Malcolm committed
69
    case GI_TYPE_TAG_UINT8:
70
71
72
73
74
75
76
        if (size_in >= 0 && size_in <= G_MAXUINT8) {
            arg_out->v_uint8 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }

David Malcolm's avatar
David Malcolm committed
77
    case GI_TYPE_TAG_INT16:
78
79
80
81
82
83
84
        if (size_in >= G_MININT16 && size_in <= G_MAXINT16) {
            arg_out->v_int16 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }

David Malcolm's avatar
David Malcolm committed
85
    case GI_TYPE_TAG_UINT16:
86
87
88
89
90
91
        if (size_in >= 0 && size_in <= G_MAXUINT16) {
            arg_out->v_uint16 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }
David Malcolm's avatar
David Malcolm committed
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

        /* Ranges assume two's complement */
    case GI_TYPE_TAG_INT32:
        if (size_in >= G_MININT32 && size_in <= G_MAXINT32) {
            arg_out->v_int32 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }

    case GI_TYPE_TAG_UINT32:
        if (size_in >= 0 && size_in <= G_MAXUINT32) {
            arg_out->v_uint32 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }

    case GI_TYPE_TAG_INT64:
        arg_out->v_int64 = size_in;
        return TRUE;

    case GI_TYPE_TAG_UINT64:
        if (size_in >= 0) {
            arg_out->v_uint64 = size_in;
            return TRUE;
        } else {
            goto overflow;
        }
            
    case GI_TYPE_TAG_FLOAT:
    case GI_TYPE_TAG_DOUBLE:
    case GI_TYPE_TAG_GTYPE:
    case GI_TYPE_TAG_UTF8:
    case GI_TYPE_TAG_FILENAME:
    case GI_TYPE_TAG_ARRAY:
    case GI_TYPE_TAG_INTERFACE:
    case GI_TYPE_TAG_GLIST:
    case GI_TYPE_TAG_GSLIST:
    case GI_TYPE_TAG_GHASH:
    case GI_TYPE_TAG_ERROR:
    case GI_TYPE_TAG_UNICHAR:
    default:
        goto unhandled_type;
    }

 overflow:
    PyErr_Format (PyExc_OverflowError,
                  "Unable to marshal C Py_ssize_t %zd to %s",
                  size_in,
                  g_type_tag_to_string (type_tag));
    return FALSE;

 unhandled_type:
    PyErr_Format (PyExc_TypeError,
                  "Unable to marshal C Py_ssize_t %zd to %s",
                  size_in,
                  g_type_tag_to_string (type_tag));
    return FALSE;
}

153
static gboolean
David Malcolm's avatar
David Malcolm committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
gi_argument_from_c_long (GIArgument *arg_out,
                         long        c_long_in,
                         GITypeTag   type_tag)
{
    switch (type_tag) {
      case GI_TYPE_TAG_INT8:
          arg_out->v_int8 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_UINT8:
          arg_out->v_uint8 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_INT16:
          arg_out->v_int16 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_UINT16:
          arg_out->v_uint16 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_INT32:
          arg_out->v_int32 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_UINT32:
          arg_out->v_uint32 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_INT64:
          arg_out->v_int64 = c_long_in;
          return TRUE;
      case GI_TYPE_TAG_UINT64:
          arg_out->v_uint64 = c_long_in;
          return TRUE;
      default:
          PyErr_Format (PyExc_TypeError,
                        "Unable to marshal C long %ld to %s",
                        c_long_in,
                        g_type_tag_to_string (type_tag));
          return FALSE;
    }
}

192
193
194
195
196
/*
 * _is_union_member - check to see if the py_arg is actually a member of the
 * expected C union
 */
static gboolean
197
_is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
198
199
200
201
202
203
    gint i;
    gint n_fields;
    GIUnionInfo *union_info;
    GIInfoType info_type;
    gboolean is_member = FALSE;

204
    info_type = g_base_info_get_type (interface_info);
205
206
207
208

    if (info_type != GI_INFO_TYPE_UNION)
        return FALSE;

209
    union_info = (GIUnionInfo *) interface_info;
210
211
212
213
214
215
216
217
218
219
220
    n_fields = g_union_info_get_n_fields (union_info);

    for (i = 0; i < n_fields; i++) {
        GIFieldInfo *field_info;
        GITypeInfo *field_type_info;

        field_info = g_union_info_get_field (union_info, i);
        field_type_info = g_field_info_get_type (field_info);

        /* we can only check if the members are interfaces */
        if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
221
            GIInterfaceInfo *field_iface_info;
222
223
            PyObject *py_type;

224
225
            field_iface_info = g_type_info_get_interface (field_type_info);
            py_type = _pygi_type_import_by_gi_info ((GIBaseInfo *) field_iface_info);
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

            if (py_type != NULL && PyObject_IsInstance (py_arg, py_type)) {
                is_member = TRUE;
            }

            Py_XDECREF (py_type);
            g_base_info_unref ( ( GIBaseInfo *) field_iface_info);
        }

        g_base_info_unref ( ( GIBaseInfo *) field_type_info);
        g_base_info_unref ( ( GIBaseInfo *) field_info);

        if (is_member)
            break;
    }

    return is_member;
}

245
gboolean
246
247
248
249
_pygi_marshal_from_py_void (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
                            PyGIArgCache      *arg_cache,
                            PyObject          *py_arg,
250
251
                            GIArgument        *arg,
                            gpointer          *cleanup_data)
252
253
254
{
    g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING);

255
256
257
    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
    } else if (PYGLIB_CPointer_Check(py_arg)) {
258
        arg->v_pointer = PYGLIB_CPointer_GetPointer (py_arg, NULL);
259
260
    } else if (PYGLIB_PyLong_Check(py_arg) || PyLong_Check(py_arg)) {
        arg->v_pointer = PyLong_AsVoidPtr (py_arg);
261
    } else {
262
263
264
265
        PyErr_SetString(PyExc_ValueError,
                        "Pointer arguments are restricted to integers, capsules, and None. "
                        "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599");
        return FALSE;
266
    }
267

268
    *cleanup_data = arg->v_pointer;
269
270
271
    return TRUE;
}

272
273
274
275
276
277
278
279
280
281
282
static gboolean
check_valid_double (double x, double min, double max)
{
    char buf[100];

    if ((x < min || x > max) && x != INFINITY && x != -INFINITY && x != NAN) {
        if (PyErr_Occurred())
            PyErr_Clear ();

        /* we need this as PyErr_Format() does not support float types */
        snprintf (buf, sizeof (buf), "%g not in range %g to %g", x, min, max);
283
        PyErr_SetString (PyExc_OverflowError, buf);
284
285
286
287
288
        return FALSE;
    }
    return TRUE;
}

289
290
static gboolean
_pygi_py_arg_to_double (PyObject *py_arg, double *double_)
291
292
293
{
    PyObject *py_float;

294
    if (!PyNumber_Check (py_arg)) {
295
296
297
298
299
        PyErr_Format (PyExc_TypeError, "Must be number, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

300
    py_float = PyNumber_Float (py_arg);
301
302
303
    if (!py_float)
        return FALSE;

304
    *double_ = PyFloat_AsDouble (py_float);
305
    Py_DECREF (py_float);
306

307
308
309
310

    return TRUE;
}

311
312
static gboolean
_pygi_marshal_from_py_float (PyObject          *py_arg,
313
314
315
316
317
318
319
                             GIArgument        *arg)
{
    double double_;

    if (!_pygi_py_arg_to_double (py_arg, &double_))
        return FALSE;

320
    if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXFLOAT, G_MAXFLOAT))
321
322
323
324
325
326
        return FALSE;

    arg->v_float = double_;
    return TRUE;
}

327
328
static gboolean
_pygi_marshal_from_py_double (PyObject          *py_arg,
329
                              GIArgument        *arg)
330
331
332
{
    double double_;

333
    if (!_pygi_py_arg_to_double (py_arg, &double_))
334
335
        return FALSE;

336
    if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXDOUBLE, G_MAXDOUBLE))
337
338
339
340
341
342
        return FALSE;

    arg->v_double = double_;
    return TRUE;
}

343
344
static gboolean
_pygi_marshal_from_py_unichar (PyObject          *py_arg,
345
                               GIArgument        *arg)
346
347
348
349
{
    Py_ssize_t size;
    gchar *string_;

350
351
352
353
354
    if (py_arg == Py_None) {
        arg->v_uint32 = 0;
        return FALSE;
    }

355
356
357
358
    if (PyUnicode_Check (py_arg)) {
       PyObject *py_bytes;

       size = PyUnicode_GET_SIZE (py_arg);
359
       py_bytes = PyUnicode_AsUTF8String (py_arg);
360
361
362
       if (!py_bytes)
           return FALSE;

Martin Pitt's avatar
Martin Pitt committed
363
       string_ = g_strdup(PYGLIB_PyBytes_AsString (py_bytes));
364
       Py_DECREF (py_bytes);
365
366
367
368
369
370
371
372

#if PY_VERSION_HEX < 0x03000000
    } else if (PyString_Check (py_arg)) {
       PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict");
       if (!pyuni)
           return FALSE;

       size = PyUnicode_GET_SIZE (pyuni);
373
374
       string_ = g_strdup (PyString_AsString(py_arg));
       Py_DECREF (pyuni);
375
376
377
378
379
380
381
382
#endif
    } else {
       PyErr_Format (PyExc_TypeError, "Must be string, not %s",
                     py_arg->ob_type->tp_name);
       return FALSE;
    }

    if (size != 1) {
383
384
       PyErr_Format (PyExc_TypeError, "Must be a one character string, not %lld characters",
                     (long long) size);
385
       g_free (string_);
386
387
388
       return FALSE;
    }

389
390
    arg->v_uint32 = g_utf8_get_char (string_);
    g_free (string_);
391
392
393

    return TRUE;
}
394

395
396
static gboolean
_pygi_marshal_from_py_gtype (PyObject          *py_arg,
397
                             GIArgument        *arg)
398
399
400
401
402
403
404
405
406
407
408
409
{
    long type_ = pyg_type_from_object (py_arg);

    if (type_ == 0) {
        PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

    arg->v_long = type_;
    return TRUE;
}
410
411
412

static gboolean
_pygi_marshal_from_py_utf8 (PyObject          *py_arg,
413
414
                            GIArgument        *arg,
                            gpointer          *cleanup_data)
415
416
417
418
419
420
421
422
{
    gchar *string_;

    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
        return TRUE;
    }

423
    if (PyUnicode_Check (py_arg)) {
424
425
426
427
        PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
        if (!pystr_obj)
            return FALSE;

428
429
        string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
        Py_DECREF (pystr_obj);
430
431
    }
#if PY_VERSION_HEX < 0x03000000
432
433
    else if (PyString_Check (py_arg)) {
        string_ = g_strdup (PyString_AsString (py_arg));
434
435
436
437
438
439
440
441
442
    }
#endif
    else {
        PyErr_Format (PyExc_TypeError, "Must be string, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

    arg->v_string = string_;
443
    *cleanup_data = arg->v_string;
444
445
446
    return TRUE;
}

447
448
static gboolean
_pygi_marshal_from_py_filename (PyObject          *py_arg,
449
450
                                GIArgument        *arg,
                                gpointer          *cleanup_data)
451
452
453
454
{
    gchar *string_;
    GError *error = NULL;

455
    if (PyUnicode_Check (py_arg)) {
456
457
458
459
        PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
        if (!pystr_obj)
            return FALSE;

460
461
        string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
        Py_DECREF (pystr_obj);
462
463
    }
#if PY_VERSION_HEX < 0x03000000
464
465
    else if (PyString_Check (py_arg)) {
        string_ = g_strdup (PyString_AsString (py_arg));
466
467
468
469
470
471
472
473
474
    }
#endif
    else {
        PyErr_Format (PyExc_TypeError, "Must be string, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

    arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error);
475
    g_free (string_);
476
477
478

    if (arg->v_string == NULL) {
        PyErr_SetString (PyExc_Exception, error->message);
479
        g_error_free (error);
480
481
482
483
        /* TODO: Convert the error to an exception. */
        return FALSE;
    }

484
    *cleanup_data = arg->v_string;
485
486
487
    return TRUE;
}

488
489
490
491
492
493
494
495
static gboolean
_pygi_marshal_from_py_long (PyObject   *object,   /* in */
                            GIArgument *arg,      /* out */
                            GITypeTag   type_tag,
                            GITransfer  transfer)
{
    PyObject *number;

496
497
498
499
500
501
    if (!PyNumber_Check (object)) {
        PyErr_Format (PyExc_TypeError, "Must be number, not %s",
                      object->ob_type->tp_name);
        return FALSE;
    }

502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
#if PY_MAJOR_VERSION < 3
    {
        PyObject *tmp = PyNumber_Int (object);
        if (tmp) {
            number = PyNumber_Long (tmp);
            Py_DECREF (tmp);
        } else {
            number = PyNumber_Long (object);
        }
    }
#else
    number = PyNumber_Long (object);
#endif

    if (number == NULL) {
        PyErr_SetString (PyExc_TypeError, "expected int argument");
        return FALSE;
    }

    switch (type_tag) {
        case GI_TYPE_TAG_INT8:
523
524
        {
            long long_value = PyLong_AsLong (number);
525
526
527
528
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < G_MININT8 || long_value > G_MAXINT8) {
                PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
529
530
531
532
533
534
535
536
537
538
                              long_value, (long)G_MININT8, (long)G_MAXINT8);
            } else {
                arg->v_int8 = long_value;
            }
            break;
        }

        case GI_TYPE_TAG_UINT8:
        {
            long long_value = PyLong_AsLong (number);
539
540
541
542
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < 0 || long_value > G_MAXUINT8) {
                PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
543
544
545
546
                              long_value, (long)0, (long)G_MAXUINT8);
            } else {
                arg->v_uint8 = long_value;
            }
547
            break;
548
        }
549
550

        case GI_TYPE_TAG_INT16:
551
552
        {
            long long_value = PyLong_AsLong (number);
553
554
555
556
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < G_MININT16 || long_value > G_MAXINT16) {
                PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
557
558
559
560
                              long_value, (long)G_MININT16, (long)G_MAXINT16);
            } else {
                arg->v_int16 = long_value;
            }
561
            break;
562
        }
563

564
565
566
        case GI_TYPE_TAG_UINT16:
        {
            long long_value = PyLong_AsLong (number);
567
568
569
570
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < 0 || long_value > G_MAXUINT16) {
                PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
571
572
573
574
                              long_value, (long)0, (long)G_MAXUINT16);
            } else {
                arg->v_uint16 = long_value;
            }
575
            break;
576
        }
577

578
579
580
        case GI_TYPE_TAG_INT32:
        {
            long long_value = PyLong_AsLong (number);
581
582
583
584
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < G_MININT32 || long_value > G_MAXINT32) {
                PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
585
586
587
588
                              long_value, (long)G_MININT32, (long)G_MAXINT32);
            } else {
                arg->v_int32 = long_value;
            }
589
            break;
590
        }
591

592
593
594
        case GI_TYPE_TAG_UINT32:
        {
            PY_LONG_LONG long_value = PyLong_AsLongLong (number);
595
596
597
598
            if (PyErr_Occurred()) {
                break;
            } else if (long_value < 0 || long_value > G_MAXUINT32) {
                PyErr_Format (PyExc_OverflowError, "%lld not in range %ld to %lu",
599
600
601
602
                              long_value, (long)0, (unsigned long)G_MAXUINT32);
            } else {
                arg->v_uint32 = long_value;
            }
603
            break;
604
        }
605

606
        case GI_TYPE_TAG_INT64:
607
608
        {
            /* Rely on Python overflow error and convert to ValueError for 64 bit values */
609
            arg->v_int64 = PyLong_AsLongLong (number);
610
            break;
611
        }
612
613

        case GI_TYPE_TAG_UINT64:
614
615
        {
            /* Rely on Python overflow error and convert to ValueError for 64 bit values */
616
            arg->v_uint64 = PyLong_AsUnsignedLongLong (number);
617
            break;
618
        }
619
620
621
622
623
624
625
626
627
628
629
630

        default:
            g_assert_not_reached ();
    }

    Py_DECREF (number);

    if (PyErr_Occurred())
        return FALSE;
    return TRUE;
}

631
632
633
634
gboolean
_pygi_marshal_from_py_basic_type (PyObject   *object,   /* in */
                                  GIArgument *arg,      /* out */
                                  GITypeTag   type_tag,
635
636
                                  GITransfer  transfer,
                                  gpointer   *cleanup_data /* out */)
637
638
639
640
641
642
643
644
645
646
647
648
{
    switch (type_tag) {
        case GI_TYPE_TAG_VOID:
            g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
            if (object == Py_None) {
                arg->v_pointer = NULL;
            } else if (!PYGLIB_PyLong_Check(object)  && !PyLong_Check(object)) {
                PyErr_SetString(PyExc_TypeError,
                    "Pointer assignment is restricted to integer values. "
                    "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599");
            } else {
                arg->v_pointer = PyLong_AsVoidPtr (object);
649
                *cleanup_data = arg->v_pointer;
650
651
652
653
            }
            break;
        case GI_TYPE_TAG_INT8:
        case GI_TYPE_TAG_UINT8:
654
655
656
657
658
659
660
661
662
663
664
665
666
667
            if (PYGLIB_PyBytes_Check (object)) {
                if (PYGLIB_PyBytes_Size (object) != 1) {
                    PyErr_Format (PyExc_TypeError, "Must be a single character");
                    return FALSE;
                }
                if (type_tag == GI_TYPE_TAG_INT8) {
                    arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]);
                } else {
                    arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]);
                }
            } else {
                return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
            }
            break;
668
        case GI_TYPE_TAG_INT16:
669
        case GI_TYPE_TAG_UINT16:
670
        case GI_TYPE_TAG_INT32:
671
        case GI_TYPE_TAG_UINT32:
672
        case GI_TYPE_TAG_INT64:
673
        case GI_TYPE_TAG_UINT64:
674
            return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
675

676
677
        case GI_TYPE_TAG_BOOLEAN:
            arg->v_boolean = PyObject_IsTrue (object);
678
            break;
679

680
        case GI_TYPE_TAG_FLOAT:
681
682
            return _pygi_marshal_from_py_float (object, arg);

683
        case GI_TYPE_TAG_DOUBLE:
684
685
            return _pygi_marshal_from_py_double (object, arg);

686
        case GI_TYPE_TAG_GTYPE:
687
            return _pygi_marshal_from_py_gtype (object, arg);
688
689

        case GI_TYPE_TAG_UNICHAR:
690
691
            return _pygi_marshal_from_py_unichar (object, arg);

692
        case GI_TYPE_TAG_UTF8:
693
            return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data);
694

695
        case GI_TYPE_TAG_FILENAME:
696
            return _pygi_marshal_from_py_filename (object, arg, cleanup_data);
697

698
699
700
        default:
            return FALSE;
    }
701
702
703
704

    if (PyErr_Occurred())
        return FALSE;

705
706
707
    return TRUE;
}

708
709
710
711
712
gboolean
_pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState   *state,
                                                PyGICallableCache *callable_cache,
                                                PyGIArgCache      *arg_cache,
                                                PyObject          *py_arg,
713
714
                                                GIArgument        *arg,
                                                gpointer          *cleanup_data)
715
716
717
718
{
    return _pygi_marshal_from_py_basic_type (py_arg,
                                             arg,
                                             arg_cache->type_tag,
719
720
                                             arg_cache->transfer,
                                             cleanup_data);
721
}
722

723
gboolean
724
725
726
727
_pygi_marshal_from_py_array (PyGIInvokeState   *state,
                             PyGICallableCache *callable_cache,
                             PyGIArgCache      *arg_cache,
                             PyObject          *py_arg,
728
729
                             GIArgument        *arg,
                             gpointer          *cleanup_data)
730
{
731
    PyGIMarshalFromPyFunc from_py_marshaller;
732
    int i = 0;
733
    int success_count = 0;
734
    Py_ssize_t length;
735
    gssize item_size;
736
    gboolean is_ptr_array;
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    GArray *array_ = NULL;
    PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;


    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
        return TRUE;
    }

    if (!PySequence_Check (py_arg)) {
        PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

    length = PySequence_Length (py_arg);
    if (length < 0)
        return FALSE;

    if (sequence_cache->fixed_size >= 0 &&
        sequence_cache->fixed_size != length) {
        PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
                      sequence_cache->fixed_size, length);

        return FALSE;
    }

764
    item_size = sequence_cache->item_size;
765
766
    is_ptr_array = (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
    if (is_ptr_array) {
767
        array_ = (GArray *)g_ptr_array_sized_new (length);
768
769
    } else {
        array_ = g_array_sized_new (sequence_cache->is_zero_terminated,
770
                                    TRUE,
771
                                    item_size,
772
773
                                    length);
    }
774
775

    if (array_ == NULL) {
776
        PyErr_NoMemory ();
777
778
779
780
        return FALSE;
    }

    if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
781
782
        PYGLIB_PyBytes_Check (py_arg)) {
        memcpy(array_->data, PYGLIB_PyBytes_AsString (py_arg), length);
Martin Pitt's avatar
Martin Pitt committed
783
        array_->len = length;
784
785
786
787
788
        if (sequence_cache->is_zero_terminated) {
            /* If array_ has been created with zero_termination, space for the
             * terminator is properly allocated, so we're not off-by-one here. */
            array_->data[length] = '\0';
        }
789
790
791
        goto array_success;
    }

792
    from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
793
794
    for (i = 0, success_count = 0; i < length; i++) {
        GIArgument item = {0};
795
        gpointer item_cleanup_data = NULL;
796
797
798
799
        PyObject *py_item = PySequence_GetItem (py_arg, i);
        if (py_item == NULL)
            goto err;

800
801
802
803
        if (!from_py_marshaller ( state,
                                  callable_cache,
                                  sequence_cache->item_cache,
                                  py_item,
804
805
                                 &item,
                                 &item_cleanup_data)) {
806
            Py_DECREF (py_item);
807
            goto err;
808
809
        }
        Py_DECREF (py_item);
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

        if (item_cleanup_data != NULL && item_cleanup_data != item.v_pointer) {
            /* We only support one level of data discrepancy between an items
             * data and its cleanup data. This is because we only track a single
             * extra cleanup data pointer per-argument and cannot track the entire
             * array of items differing data and cleanup_data.
             * For example, this would fail if trying to marshal an array of
             * callback closures marked with SCOPE call type where the cleanup data
             * is different from the items v_pointer, likewise an array of arrays.
             */
            PyErr_SetString(PyExc_RuntimeError, "Cannot cleanup item data for array due to "
                                                "the items data its cleanup data being different.");
            goto err;
        }

825
826
827
828
        /* FIXME: it is much more efficent to have seperate marshaller
         *        for ptr arrays than doing the evaluation
         *        and casting each loop iteration
         */
829
        if (is_ptr_array) {
830
            g_ptr_array_add((GPtrArray *)array_, item.v_pointer);
831
832
833
834
        } else if (sequence_cache->item_cache->is_pointer) {
            /* if the item is a pointer, simply copy the pointer */
            g_assert (item_size == sizeof (item.v_pointer));
            g_array_insert_val (array_, i, item);
835
        } else if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
836
            /* Special case handling of flat arrays of gvalue/boxed/struct */
837
838
839
840
841
842
843
844
845
846
            PyGIInterfaceCache *item_iface_cache = (PyGIInterfaceCache *) sequence_cache->item_cache;
            GIBaseInfo *base_info = (GIBaseInfo *) item_iface_cache->interface_info;
            GIInfoType info_type = g_base_info_get_type (base_info);

            switch (info_type) {
                case GI_INFO_TYPE_UNION:
                case GI_INFO_TYPE_STRUCT:
                {
                    PyGIArgCache *item_arg_cache = (PyGIArgCache *)item_iface_cache;
                    PyGIMarshalCleanupFunc from_py_cleanup = item_arg_cache->from_py_cleanup;
847
848
849

                    if (g_type_is_a (item_iface_cache->g_type, G_TYPE_VALUE)) {
                        /* Special case GValue flat arrays to properly init and copy the contents. */
850
851
                        GValue* dest = (GValue*) (array_->data + (i * item_size));
                        if (item.v_pointer != NULL) {
852
                            memset (dest, 0, item_size);
853
854
855
                            g_value_init (dest, G_VALUE_TYPE ((GValue*) item.v_pointer));
                            g_value_copy ((GValue*) item.v_pointer, dest);
                        }
856
857
                        /* Manually increment the length because we are manually setting the memory. */
                        array_->len++;
858

859
                    } else {
860
861
                        /* Handles flat arrays of boxed or struct types. */
                        g_array_insert_vals (array_, i, item.v_pointer, 1);
862
                    }
863
864
865
866
867
868

                    /* Cleanup any memory left by the per-item marshaler because
                     * _pygi_marshal_cleanup_from_py_array will not know about this
                     * due to "item" being a temporarily marshaled value done on the stack.
                     */
                    if (from_py_cleanup)
869
                        from_py_cleanup (state, item_arg_cache, py_item, item_cleanup_data, TRUE);
870

871
872
873
874
875
876
                    break;
                }
                default:
                    g_array_insert_val (array_, i, item);
            }
        } else {
877
            /* default value copy of a simple type */
878
            g_array_insert_val (array_, i, item);
879
        }
880

881
        success_count++;
882
883
        continue;
err:
884
        if (sequence_cache->item_cache->from_py_cleanup != NULL) {
885
886
            gsize j;
            PyGIMarshalCleanupFunc cleanup_func =
887
                sequence_cache->item_cache->from_py_cleanup;
888

889
890
891
892
893
894
895
896
897
898
899
900
901
            /* Only attempt per item cleanup on pointer items */
            if (sequence_cache->item_cache->is_pointer) {
                for(j = 0; j < success_count; j++) {
                    PyObject *py_item = PySequence_GetItem (py_arg, j);
                    cleanup_func (state,
                                  sequence_cache->item_cache,
                                  py_item,
                                  is_ptr_array ?
                                          g_ptr_array_index ((GPtrArray *)array_, j) :
                                          g_array_index (array_, gpointer, j),
                                  TRUE);
                    Py_DECREF (py_item);
                }
902
            }
903
904
        }

905
        if (is_ptr_array)
906
            g_ptr_array_free ( ( GPtrArray *)array_, TRUE);
907
908
        else
            g_array_free (array_, TRUE);
909
910
911
912
913
914
        _PyGI_ERROR_PREFIX ("Item %i: ", i);
        return FALSE;
    }

array_success:
    if (sequence_cache->len_arg_index >= 0) {
915
916
        /* we have an child arg to handle */
        PyGIArgCache *child_cache =
917
            _pygi_callable_cache_get_arg (callable_cache, sequence_cache->len_arg_index);
918

919
        if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) {
920
            gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer;
921
            /* if we are not setup yet just set the in arg */
David Malcolm's avatar
David Malcolm committed
922
923
924
925
926
927
928
            if (len_arg == NULL) {
                if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
                                                  length,
                                                  child_cache->type_tag)) {
                    goto err;
                }
            } else {
929
                *len_arg = length;
David Malcolm's avatar
David Malcolm committed
930
            }
931
        } else {
David Malcolm's avatar
David Malcolm committed
932
933
934
935
936
            if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
                                              length,
                                              child_cache->type_tag)) {
                goto err;
            }
937
938
939
940
        }
    }

    if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
941
942
943
944
        /* In the case of GI_ARRAY_C, we give the data directly as the argument
         * but keep the array_ wrapper as cleanup data so we don't have to find
         * it's length again.
         */
945
        arg->v_pointer = array_->data;
946
947
948
949
950
951
952

        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
            g_array_free (array_, FALSE);
            *cleanup_data = NULL;
        } else {
            *cleanup_data = array_;
        }
953
954
955
    } else {
        arg->v_pointer = array_;

956
957
958
959
960
961
962
963
964
965
966
967
968
969
        if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
            /* Free everything in cleanup. */
            *cleanup_data = array_;
        } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
            /* Make a shallow copy so we can free the elements later in cleanup
             * because it is possible invoke will free the list before our cleanup. */
            *cleanup_data = is_ptr_array ?
                    (gpointer)g_ptr_array_ref ((GPtrArray *)array_) :
                    (gpointer)g_array_ref (array_);
        } else { /* GI_TRANSFER_EVERYTHING */
            /* No cleanup, everything is given to the callee. */
            *cleanup_data = NULL;
        }
    }
970

971
972
973
974
    return TRUE;
}

gboolean
975
976
977
978
_pygi_marshal_from_py_glist (PyGIInvokeState   *state,
                             PyGICallableCache *callable_cache,
                             PyGIArgCache      *arg_cache,
                             PyObject          *py_arg,
979
980
                             GIArgument        *arg,
                             gpointer          *cleanup_data)
981
{
982
    PyGIMarshalFromPyFunc from_py_marshaller;
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
    int i;
    Py_ssize_t length;
    GList *list_ = NULL;
    PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;


    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
        return TRUE;
    }

    if (!PySequence_Check (py_arg)) {
        PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

1000
    length = PySequence_Length (py_arg);
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
    if (length < 0)
        return FALSE;

    if (sequence_cache->fixed_size >= 0 &&
        sequence_cache->fixed_size != length) {
        PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
                      sequence_cache->fixed_size, length);

        return FALSE;
    }

1012
    from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
1013
    for (i = 0; i < length; i++) {
1014
1015
        GIArgument item = {0};
        gpointer item_cleanup_data = NULL;
1016
1017
1018
1019
        PyObject *py_item = PySequence_GetItem (py_arg, i);
        if (py_item == NULL)
            goto err;

1020
1021
1022
1023
        if (!from_py_marshaller ( state,
                                  callable_cache,
                                  sequence_cache->item_cache,
                                  py_item,
1024
1025
                                 &item,
                                 &item_cleanup_data))
1026
1027
            goto err;

1028
        Py_DECREF (py_item);
1029
        list_ = g_list_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
1030
1031
        continue;
err:
John (J5) Palmieri's avatar
John (J5) Palmieri committed
1032
        /* FIXME: clean up list
1033
1034
        if (sequence_cache->item_cache->from_py_cleanup != NULL) {
            PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup;
1035
        }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
1036
        */
1037
        Py_DECREF (py_item);
1038
        g_list_free (list_);
1039
1040
1041
1042
        _PyGI_ERROR_PREFIX ("Item %i: ", i);
        return FALSE;
    }

1043
    arg->v_pointer = g_list_reverse (list_);
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055

    if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
        /* Free everything in cleanup. */
        *cleanup_data = arg->v_pointer;
    } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
        /* Make a shallow copy so we can free the elements later in cleanup
         * because it is possible invoke will free the list before our cleanup. */
        *cleanup_data = g_list_copy (arg->v_pointer);
    } else { /* GI_TRANSFER_EVERYTHING */
        /* No cleanup, everything is given to the callee. */
        *cleanup_data = NULL;
    }
1056
1057
1058
1059
    return TRUE;
}

gboolean
1060
1061
1062
1063
_pygi_marshal_from_py_gslist (PyGIInvokeState   *state,
                              PyGICallableCache *callable_cache,
                              PyGIArgCache      *arg_cache,
                              PyObject          *py_arg,
1064
1065
                              GIArgument        *arg,
                              gpointer          *cleanup_data)
1066
{
1067
    PyGIMarshalFromPyFunc from_py_marshaller;
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
    int i;
    Py_ssize_t length;
    GSList *list_ = NULL;
    PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;

    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
        return TRUE;
    }

    if (!PySequence_Check (py_arg)) {
        PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

1084
    length = PySequence_Length (py_arg);
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
    if (length < 0)
        return FALSE;

    if (sequence_cache->fixed_size >= 0 &&
        sequence_cache->fixed_size != length) {
        PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
                      sequence_cache->fixed_size, length);

        return FALSE;
    }

1096
    from_py_marshaller = sequence_cache->item_cache->from_py_marshaller;
1097
    for (i = 0; i < length; i++) {
1098
1099
        GIArgument item = {0};
        gpointer item_cleanup_data = NULL;
1100
1101
1102
1103
        PyObject *py_item = PySequence_GetItem (py_arg, i);
        if (py_item == NULL)
            goto err;

1104
        if (!from_py_marshaller ( state,
1105
1106
1107
                             callable_cache,
                             sequence_cache->item_cache,
                             py_item,
1108
1109
                            &item,
                            &item_cleanup_data))
1110
1111
            goto err;

1112
        Py_DECREF (py_item);
1113
        list_ = g_slist_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
1114
1115
        continue;
err:
John (J5) Palmieri's avatar
John (J5) Palmieri committed
1116
        /* FIXME: Clean up list
1117
1118
        if (sequence_cache->item_cache->from_py_cleanup != NULL) {
            PyGIMarshalCleanupFunc cleanup = sequence_cache->item_cache->from_py_cleanup;
1119
        }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
1120
        */
1121

1122
        Py_DECREF (py_item);
1123
        g_slist_free (list_);
1124
1125
1126
1127
        _PyGI_ERROR_PREFIX ("Item %i: ", i);
        return FALSE;
    }

1128
    arg->v_pointer = g_slist_reverse (list_);
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

    if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
        /* Free everything in cleanup. */
        *cleanup_data = arg->v_pointer;
    } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
        /* Make a shallow copy so we can free the elements later in cleanup
         * because it is possible invoke will free the list before our cleanup. */
        *cleanup_data = g_slist_copy (arg->v_pointer);
    } else { /* GI_TRANSFER_EVERYTHING */
        /* No cleanup, everything is given to the callee. */
        *cleanup_data = NULL;
    }

1142
1143
1144
1145
    return TRUE;
}

gboolean
1146
1147
1148
1149
_pygi_marshal_from_py_ghash (PyGIInvokeState   *state,
                             PyGICallableCache *callable_cache,
                             PyGIArgCache      *arg_cache,
                             PyObject          *py_arg,
1150
1151
                             GIArgument        *arg,
                             gpointer          *cleanup_data)
1152
{
1153
1154
    PyGIMarshalFromPyFunc key_from_py_marshaller;
    PyGIMarshalFromPyFunc value_from_py_marshaller;
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170

    int i;
    Py_ssize_t length;
    PyObject *py_keys, *py_values;

    GHashFunc hash_func;
    GEqualFunc equal_func;

    GHashTable *hash_ = NULL;
    PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;

    if (py_arg == Py_None) {
        arg->v_pointer = NULL;
        return TRUE;
    }

1171
    py_keys = PyMapping_Keys (py_arg);
1172
1173
1174
1175
1176
1177
    if (py_keys == NULL) {
        PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
                      py_arg->ob_type->tp_name);
        return FALSE;
    }

1178
    length = PyMapping_Length (py_arg);
1179
    if (length < 0) {
1180
        Py_DECREF (py_keys);
1181
1182
1183
        return FALSE;
    }

1184
    py_values = PyMapping_Values (py_arg);
1185
    if (py_values == NULL) {
1186
        Py_DECREF (py_keys);
1187
1188
1189
        return FALSE;
    }

1190
1191
    key_from_py_marshaller = hash_cache->key_cache->from_py_marshaller;
    value_from_py_marshaller = hash_cache->value_cache->from_py_marshaller;
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205

    switch (hash_cache->key_cache->type_tag) {
        case GI_TYPE_TAG_UTF8:
        case GI_TYPE_TAG_FILENAME:
            hash_func = g_str_hash;
            equal_func = g_str_equal;
            break;
        default:
            hash_func = NULL;
            equal_func = NULL;
    }

    hash_ = g_hash_table_new (hash_func, equal_func);
    if (hash_ == NULL) {
1206
1207
1208
        PyErr_NoMemory ();
        Py_DECREF (py_keys);
        Py_DECREF (py_values);
1209
1210
1211
1212
1213
        return FALSE;
    }

    for (i = 0; i < length; i++) {
        GIArgument key, value;
1214
1215
        gpointer key_cleanup_data = NULL;
        gpointer value_cleanup_data = NULL;
1216
1217
1218
1219
1220
        PyObject *py_key = PyList_GET_ITEM (py_keys, i);
        PyObject *py_value = PyList_GET_ITEM (py_values, i);
        if (py_key == NULL || py_value == NULL)
            goto err;

1221
1222
1223
1224
        if (!key_from_py_marshaller ( state,
                                      callable_cache,
                                      hash_cache->key_cache,
                                      py_key,
1225
1226
                                     &key,
                                     &key_cleanup_data))
1227
1228
            goto err;

1229
1230
1231
1232
        if (!value_from_py_marshaller ( state,
                                        callable_cache,
                                        hash_cache->value_cache,
                                        py_value,
1233
1234
                                       &value,
                                       &value_cleanup_data))
1235
1236
            goto err;

1237
1238
1239
        g_hash_table_insert (hash_,
                             _pygi_arg_to_hash_pointer (&key, hash_cache->key_cache->type_tag),
                             _pygi_arg_to_hash_pointer (&value, hash_cache->value_cache->type_tag));
1240
1241
1242
        continue;
err:
        /* FIXME: cleanup hash keys and values */
1243
1244
1245
1246
1247
        Py_XDECREF (py_key);
        Py_XDECREF (py_value);
        Py_DECREF (py_keys);
        Py_DECREF (py_values);
        g_hash_table_unref (hash_);
1248
1249
1250
1251
1252
        _PyGI_ERROR_PREFIX ("Item %i: ", i);
        return FALSE;
    }

    arg->v_pointer = hash_;
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267

    if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
        /* Free everything in cleanup. */
        *cleanup_data = arg->v_pointer;
    } else if (arg_cache->transfer == GI_TRANSFER_CONTAINER) {
        /* Make a shallow copy so we can free the elements later in cleanup
         * because it is possible invoke will free the list before our cleanup. */
        *cleanup_data = g_hash_table_ref (arg->v_pointer);
    } else { /* GI_TRANSFER_EVERYTHING */
        /* No cleanup, everything is given to the callee.
         * Note that the keys and values will leak for transfer everything because
         * we do not use g_hash_table_new_full and set key/value_destroy_func. */
        *cleanup_data = NULL;
    }

1268
1269
1270
1271
    return TRUE;
}

gboolean
1272
1273
1274
1275
_pygi_marshal_from_py_gerror (PyGIInvokeState   *state,
                              PyGICallableCache *callable_cache,
                              PyGIArgCache      *arg_cache,
                              PyObject          *py_arg,
1276
1277
                              GIArgument        *arg,
                              gpointer          *cleanup_data)
1278
{
1279
1280
    PyErr_Format (PyExc_NotImplementedError,
                  "Marshalling for GErrors is not implemented");
1281
1282
1283
    return FALSE;
}

1284
1285
1286
1287
1288
1289
1290
1291
1292
/* _pygi_destroy_notify_dummy:
 *
 * Dummy method used in the occasion when a method has a GDestroyNotify
 * argument without user data.
 */
static void
_pygi_destroy_notify_dummy (gpointer data) {
}