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
= (gint8
)c_long_in
;
39 case GI_TYPE_TAG_UINT8
:
40 arg_out
->v_uint8
= (guint8
)c_long_in
;
42 case GI_TYPE_TAG_INT16
:
43 arg_out
->v_int16
= (gint16
)c_long_in
;
45 case GI_TYPE_TAG_UINT16
:
46 arg_out
->v_uint16
= (guint16
)c_long_in
;
48 case GI_TYPE_TAG_INT32
:
49 arg_out
->v_int32
= (gint32
)c_long_in
;
51 case GI_TYPE_TAG_UINT32
:
52 arg_out
->v_uint32
= (guint32
)c_long_in
;
54 case GI_TYPE_TAG_INT64
:
55 arg_out
->v_int64
= (gint64
)c_long_in
;
57 case GI_TYPE_TAG_UINT64
:
58 arg_out
->v_uint64
= (guint64
)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 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
));
100 *c_long_out
= (glong
)arg_in
->v_int64
;
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
));
109 *c_long_out
= (glong
)arg_in
->v_uint64
;
112 PyErr_Format (PyExc_TypeError
,
113 "Unable to marshal %s to C long",
114 g_type_tag_to_string (type_tag
));
120 _pygi_marshal_from_py_interface_enum (PyGIInvokeState
*state
,
121 PyGICallableCache
*callable_cache
,
122 PyGIArgCache
*arg_cache
,
125 gpointer
*cleanup_data
)
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
) {
141 c_long
= PYGLIB_PyLong_AsLong (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
,
149 g_enum_info_get_storage_type ((GIEnumInfo
*)interface
))) {
150 g_assert_not_reached();
151 g_base_info_unref (interface
);
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
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
) {
177 g_base_info_unref (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
);
189 _pygi_marshal_from_py_interface_flags (PyGIInvokeState
*state
,
190 PyGICallableCache
*callable_cache
,
191 PyGIArgCache
*arg_cache
,
194 gpointer
*cleanup_data
)
197 unsigned long c_ulong
;
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
) {
210 c_ulong
= PYGLIB_PyLong_AsUnsignedLong (py_long
);
213 /* only 0 or argument of type Flag is allowed */
214 if (!is_instance
&& c_ulong
!= 0)
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
);
226 g_base_info_unref (interface
);
230 PyErr_Format (PyExc_TypeError
, "Expected a %s, but got %s",
231 iface_cache
->type_name
, Py_TYPE (py_arg
)->tp_name
);
237 _pygi_marshal_to_py_interface_enum (PyGIInvokeState
*state
,
238 PyGICallableCache
*callable_cache
,
239 PyGIArgCache
*arg_cache
,
241 gpointer
*cleanup_data
)
243 PyObject
*py_obj
= NULL
;
244 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
245 GIBaseInfo
*interface
;
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
))) {
256 if (iface_cache
->g_type
== G_TYPE_NONE
) {
257 py_obj
= PyObject_CallFunction (iface_cache
->py_type
, "l", c_long
);
259 py_obj
= pyg_enum_from_gtype (iface_cache
->g_type
, (gint
)c_long
);
261 g_base_info_unref (interface
);
266 _pygi_marshal_to_py_interface_flags (PyGIInvokeState
*state
,
267 PyGICallableCache
*callable_cache
,
268 PyGIArgCache
*arg_cache
,
270 gpointer
*cleanup_data
)
272 PyObject
*py_obj
= NULL
;
273 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
274 GIBaseInfo
*interface
;
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
);
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
;
296 py_args
= PyTuple_New (1);
297 if (PyTuple_SetItem (py_args
, 0, PyLong_FromLong (c_long
)) != 0) {
303 py_obj
= PyObject_CallFunction (py_type
, "l", c_long
);
308 py_obj
= pyg_flags_from_gtype (iface_cache
->g_type
, (guint
)c_long
);
315 pygi_arg_enum_setup_from_info (PyGIArgCache
*arg_cache
,
316 GITypeInfo
*type_info
,
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
;
332 pygi_arg_enum_new_from_info (GITypeInfo
*type_info
,
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
,
349 res
= pygi_arg_enum_setup_from_info (cache
,
357 pygi_arg_cache_free (cache
);
363 pygi_arg_flags_setup_from_info (PyGIArgCache
*arg_cache
,
364 GITypeInfo
*type_info
,
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
;
380 pygi_arg_flags_new_from_info (GITypeInfo
*type_info
,
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
,
397 res
= pygi_arg_flags_setup_from_info (cache
,
405 pygi_arg_cache_free (cache
);