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-type.h"
31 gi_argument_from_c_long (GIArgument *arg_out,
36 case GI_TYPE_TAG_INT8:
37 arg_out->v_int8 = c_long_in;
39 case GI_TYPE_TAG_UINT8:
40 arg_out->v_uint8 = c_long_in;
42 case GI_TYPE_TAG_INT16:
43 arg_out->v_int16 = c_long_in;
45 case GI_TYPE_TAG_UINT16:
46 arg_out->v_uint16 = c_long_in;
48 case GI_TYPE_TAG_INT32:
49 arg_out->v_int32 = c_long_in;
51 case GI_TYPE_TAG_UINT32:
52 arg_out->v_uint32 = c_long_in;
54 case GI_TYPE_TAG_INT64:
55 arg_out->v_int64 = c_long_in;
57 case GI_TYPE_TAG_UINT64:
58 arg_out->v_uint64 = c_long_in;
61 PyErr_Format (PyExc_TypeError,
62 "Unable to marshal C long %ld to %s",
64 g_type_tag_to_string (type_tag));
70 gi_argument_to_c_long (GIArgument *arg_in,
75 case GI_TYPE_TAG_INT8:
76 *c_long_out = arg_in->v_int8;
78 case GI_TYPE_TAG_UINT8:
79 *c_long_out = arg_in->v_uint8;
81 case GI_TYPE_TAG_INT16:
82 *c_long_out = arg_in->v_int16;
84 case GI_TYPE_TAG_UINT16:
85 *c_long_out = arg_in->v_uint16;
87 case GI_TYPE_TAG_INT32:
88 *c_long_out = arg_in->v_int32;
90 case GI_TYPE_TAG_UINT32:
91 *c_long_out = arg_in->v_uint32;
93 case GI_TYPE_TAG_INT64:
94 *c_long_out = arg_in->v_int64;
96 case GI_TYPE_TAG_UINT64:
97 *c_long_out = arg_in->v_uint64;
100 PyErr_Format (PyExc_TypeError,
101 "Unable to marshal %s to C long",
102 g_type_tag_to_string (type_tag));
108 _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state,
109 PyGICallableCache *callable_cache,
110 PyGIArgCache *arg_cache,
113 gpointer *cleanup_data)
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) {
129 c_long = PYGLIB_PyLong_AsLong (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,
137 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
138 g_assert_not_reached();
139 g_base_info_unref (interface);
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
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) {
165 g_base_info_unref (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);
177 _pygi_marshal_from_py_interface_flags (PyGIInvokeState *state,
178 PyGICallableCache *callable_cache,
179 PyGIArgCache *arg_cache,
182 gpointer *cleanup_data)
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) {
198 c_long = PYGLIB_PyLong_AsLong (py_long);
201 /* only 0 or argument of type Flag is allowed */
202 if (!is_instance && c_long != 0)
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_long,
209 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
210 g_base_info_unref (interface);
214 g_base_info_unref (interface);
218 PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
219 iface_cache->type_name, py_arg->ob_type->tp_name);
225 _pygi_marshal_to_py_interface_enum (PyGIInvokeState *state,
226 PyGICallableCache *callable_cache,
227 PyGIArgCache *arg_cache,
230 PyObject *py_obj = NULL;
231 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
232 GIBaseInfo *interface;
235 interface = g_type_info_get_interface (arg_cache->type_info);
236 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
238 if (!gi_argument_to_c_long(arg, &c_long,
239 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
243 if (iface_cache->g_type == G_TYPE_NONE) {
244 py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
246 py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
248 g_base_info_unref (interface);
253 _pygi_marshal_to_py_interface_flags (PyGIInvokeState *state,
254 PyGICallableCache *callable_cache,
255 PyGIArgCache *arg_cache,
258 PyObject *py_obj = NULL;
259 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
260 GIBaseInfo *interface;
263 interface = g_type_info_get_interface (arg_cache->type_info);
264 g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
266 if (!gi_argument_to_c_long(arg, &c_long,
267 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
268 g_base_info_unref (interface);
272 g_base_info_unref (interface);
273 if (iface_cache->g_type == G_TYPE_NONE) {
274 /* An enum with a GType of None is an enum without GType */
276 PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info);
277 PyObject *py_args = NULL;
282 py_args = PyTuple_New (1);
283 if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
289 py_obj = PyObject_CallFunction (py_type, "l", c_long);
294 py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
301 pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache,
302 GITypeInfo *type_info,
305 PyGIDirection direction)
307 if (direction & PYGI_DIRECTION_FROM_PYTHON)
308 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
310 if (direction & PYGI_DIRECTION_TO_PYTHON)
311 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
318 pygi_arg_enum_new_from_info (GITypeInfo *type_info,
321 PyGIDirection direction,
322 GIInterfaceInfo *iface_info)
324 gboolean res = FALSE;
325 PyGIArgCache *cache = NULL;
327 cache = pygi_arg_interface_new_from_info (type_info,
335 res = pygi_arg_enum_setup_from_info (cache,
343 pygi_arg_cache_free (cache);
349 pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache,
350 GITypeInfo *type_info,
353 PyGIDirection direction)
355 if (direction & PYGI_DIRECTION_FROM_PYTHON)
356 arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
358 if (direction & PYGI_DIRECTION_TO_PYTHON)
359 arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
366 pygi_arg_flags_new_from_info (GITypeInfo *type_info,
369 PyGIDirection direction,
370 GIInterfaceInfo *iface_info)
372 gboolean res = FALSE;
373 PyGIArgCache *cache = NULL;
375 cache = pygi_arg_interface_new_from_info (type_info,
383 res = pygi_arg_flags_setup_from_info (cache,
391 pygi_arg_cache_free (cache);