tests: don't test for specific device labels
[pygobject.git] / gi / pygi-enum-marshal.c
blobfc330895e5e074426f404f84e8b88826744593f9
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 = (gint8)c_long_in;
38 return TRUE;
39 case GI_TYPE_TAG_UINT8:
40 arg_out->v_uint8 = (guint8)c_long_in;
41 return TRUE;
42 case GI_TYPE_TAG_INT16:
43 arg_out->v_int16 = (gint16)c_long_in;
44 return TRUE;
45 case GI_TYPE_TAG_UINT16:
46 arg_out->v_uint16 = (guint16)c_long_in;
47 return TRUE;
48 case GI_TYPE_TAG_INT32:
49 arg_out->v_int32 = (gint32)c_long_in;
50 return TRUE;
51 case GI_TYPE_TAG_UINT32:
52 arg_out->v_uint32 = (guint32)c_long_in;
53 return TRUE;
54 case GI_TYPE_TAG_INT64:
55 arg_out->v_int64 = (gint64)c_long_in;
56 return TRUE;
57 case GI_TYPE_TAG_UINT64:
58 arg_out->v_uint64 = (guint64)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 if (arg_in->v_int64 > G_MAXLONG || arg_in->v_int64 < G_MINLONG) {
95 PyErr_Format (PyExc_TypeError,
96 "Unable to marshal %s to C long",
97 g_type_tag_to_string(type_tag));
98 return FALSE;
100 *c_long_out = (glong)arg_in->v_int64;
101 return TRUE;
102 case GI_TYPE_TAG_UINT64:
103 if (arg_in->v_uint64 > G_MAXLONG) {
104 PyErr_Format (PyExc_TypeError,
105 "Unable to marshal %s to C long",
106 g_type_tag_to_string(type_tag));
107 return FALSE;
109 *c_long_out = (glong)arg_in->v_uint64;
110 return TRUE;
111 default:
112 PyErr_Format (PyExc_TypeError,
113 "Unable to marshal %s to C long",
114 g_type_tag_to_string (type_tag));
115 return FALSE;
119 static gboolean
120 _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state,
121 PyGICallableCache *callable_cache,
122 PyGIArgCache *arg_cache,
123 PyObject *py_arg,
124 GIArgument *arg,
125 gpointer *cleanup_data)
127 PyObject *py_long;
128 long c_long;
129 gint is_instance;
130 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
131 GIBaseInfo *interface = NULL;
133 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
135 py_long = PYGLIB_PyNumber_Long (py_arg);
136 if (py_long == NULL) {
137 PyErr_Clear();
138 goto err;
141 c_long = PYGLIB_PyLong_AsLong (py_long);
142 Py_DECREF (py_long);
144 /* Write c_long into arg */
145 interface = g_type_info_get_interface (arg_cache->type_info);
146 assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
147 if (!gi_argument_from_c_long(arg,
148 c_long,
149 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
150 g_assert_not_reached();
151 g_base_info_unref (interface);
152 return FALSE;
155 /* If this is not an instance of the Enum type that we want
156 * we need to check if the value is equivilant to one of the
157 * Enum's memebers */
158 if (!is_instance) {
159 int i;
160 gboolean is_found = FALSE;
162 for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) {
163 GIValueInfo *value_info =
164 g_enum_info_get_value (iface_cache->interface_info, i);
165 gint64 enum_value = g_value_info_get_value (value_info);
166 g_base_info_unref ( (GIBaseInfo *)value_info);
167 if (c_long == enum_value) {
168 is_found = TRUE;
169 break;
173 if (!is_found)
174 goto err;
177 g_base_info_unref (interface);
178 return TRUE;
180 err:
181 if (interface)
182 g_base_info_unref (interface);
183 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
184 iface_cache->type_name, Py_TYPE (py_arg)->tp_name);
185 return FALSE;
188 static gboolean
189 _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state,
190 PyGICallableCache *callable_cache,
191 PyGIArgCache *arg_cache,
192 PyObject *py_arg,
193 GIArgument *arg,
194 gpointer *cleanup_data)
196 PyObject *py_long;
197 unsigned long c_ulong;
198 gint is_instance;
199 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
200 GIBaseInfo *interface;
202 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
204 py_long = PYGLIB_PyNumber_Long (py_arg);
205 if (py_long == NULL) {
206 PyErr_Clear ();
207 goto err;
210 c_ulong = PYGLIB_PyLong_AsUnsignedLong (py_long);
211 Py_DECREF (py_long);
213 /* only 0 or argument of type Flag is allowed */
214 if (!is_instance && c_ulong != 0)
215 goto err;
217 /* Write c_long into arg */
218 interface = g_type_info_get_interface (arg_cache->type_info);
219 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
220 if (!gi_argument_from_c_long(arg, c_ulong,
221 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
222 g_base_info_unref (interface);
223 return FALSE;
226 g_base_info_unref (interface);
227 return TRUE;
229 err:
230 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
231 iface_cache->type_name, Py_TYPE (py_arg)->tp_name);
232 return FALSE;
236 static PyObject *
237 _pygi_marshal_to_py_interface_enum (PyGIInvokeState *state,
238 PyGICallableCache *callable_cache,
239 PyGIArgCache *arg_cache,
240 GIArgument *arg,
241 gpointer *cleanup_data)
243 PyObject *py_obj = NULL;
244 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
245 GIBaseInfo *interface;
246 long c_long;
248 interface = g_type_info_get_interface (arg_cache->type_info);
249 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
251 if (!gi_argument_to_c_long(arg, &c_long,
252 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
253 return NULL;
256 if (iface_cache->g_type == G_TYPE_NONE) {
257 py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
258 } else {
259 py_obj = pyg_enum_from_gtype (iface_cache->g_type, (gint)c_long);
261 g_base_info_unref (interface);
262 return py_obj;
265 static PyObject *
266 _pygi_marshal_to_py_interface_flags (PyGIInvokeState *state,
267 PyGICallableCache *callable_cache,
268 PyGIArgCache *arg_cache,
269 GIArgument *arg,
270 gpointer *cleanup_data)
272 PyObject *py_obj = NULL;
273 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
274 GIBaseInfo *interface;
275 long c_long;
277 interface = g_type_info_get_interface (arg_cache->type_info);
278 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
280 if (!gi_argument_to_c_long(arg, &c_long,
281 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
282 g_base_info_unref (interface);
283 return NULL;
286 g_base_info_unref (interface);
287 if (iface_cache->g_type == G_TYPE_NONE) {
288 /* An enum with a GType of None is an enum without GType */
290 PyObject *py_type = pygi_type_import_by_gi_info (iface_cache->interface_info);
291 PyObject *py_args = NULL;
293 if (!py_type)
294 return NULL;
296 py_args = PyTuple_New (1);
297 if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
298 Py_DECREF (py_args);
299 Py_DECREF (py_type);
300 return NULL;
303 py_obj = PyObject_CallFunction (py_type, "l", c_long);
305 Py_DECREF (py_args);
306 Py_DECREF (py_type);
307 } else {
308 py_obj = pyg_flags_from_gtype (iface_cache->g_type, (guint)c_long);
311 return py_obj;
314 static gboolean
315 pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache,
316 GITypeInfo *type_info,
317 GIArgInfo *arg_info,
318 GITransfer transfer,
319 PyGIDirection direction)
321 if (direction & PYGI_DIRECTION_FROM_PYTHON)
322 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
324 if (direction & PYGI_DIRECTION_TO_PYTHON)
325 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
327 return TRUE;
331 PyGIArgCache *
332 pygi_arg_enum_new_from_info (GITypeInfo *type_info,
333 GIArgInfo *arg_info,
334 GITransfer transfer,
335 PyGIDirection direction,
336 GIInterfaceInfo *iface_info)
338 gboolean res = FALSE;
339 PyGIArgCache *cache = NULL;
341 cache = pygi_arg_interface_new_from_info (type_info,
342 arg_info,
343 transfer,
344 direction,
345 iface_info);
346 if (cache == NULL)
347 return NULL;
349 res = pygi_arg_enum_setup_from_info (cache,
350 type_info,
351 arg_info,
352 transfer,
353 direction);
354 if (res) {
355 return cache;
356 } else {
357 pygi_arg_cache_free (cache);
358 return NULL;
362 static gboolean
363 pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache,
364 GITypeInfo *type_info,
365 GIArgInfo *arg_info,
366 GITransfer transfer,
367 PyGIDirection direction)
369 if (direction & PYGI_DIRECTION_FROM_PYTHON)
370 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
372 if (direction & PYGI_DIRECTION_TO_PYTHON)
373 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
375 return TRUE;
379 PyGIArgCache *
380 pygi_arg_flags_new_from_info (GITypeInfo *type_info,
381 GIArgInfo *arg_info,
382 GITransfer transfer,
383 PyGIDirection direction,
384 GIInterfaceInfo *iface_info)
386 gboolean res = FALSE;
387 PyGIArgCache *cache = NULL;
389 cache = pygi_arg_interface_new_from_info (type_info,
390 arg_info,
391 transfer,
392 direction,
393 iface_info);
394 if (cache == NULL)
395 return NULL;
397 res = pygi_arg_flags_setup_from_info (cache,
398 type_info,
399 arg_info,
400 transfer,
401 direction);
402 if (res) {
403 return cache;
404 } else {
405 pygi_arg_cache_free (cache);
406 return NULL;