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/>.
24 #include "pygi-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
)
185 unsigned long c_ulong
;
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_ulong
= PYGLIB_PyLong_AsUnsignedLong (py_long
);
201 /* only 0 or argument of type Flag is allowed */
202 if (!is_instance
&& c_ulong
!= 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_ulong
,
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
,
229 gpointer
*cleanup_data
)
231 PyObject
*py_obj
= NULL
;
232 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
233 GIBaseInfo
*interface
;
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
))) {
244 if (iface_cache
->g_type
== G_TYPE_NONE
) {
245 py_obj
= PyObject_CallFunction (iface_cache
->py_type
, "l", c_long
);
247 py_obj
= pyg_enum_from_gtype (iface_cache
->g_type
, c_long
);
249 g_base_info_unref (interface
);
254 _pygi_marshal_to_py_interface_flags (PyGIInvokeState
*state
,
255 PyGICallableCache
*callable_cache
,
256 PyGIArgCache
*arg_cache
,
258 gpointer
*cleanup_data
)
260 PyObject
*py_obj
= NULL
;
261 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
262 GIBaseInfo
*interface
;
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
);
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
;
284 py_args
= PyTuple_New (1);
285 if (PyTuple_SetItem (py_args
, 0, PyLong_FromLong (c_long
)) != 0) {
291 py_obj
= PyObject_CallFunction (py_type
, "l", c_long
);
296 py_obj
= pyg_flags_from_gtype (iface_cache
->g_type
, c_long
);
303 pygi_arg_enum_setup_from_info (PyGIArgCache
*arg_cache
,
304 GITypeInfo
*type_info
,
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
;
320 pygi_arg_enum_new_from_info (GITypeInfo
*type_info
,
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
,
337 res
= pygi_arg_enum_setup_from_info (cache
,
345 pygi_arg_cache_free (cache
);
351 pygi_arg_flags_setup_from_info (PyGIArgCache
*arg_cache
,
352 GITypeInfo
*type_info
,
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
;
368 pygi_arg_flags_new_from_info (GITypeInfo
*type_info
,
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
,
385 res
= pygi_arg_flags_setup_from_info (cache
,
393 pygi_arg_cache_free (cache
);