Rename pyglib-python-compat.h to pygi-python-compat.h
[pygobject.git] / gi / pygi-enum-marshal.c
blobdc36dfe3cd6b8b0931210828fe0f2562e958f94a
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5 * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
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.
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.
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/>.
21 #include <Python.h>
22 #include <glib.h>
24 #include "pygi-python-compat.h"
25 #include "pygi-enum-marshal.h"
26 #include "pygi-type.h"
27 #include "pygenum.h"
28 #include "pygflags.h"
30 static gboolean
31 gi_argument_from_c_long (GIArgument *arg_out,
32 long c_long_in,
33 GITypeTag type_tag)
35 switch (type_tag) {
36 case GI_TYPE_TAG_INT8:
37 arg_out->v_int8 = c_long_in;
38 return TRUE;
39 case GI_TYPE_TAG_UINT8:
40 arg_out->v_uint8 = c_long_in;
41 return TRUE;
42 case GI_TYPE_TAG_INT16:
43 arg_out->v_int16 = c_long_in;
44 return TRUE;
45 case GI_TYPE_TAG_UINT16:
46 arg_out->v_uint16 = c_long_in;
47 return TRUE;
48 case GI_TYPE_TAG_INT32:
49 arg_out->v_int32 = c_long_in;
50 return TRUE;
51 case GI_TYPE_TAG_UINT32:
52 arg_out->v_uint32 = c_long_in;
53 return TRUE;
54 case GI_TYPE_TAG_INT64:
55 arg_out->v_int64 = c_long_in;
56 return TRUE;
57 case GI_TYPE_TAG_UINT64:
58 arg_out->v_uint64 = c_long_in;
59 return TRUE;
60 default:
61 PyErr_Format (PyExc_TypeError,
62 "Unable to marshal C long %ld to %s",
63 c_long_in,
64 g_type_tag_to_string (type_tag));
65 return FALSE;
69 static gboolean
70 gi_argument_to_c_long (GIArgument *arg_in,
71 long *c_long_out,
72 GITypeTag type_tag)
74 switch (type_tag) {
75 case GI_TYPE_TAG_INT8:
76 *c_long_out = arg_in->v_int8;
77 return TRUE;
78 case GI_TYPE_TAG_UINT8:
79 *c_long_out = arg_in->v_uint8;
80 return TRUE;
81 case GI_TYPE_TAG_INT16:
82 *c_long_out = arg_in->v_int16;
83 return TRUE;
84 case GI_TYPE_TAG_UINT16:
85 *c_long_out = arg_in->v_uint16;
86 return TRUE;
87 case GI_TYPE_TAG_INT32:
88 *c_long_out = arg_in->v_int32;
89 return TRUE;
90 case GI_TYPE_TAG_UINT32:
91 *c_long_out = arg_in->v_uint32;
92 return TRUE;
93 case GI_TYPE_TAG_INT64:
94 *c_long_out = arg_in->v_int64;
95 return TRUE;
96 case GI_TYPE_TAG_UINT64:
97 *c_long_out = arg_in->v_uint64;
98 return TRUE;
99 default:
100 PyErr_Format (PyExc_TypeError,
101 "Unable to marshal %s to C long",
102 g_type_tag_to_string (type_tag));
103 return FALSE;
107 static gboolean
108 _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state,
109 PyGICallableCache *callable_cache,
110 PyGIArgCache *arg_cache,
111 PyObject *py_arg,
112 GIArgument *arg,
113 gpointer *cleanup_data)
115 PyObject *py_long;
116 long c_long;
117 gint is_instance;
118 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
119 GIBaseInfo *interface = NULL;
121 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
123 py_long = PYGLIB_PyNumber_Long (py_arg);
124 if (py_long == NULL) {
125 PyErr_Clear();
126 goto err;
129 c_long = PYGLIB_PyLong_AsLong (py_long);
130 Py_DECREF (py_long);
132 /* Write c_long into arg */
133 interface = g_type_info_get_interface (arg_cache->type_info);
134 assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
135 if (!gi_argument_from_c_long(arg,
136 c_long,
137 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
138 g_assert_not_reached();
139 g_base_info_unref (interface);
140 return FALSE;
143 /* If this is not an instance of the Enum type that we want
144 * we need to check if the value is equivilant to one of the
145 * Enum's memebers */
146 if (!is_instance) {
147 int i;
148 gboolean is_found = FALSE;
150 for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) {
151 GIValueInfo *value_info =
152 g_enum_info_get_value (iface_cache->interface_info, i);
153 glong enum_value = g_value_info_get_value (value_info);
154 g_base_info_unref ( (GIBaseInfo *)value_info);
155 if (c_long == enum_value) {
156 is_found = TRUE;
157 break;
161 if (!is_found)
162 goto err;
165 g_base_info_unref (interface);
166 return TRUE;
168 err:
169 if (interface)
170 g_base_info_unref (interface);
171 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
172 iface_cache->type_name, py_arg->ob_type->tp_name);
173 return FALSE;
176 static gboolean
177 _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state,
178 PyGICallableCache *callable_cache,
179 PyGIArgCache *arg_cache,
180 PyObject *py_arg,
181 GIArgument *arg,
182 gpointer *cleanup_data)
184 PyObject *py_long;
185 unsigned long c_ulong;
186 gint is_instance;
187 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
188 GIBaseInfo *interface;
190 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
192 py_long = PYGLIB_PyNumber_Long (py_arg);
193 if (py_long == NULL) {
194 PyErr_Clear ();
195 goto err;
198 c_ulong = PYGLIB_PyLong_AsUnsignedLong (py_long);
199 Py_DECREF (py_long);
201 /* only 0 or argument of type Flag is allowed */
202 if (!is_instance && c_ulong != 0)
203 goto err;
205 /* Write c_long into arg */
206 interface = g_type_info_get_interface (arg_cache->type_info);
207 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
208 if (!gi_argument_from_c_long(arg, c_ulong,
209 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
210 g_base_info_unref (interface);
211 return FALSE;
214 g_base_info_unref (interface);
215 return TRUE;
217 err:
218 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
219 iface_cache->type_name, py_arg->ob_type->tp_name);
220 return FALSE;
224 static PyObject *
225 _pygi_marshal_to_py_interface_enum (PyGIInvokeState *state,
226 PyGICallableCache *callable_cache,
227 PyGIArgCache *arg_cache,
228 GIArgument *arg,
229 gpointer *cleanup_data)
231 PyObject *py_obj = NULL;
232 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
233 GIBaseInfo *interface;
234 long c_long;
236 interface = g_type_info_get_interface (arg_cache->type_info);
237 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
239 if (!gi_argument_to_c_long(arg, &c_long,
240 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
241 return NULL;
244 if (iface_cache->g_type == G_TYPE_NONE) {
245 py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
246 } else {
247 py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
249 g_base_info_unref (interface);
250 return py_obj;
253 static PyObject *
254 _pygi_marshal_to_py_interface_flags (PyGIInvokeState *state,
255 PyGICallableCache *callable_cache,
256 PyGIArgCache *arg_cache,
257 GIArgument *arg,
258 gpointer *cleanup_data)
260 PyObject *py_obj = NULL;
261 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
262 GIBaseInfo *interface;
263 long c_long;
265 interface = g_type_info_get_interface (arg_cache->type_info);
266 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
268 if (!gi_argument_to_c_long(arg, &c_long,
269 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
270 g_base_info_unref (interface);
271 return NULL;
274 g_base_info_unref (interface);
275 if (iface_cache->g_type == G_TYPE_NONE) {
276 /* An enum with a GType of None is an enum without GType */
278 PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info);
279 PyObject *py_args = NULL;
281 if (!py_type)
282 return NULL;
284 py_args = PyTuple_New (1);
285 if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
286 Py_DECREF (py_args);
287 Py_DECREF (py_type);
288 return NULL;
291 py_obj = PyObject_CallFunction (py_type, "l", c_long);
293 Py_DECREF (py_args);
294 Py_DECREF (py_type);
295 } else {
296 py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
299 return py_obj;
302 static gboolean
303 pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache,
304 GITypeInfo *type_info,
305 GIArgInfo *arg_info,
306 GITransfer transfer,
307 PyGIDirection direction)
309 if (direction & PYGI_DIRECTION_FROM_PYTHON)
310 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
312 if (direction & PYGI_DIRECTION_TO_PYTHON)
313 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
315 return TRUE;
319 PyGIArgCache *
320 pygi_arg_enum_new_from_info (GITypeInfo *type_info,
321 GIArgInfo *arg_info,
322 GITransfer transfer,
323 PyGIDirection direction,
324 GIInterfaceInfo *iface_info)
326 gboolean res = FALSE;
327 PyGIArgCache *cache = NULL;
329 cache = pygi_arg_interface_new_from_info (type_info,
330 arg_info,
331 transfer,
332 direction,
333 iface_info);
334 if (cache == NULL)
335 return NULL;
337 res = pygi_arg_enum_setup_from_info (cache,
338 type_info,
339 arg_info,
340 transfer,
341 direction);
342 if (res) {
343 return cache;
344 } else {
345 pygi_arg_cache_free (cache);
346 return NULL;
350 static gboolean
351 pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache,
352 GITypeInfo *type_info,
353 GIArgInfo *arg_info,
354 GITransfer transfer,
355 PyGIDirection direction)
357 if (direction & PYGI_DIRECTION_FROM_PYTHON)
358 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
360 if (direction & PYGI_DIRECTION_TO_PYTHON)
361 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
363 return TRUE;
367 PyGIArgCache *
368 pygi_arg_flags_new_from_info (GITypeInfo *type_info,
369 GIArgInfo *arg_info,
370 GITransfer transfer,
371 PyGIDirection direction,
372 GIInterfaceInfo *iface_info)
374 gboolean res = FALSE;
375 PyGIArgCache *cache = NULL;
377 cache = pygi_arg_interface_new_from_info (type_info,
378 arg_info,
379 transfer,
380 direction,
381 iface_info);
382 if (cache == NULL)
383 return NULL;
385 res = pygi_arg_flags_setup_from_info (cache,
386 type_info,
387 arg_info,
388 transfer,
389 direction);
390 if (res) {
391 return cache;
392 } else {
393 pygi_arg_cache_free (cache);
394 return NULL;