[pygobject] cache refactoring: Move enum and flags arg setup and marshaling to new file
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] cache refactoring: Move enum and flags arg setup and marshaling to new file
- Date: Mon, 3 Feb 2014 13:56:00 +0000 (UTC)
commit c2d5857e9b964427190e1230be32ae7919e86bc0
Author: Simon Feltman <sfeltman src gnome org>
Date: Sat Oct 12 21:26:55 2013 -0700
cache refactoring: Move enum and flags arg setup and marshaling to new file
Move enum and flags argument cache setup and marshaling fragments into
isolated file: pygi-enum-marshal.c. Remove pygi-marshal-from/to files.
https://bugzilla.gnome.org/show_bug.cgi?id=709700
gi/Makefile.am | 6 +-
gi/pygi-argument.c | 2 -
gi/pygi-cache.c | 74 ++-------
gi/pygi-enum-marshal.c | 408 +++++++++++++++++++++++++++++++++++++++++++++
gi/pygi-enum-marshal.h | 42 +++++
gi/pygi-marshal-from-py.c | 206 -----------------------
gi/pygi-marshal-from-py.h | 57 -------
gi/pygi-marshal-to-py.c | 152 -----------------
gi/pygi-marshal-to-py.h | 34 ----
9 files changed, 464 insertions(+), 517 deletions(-)
---
diff --git a/gi/Makefile.am b/gi/Makefile.am
index 9c34c03..2a2473d 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -97,10 +97,6 @@ _gi_la_SOURCES = \
pygi-invoke-state-struct.h \
pygi-cache.h \
pygi-cache.c \
- pygi-marshal-from-py.c \
- pygi-marshal-from-py.h \
- pygi-marshal-to-py.c \
- pygi-marshal-to-py.h \
pygi-marshal-cleanup.c \
pygi-marshal-cleanup.h \
pygi-basictype.c \
@@ -113,6 +109,8 @@ _gi_la_SOURCES = \
pygi-error.h \
pygi-object.c \
pygi-object.h \
+ pygi-enum-marshal.c \
+ pygi-enum-marshal.h \
pygi-struct-marshal.c \
pygi-struct-marshal.h \
pygi-hashtable.c \
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index f88ff62..5da8398 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -31,8 +31,6 @@
#include <pyglib-python-compat.h>
#include <pyglib.h>
-#include "pygi-marshal-from-py.h"
-#include "pygi-marshal-to-py.h"
#include "pygi-basictype.h"
#include "pygi-object.h"
#include "pygi-struct-marshal.h"
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index aab2534..012ebcb 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -24,8 +24,6 @@
#include "pygi-info.h"
#include "pygi-cache.h"
-#include "pygi-marshal-to-py.h"
-#include "pygi-marshal-from-py.h"
#include "pygi-marshal-cleanup.h"
#include "pygi-type.h"
#include "pygi-hashtable.h"
@@ -36,6 +34,7 @@
#include "pygi-error.h"
#include "pygi-object.h"
#include "pygi-struct-marshal.h"
+#include "pygi-enum-marshal.h"
/* _arg_info_default_value
@@ -252,35 +251,6 @@ _arg_cache_alloc (void)
return g_slice_new0 (PyGIArgCache);
}
-static void
-_arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache,
- GITransfer transfer)
-{
- arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
-}
-
-static void
-_arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache,
- GITransfer transfer)
-{
- arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
-}
-
-static void
-_arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache,
- GITransfer transfer)
-{
- arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
-}
-
-static void
-_arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache,
- GITransfer transfer)
-{
- arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
-}
-
-
static PyGIArgCache *
_arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
GITypeInfo *type_info,
@@ -289,21 +259,18 @@ _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
PyGIDirection direction,
PyGICallableCache *callable_cache)
{
- PyGIArgCache *arg_cache = NULL;
GIInfoType info_type;
info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);
switch (info_type) {
case GI_INFO_TYPE_CALLBACK:
- {
return pygi_arg_callback_new_from_info (type_info,
arg_info,
transfer,
direction,
iface_info,
callable_cache);
- }
case GI_INFO_TYPE_OBJECT:
case GI_INFO_TYPE_INTERFACE:
return pygi_arg_gobject_new_from_info (type_info,
@@ -319,40 +286,23 @@ _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
transfer,
direction,
iface_info);
- default:
- ; /* pass through to old model of setup */
- }
-
- arg_cache = pygi_arg_interface_new_from_info (type_info,
- arg_info,
- transfer,
- direction,
- iface_info);
- if (arg_cache == NULL)
- return NULL;
-
- switch (info_type) {
case GI_INFO_TYPE_ENUM:
- if (direction & PYGI_DIRECTION_FROM_PYTHON)
- _arg_cache_from_py_interface_enum_setup (arg_cache, transfer);
-
- if (direction & PYGI_DIRECTION_TO_PYTHON)
- _arg_cache_to_py_interface_enum_setup (arg_cache, transfer);
-
- break;
+ return pygi_arg_enum_new_from_info (type_info,
+ arg_info,
+ transfer,
+ direction,
+ iface_info);
case GI_INFO_TYPE_FLAGS:
- if (direction & PYGI_DIRECTION_FROM_PYTHON)
- _arg_cache_from_py_interface_flags_setup (arg_cache, transfer);
-
- if (direction & PYGI_DIRECTION_TO_PYTHON)
- _arg_cache_to_py_interface_flags_setup (arg_cache, transfer);
-
- break;
+ return pygi_arg_flags_new_from_info (type_info,
+ arg_info,
+ transfer,
+ direction,
+ iface_info);
default:
g_assert_not_reached ();
}
- return arg_cache;
+ return NULL;
}
PyGIArgCache *
diff --git a/gi/pygi-enum-marshal.c b/gi/pygi-enum-marshal.c
new file mode 100644
index 0000000..0a8e7e4
--- /dev/null
+++ b/gi/pygi-enum-marshal.c
@@ -0,0 +1,408 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>
+ * Copyright (C) 2014 Simon Feltman <sfeltman gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <Python.h>
+#include <pyglib-python-compat.h>
+
+#include "pygi-enum-marshal.h"
+#include "pygi-private.h"
+
+#ifdef _WIN32
+#ifdef _MSC_VER
+#include <math.h>
+
+#ifndef NAN
+static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
+#define NAN (*(const float *) __nan)
+#endif
+
+#ifndef INFINITY
+#define INFINITY HUGE_VAL
+#endif
+
+#endif
+#endif
+
+static gboolean
+gi_argument_from_c_long (GIArgument *arg_out,
+ long c_long_in,
+ GITypeTag type_tag)
+{
+ switch (type_tag) {
+ case GI_TYPE_TAG_INT8:
+ arg_out->v_int8 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_UINT8:
+ arg_out->v_uint8 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_INT16:
+ arg_out->v_int16 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_UINT16:
+ arg_out->v_uint16 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_INT32:
+ arg_out->v_int32 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_UINT32:
+ arg_out->v_uint32 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_INT64:
+ arg_out->v_int64 = c_long_in;
+ return TRUE;
+ case GI_TYPE_TAG_UINT64:
+ arg_out->v_uint64 = c_long_in;
+ return TRUE;
+ default:
+ PyErr_Format (PyExc_TypeError,
+ "Unable to marshal C long %ld to %s",
+ c_long_in,
+ g_type_tag_to_string (type_tag));
+ return FALSE;
+ }
+}
+
+static gboolean
+gi_argument_to_c_long (GIArgument *arg_in,
+ long *c_long_out,
+ GITypeTag type_tag)
+{
+ switch (type_tag) {
+ case GI_TYPE_TAG_INT8:
+ *c_long_out = arg_in->v_int8;
+ return TRUE;
+ case GI_TYPE_TAG_UINT8:
+ *c_long_out = arg_in->v_uint8;
+ return TRUE;
+ case GI_TYPE_TAG_INT16:
+ *c_long_out = arg_in->v_int16;
+ return TRUE;
+ case GI_TYPE_TAG_UINT16:
+ *c_long_out = arg_in->v_uint16;
+ return TRUE;
+ case GI_TYPE_TAG_INT32:
+ *c_long_out = arg_in->v_int32;
+ return TRUE;
+ case GI_TYPE_TAG_UINT32:
+ *c_long_out = arg_in->v_uint32;
+ return TRUE;
+ case GI_TYPE_TAG_INT64:
+ *c_long_out = arg_in->v_int64;
+ return TRUE;
+ case GI_TYPE_TAG_UINT64:
+ *c_long_out = arg_in->v_uint64;
+ return TRUE;
+ default:
+ PyErr_Format (PyExc_TypeError,
+ "Unable to marshal %s to C long",
+ g_type_tag_to_string (type_tag));
+ return FALSE;
+ }
+}
+
+static gboolean
+_pygi_marshal_from_py_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg,
+ gpointer *cleanup_data)
+{
+ PyObject *py_long;
+ long c_long;
+ gint is_instance;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ GIBaseInfo *interface = NULL;
+
+ is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (py_long == NULL) {
+ PyErr_Clear();
+ goto err;
+ }
+
+ c_long = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ /* Write c_long into arg */
+ interface = g_type_info_get_interface (arg_cache->type_info);
+ assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
+ if (!gi_argument_from_c_long(arg,
+ c_long,
+ g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+ g_assert_not_reached();
+ g_base_info_unref (interface);
+ return FALSE;
+ }
+
+ /* If this is not an instance of the Enum type that we want
+ * we need to check if the value is equivilant to one of the
+ * Enum's memebers */
+ if (!is_instance) {
+ int i;
+ gboolean is_found = FALSE;
+
+ for (i = 0; i < g_enum_info_get_n_values (iface_cache->interface_info); i++) {
+ GIValueInfo *value_info =
+ g_enum_info_get_value (iface_cache->interface_info, i);
+ glong enum_value = g_value_info_get_value (value_info);
+ g_base_info_unref ( (GIBaseInfo *)value_info);
+ if (c_long == enum_value) {
+ is_found = TRUE;
+ break;
+ }
+ }
+
+ if (!is_found)
+ goto err;
+ }
+
+ g_base_info_unref (interface);
+ return TRUE;
+
+err:
+ if (interface)
+ g_base_info_unref (interface);
+ PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
+ iface_cache->type_name, py_arg->ob_type->tp_name);
+ return FALSE;
+}
+
+static gboolean
+_pygi_marshal_from_py_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg,
+ gpointer *cleanup_data)
+{
+ PyObject *py_long;
+ long c_long;
+ gint is_instance;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ GIBaseInfo *interface;
+
+ is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (py_long == NULL) {
+ PyErr_Clear ();
+ goto err;
+ }
+
+ c_long = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ /* only 0 or argument of type Flag is allowed */
+ if (!is_instance && c_long != 0)
+ goto err;
+
+ /* Write c_long into arg */
+ interface = g_type_info_get_interface (arg_cache->type_info);
+ g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
+ if (!gi_argument_from_c_long(arg, c_long,
+ g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+ g_base_info_unref (interface);
+ return FALSE;
+ }
+
+ g_base_info_unref (interface);
+ return TRUE;
+
+err:
+ PyErr_Format (PyExc_TypeError, "Expected a %s, but got %s",
+ iface_cache->type_name, py_arg->ob_type->tp_name);
+ return FALSE;
+
+}
+
+static PyObject *
+_pygi_marshal_to_py_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ GIBaseInfo *interface;
+ long c_long;
+
+ interface = g_type_info_get_interface (arg_cache->type_info);
+ g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
+
+ if (!gi_argument_to_c_long(arg, &c_long,
+ g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+ return NULL;
+ }
+
+ if (iface_cache->g_type == G_TYPE_NONE) {
+ py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
+ } else {
+ py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
+ }
+ g_base_info_unref (interface);
+ return py_obj;
+}
+
+static PyObject *
+_pygi_marshal_to_py_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ GIBaseInfo *interface;
+ long c_long;
+
+ interface = g_type_info_get_interface (arg_cache->type_info);
+ g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
+
+ if (!gi_argument_to_c_long(arg, &c_long,
+ g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+ g_base_info_unref (interface);
+ return NULL;
+ }
+
+ g_base_info_unref (interface);
+ if (iface_cache->g_type == G_TYPE_NONE) {
+ /* An enum with a GType of None is an enum without GType */
+
+ PyObject *py_type = _pygi_type_import_by_gi_info (iface_cache->interface_info);
+ PyObject *py_args = NULL;
+
+ if (!py_type)
+ return NULL;
+
+ py_args = PyTuple_New (1);
+ if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
+ Py_DECREF (py_args);
+ Py_DECREF (py_type);
+ return NULL;
+ }
+
+ py_obj = PyObject_CallFunction (py_type, "l", c_long);
+
+ Py_DECREF (py_args);
+ Py_DECREF (py_type);
+ } else {
+ py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
+ }
+
+ return py_obj;
+}
+
+static gboolean
+pygi_arg_enum_setup_from_info (PyGIArgCache *arg_cache,
+ GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction)
+{
+ if (direction & PYGI_DIRECTION_FROM_PYTHON)
+ arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
+
+ if (direction & PYGI_DIRECTION_TO_PYTHON)
+ arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
+
+ return TRUE;
+}
+
+
+PyGIArgCache *
+pygi_arg_enum_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction,
+ GIInterfaceInfo *iface_info)
+{
+ gboolean res = FALSE;
+ PyGIArgCache *cache = NULL;
+
+ cache = pygi_arg_interface_new_from_info (type_info,
+ arg_info,
+ transfer,
+ direction,
+ iface_info);
+ if (cache == NULL)
+ return NULL;
+
+ res = pygi_arg_enum_setup_from_info (cache,
+ type_info,
+ arg_info,
+ transfer,
+ direction);
+ if (res) {
+ return cache;
+ } else {
+ _pygi_arg_cache_free (cache);
+ return NULL;
+ }
+}
+
+static gboolean
+pygi_arg_flags_setup_from_info (PyGIArgCache *arg_cache,
+ GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction)
+{
+ if (direction & PYGI_DIRECTION_FROM_PYTHON)
+ arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
+
+ if (direction & PYGI_DIRECTION_TO_PYTHON)
+ arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
+
+ return TRUE;
+}
+
+
+PyGIArgCache *
+pygi_arg_flags_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info,
+ GITransfer transfer,
+ PyGIDirection direction,
+ GIInterfaceInfo *iface_info)
+{
+ gboolean res = FALSE;
+ PyGIArgCache *cache = NULL;
+
+ cache = pygi_arg_interface_new_from_info (type_info,
+ arg_info,
+ transfer,
+ direction,
+ iface_info);
+ if (cache == NULL)
+ return NULL;
+
+ res = pygi_arg_flags_setup_from_info (cache,
+ type_info,
+ arg_info,
+ transfer,
+ direction);
+ if (res) {
+ return cache;
+ } else {
+ _pygi_arg_cache_free (cache);
+ return NULL;
+ }
+}
diff --git a/gi/pygi-enum-marshal.h b/gi/pygi-enum-marshal.h
new file mode 100644
index 0000000..2fdcbc4
--- /dev/null
+++ b/gi/pygi-enum-marshal.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2014 Simon Feltman <sfeltman gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PYGI_ENUM_MARSHAL_H__
+#define __PYGI_ENUM_MARSHAL_H__
+
+#include <girepository.h>
+#include "pygi-cache.h"
+
+G_BEGIN_DECLS
+
+PyGIArgCache *pygi_arg_enum_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info, /* may be null */
+ GITransfer transfer,
+ PyGIDirection direction,
+ GIInterfaceInfo *iface_info);
+
+PyGIArgCache *pygi_arg_flags_new_from_info (GITypeInfo *type_info,
+ GIArgInfo *arg_info, /* may be null */
+ GITransfer transfer,
+ PyGIDirection direction,
+ GIInterfaceInfo *iface_info);
+
+G_END_DECLS
+
+#endif /*__PYGI_ENUM_MARSHAL_H__*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]