432559dc3876cae6781408cf2c19336cc21a784e
[platform/upstream/python-gobject.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 "pygi-basictype.h"
25 #include "pygi-argument.h"
26 #include "pygi-private.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 static gboolean
250 _pygi_marshal_from_py_filename (PyObject          *py_arg,
251                                 GIArgument        *arg,
252                                 gpointer          *cleanup_data)
253 {
254     gchar *string_;
255     GError *error = NULL;
256     PyObject *tmp = NULL;
257
258     if (PyUnicode_Check (py_arg)) {
259         tmp = PyUnicode_AsUTF8String (py_arg);
260         if (!tmp)
261             return FALSE;
262
263         string_ = PYGLIB_PyBytes_AsString (tmp);
264     }
265 #if PY_VERSION_HEX < 0x03000000
266     else if (PyString_Check (py_arg)) {
267         string_ = PyString_AsString (py_arg);
268     }
269 #endif
270     else {
271         PyErr_Format (PyExc_TypeError, "Must be string, not %s",
272                       py_arg->ob_type->tp_name);
273         return FALSE;
274     }
275
276     arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error);
277     Py_XDECREF (tmp);
278
279     if (arg->v_string == NULL) {
280         PyErr_SetString (PyExc_Exception, error->message);
281         g_error_free (error);
282         /* TODO: Convert the error to an exception. */
283         return FALSE;
284     }
285
286     *cleanup_data = arg->v_string;
287     return TRUE;
288 }
289
290 static gboolean
291 _pygi_marshal_from_py_long (PyObject   *object,   /* in */
292                             GIArgument *arg,      /* out */
293                             GITypeTag   type_tag,
294                             GITransfer  transfer)
295 {
296     PyObject *number;
297
298     if (!PyNumber_Check (object)) {
299         PyErr_Format (PyExc_TypeError, "Must be number, not %s",
300                       object->ob_type->tp_name);
301         return FALSE;
302     }
303
304 #if PY_MAJOR_VERSION < 3
305     {
306         PyObject *tmp = PyNumber_Int (object);
307         if (tmp) {
308             number = PyNumber_Long (tmp);
309             Py_DECREF (tmp);
310         } else {
311             number = PyNumber_Long (object);
312         }
313     }
314 #else
315     number = PyNumber_Long (object);
316 #endif
317
318     if (number == NULL) {
319         PyErr_SetString (PyExc_TypeError, "expected int argument");
320         return FALSE;
321     }
322
323     switch (type_tag) {
324         case GI_TYPE_TAG_INT8:
325         {
326             long long_value = PyLong_AsLong (number);
327             if (PyErr_Occurred()) {
328                 break;
329             } else if (long_value < G_MININT8 || long_value > G_MAXINT8) {
330                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
331                               long_value, (long)G_MININT8, (long)G_MAXINT8);
332             } else {
333                 arg->v_int8 = long_value;
334             }
335             break;
336         }
337
338         case GI_TYPE_TAG_UINT8:
339         {
340             long long_value = PyLong_AsLong (number);
341             if (PyErr_Occurred()) {
342                 break;
343             } else if (long_value < 0 || long_value > G_MAXUINT8) {
344                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
345                               long_value, (long)0, (long)G_MAXUINT8);
346             } else {
347                 arg->v_uint8 = long_value;
348             }
349             break;
350         }
351
352         case GI_TYPE_TAG_INT16:
353         {
354             long long_value = PyLong_AsLong (number);
355             if (PyErr_Occurred()) {
356                 break;
357             } else if (long_value < G_MININT16 || long_value > G_MAXINT16) {
358                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
359                               long_value, (long)G_MININT16, (long)G_MAXINT16);
360             } else {
361                 arg->v_int16 = long_value;
362             }
363             break;
364         }
365
366         case GI_TYPE_TAG_UINT16:
367         {
368             long long_value = PyLong_AsLong (number);
369             if (PyErr_Occurred()) {
370                 break;
371             } else if (long_value < 0 || long_value > G_MAXUINT16) {
372                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
373                               long_value, (long)0, (long)G_MAXUINT16);
374             } else {
375                 arg->v_uint16 = long_value;
376             }
377             break;
378         }
379
380         case GI_TYPE_TAG_INT32:
381         {
382             long long_value = PyLong_AsLong (number);
383             if (PyErr_Occurred()) {
384                 break;
385             } else if (long_value < G_MININT32 || long_value > G_MAXINT32) {
386                 PyErr_Format (PyExc_OverflowError, "%ld not in range %ld to %ld",
387                               long_value, (long)G_MININT32, (long)G_MAXINT32);
388             } else {
389                 arg->v_int32 = long_value;
390             }
391             break;
392         }
393
394         case GI_TYPE_TAG_UINT32:
395         {
396             PY_LONG_LONG long_value = PyLong_AsLongLong (number);
397             if (PyErr_Occurred()) {
398                 break;
399             } else if (long_value < 0 || long_value > G_MAXUINT32) {
400                 PyErr_Format (PyExc_OverflowError, "%lld not in range %ld to %lu",
401                               long_value, (long)0, (unsigned long)G_MAXUINT32);
402             } else {
403                 arg->v_uint32 = long_value;
404             }
405             break;
406         }
407
408         case GI_TYPE_TAG_INT64:
409         {
410             /* Rely on Python overflow error and convert to ValueError for 64 bit values */
411             arg->v_int64 = PyLong_AsLongLong (number);
412             break;
413         }
414
415         case GI_TYPE_TAG_UINT64:
416         {
417             /* Rely on Python overflow error and convert to ValueError for 64 bit values */
418             arg->v_uint64 = PyLong_AsUnsignedLongLong (number);
419             break;
420         }
421
422         default:
423             g_assert_not_reached ();
424     }
425
426     Py_DECREF (number);
427
428     if (PyErr_Occurred())
429         return FALSE;
430     return TRUE;
431 }
432
433 gboolean
434 _pygi_marshal_from_py_basic_type (PyObject   *object,   /* in */
435                                   GIArgument *arg,      /* out */
436                                   GITypeTag   type_tag,
437                                   GITransfer  transfer,
438                                   gpointer   *cleanup_data /* out */)
439 {
440     switch (type_tag) {
441         case GI_TYPE_TAG_VOID:
442             g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
443             if (object == Py_None) {
444                 arg->v_pointer = NULL;
445             } else if (!PYGLIB_PyLong_Check(object)  && !PyLong_Check(object)) {
446                 PyErr_SetString(PyExc_TypeError,
447                     "Pointer assignment is restricted to integer values. "
448                     "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599");
449             } else {
450                 arg->v_pointer = PyLong_AsVoidPtr (object);
451                 *cleanup_data = arg->v_pointer;
452             }
453             break;
454         case GI_TYPE_TAG_INT8:
455         case GI_TYPE_TAG_UINT8:
456             if (PYGLIB_PyBytes_Check (object)) {
457                 if (PYGLIB_PyBytes_Size (object) != 1) {
458                     PyErr_Format (PyExc_TypeError, "Must be a single character");
459                     return FALSE;
460                 }
461                 if (type_tag == GI_TYPE_TAG_INT8) {
462                     arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]);
463                 } else {
464                     arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]);
465                 }
466             } else {
467                 return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
468             }
469             break;
470         case GI_TYPE_TAG_INT16:
471         case GI_TYPE_TAG_UINT16:
472         case GI_TYPE_TAG_INT32:
473         case GI_TYPE_TAG_UINT32:
474         case GI_TYPE_TAG_INT64:
475         case GI_TYPE_TAG_UINT64:
476             return _pygi_marshal_from_py_long (object, arg, type_tag, transfer);
477
478         case GI_TYPE_TAG_BOOLEAN:
479             arg->v_boolean = PyObject_IsTrue (object);
480             break;
481
482         case GI_TYPE_TAG_FLOAT:
483             return _pygi_marshal_from_py_float (object, arg);
484
485         case GI_TYPE_TAG_DOUBLE:
486             return _pygi_marshal_from_py_double (object, arg);
487
488         case GI_TYPE_TAG_GTYPE:
489             return _pygi_marshal_from_py_gtype (object, arg);
490
491         case GI_TYPE_TAG_UNICHAR:
492             return _pygi_marshal_from_py_unichar (object, arg);
493
494         case GI_TYPE_TAG_UTF8:
495             return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data);
496
497         case GI_TYPE_TAG_FILENAME:
498             return _pygi_marshal_from_py_filename (object, arg, cleanup_data);
499
500         default:
501             return FALSE;
502     }
503
504     if (PyErr_Occurred())
505         return FALSE;
506
507     return TRUE;
508 }
509
510 gboolean
511 _pygi_marshal_from_py_basic_type_cache_adapter (PyGIInvokeState   *state,
512                                                 PyGICallableCache *callable_cache,
513                                                 PyGIArgCache      *arg_cache,
514                                                 PyObject          *py_arg,
515                                                 GIArgument        *arg,
516                                                 gpointer          *cleanup_data)
517 {
518     return _pygi_marshal_from_py_basic_type (py_arg,
519                                              arg,
520                                              arg_cache->type_tag,
521                                              arg_cache->transfer,
522                                              cleanup_data);
523 }
524
525 static void
526 _pygi_marshal_cleanup_from_py_utf8 (PyGIInvokeState *state,
527                                     PyGIArgCache    *arg_cache,
528                                     PyObject        *py_arg,
529                                     gpointer         data,
530                                     gboolean         was_processed)
531 {
532     /* We strdup strings so free unless ownership is transferred to C. */
533     if (was_processed && arg_cache->transfer == GI_TRANSFER_NOTHING)
534         g_free (data);
535 }
536
537 static void
538 _arg_cache_from_py_void_setup (PyGIArgCache *arg_cache)
539 {
540     arg_cache->from_py_marshaller = _pygi_marshal_from_py_void;
541 }
542
543
544 static void
545 _arg_cache_from_py_basic_type_setup (PyGIArgCache *arg_cache)
546 {
547     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
548 }
549
550 static void
551 _arg_cache_from_py_utf8_setup (PyGIArgCache *arg_cache,
552                                GITransfer transfer)
553 {
554     arg_cache->from_py_marshaller = _pygi_marshal_from_py_basic_type_cache_adapter;
555     arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_utf8;
556 }
557
558
559 /*
560  * To Python Marshaling
561  */
562
563
564 static PyObject *
565 _pygi_marshal_to_py_void (PyGIInvokeState   *state,
566                           PyGICallableCache *callable_cache,
567                           PyGIArgCache      *arg_cache,
568                           GIArgument        *arg)
569 {
570     if (arg_cache->is_pointer) {
571         return PyLong_FromVoidPtr (arg->v_pointer);
572     }
573     Py_RETURN_NONE;
574 }
575
576 static PyObject *
577 _pygi_marshal_to_py_unichar (GIArgument *arg)
578 {
579     PyObject *py_obj = NULL;
580
581     /* Preserve the bidirectional mapping between 0 and "" */
582     if (arg->v_uint32 == 0) {
583         py_obj = PYGLIB_PyUnicode_FromString ("");
584     } else if (g_unichar_validate (arg->v_uint32)) {
585         gchar utf8[6];
586         gint bytes;
587
588         bytes = g_unichar_to_utf8 (arg->v_uint32, utf8);
589         py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
590     } else {
591         /* TODO: Convert the error to an exception. */
592         PyErr_Format (PyExc_TypeError,
593                       "Invalid unicode codepoint %" G_GUINT32_FORMAT,
594                       arg->v_uint32);
595     }
596
597     return py_obj;
598 }
599
600 static PyObject *
601 _pygi_marshal_to_py_utf8 (GIArgument *arg)
602 {
603     PyObject *py_obj = NULL;
604     if (arg->v_string == NULL) {
605         Py_RETURN_NONE;
606      }
607
608     py_obj = PYGLIB_PyUnicode_FromString (arg->v_string);
609     return py_obj;
610 }
611
612 static PyObject *
613 _pygi_marshal_to_py_filename (GIArgument *arg)
614 {
615     gchar *string = NULL;
616     PyObject *py_obj = NULL;
617     GError *error = NULL;
618
619     if (arg->v_string == NULL) {
620         Py_RETURN_NONE;
621     }
622
623     string = g_filename_to_utf8 (arg->v_string, -1, NULL, NULL, &error);
624     if (string == NULL) {
625         PyErr_SetString (PyExc_Exception, error->message);
626         /* TODO: Convert the error to an exception. */
627         return NULL;
628     }
629
630     py_obj = PYGLIB_PyUnicode_FromString (string);
631     g_free (string);
632
633     return py_obj;
634 }
635
636
637 /**
638  * _pygi_marshal_to_py_basic_type:
639  * @arg: The argument to convert to an object.
640  * @type_tag: Type tag for @arg
641  * @transfer: Transfer annotation
642  *
643  * Convert the given argument to a Python object. This function
644  * is restricted to simple types that only require the GITypeTag
645  * and GITransfer. For a more complete conversion routine, use:
646  * _pygi_argument_to_object.
647  *
648  * Returns: A PyObject representing @arg or NULL if it cannot convert
649  *          the argument.
650  */
651 PyObject *
652 _pygi_marshal_to_py_basic_type (GIArgument  *arg,
653                                 GITypeTag type_tag,
654                                 GITransfer transfer)
655 {
656     switch (type_tag) {
657         case GI_TYPE_TAG_BOOLEAN:
658             return PyBool_FromLong (arg->v_boolean);
659
660         case GI_TYPE_TAG_INT8:
661             return PYGLIB_PyLong_FromLong (arg->v_int8);
662
663         case GI_TYPE_TAG_UINT8:
664             return PYGLIB_PyLong_FromLong (arg->v_uint8);
665
666         case GI_TYPE_TAG_INT16:
667             return PYGLIB_PyLong_FromLong (arg->v_int16);
668
669         case GI_TYPE_TAG_UINT16:
670             return PYGLIB_PyLong_FromLong (arg->v_uint16);
671
672         case GI_TYPE_TAG_INT32:
673             return PYGLIB_PyLong_FromLong (arg->v_int32);
674
675         case GI_TYPE_TAG_UINT32:
676             return PyLong_FromLongLong (arg->v_uint32);
677
678         case GI_TYPE_TAG_INT64:
679             return PyLong_FromLongLong (arg->v_int64);
680
681         case GI_TYPE_TAG_UINT64:
682             return PyLong_FromUnsignedLongLong (arg->v_uint64);
683
684         case GI_TYPE_TAG_FLOAT:
685             return PyFloat_FromDouble (arg->v_float);
686
687         case GI_TYPE_TAG_DOUBLE:
688             return PyFloat_FromDouble (arg->v_double);
689
690         case GI_TYPE_TAG_GTYPE:
691             return pyg_type_wrapper_new ( (GType) arg->v_long);
692
693         case GI_TYPE_TAG_UNICHAR:
694             return _pygi_marshal_to_py_unichar (arg);
695
696         case GI_TYPE_TAG_UTF8:
697             return _pygi_marshal_to_py_utf8 (arg);
698
699         case GI_TYPE_TAG_FILENAME:
700             return _pygi_marshal_to_py_filename (arg);
701
702         default:
703             return NULL;
704     }
705     return NULL;
706 }
707
708 PyObject *
709 _pygi_marshal_to_py_basic_type_cache_adapter (PyGIInvokeState   *state,
710                                               PyGICallableCache *callable_cache,
711                                               PyGIArgCache      *arg_cache,
712                                               GIArgument        *arg)
713 {
714     return _pygi_marshal_to_py_basic_type (arg,
715                                             arg_cache->type_tag,
716                                             arg_cache->transfer);
717 }
718
719 static void
720 _pygi_marshal_cleanup_to_py_utf8 (PyGIInvokeState *state,
721                                   PyGIArgCache    *arg_cache,
722                                   PyObject        *dummy,
723                                   gpointer         data,
724                                   gboolean         was_processed)
725 {
726     /* Python copies the string so we need to free it
727        if the interface is transfering ownership, 
728        whether or not it has been processed yet */
729     if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
730         g_free (data);
731 }
732
733
734
735 static void
736 _arg_cache_to_py_basic_type_setup (PyGIArgCache *arg_cache)
737 {
738     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
739 }
740
741 static void
742 _arg_cache_to_py_void_setup (PyGIArgCache *arg_cache)
743 {
744     arg_cache->to_py_marshaller = _pygi_marshal_to_py_void;
745 }
746
747 static void
748 _arg_cache_to_py_utf8_setup (PyGIArgCache *arg_cache,
749                                GITransfer transfer)
750 {
751     arg_cache->to_py_marshaller = _pygi_marshal_to_py_basic_type_cache_adapter;
752     arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_utf8;
753 }
754
755 /*
756  * Basic Type Interface
757  */
758
759 static gboolean
760 pygi_arg_basic_type_setup_from_info (PyGIArgCache  *arg_cache,
761                                      GITypeInfo    *type_info,
762                                      GIArgInfo     *arg_info,
763                                      GITransfer     transfer,
764                                      PyGIDirection  direction)
765 {
766     GITypeTag type_tag = g_type_info_get_tag (type_info);
767
768     if (!pygi_arg_base_setup (arg_cache, type_info, arg_info, transfer, direction))
769         return FALSE;
770
771     switch (type_tag) {
772        case GI_TYPE_TAG_VOID:
773            if (direction & PYGI_DIRECTION_FROM_PYTHON)
774                _arg_cache_from_py_void_setup (arg_cache);
775
776            if (direction & PYGI_DIRECTION_TO_PYTHON)
777                _arg_cache_to_py_void_setup (arg_cache);
778
779            break;
780        case GI_TYPE_TAG_BOOLEAN:
781        case GI_TYPE_TAG_INT8:
782        case GI_TYPE_TAG_UINT8:
783        case GI_TYPE_TAG_INT16:
784        case GI_TYPE_TAG_UINT16:
785        case GI_TYPE_TAG_INT32:
786        case GI_TYPE_TAG_UINT32:
787        case GI_TYPE_TAG_INT64:
788        case GI_TYPE_TAG_UINT64:
789        case GI_TYPE_TAG_FLOAT:
790        case GI_TYPE_TAG_DOUBLE:
791        case GI_TYPE_TAG_UNICHAR:
792        case GI_TYPE_TAG_GTYPE:
793            if (direction & PYGI_DIRECTION_FROM_PYTHON)
794                _arg_cache_from_py_basic_type_setup (arg_cache);
795
796            if (direction & PYGI_DIRECTION_TO_PYTHON)
797                _arg_cache_to_py_basic_type_setup (arg_cache);
798
799            break;
800        case GI_TYPE_TAG_UTF8:
801        case GI_TYPE_TAG_FILENAME:
802            if (direction & PYGI_DIRECTION_FROM_PYTHON)
803                _arg_cache_from_py_utf8_setup (arg_cache, transfer);
804
805            if (direction & PYGI_DIRECTION_TO_PYTHON)
806                _arg_cache_to_py_utf8_setup (arg_cache, transfer);
807
808            break;
809        default:
810            g_assert_not_reached ();
811     }
812
813     return TRUE;
814 }
815
816 PyGIArgCache *
817 pygi_arg_basic_type_new_from_info (GITypeInfo   *type_info,
818                                    GIArgInfo    *arg_info,
819                                    GITransfer    transfer,
820                                    PyGIDirection direction)
821 {
822     gboolean res = FALSE;
823     PyGIArgCache *arg_cache = pygi_arg_cache_alloc ();
824     if (arg_cache == NULL)
825         return NULL;
826
827     res = pygi_arg_basic_type_setup_from_info (arg_cache,
828                                                type_info,
829                                                arg_info,
830                                                transfer,
831                                                direction);
832     if (res) {
833         return arg_cache;
834     } else {
835         pygi_arg_cache_free (arg_cache);
836         return NULL;
837     }
838 }