Imported Upstream version 3.25.1
[platform/upstream/pygobject2.git] / gi / pygi-basictype.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <Python.h>
22 #include <pyglib-python-compat.h>
23
24 #include "pygtype.h"
25 #include "pygi-basictype.h"
26 #include "pygi-argument.h"
27
28 #ifdef G_OS_WIN32
29 #include <math.h>
30
31 #ifndef NAN
32 static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
33 #define NAN (*(const float *) __nan)
34 #endif
35
36 #ifndef INFINITY
37 #define INFINITY HUGE_VAL
38 #endif
39
40 #endif
41
42
43 /*
44  * From Python Marshaling
45  */
46
47 static gboolean
48 _pygi_marshal_from_py_void (PyGIInvokeState   *state,
49                             PyGICallableCache *callable_cache,
50                             PyGIArgCache      *arg_cache,
51                             PyObject          *py_arg,
52                             GIArgument        *arg,
53                             gpointer          *cleanup_data)
54 {
55     g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING);
56
57     if (py_arg == Py_None) {
58         arg->v_pointer = NULL;
59     } else if (PYGLIB_CPointer_Check(py_arg)) {
60         arg->v_pointer = PYGLIB_CPointer_GetPointer (py_arg, NULL);
61     } else if (PYGLIB_PyLong_Check(py_arg) || PyLong_Check(py_arg)) {
62         arg->v_pointer = PyLong_AsVoidPtr (py_arg);
63     } else {
64         PyErr_SetString(PyExc_ValueError,
65                         "Pointer arguments are restricted to integers, capsules, and None. "
66                         "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599");
67         return FALSE;
68     }
69
70     *cleanup_data = arg->v_pointer;
71     return TRUE;
72 }
73
74 static gboolean
75 check_valid_double (double x, double min, double max)
76 {
77     char buf[100];
78
79     if ((x < min || x > max) && x != INFINITY && x != -INFINITY && x != NAN) {
80         if (PyErr_Occurred())
81             PyErr_Clear ();
82
83         /* we need this as PyErr_Format() does not support float types */
84         snprintf (buf, sizeof (buf), "%g not in range %g to %g", x, min, max);
85         PyErr_SetString (PyExc_OverflowError, buf);
86         return FALSE;
87     }
88     return TRUE;
89 }
90
91 static gboolean
92 _pygi_py_arg_to_double (PyObject *py_arg, double *double_)
93 {
94     PyObject *py_float;
95
96     if (!PyNumber_Check (py_arg)) {
97         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
98                       py_arg->ob_type->tp_name);
99         return FALSE;
100     }
101
102     py_float = PyNumber_Float (py_arg);
103     if (!py_float)
104         return FALSE;
105
106     *double_ = PyFloat_AsDouble (py_float);
107     Py_DECREF (py_float);
108
109
110     return TRUE;
111 }
112
113 static gboolean
114 _pygi_marshal_from_py_float (PyObject          *py_arg,
115                              GIArgument        *arg)
116 {
117     double double_;
118
119     if (!_pygi_py_arg_to_double (py_arg, &double_))
120         return FALSE;
121
122     if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXFLOAT, G_MAXFLOAT))
123         return FALSE;
124
125     arg->v_float = double_;
126     return TRUE;
127 }
128
129 static gboolean
130 _pygi_marshal_from_py_double (PyObject          *py_arg,
131                               GIArgument        *arg)
132 {
133     double double_;
134
135     if (!_pygi_py_arg_to_double (py_arg, &double_))
136         return FALSE;
137
138     if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXDOUBLE, G_MAXDOUBLE))
139         return FALSE;
140
141     arg->v_double = double_;
142     return TRUE;
143 }
144
145 static gboolean
146 _pygi_marshal_from_py_unichar (PyObject          *py_arg,
147                                GIArgument        *arg)
148 {
149     Py_ssize_t size;
150     gchar *string_;
151
152     if (py_arg == Py_None) {
153         arg->v_uint32 = 0;
154         return FALSE;
155     }
156
157     if (PyUnicode_Check (py_arg)) {
158        PyObject *py_bytes;
159
160        size = PyUnicode_GET_SIZE (py_arg);
161        py_bytes = PyUnicode_AsUTF8String (py_arg);
162        if (!py_bytes)
163            return FALSE;
164
165        string_ = g_strdup(PYGLIB_PyBytes_AsString (py_bytes));
166        Py_DECREF (py_bytes);
167
168 #if PY_VERSION_HEX < 0x03000000
169     } else if (PyString_Check (py_arg)) {
170        PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict");
171        if (!pyuni)
172            return FALSE;
173
174        size = PyUnicode_GET_SIZE (pyuni);
175        string_ = g_strdup (PyString_AsString(py_arg));
176        Py_DECREF (pyuni);
177 #endif
178     } else {
179        PyErr_Format (PyExc_TypeError, "Must be string, not %s",
180                      py_arg->ob_type->tp_name);
181        return FALSE;
182     }
183
184     if (size != 1) {
185        PyErr_Format (PyExc_TypeError, "Must be a one character string, not %lld characters",
186                      (long long) size);
187        g_free (string_);
188        return FALSE;
189     }
190
191     arg->v_uint32 = g_utf8_get_char (string_);
192     g_free (string_);
193
194     return TRUE;
195 }
196
197 static gboolean
198 _pygi_marshal_from_py_gtype (PyObject          *py_arg,
199                              GIArgument        *arg)
200 {
201     long type_ = pyg_type_from_object (py_arg);
202
203     if (type_ == 0) {
204         PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
205                       py_arg->ob_type->tp_name);
206         return FALSE;
207     }
208
209     arg->v_long = type_;
210     return TRUE;
211 }
212
213 static gboolean
214 _pygi_marshal_from_py_utf8 (PyObject          *py_arg,
215                             GIArgument        *arg,
216                             gpointer          *cleanup_data)
217 {
218     gchar *string_;
219
220     if (py_arg == Py_None) {
221         arg->v_pointer = NULL;
222         return TRUE;
223     }
224
225     if (PyUnicode_Check (py_arg)) {
226         PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
227         if (!pystr_obj)
228             return FALSE;
229
230         string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
231         Py_DECREF (pystr_obj);
232     }
233 #if PY_VERSION_HEX < 0x03000000
234     else if (PyString_Check (py_arg)) {
235         string_ = g_strdup (PyString_AsString (py_arg));
236     }
237 #endif
238     else {
239         PyErr_Format (PyExc_TypeError, "Must be string, not %s",
240                       py_arg->ob_type->tp_name);
241         return FALSE;
242     }
243
244     arg->v_string = string_;
245     *cleanup_data = arg->v_string;
246     return TRUE;
247 }
248
249 G_GNUC_UNUSED static gboolean
250 _pygi_marshal_from_py_filename_unix (PyObject          *py_arg,
251                                      GIArgument        *arg,
252                                      gpointer          *cleanup_data)
253 {
254     gchar *filename;
255
256     if (py_arg == Py_None) {
257         arg->v_pointer = NULL;
258         return TRUE;
259     }
260
261     if (PYGLIB_PyBytes_Check (py_arg)) {
262         char *buffer;
263
264         if (PYGLIB_PyBytes_AsStringAndSize (py_arg, &buffer, NULL) == -1)
265             return FALSE;
266
267         filename = g_strdup (buffer);
268     } else if (PyUnicode_Check (py_arg)) {
269         PyObject *bytes;
270         char *buffer;
271
272 #if PY_VERSION_HEX < 0x03000000
273         bytes = PyUnicode_AsEncodedString (py_arg, Py_FileSystemDefaultEncoding,
274                                            NULL);
275 #else
276         bytes = PyUnicode_EncodeFSDefault (py_arg);
277 #endif
278
279         if (!bytes)
280             return FALSE;
281
282         if (PYGLIB_PyBytes_AsStringAndSize (bytes, &buffer, NULL) == -1) {
283             Py_DECREF (bytes);
284             return FALSE;
285         }
286
287         filename = g_strdup (buffer);
288         Py_DECREF (bytes);
289     } else {
290         PyErr_Format (PyExc_TypeError, "Must be bytes, not %s",
291                       py_arg->ob_type->tp_name);
292         return FALSE;
293     }
294
295     arg->v_string = filename;
296     *cleanup_data = filename;
297     return TRUE;
298 }
299
300 G_GNUC_UNUSED static gboolean
301 _pygi_marshal_from_py_filename_win32 (PyObject          *py_arg,
302                                       GIArgument        *arg,
303                                       gpointer          *cleanup_data)
304 {
305     gchar *filename;
306
307     if (py_arg == Py_None) {
308         arg->v_pointer = NULL;
309         return TRUE;
310     }
311
312 #if PY_VERSION_HEX < 0x03000000
313     if (PYGLIB_PyBytes_Check (py_arg)) {
314         char *buffer;
315
316         if (PYGLIB_PyBytes_AsStringAndSize (py_arg, &buffer, NULL) == -1)
317             return FALSE;
318
319         filename = g_strdup (buffer);
320     } else if (PyUnicode_Check (py_arg)) {
321         PyObject *bytes;
322         char *buffer;
323
324         bytes = PyUnicode_AsUTF8String (py_arg);
325         if (!bytes)
326             return FALSE;
327
328         if (PYGLIB_PyBytes_AsStringAndSize (bytes, &buffer, NULL) == -1) {
329             Py_DECREF (bytes);
330             return FALSE;
331         }
332
333         filename = g_strdup (buffer);
334         Py_DECREF (bytes);
335     } else {
336         PyErr_Format (PyExc_TypeError, "Must be unicode, not %s",
337                       py_arg->ob_type->tp_name);
338         return FALSE;
339     }
340 #else
341     if (PYGLIB_PyBytes_Check (py_arg)) {
342         PyObject *uni_arg;
343         gboolean result;
344         char *buffer;
345
346         if (PYGLIB_PyBytes_AsStringAndSize (py_arg, &buffer, NULL) == -1)
347             return FALSE;
348
349         uni_arg = PyUnicode_DecodeFSDefault (buffer);
350         if (!uni_arg)
351             return FALSE;
352         result = _pygi_marshal_from_py_filename_win32 (uni_arg, arg, cleanup_data);
353         Py_DECREF (uni_arg);
354         return result;
355     } else if (PyUnicode_Check (py_arg)) {
356         PyObject *bytes, *temp_uni;
357         char *buffer;
358
359         /* The roundtrip merges lone surrogates, so we get the same output as
360          * with Py 2. Requires 3.4+ because of https://bugs.python.org/issue27971
361          * Separated lone surrogates can occur when concatenating two paths.
362          */
363         bytes = PyUnicode_AsEncodedString (py_arg, "utf-16-le", "surrogatepass");
364         if (!bytes)
365             return FALSE;
366         temp_uni = PyUnicode_FromEncodedObject (bytes, "utf-16-le", "surrogatepass");
367         Py_DECREF (bytes);
368         if (!temp_uni)
369             return FALSE;
370         /* glib uses utf-8, so encode to that and allow surrogates so we can
371          * represent all possible path values
372          */
373         bytes = PyUnicode_AsEncodedString (temp_uni, "utf-8", "surrogatepass");
374         Py_DECREF (temp_uni);
375         if (!bytes)
376             return FALSE;
377
378         if (PYGLIB_PyBytes_AsStringAndSize (bytes, &buffer, NULL) == -1) {
379             Py_DECREF (bytes);
380             return FALSE;
381         }
382
383         filename = g_strdup (buffer);
384         Py_DECREF (bytes);
385     } else {
386         PyErr_Format (PyExc_TypeError, "Must be str, not %s",
387                       py_arg->ob_type->tp_name);
388         return FALSE;
389     }
390 #endif
391
392     arg->v_string = filename;
393     *cleanup_data = filename;
394     return TRUE;
395 }
396
397 static gboolean
398 _pygi_marshal_from_py_filename (PyObject          *py_arg,
399                                 GIArgument        *arg,
400                                 gpointer          *cleanup_data)
401 {
402 #ifdef G_OS_WIN32
403     return _pygi_marshal_from_py_filename_win32 (py_arg, arg, cleanup_data);
404 #else
405     return _pygi_marshal_from_py_filename_unix (py_arg, arg, cleanup_data);
406 #endif
407 }
408
409 static gboolean
410 _pygi_marshal_from_py_long (PyObject   *object,   /* in */
411                             GIArgument *arg,      /* out */
412                             GITypeTag   type_tag,
413                             GITransfer  transfer)
414 {
415     PyObject *number;
416
417     if (!PyNumber_Check (object)) {
418         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
419                       object->ob_type->tp_name);
420         return FALSE;
421     }
422
423 #if PY_MAJOR_VERSION < 3
424     {
425         PyObject *tmp = PyNumber_Int (object);
426         if (tmp) {
427             number = PyNumber_Long (tmp);
428             Py_DECREF (tmp);
429         } else {
430             number = PyNumber_Long (object);
431         }
432     }
433 #else
434     number = PyNumber_Long (object);
435 #endif
436
437     if (number == NULL) {
438         PyErr_SetString (PyExc_TypeError, "expected int argument");
439         return FALSE;
440     }
441
442     switch (type_tag) {
443         case GI_TYPE_TAG_INT8:
444         {
445             long long_value = PyLong_AsLong (number);
446             if (PyErr_Occurred()) {
447                 break;
448             } else if (long_value < G_MININT8 || long_value > G_MAXINT8) {
449                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
450                               long_value, (long)G_MININT8, (long)G_MAXINT8);
451             } else {
452                 arg->v_int8 = long_value;
453             }
454             break;
455         }
456
457         case GI_TYPE_TAG_UINT8:
458         {
459             long long_value = PyLong_AsLong (number);
460             if (PyErr_Occurred()) {
461                 break;
462             } else if (long_value < 0 || long_value > G_MAXUINT8) {
463                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
464                               long_value, (long)0, (long)G_MAXUINT8);
465             } else {
466                 arg->v_uint8 = long_value;
467             }
468             break;
469         }
470
471         case GI_TYPE_TAG_INT16:
472         {
473             long long_value = PyLong_AsLong (number);
474             if (PyErr_Occurred()) {
475                 break;
476             } else if (long_value < G_MININT16 || long_value > G_MAXINT16) {
477                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
478                               long_value, (long)G_MININT16, (long)G_MAXINT16);
479             } else {
480                 arg->v_int16 = long_value;
481             }
482             break;
483         }
484
485         case GI_TYPE_TAG_UINT16:
486         {
487             long long_value = PyLong_AsLong (number);
488             if (PyErr_Occurred()) {
489                 break;
490             } else if (long_value < 0 || long_value > G_MAXUINT16) {
491                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
492                               long_value, (long)0, (long)G_MAXUINT16);
493             } else {
494                 arg->v_uint16 = long_value;
495             }
496             break;
497         }
498
499         case GI_TYPE_TAG_INT32:
500         {
501             long long_value = PyLong_AsLong (number);
502             if (PyErr_Occurred()) {
503                 break;
504             } else if (long_value < G_MININT32 || long_value > G_MAXINT32) {
505                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
506                               long_value, (long)G_MININT32, (long)G_MAXINT32);
507             } else {
508                 arg->v_int32 = long_value;
509             }
510             break;
511         }
512
513         case GI_TYPE_TAG_UINT32:
514         {
515             PY_LONG_LONG long_value = PyLong_AsLongLong (number);
516             if (PyErr_Occurred()) {
517                 break;
518             } else if (long_value < 0 || long_value > G_MAXUINT32) {
519                 PyErr_Format (PyExc_OverflowError, "%lld not in range %ld to %lu",
520                               long_value, (long)0, (unsigned long)G_MAXUINT32);
521             } else {
522                 arg->v_uint32 = long_value;
523             }
524             break;
525         }
526
527         case GI_TYPE_TAG_INT64:
528         {
529             /* Rely on Python overflow error and convert to ValueError for 64 bit values */
530             arg->v_int64 = PyLong_AsLongLong (number);
531             break;
532         }
533
534         case GI_TYPE_TAG_UINT64:
535         {
536             /* Rely on Python overflow error and convert to ValueError for 64 bit values */
537             arg->v_uint64 = PyLong_AsUnsignedLongLong (number);
538             break;
539         }
540
541         default:
542             g_assert_not_reached ();
543     }
544
545     Py_DECREF (number);
546
547     if (PyErr_Occurred())
548         return FALSE;
549     return TRUE;
550 }
551
552 gboolean
553 _pygi_marshal_from_py_basic_type (PyObject   *object,   /* in */
554                                   GIArgument *arg,      /* out */
555                                   GITypeTag   type_tag,
556                                   GITransfer  transfer,
557                                   gpointer   *cleanup_data /* out */)
558 {
559     switch (type_tag) {
560         case GI_TYPE_TAG_VOID:
561             g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
562             if (object == Py_None) {
563                 arg->v_pointer = NULL;
564             } else if (!PYGLIB_PyLong_Check(object)  && !PyLong_Check(object)) {
565                 PyErr_SetString(PyExc_TypeError,
566                     "Pointer assignment is restricted to integer values. "
567                     "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599");
568             } else {
569                 arg->v_pointer = PyLong_AsVoidPtr (object);
570                 *cleanup_data = arg->v_pointer;
571             }
572             break;
573         case GI_TYPE_TAG_INT8:
574         case GI_TYPE_TAG_UINT8:
575             if (PYGLIB_PyBytes_Check (object)) {
576                 if (PYGLIB_PyBytes_Size (object) != 1) {
577                     PyErr_Format (PyExc_TypeError, "Must be a single character");
578                     return FALSE;
579                 }
580                 if (type_tag == GI_TYPE_TAG_INT8) {
581                     arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]);
582                 } else {
583                     arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]);
584                 }
585             } else {
586                 return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
587             }
588             break;
589         case GI_TYPE_TAG_INT16:
590         case GI_TYPE_TAG_UINT16:
591         case GI_TYPE_TAG_INT32:
592         case GI_TYPE_TAG_UINT32:
593         case GI_TYPE_TAG_INT64:
594         case GI_TYPE_TAG_UINT64:
595             return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
596
597         case GI_TYPE_TAG_BOOLEAN:
598             arg->v_boolean = PyObject_IsTrue (object);
599             break;
600
601         case GI_TYPE_TAG_FLOAT:
602             return _pygi_marshal_from_py_float (object, arg);
603
604         case GI_TYPE_TAG_DOUBLE:
605             return _pygi_marshal_from_py_double (object, arg);
606
607         case GI_TYPE_TAG_GTYPE:
608             return _pygi_marshal_from_py_gtype (object, arg);
609
610         case GI_TYPE_TAG_UNICHAR:
611             return _pygi_marshal_from_py_unichar (object, arg);
612
613         case GI_TYPE_TAG_UTF8:
614             return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data);
615
616         case GI_TYPE_TAG_FILENAME:
617             return _pygi_marshal_from_py_filename (object, arg, cleanup_data);
618
619         default:
620             return FALSE;
621     }
622
623     if (PyErr_Occurred())
624         return FALSE;
625
626     return TRUE;
627 }
628
629 gboolean
630 _pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState   *state,
631                                                 PyGICallableCache *callable_cache,
632                                                 PyGIArgCache      *arg_cache,
633                                                 PyObject          *py_arg,
634                                                 GIArgument        *arg,
635                                                 gpointer          *cleanup_data)
636 {
637     return _pygi_marshal_from_py_basic_type (py_arg,
638                                              arg,
639                                              arg_cache->type_tag,
640                                              arg_cache->transfer,
641                                              cleanup_data);
642 }
643
644 static void
645 _pygi_marshal_cleanup_from_py_utf8 (PyGIInvokeState *state,
646                                     PyGIArgCache    *arg_cache,
647                                     PyObject        *py_arg,
648                                     gpointer         data,
649                                     gboolean         was_processed)
650 {
651     /* We strdup strings so free unless ownership is transferred to C. */
652     if (was_processed && arg_cache->transfer == GI_TRANSFER_NOTHING)
653         g_free (data);
654 }
655
656 static void
657 _arg_cache_from_py_void_setup (PyGIArgCache *arg_cache)
658 {
659     arg_cache->from_py_marshaller = _pygi_marshal_from_py_void;
660 }
661
662
663 static void
664 _arg_cache_from_py_basic_type_setup (PyGIArgCache *arg_cache)
665 {
666     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
667 }
668
669 static void
670 _arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache,
671                                GITransfer transfer)
672 {
673     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
674     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
675 }
676
677
678 /*
679  * To Python Marshaling
680  */
681
682
683 static PyObject *
684 _pygi_marshal_to_py_void (PyGIInvokeState   *state,
685                           PyGICallableCache *callable_cache,
686                           PyGIArgCache      *arg_cache,
687                           GIArgument        *arg)
688 {
689     if (arg_cache->is_pointer) {
690         return PyLong_FromVoidPtr (arg->v_pointer);
691     }
692     Py_RETURN_NONE;
693 }
694
695 static PyObject *
696 _pygi_marshal_to_py_unichar (GIArgument *arg)
697 {
698     PyObject *py_obj = NULL;
699
700     /* Preserve the bidirectional mapping between 0 and "" */
701     if (arg->v_uint32 == 0) {
702         py_obj = PYGLIB_PyUnicode_FromString ("");
703     } else if (g_unichar_validate (arg->v_uint32)) {
704         gchar utf8[6];
705         gint bytes;
706
707         bytes = g_unichar_to_utf8 (arg->v_uint32, utf8);
708         py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
709     } else {
710         /* TODO: Convert the error to an exception. */
711         PyErr_Format (PyExc_TypeError,
712                       "Invalid unicode codepoint %" G_GUINT32_FORMAT,
713                       arg->v_uint32);
714     }
715
716     return py_obj;
717 }
718
719 static PyObject *
720 _pygi_marshal_to_py_utf8 (GIArgument *arg)
721 {
722     PyObject *py_obj = NULL;
723     if (arg->v_string == NULL) {
724         Py_RETURN_NONE;
725      }
726
727     py_obj = PYGLIB_PyUnicode_FromString (arg->v_string);
728     return py_obj;
729 }
730
731 static PyObject *
732 _pygi_marshal_to_py_filename (GIArgument *arg)
733 {
734     PyObject *py_obj;
735
736     if (arg->v_string == NULL) {
737         Py_RETURN_NONE;
738     }
739
740 #if PY_VERSION_HEX < 0x03000000
741     /* On PY2 we return str as is */
742     py_obj = PyString_FromString (arg->v_string);
743 #else
744 #ifdef G_OS_WIN32
745     py_obj = PyUnicode_DecodeUTF8 (arg->v_string, strlen(arg->v_string),
746                                    "surrogatepass");
747 #else
748     py_obj = PyUnicode_DecodeFSDefault (arg->v_string);
749 #endif
750 #endif
751
752     return py_obj;
753 }
754
755
756 /**
757  * _pygi_marshal_to_py_basic_type:
758  * @arg: The argument to convert to an object.
759  * @type_tag: Type tag for @arg
760  * @transfer: Transfer annotation
761  *
762  * Convert the given argument to a Python object. This function
763  * is restricted to simple types that only require the GITypeTag
764  * and GITransfer. For a more complete conversion routine, use:
765  * _pygi_argument_to_object.
766  *
767  * Returns: A PyObject representing @arg or NULL if it cannot convert
768  *          the argument.
769  */
770 PyObject *
771 _pygi_marshal_to_py_basic_type (GIArgument  *arg,
772                                 GITypeTag type_tag,
773                                 GITransfer transfer)
774 {
775     switch (type_tag) {
776         case GI_TYPE_TAG_BOOLEAN:
777             return PyBool_FromLong (arg->v_boolean);
778
779         case GI_TYPE_TAG_INT8:
780             return PYGLIB_PyLong_FromLong (arg->v_int8);
781
782         case GI_TYPE_TAG_UINT8:
783             return PYGLIB_PyLong_FromLong (arg->v_uint8);
784
785         case GI_TYPE_TAG_INT16:
786             return PYGLIB_PyLong_FromLong (arg->v_int16);
787
788         case GI_TYPE_TAG_UINT16:
789             return PYGLIB_PyLong_FromLong (arg->v_uint16);
790
791         case GI_TYPE_TAG_INT32:
792             return PYGLIB_PyLong_FromLong (arg->v_int32);
793
794         case GI_TYPE_TAG_UINT32:
795             return PyLong_FromLongLong (arg->v_uint32);
796
797         case GI_TYPE_TAG_INT64:
798             return PyLong_FromLongLong (arg->v_int64);
799
800         case GI_TYPE_TAG_UINT64:
801             return PyLong_FromUnsignedLongLong (arg->v_uint64);
802
803         case GI_TYPE_TAG_FLOAT:
804             return PyFloat_FromDouble (arg->v_float);
805
806         case GI_TYPE_TAG_DOUBLE:
807             return PyFloat_FromDouble (arg->v_double);
808
809         case GI_TYPE_TAG_GTYPE:
810             return pyg_type_wrapper_new ( (GType) arg->v_long);
811
812         case GI_TYPE_TAG_UNICHAR:
813             return _pygi_marshal_to_py_unichar (arg);
814
815         case GI_TYPE_TAG_UTF8:
816             return _pygi_marshal_to_py_utf8 (arg);
817
818         case GI_TYPE_TAG_FILENAME:
819             return _pygi_marshal_to_py_filename (arg);
820
821         default:
822             return NULL;
823     }
824     return NULL;
825 }
826
827 PyObject *
828 _pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState   *state,
829                                               PyGICallableCache *callable_cache,
830                                               PyGIArgCache      *arg_cache,
831                                               GIArgument        *arg)
832 {
833     return _pygi_marshal_to_py_basic_type (arg,
834                                             arg_cache->type_tag,
835                                             arg_cache->transfer);
836 }
837
838 static void
839 _pygi_marshal_cleanup_to_py_utf8 (PyGIInvokeState *state,
840                                   PyGIArgCache    *arg_cache,
841                                   PyObject        *dummy,
842                                   gpointer         data,
843                                   gboolean         was_processed)
844 {
845     /* Python copies the string so we need to free it
846        if the interface is transfering ownership, 
847        whether or not it has been processed yet */
848     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
849         g_free (data);
850 }
851
852
853
854 static void
855 _arg_cache_to_py_basic_type_setup (PyGIArgCache *arg_cache)
856 {
857     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
858 }
859
860 static void
861 _arg_cache_to_py_void_setup (PyGIArgCache *arg_cache)
862 {
863     arg_cache->to_py_marshaller = _pygi_marshal_to_py_void;
864 }
865
866 static void
867 _arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache,
868                                GITransfer transfer)
869 {
870     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
871     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
872 }
873
874 /*
875  * Basic Type Interface
876  */
877
878 static gboolean
879 pygi_arg_basic_type_setup_from_info (PyGIArgCache  *arg_cache,
880                                      GITypeInfo    *type_info,
881                                      GIArgInfo     *arg_info,
882                                      GITransfer     transfer,
883                                      PyGIDirection  direction)
884 {
885     GITypeTag type_tag = g_type_info_get_tag (type_info);
886
887     if (!pygi_arg_base_setup (arg_cache, type_info, arg_info, transfer, direction))
888         return FALSE;
889
890     switch (type_tag) {
891        case GI_TYPE_TAG_VOID:
892            if (direction & PYGI_DIRECTION_FROM_PYTHON)
893                _arg_cache_from_py_void_setup (arg_cache);
894
895            if (direction & PYGI_DIRECTION_TO_PYTHON)
896                _arg_cache_to_py_void_setup (arg_cache);
897
898            break;
899        case GI_TYPE_TAG_BOOLEAN:
900        case GI_TYPE_TAG_INT8:
901        case GI_TYPE_TAG_UINT8:
902        case GI_TYPE_TAG_INT16:
903        case GI_TYPE_TAG_UINT16:
904        case GI_TYPE_TAG_INT32:
905        case GI_TYPE_TAG_UINT32:
906        case GI_TYPE_TAG_INT64:
907        case GI_TYPE_TAG_UINT64:
908        case GI_TYPE_TAG_FLOAT:
909        case GI_TYPE_TAG_DOUBLE:
910        case GI_TYPE_TAG_UNICHAR:
911        case GI_TYPE_TAG_GTYPE:
912            if (direction & PYGI_DIRECTION_FROM_PYTHON)
913                _arg_cache_from_py_basic_type_setup (arg_cache);
914
915            if (direction & PYGI_DIRECTION_TO_PYTHON)
916                _arg_cache_to_py_basic_type_setup (arg_cache);
917
918            break;
919        case GI_TYPE_TAG_UTF8:
920        case GI_TYPE_TAG_FILENAME:
921            if (direction & PYGI_DIRECTION_FROM_PYTHON)
922                _arg_cache_from_py_utf8_setup (arg_cache, transfer);
923
924            if (direction & PYGI_DIRECTION_TO_PYTHON)
925                _arg_cache_to_py_utf8_setup (arg_cache, transfer);
926
927            break;
928        default:
929            g_assert_not_reached ();
930     }
931
932     return TRUE;
933 }
934
935 PyGIArgCache *
936 pygi_arg_basic_type_new_from_info (GITypeInfo   *type_info,
937                                    GIArgInfo    *arg_info,
938                                    GITransfer    transfer,
939                                    PyGIDirection direction)
940 {
941     gboolean res = FALSE;
942     PyGIArgCache *arg_cache = pygi_arg_cache_alloc ();
943     if (arg_cache == NULL)
944         return NULL;
945
946     res = pygi_arg_basic_type_setup_from_info (arg_cache,
947                                                type_info,
948                                                arg_info,
949                                                transfer,
950                                                direction);
951     if (res) {
952         return arg_cache;
953     } else {
954         pygi_arg_cache_free (arg_cache);
955         return NULL;
956     }
957 }