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/>.
23 #include <pyglib-python-compat.h>
25 #include "pygi-enum-marshal.h"
26 #include "pygi-private.h"
29 gi_argument_from_c_long (GIArgument *arg_out,
34 case GI_TYPE_TAG_INT8:
35 arg_out->v_int8 = c_long_in;
37 case GI_TYPE_TAG_UINT8:
38 arg_out->v_uint8 = c_long_in;
40 case GI_TYPE_TAG_INT16:
41 arg_out->v_int16 = c_long_in;
43 case GI_TYPE_TAG_UINT16:
44 arg_out->v_uint16 = c_long_in;
46 case GI_TYPE_TAG_INT32:
47 arg_out->v_int32 = c_long_in;
49 case GI_TYPE_TAG_UINT32:
50 arg_out->v_uint32 = c_long_in;
52 case GI_TYPE_TAG_INT64:
53 arg_out->v_int64 = c_long_in;
55 case GI_TYPE_TAG_UINT64:
56 arg_out->v_uint64 = c_long_in;
59 PyErr_Format (PyExc_TypeError,
60 "Unable to marshal C long %ld to %s",
62 g_type_tag_to_string (type_tag));
68 gi_argument_to_c_long (GIArgument *arg_in,
73 case GI_TYPE_TAG_INT8:
74 *c_long_out = arg_in->v_int8;
76 case GI_TYPE_TAG_UINT8:
77 *c_long_out = arg_in->v_uint8;
79 case GI_TYPE_TAG_INT16:
80 *c_long_out = arg_in->v_int16;
82 case GI_TYPE_TAG_UINT16:
83 *c_long_out = arg_in->v_uint16;
85 case GI_TYPE_TAG_INT32:
86 *c_long_out = arg_in->v_int32;
88 case GI_TYPE_TAG_UINT32:
89 *c_long_out = arg_in->v_uint32;
91 case GI_TYPE_TAG_INT64:
92 *c_long_out = arg_in->v_int64;
94 case GI_TYPE_TAG_UINT64:
95 *c_long_out = arg_in->v_uint64;
98 PyErr_Format (PyExc_TypeError,
99 "Unable to marshal %s to C long",
100 g_type_tag_to_string (type_tag));
106 _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state,
107 PyGICallableCache *callable_cache,
108 PyGIArgCache *arg_cache,
111 gpointer *cleanup_data)
116 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
117 GIBaseInfo *interface = NULL;
119 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
121 py_long = PYGLIB_PyNumber_Long (py_arg);
122 if (py_long == NULL) {
127 c_long = PYGLIB_PyLong_AsLong (py_long);
130 /* Write c_long into arg */
131 interface = g_type_info_get_interface (arg_cache->type_info);
132 assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
133 if (!gi_argument_from_c_long(arg,
135 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
136 g_assert_not_reached();
137 g_base_info_unref (interface);
141 /* If this is not an instance of the Enum type that we want
142 * we need to check if the value is equivilant to one of the
146 gboolean is_found = FALSE;
148 for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) {
149 GIValueInfo *value_info =
150 g_enum_info_get_value (iface_cache->interface_info, i);
151 glong enum_value = g_value_info_get_value (value_info);
152 g_base_info_unref ( (GIBaseInfo *)value_info);
153 if (c_long == enum_value) {
163 g_base_info_unref (interface);
168 g_base_info_unref (interface);
169 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
170 iface_cache->type_name, py_arg->ob_type->tp_name);
175 _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state,
176 PyGICallableCache *callable_cache,
177 PyGIArgCache *arg_cache,
180 gpointer *cleanup_data)
185 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
186 GIBaseInfo *interface;
188 is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
190 py_long = PYGLIB_PyNumber_Long (py_arg);
191 if (py_long == NULL) {
196 c_long = PYGLIB_PyLong_AsLong (py_long);
199 /* only 0 or argument of type Flag is allowed */
200 if (!is_instance && c_long != 0)
203 /* Write c_long into arg */
204 interface = g_type_info_get_interface (arg_cache->type_info);
205 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
206 if (!gi_argument_from_c_long(arg, c_long,
207 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
208 g_base_info_unref (interface);
212 g_base_info_unref (interface);
216 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
217 iface_cache->type_name, py_arg->ob_type->tp_name);
223 _pygi_marshal_to_py_interface_enum (PyGIInvokeState *state,
224 PyGICallableCache *callable_cache,
225 PyGIArgCache *arg_cache,
228 PyObject *py_obj = NULL;
229 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
230 GIBaseInfo *interface;
233 interface = g_type_info_get_interface (arg_cache->type_info);
234 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
236 if (!gi_argument_to_c_long(arg, &c_long,
237 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
241 if (iface_cache->g_type == G_TYPE_NONE) {
242 py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
244 py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
246 g_base_info_unref (interface);
251 _pygi_marshal_to_py_interface_flags (PyGIInvokeState *state,
252 PyGICallableCache *callable_cache,
253 PyGIArgCache *arg_cache,
256 PyObject *py_obj = NULL;
257 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
258 GIBaseInfo *interface;
261 interface = g_type_info_get_interface (arg_cache->type_info);
262 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
264 if (!gi_argument_to_c_long(arg, &c_long,
265 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
266 g_base_info_unref (interface);
270 g_base_info_unref (interface);
271 if (iface_cache->g_type == G_TYPE_NONE) {
272 /* An enum with a GType of None is an enum without GType */
274 PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info);
275 PyObject *py_args = NULL;
280 py_args = PyTuple_New (1);
281 if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
287 py_obj = PyObject_CallFunction (py_type, "l", c_long);
292 py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
299 pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache,
300 GITypeInfo *type_info,
303 PyGIDirection direction)
305 if (direction & PYGI_DIRECTION_FROM_PYTHON)
306 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
308 if (direction & PYGI_DIRECTION_TO_PYTHON)
309 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
316 pygi_arg_enum_new_from_info (GITypeInfo *type_info,
319 PyGIDirection direction,
320 GIInterfaceInfo *iface_info)
322 gboolean res = FALSE;
323 PyGIArgCache *cache = NULL;
325 cache = pygi_arg_interface_new_from_info (type_info,
333 res = pygi_arg_enum_setup_from_info (cache,
341 pygi_arg_cache_free (cache);
347 pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache,
348 GITypeInfo *type_info,
351 PyGIDirection direction)
353 if (direction & PYGI_DIRECTION_FROM_PYTHON)
354 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
356 if (direction & PYGI_DIRECTION_TO_PYTHON)
357 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
364 pygi_arg_flags_new_from_info (GITypeInfo *type_info,
367 PyGIDirection direction,
368 GIInterfaceInfo *iface_info)
370 gboolean res = FALSE;
371 PyGIArgCache *cache = NULL;
373 cache = pygi_arg_interface_new_from_info (type_info,
381 res = pygi_arg_flags_setup_from_info (cache,
389 pygi_arg_cache_free (cache);