[pygobject/invoke-rewrite] split the marshalling routines into two source files
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] split the marshalling routines into two source files
- Date: Mon, 18 Jul 2011 14:36:33 +0000 (UTC)
commit bab7e88251bffcd360186c6dedc26be8eb077084
Author: John (J5) Palmieri <johnp redhat com>
Date: Mon Jul 18 10:35:10 2011 -0400
split the marshalling routines into two source files
* update copy and paste copyright info to list the correct owner
gi/Makefile.am | 6 +-
gi/pygi-cache.c | 3 +-
gi/pygi-marshal-in.c | 1412 ++++++++++++++++++++++++++++++++
gi/pygi-marshal-in.h | 186 +++++
gi/pygi-marshal-out.c | 767 ++++++++++++++++++
gi/pygi-marshal-out.h | 144 ++++
gi/pygi-marshal.c | 2145 -------------------------------------------------
gi/pygi-marshal.h | 303 -------
8 files changed, 2515 insertions(+), 2451 deletions(-)
---
diff --git a/gi/Makefile.am b/gi/Makefile.am
index 500828d..fe1e114 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -63,8 +63,10 @@ _gi_la_SOURCES += \
pygi-invoke-state-struct.h \
pygi-cache.h \
pygi-cache.c \
- pygi-marshal.c \
- pygi-marshal.h \
+ pygi-marshal-in.c \
+ pygi-marshal-in.h \
+ pygi-marshal-out.c \
+ pygi-marshal-out.h \
pygi-marshal-cleanup.c \
pygi-marshal-cleanup.h
else
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index ac1e39e..aed59e0 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -21,7 +21,8 @@
#include "pygi-info.h"
#include "pygi-cache.h"
-#include "pygi-marshal.h"
+#include "pygi-marshal-in.h"
+#include "pygi-marshal-out.h"
#include "pygi-marshal-cleanup.h"
#include "pygi-type.h"
#include <girepository.h>
diff --git a/gi/pygi-marshal-in.c b/gi/pygi-marshal-in.c
new file mode 100644
index 0000000..9ae7def
--- /dev/null
+++ b/gi/pygi-marshal-in.c
@@ -0,0 +1,1412 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>, Red Hat, Inc.
+ *
+ * pygi-marshal-in.c: PyObject conversion functions for in parameters.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <string.h>
+#include <time.h>
+
+#include <datetime.h>
+#include <pygobject.h>
+#include <pyglib-python-compat.h>
+
+#include "pygi-cache.h"
+#include "pygi-marshal-cleanup.h"
+#include "pygi-marshal-in.h"
+
+gboolean
+_pygi_marshal_in_void (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING);
+
+ arg->v_pointer = py_arg;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_boolean (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ arg->v_boolean = PyObject_IsTrue (py_arg);
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_int8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+ long_ = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
+ return FALSE;
+ }
+
+ if (long_ < -128 || long_ > 127) {
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -128, 127);
+ return FALSE;
+ }
+
+ arg->v_long = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_uint8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ unsigned long long_;
+
+ if (PYGLIB_PyBytes_Check (py_arg)) {
+
+ if (PYGLIB_PyBytes_Size (py_arg) != 1) {
+ PyErr_Format (PyExc_TypeError, "Must be a single character");
+ return FALSE;
+ }
+
+ long_ = (unsigned char)(PYGLIB_PyBytes_AsString (py_arg)[0]);
+
+ } else if (PyNumber_Check (py_arg)) {
+ PyObject *py_long;
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+ long_ = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear();
+
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, 0, 255);
+ return FALSE;
+ }
+ } else {
+ PyErr_Format (PyExc_TypeError, "Must be number or single byte string, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ if (long_ < 0 || long_ > 255) {
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, 0, 255);
+ return FALSE;
+ }
+
+ arg->v_long = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_int16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+ long_ = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -32768, 32767);
+ return FALSE;
+ }
+
+ if (long_ < -32768 || long_ > 32767) {
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, -32768, 32767);
+ return FALSE;
+ }
+
+ arg->v_long = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_uint16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+ long_ = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%li not in range %d to %d", long_, 0, 65535);
+ return FALSE;
+ }
+
+ if (long_ < 0 || long_ > 65535) {
+ PyErr_Format (PyExc_ValueError, "%li not in range %d to %d", long_, 0, 65535);
+ return FALSE;
+ }
+
+ arg->v_long = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_int32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+ long_ = PYGLIB_PyLong_AsLong (py_long);
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear();
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, G_MININT32, G_MAXINT32);
+ return FALSE;
+ }
+
+ if (long_ < G_MININT32 || long_ > G_MAXINT32) {
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %d", long_, G_MININT32, G_MAXINT32);
+ return FALSE;
+ }
+
+ arg->v_long = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_uint32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check (py_long))
+ long_ = PyInt_AsLong (py_long);
+ else
+#endif
+ long_ = PyLong_AsLongLong (py_long);
+
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%lli not in range %i to %u", long_, 0, G_MAXUINT32);
+ return FALSE;
+ }
+
+ if (long_ < 0 || long_ > G_MAXUINT32) {
+ PyErr_Format (PyExc_ValueError, "%lli not in range %i to %u", long_, 0, G_MAXUINT32);
+ return FALSE;
+ }
+
+ arg->v_uint64 = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_int64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ long long long_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check (py_long))
+ long_ = PyInt_AS_LONG (py_long);
+ else
+#endif
+ long_ = PyLong_AsLongLong (py_long);
+
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ /* OverflowError occured but range errors should be returned as ValueError */
+ char *long_str;
+ PyObject *py_str;
+
+ PyErr_Clear ();
+
+ py_str = PyObject_Str (py_long);
+
+ if (PyUnicode_Check (py_str)) {
+ PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
+ if (py_bytes == NULL)
+ return FALSE;
+
+ long_str = g_strdup (PYGLIB_PyBytes_AsString (py_bytes));
+ if (long_str == NULL) {
+ PyErr_NoMemory ();
+ return FALSE;
+ }
+
+ Py_DECREF (py_bytes);
+ } else {
+ long_str = g_strdup (PYGLIB_PyBytes_AsString(py_str));
+ }
+
+ Py_DECREF (py_str);
+ PyErr_Format (PyExc_ValueError, "%s not in range %ld to %ld",
+ long_str, G_MININT64, G_MAXINT64);
+
+ g_free (long_str);
+ return FALSE;
+ }
+
+ if (long_ < G_MININT64 || long_ > G_MAXINT64) {
+ PyErr_Format (PyExc_ValueError, "%lld not in range %ld to %ld", long_, G_MININT64, G_MAXINT64);
+ return FALSE;
+ }
+
+ arg->v_int64 = long_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_uint64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_long;
+ guint64 ulong_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_long = PYGLIB_PyNumber_Long (py_arg);
+ if (!py_long)
+ return FALSE;
+
+#if PY_VERSION_HEX < 0x03000000
+ if (PyInt_Check (py_long)) {
+ long long_ = PyInt_AsLong (py_long);
+ if (long_ < 0) {
+ PyErr_Format (PyExc_ValueError, "%ld not in range %d to %llu",
+ long_, 0, G_MAXUINT64);
+ return FALSE;
+ }
+ ulong_ = long_;
+ } else
+#endif
+ ulong_ = PyLong_AsUnsignedLongLong (py_long);
+
+ Py_DECREF (py_long);
+
+ if (PyErr_Occurred ()) {
+ /* OverflowError occured but range errors should be returned as ValueError */
+ char *long_str;
+ PyObject *py_str;
+
+ PyErr_Clear ();
+
+ py_str = PyObject_Str (py_long);
+
+ if (PyUnicode_Check (py_str)) {
+ PyObject *py_bytes = PyUnicode_AsUTF8String (py_str);
+ if (py_bytes == NULL)
+ return FALSE;
+
+ long_str = g_strdup (PYGLIB_PyBytes_AsString (py_bytes));
+ if (long_str == NULL) {
+ PyErr_NoMemory ();
+ return FALSE;
+ }
+
+ Py_DECREF (py_bytes);
+ } else {
+ long_str = g_strdup (PYGLIB_PyBytes_AsString (py_str));
+ }
+
+ Py_DECREF (py_str);
+
+ PyErr_Format (PyExc_ValueError, "%s not in range %d to %llu",
+ long_str, 0, G_MAXUINT64);
+
+ g_free (long_str);
+ return FALSE;
+ }
+
+ if (ulong_ > G_MAXUINT64) {
+ PyErr_Format (PyExc_ValueError, "%llu not in range %d to %llu", ulong_, 0, G_MAXUINT64);
+ return FALSE;
+ }
+
+ arg->v_uint64 = ulong_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_float (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_float;
+ double double_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_float = PyNumber_Float (py_arg);
+ if (!py_float)
+ return FALSE;
+
+ double_ = PyFloat_AsDouble (py_float);
+ Py_DECREF (py_float);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
+ return FALSE;
+ }
+
+ if (double_ < -G_MAXFLOAT || double_ > G_MAXFLOAT) {
+ PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
+ return FALSE;
+ }
+
+ arg->v_float = double_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_double (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *py_float;
+ double double_;
+
+ if (!PyNumber_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be number, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ py_float = PyNumber_Float (py_arg);
+ if (!py_float)
+ return FALSE;
+
+ double_ = PyFloat_AsDouble (py_float);
+ Py_DECREF (py_float);
+
+ if (PyErr_Occurred ()) {
+ PyErr_Clear ();
+ PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
+ return FALSE;
+ }
+
+ if (double_ < -G_MAXDOUBLE || double_ > G_MAXDOUBLE) {
+ PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
+ return FALSE;
+ }
+
+ arg->v_double = double_;
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_unichar (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ Py_ssize_t size;
+ gchar *string_;
+
+ if (PyUnicode_Check (py_arg)) {
+ PyObject *py_bytes;
+
+ size = PyUnicode_GET_SIZE (py_arg);
+ py_bytes = PyUnicode_AsUTF8String (py_arg);
+ string_ = strdup(PYGLIB_PyBytes_AsString (py_bytes));
+ Py_DECREF (py_bytes);
+
+#if PY_VERSION_HEX < 0x03000000
+ } else if (PyString_Check (py_arg)) {
+ PyObject *pyuni = PyUnicode_FromEncodedObject (py_arg, "UTF-8", "strict");
+ if (!pyuni)
+ return FALSE;
+
+ size = PyUnicode_GET_SIZE (pyuni);
+ string_ = g_strdup (PyString_AsString(py_arg));
+ Py_DECREF (pyuni);
+#endif
+ } else {
+ PyErr_Format (PyExc_TypeError, "Must be string, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ if (size != 1) {
+ PyErr_Format (PyExc_TypeError, "Must be a one character string, not %ld characters",
+ size);
+ g_free (string_);
+ return FALSE;
+ }
+
+ arg->v_uint32 = g_utf8_get_char (string_);
+ g_free (string_);
+
+ return TRUE;
+}
+gboolean
+_pygi_marshal_in_gtype (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ long type_ = pyg_type_from_object (py_arg);
+
+ if (type_ == 0) {
+ PyErr_Format (PyExc_TypeError, "Must be gobject.GType, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ arg->v_long = type_;
+ return TRUE;
+}
+gboolean
+_pygi_marshal_in_utf8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ gchar *string_;
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (PyUnicode_Check (py_arg)) {
+ PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
+ if (!pystr_obj)
+ return FALSE;
+
+ string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
+ Py_DECREF (pystr_obj);
+ }
+#if PY_VERSION_HEX < 0x03000000
+ else if (PyString_Check (py_arg)) {
+ string_ = g_strdup (PyString_AsString (py_arg));
+ }
+#endif
+ else {
+ PyErr_Format (PyExc_TypeError, "Must be string, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ arg->v_string = string_;
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_filename (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ gchar *string_;
+ GError *error = NULL;
+
+ if (PyUnicode_Check (py_arg)) {
+ PyObject *pystr_obj = PyUnicode_AsUTF8String (py_arg);
+ if (!pystr_obj)
+ return FALSE;
+
+ string_ = g_strdup (PYGLIB_PyBytes_AsString (pystr_obj));
+ Py_DECREF (pystr_obj);
+ }
+#if PY_VERSION_HEX < 0x03000000
+ else if (PyString_Check (py_arg)) {
+ string_ = g_strdup (PyString_AsString (py_arg));
+ }
+#endif
+ else {
+ PyErr_Format (PyExc_TypeError, "Must be string, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ arg->v_string = g_filename_from_utf8 (string_, -1, NULL, NULL, &error);
+ g_free (string_);
+
+ if (arg->v_string == NULL) {
+ PyErr_SetString (PyExc_Exception, error->message);
+ g_error_free (error);
+ /* TODO: Convert the error to an exception. */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_array (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyGIMarshalInFunc in_marshaller;
+ int i;
+ Py_ssize_t length;
+ gboolean is_ptr_array;
+ GArray *array_ = NULL;
+ PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
+
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (!PySequence_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PySequence_Length (py_arg);
+ if (length < 0)
+ return FALSE;
+
+ if (sequence_cache->fixed_size >= 0 &&
+ sequence_cache->fixed_size != length) {
+ PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
+ sequence_cache->fixed_size, length);
+
+ return FALSE;
+ }
+
+ is_ptr_array = (sequence_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY);
+ if (is_ptr_array) {
+ array_ = (GArray *)g_ptr_array_new ();
+ } else {
+ array_ = g_array_sized_new (sequence_cache->is_zero_terminated,
+ FALSE,
+ sequence_cache->item_size,
+ length);
+ }
+
+ if (array_ == NULL) {
+ PyErr_NoMemory ();
+ return FALSE;
+ }
+
+ if (sequence_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8 &&
+ PYGLIB_PyBytes_Check (py_arg)) {
+ memcpy(array_->data, PYGLIB_PyBytes_AsString (py_arg), length);
+
+ goto array_success;
+ }
+
+ in_marshaller = sequence_cache->item_cache->in_marshaller;
+ for (i = 0; i < length; i++) {
+ GIArgument item;
+ PyObject *py_item = PySequence_GetItem (py_arg, i);
+ if (py_item == NULL)
+ goto err;
+
+ if (!in_marshaller ( state,
+ callable_cache,
+ sequence_cache->item_cache,
+ py_item,
+ &item))
+ goto err;
+
+ /* FIXME: it is much more efficent to have seperate marshaller
+ * for ptr arrays than doing the evaluation
+ * and casting each loop iteration
+ */
+ if (is_ptr_array)
+ g_ptr_array_add((GPtrArray *)array_, item.v_pointer);
+ else
+ g_array_insert_val (array_, i, item);
+ continue;
+err:
+ if (sequence_cache->item_cache->in_cleanup != NULL) {
+ gsize j;
+ PyGIMarshalCleanupFunc cleanup_func =
+ sequence_cache->item_cache->in_cleanup;
+
+ for(j = 0; j < i; j++) {
+ cleanup_func (state,
+ sequence_cache->item_cache,
+ g_array_index (array_, gpointer, j),
+ TRUE);
+ }
+ }
+
+ if (is_ptr_array)
+ g_ptr_array_free (array_, TRUE);
+ else
+ g_array_free (array_, TRUE);
+ _PyGI_ERROR_PREFIX ("Item %i: ", i);
+ return FALSE;
+ }
+
+array_success:
+ if (sequence_cache->len_arg_index >= 0) {
+ /* we have an child arg to handle */
+ PyGIArgCache *child_cache =
+ callable_cache->args_cache[sequence_cache->len_arg_index];
+
+ if (child_cache->direction == GI_DIRECTION_INOUT) {
+ gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer;
+ /* if we are not setup yet just set the in arg */
+ if (len_arg == NULL)
+ state->in_args[child_cache->c_arg_index].v_long = length;
+ else
+ *len_arg = length;
+ } else {
+ state->in_args[child_cache->c_arg_index].v_long = length;
+ }
+ }
+
+ if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
+ arg->v_pointer = array_->data;
+ g_array_free (array_, FALSE);
+ } else {
+ arg->v_pointer = array_;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_glist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyGIMarshalInFunc in_marshaller;
+ int i;
+ Py_ssize_t length;
+ GList *list_ = NULL;
+ PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
+
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (!PySequence_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PySequence_Length (py_arg);
+ if (length < 0)
+ return FALSE;
+
+ if (sequence_cache->fixed_size >= 0 &&
+ sequence_cache->fixed_size != length) {
+ PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
+ sequence_cache->fixed_size, length);
+
+ return FALSE;
+ }
+
+ in_marshaller = sequence_cache->item_cache->in_marshaller;
+ for (i = 0; i < length; i++) {
+ GIArgument item;
+ PyObject *py_item = PySequence_GetItem (py_arg, i);
+ if (py_item == NULL)
+ goto err;
+
+ if (!in_marshaller ( state,
+ callable_cache,
+ sequence_cache->item_cache,
+ py_item,
+ &item))
+ goto err;
+
+ list_ = g_list_append (list_, item.v_pointer);
+ continue;
+err:
+ if (sequence_cache->item_cache->in_cleanup != NULL) {
+ GDestroyNotify cleanup = sequence_cache->item_cache->in_cleanup;
+ }
+
+ g_list_free (list_);
+ _PyGI_ERROR_PREFIX ("Item %i: ", i);
+ return FALSE;
+ }
+
+ arg->v_pointer = list_;
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_gslist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyGIMarshalInFunc in_marshaller;
+ int i;
+ Py_ssize_t length;
+ GSList *list_ = NULL;
+ PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (!PySequence_Check (py_arg)) {
+ PyErr_Format (PyExc_TypeError, "Must be sequence, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PySequence_Length (py_arg);
+ if (length < 0)
+ return FALSE;
+
+ if (sequence_cache->fixed_size >= 0 &&
+ sequence_cache->fixed_size != length) {
+ PyErr_Format (PyExc_ValueError, "Must contain %zd items, not %zd",
+ sequence_cache->fixed_size, length);
+
+ return FALSE;
+ }
+
+ in_marshaller = sequence_cache->item_cache->in_marshaller;
+ for (i = 0; i < length; i++) {
+ GIArgument item;
+ PyObject *py_item = PySequence_GetItem (py_arg, i);
+ if (py_item == NULL)
+ goto err;
+
+ if (!in_marshaller ( state,
+ callable_cache,
+ sequence_cache->item_cache,
+ py_item,
+ &item))
+ goto err;
+
+ list_ = g_slist_append (list_, item.v_pointer);
+ continue;
+err:
+ if (sequence_cache->item_cache->in_cleanup != NULL) {
+ GDestroyNotify cleanup = sequence_cache->item_cache->in_cleanup;
+ }
+
+ g_slist_free (list_);
+ _PyGI_ERROR_PREFIX ("Item %i: ", i);
+ return FALSE;
+ }
+
+ arg->v_pointer = list_;
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyGIMarshalInFunc key_in_marshaller;
+ PyGIMarshalInFunc value_in_marshaller;
+
+ int i;
+ Py_ssize_t length;
+ PyObject *py_keys, *py_values;
+
+ GHashFunc hash_func;
+ GEqualFunc equal_func;
+
+ GHashTable *hash_ = NULL;
+ PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ py_keys = PyMapping_Keys (py_arg);
+ if (py_keys == NULL) {
+ PyErr_Format (PyExc_TypeError, "Must be mapping, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ length = PyMapping_Length (py_arg);
+ if (length < 0) {
+ Py_DECREF (py_keys);
+ return FALSE;
+ }
+
+ py_values = PyMapping_Values (py_arg);
+ if (py_values == NULL) {
+ Py_DECREF (py_keys);
+ return FALSE;
+ }
+
+ key_in_marshaller = hash_cache->key_cache->in_marshaller;
+ value_in_marshaller = hash_cache->value_cache->in_marshaller;
+
+ switch (hash_cache->key_cache->type_tag) {
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ hash_func = g_str_hash;
+ equal_func = g_str_equal;
+ break;
+ default:
+ hash_func = NULL;
+ equal_func = NULL;
+ }
+
+ hash_ = g_hash_table_new (hash_func, equal_func);
+ if (hash_ == NULL) {
+ PyErr_NoMemory ();
+ Py_DECREF (py_keys);
+ Py_DECREF (py_values);
+ return FALSE;
+ }
+
+ for (i = 0; i < length; i++) {
+ GIArgument key, value;
+ PyObject *py_key = PyList_GET_ITEM (py_keys, i);
+ PyObject *py_value = PyList_GET_ITEM (py_values, i);
+ if (py_key == NULL || py_value == NULL)
+ goto err;
+
+ if (!key_in_marshaller ( state,
+ callable_cache,
+ hash_cache->key_cache,
+ py_key,
+ &key))
+ goto err;
+
+ if (!value_in_marshaller ( state,
+ callable_cache,
+ hash_cache->value_cache,
+ py_value,
+ &value))
+ goto err;
+
+ g_hash_table_insert (hash_, key.v_pointer, value.v_pointer);
+ continue;
+err:
+ /* FIXME: cleanup hash keys and values */
+ Py_XDECREF (py_key);
+ Py_XDECREF (py_value);
+ Py_DECREF (py_keys);
+ Py_DECREF (py_values);
+ g_hash_table_unref (hash_);
+ _PyGI_ERROR_PREFIX ("Item %i: ", i);
+ return FALSE;
+ }
+
+ arg->v_pointer = hash_;
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_gerror (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for GErrors is not implemented");
+ return FALSE;
+}
+
+gboolean
+_pygi_marshal_in_interface_callback (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ GICallableInfo *callable_info;
+ PyGICClosure *closure;
+ PyGIArgCache *user_data_cache = NULL;
+ PyGIArgCache *destroy_cache = NULL;
+ PyGICallbackCache *callback_cache;
+ PyObject *py_user_data = NULL;
+
+ callback_cache = (PyGICallbackCache *)arg_cache;
+
+ if (callback_cache->user_data_index > 0) {
+ user_data_cache = callable_cache->args_cache[callback_cache->user_data_index];
+ if (user_data_cache->py_arg_index < state->n_py_in_args) {
+ py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
+ if (!py_user_data)
+ return FALSE;
+ } else {
+ py_user_data = Py_None;
+ Py_INCREF (Py_None);
+ }
+ }
+
+ if (py_arg == Py_None && !(py_user_data == Py_None || py_user_data == NULL)) {
+ Py_DECREF (py_user_data);
+ PyErr_Format (PyExc_TypeError,
+ "When passing None for a callback userdata must also be None");
+
+ return FALSE;
+ }
+
+ if (py_arg == Py_None) {
+ Py_XDECREF (py_user_data);
+ return TRUE;
+ }
+
+ if (!PyCallable_Check (py_arg)) {
+ Py_XDECREF (py_user_data);
+ PyErr_Format (PyExc_TypeError,
+ "Callback needs to be a function or method not %s",
+ py_arg->ob_type->tp_name);
+
+ return FALSE;
+ }
+
+ if (callback_cache->destroy_notify_index > 0)
+ destroy_cache = callable_cache->args_cache[callback_cache->destroy_notify_index];
+
+ callable_info = (GICallableInfo *)callback_cache->interface_info;
+
+ closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data);
+ arg->v_pointer = closure->closure;
+ if (user_data_cache != NULL) {
+ state->in_args[user_data_cache->c_arg_index].v_pointer = closure;
+ }
+
+ if (destroy_cache) {
+ PyGICClosure *destroy_notify = _pygi_destroy_notify_create ();
+ state->in_args[destroy_cache->c_arg_index].v_pointer = destroy_notify->closure;
+ }
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *int_;
+ gint is_instance;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+
+ int_ = PYGLIB_PyNumber_Long (py_arg);
+ if (int_ == NULL) {
+ PyErr_Clear();
+ goto err;
+ }
+
+ arg->v_long = PYGLIB_PyLong_AsLong (int_);
+ Py_DECREF (int_);
+
+ /* 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 (arg->v_long == enum_value) {
+ is_found = TRUE;
+ break;
+ }
+ }
+
+ if (!is_found)
+ goto err;
+ }
+
+ 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;
+}
+
+gboolean
+_pygi_marshal_in_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyObject *int_;
+ gint is_instance;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
+
+ int_ = PYGLIB_PyNumber_Long (py_arg);
+ if (int_ == NULL) {
+ PyErr_Clear ();
+ goto err;
+ }
+
+ arg->v_long = PYGLIB_PyLong_AsLong (int_);
+ Py_DECREF (int_);
+
+ /* only 0 or argument of type Flag is allowed */
+ if (!is_instance && arg->v_long != 0)
+ goto err;
+
+ 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;
+
+}
+
+gboolean
+_pygi_marshal_in_interface_struct (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ /* FIXME: handle this large if statement in the cache
+ * and set the correct marshaller
+ */
+
+ if (iface_cache->g_type == G_TYPE_CLOSURE) {
+ GClosure *closure;
+ GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
+
+ if ( !(PyCallable_Check(py_arg) ||
+ g_type_is_a (object_gtype, G_TYPE_CLOSURE))) {
+ PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
+ py_arg->ob_type->tp_name);
+ return FALSE;
+ }
+
+ if (g_type_is_a (object_gtype, G_TYPE_CLOSURE))
+ closure = (GClosure *)pyg_boxed_get (py_arg, void);
+ else
+ closure = pyg_closure_new (py_arg, NULL, NULL);
+
+ if (closure == NULL) {
+ PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
+ return FALSE;
+ }
+
+ arg->v_pointer = closure;
+ return TRUE;
+ } else if (iface_cache->g_type == G_TYPE_VALUE) {
+ GValue *value;
+ GType object_type;
+
+ object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
+ if (object_type == G_TYPE_INVALID) {
+ PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
+ return FALSE;
+ }
+
+ /* if already a gvalue, use that, else marshal into gvalue */
+ if (object_type == G_TYPE_VALUE) {
+ value = (GValue *)( (PyGObject *)py_arg)->obj;
+ } else {
+ value = g_slice_new0 (GValue);
+ g_value_init (value, object_type);
+ if (pyg_value_from_pyobject (value, py_arg) < 0) {
+ g_slice_free (GValue, value);
+ PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
+ return FALSE;
+ }
+ }
+
+ arg->v_pointer = value;
+ return TRUE;
+ } else if (iface_cache->is_foreign) {
+ gboolean success;
+ success = pygi_struct_foreign_convert_to_g_argument (py_arg,
+ iface_cache->interface_info,
+ arg_cache->transfer,
+ arg);
+
+ return success;
+ } else if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
+ PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
+ iface_cache->type_name,
+ iface_cache->py_type->ob_type->tp_name);
+ return FALSE;
+ }
+
+ if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
+ arg->v_pointer = pyg_boxed_get (py_arg, void);
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+ arg->v_pointer = g_boxed_copy (iface_cache->g_type, arg->v_pointer);
+ }
+ } else if (g_type_is_a (iface_cache->g_type, G_TYPE_POINTER) ||
+ g_type_is_a (iface_cache->g_type, G_TYPE_VARIANT) ||
+ iface_cache->g_type == G_TYPE_NONE) {
+ arg->v_pointer = pyg_pointer_get (py_arg, void);
+ } else {
+ PyErr_Format (PyExc_NotImplementedError,
+ "structure type '%s' is not supported yet",
+ g_type_name(iface_cache->g_type));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_interface_boxed (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for this type is not implemented yet");
+ return FALSE;
+}
+
+gboolean
+_pygi_marshal_in_interface_object (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ if (!PyObject_IsInstance (py_arg, ( (PyGIInterfaceCache *)arg_cache)->py_type)) {
+ PyErr_Format (PyExc_TypeError, "Expected %s, but got %s",
+ ( (PyGIInterfaceCache *)arg_cache)->type_name,
+ ( (PyGIInterfaceCache *)arg_cache)->py_type->ob_type->tp_name);
+ return FALSE;
+ }
+
+ arg->v_pointer = pygobject_get(py_arg);
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+ g_object_ref (arg->v_pointer);
+
+ return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_interface_union (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ PyErr_Format(PyExc_NotImplementedError,
+ "Marshalling for this type is not implemented yet");
+ return FALSE;
+}
+
+gboolean _pygi_marshal_in_interface_instance (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg)
+{
+ GIInfoType info_type;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ /* FIXME: add instance checks */
+
+ info_type = g_base_info_get_type (iface_cache->interface_info);
+ switch (info_type) {
+ case GI_INFO_TYPE_UNION:
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type = iface_cache->g_type;
+ if (g_type_is_a (type, G_TYPE_BOXED)) {
+ arg->v_pointer = pyg_boxed_get (py_arg, void);
+ } else if (g_type_is_a (type, G_TYPE_POINTER) ||
+ g_type_is_a (type, G_TYPE_VARIANT) ||
+ type == G_TYPE_NONE) {
+ arg->v_pointer = pyg_pointer_get (py_arg, void);
+ } else {
+ PyErr_Format (PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name (type));
+ return FALSE;
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_INTERFACE:
+ arg->v_pointer = pygobject_get (py_arg);
+ break;
+ default:
+ /* Other types don't have methods. */
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
diff --git a/gi/pygi-marshal-in.h b/gi/pygi-marshal-in.h
new file mode 100644
index 0000000..7d948bc
--- /dev/null
+++ b/gi/pygi-marshal-in.h
@@ -0,0 +1,186 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>, Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_MARSHAL_H__
+#define __PYGI_MARSHAL_H__
+
+#include <Python.h>
+
+#include <girepository.h>
+
+#include "pygi-private.h"
+
+G_BEGIN_DECLS
+
+gboolean _pygi_marshal_in_void (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_boolean (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_int8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_uint8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_int16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_uint16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_int32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_uint32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_int64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_uint64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_float (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_double (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_unichar (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_gtype (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_utf8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_filename (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_array (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_glist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_gslist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_gerror (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_callback (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_struct (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_interface(PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_boxed (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_object (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_union (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+gboolean _pygi_marshal_in_interface_instance (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ PyObject *py_arg,
+ GIArgument *arg);
+
+G_END_DECLS
+
+#endif /* __PYGI_MARSHAL_H__ */
diff --git a/gi/pygi-marshal-out.c b/gi/pygi-marshal-out.c
new file mode 100644
index 0000000..f99ee25
--- /dev/null
+++ b/gi/pygi-marshal-out.c
@@ -0,0 +1,767 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>, Red Hat, Inc.
+ *
+ * pygi-marshal-out.c: PyObject conversion functions for out parameters.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <string.h>
+#include <time.h>
+
+#include <datetime.h>
+#include <pygobject.h>
+#include <pyglib-python-compat.h>
+
+#include "pygi-cache.h"
+#include "pygi-marshal-cleanup.h"
+#include "pygi-marshal-out.h"
+
+PyObject *
+_pygi_marshal_out_void (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ if (arg_cache->is_pointer)
+ py_obj = arg->v_pointer;
+ else
+ py_obj = Py_None;
+
+ Py_XINCREF (py_obj);
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_boolean (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyBool_FromLong (arg->v_boolean);
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_int8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PYGLIB_PyLong_FromLong (arg->v_int8);
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_uint8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PYGLIB_PyLong_FromLong (arg->v_uint8);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_int16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PYGLIB_PyLong_FromLong (arg->v_int16);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_uint16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PYGLIB_PyLong_FromLong (arg->v_uint16);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_int32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PYGLIB_PyLong_FromLong (arg->v_int32);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_uint32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyLong_FromLongLong (arg->v_uint32);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_int64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyLong_FromLongLong (arg->v_int64);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_uint64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyLong_FromUnsignedLongLong (arg->v_uint64);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_float (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyFloat_FromDouble (arg->v_float);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_double (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = PyFloat_FromDouble (arg->v_double);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_unichar (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ /* Preserve the bidirectional mapping between 0 and "" */
+ if (arg->v_uint32 == 0) {
+ py_obj = PYGLIB_PyUnicode_FromString ("");
+ } else if (g_unichar_validate (arg->v_uint32)) {
+ gchar utf8[6];
+ gint bytes;
+
+ bytes = g_unichar_to_utf8 (arg->v_uint32, utf8);
+ py_obj = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
+ } else {
+ /* TODO: Convert the error to an exception. */
+ PyErr_Format (PyExc_TypeError,
+ "Invalid unicode codepoint %" G_GUINT32_FORMAT,
+ arg->v_uint32);
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_gtype (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ py_obj = pyg_type_wrapper_new ( (GType)arg->v_long);
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_utf8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ if (arg->v_string == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ py_obj = PYGLIB_PyUnicode_FromString (arg->v_string);
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_filename (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ gchar *string;
+ PyObject *py_obj = NULL;
+ GError *error = NULL;
+
+ if (arg->v_string == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ string = g_filename_to_utf8 (arg->v_string, -1, NULL, NULL, &error);
+ if (string == NULL) {
+ PyErr_SetString (PyExc_Exception, error->message);
+ /* TODO: Convert the error to an exception. */
+ return NULL;
+ }
+
+ py_obj = PYGLIB_PyUnicode_FromString (string);
+ g_free (string);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_array (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ GArray *array_;
+ PyObject *py_obj = NULL;
+ PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+ gsize processed_items = 0;
+
+ array_ = arg->v_pointer;
+
+ /* GArrays make it easier to iterate over arrays
+ * with different element sizes but requires that
+ * we allocate a GArray if the argument was a C array
+ */
+ if (seq_cache->array_type == GI_ARRAY_TYPE_C) {
+ gsize len;
+ if (seq_cache->fixed_size >= 0) {
+ len = seq_cache->fixed_size;
+ } else if (seq_cache->is_zero_terminated) {
+ len = g_strv_length (arg->v_string);
+ } else {
+ GIArgument *len_arg = state->args[seq_cache->len_arg_index];
+ len = len_arg->v_long;
+ }
+
+ array_ = g_array_new (FALSE,
+ FALSE,
+ seq_cache->item_size);
+ if (array_ == NULL) {
+ PyErr_NoMemory ();
+
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+ g_free (arg->v_pointer);
+
+ return NULL;
+ }
+
+ array_->data = arg->v_pointer;
+ array_->len = len;
+ }
+
+ if (seq_cache->item_cache->type_tag == GI_TYPE_TAG_UINT8) {
+ if (arg->v_pointer == NULL) {
+ py_obj = PYGLIB_PyBytes_FromString ("");
+ } else {
+ py_obj = PYGLIB_PyBytes_FromStringAndSize (array_->data, array_->len);
+ }
+ } else {
+ if (arg->v_pointer == NULL) {
+ py_obj = PyList_New (0);
+ } else {
+ int i;
+
+ gsize item_size;
+ PyGIMarshalOutFunc item_out_marshaller;
+ PyGIArgCache *item_arg_cache;
+
+ py_obj = PyList_New (array_->len);
+ if (py_obj == NULL)
+ goto err;
+
+
+ item_arg_cache = seq_cache->item_cache;
+ item_out_marshaller = item_arg_cache->out_marshaller;
+
+ item_size = g_array_get_element_size (array_);
+
+ for (i = 0; i < array_->len; i++) {
+ GIArgument item_arg;
+ PyObject *py_item;
+
+ if (seq_cache->array_type == GI_ARRAY_TYPE_PTR_ARRAY) {
+ item_arg.v_pointer = g_ptr_array_index ( ( GPtrArray *)array_, i);
+ } else if (item_arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
+ item_arg.v_pointer = array_->data + i * item_size;
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *) item_arg_cache;
+ switch (g_base_info_get_type (iface_cache->interface_info)) {
+ case GI_INFO_TYPE_STRUCT:
+ {
+ gpointer *_struct = g_malloc (item_size);
+ memcpy (_struct, item_arg.v_pointer, item_size);
+ item_arg.v_pointer = _struct;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ } else {
+ memcpy (&item_arg, array_->data + i * item_size, item_size);
+ }
+
+ py_item = item_out_marshaller ( state,
+ callable_cache,
+ item_arg_cache,
+ &item_arg);
+
+ if (py_item == NULL) {
+ Py_CLEAR (py_obj);
+
+ if (seq_cache->array_type == GI_ARRAY_TYPE_C)
+ g_array_unref (array_);
+
+ goto err;
+ }
+ PyList_SET_ITEM (py_obj, i, py_item);
+ processed_items++;
+ }
+ }
+ }
+
+ if (seq_cache->array_type == GI_ARRAY_TYPE_C)
+ g_array_free (array_, FALSE);
+
+ return py_obj;
+
+err:
+ if (seq_cache->array_type == GI_ARRAY_TYPE_C) {
+ g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+ } else {
+ /* clean up unprocessed items */
+ if (seq_cache->item_cache->out_cleanup != NULL) {
+ int j;
+ PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->out_cleanup;
+ for (j = processed_items; j < array_->len; j++) {
+ cleanup_func (state,
+ seq_cache->item_cache,
+ g_array_index (array_, gpointer, j),
+ FALSE);
+ }
+ }
+
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+ g_array_free (array_, TRUE);
+ }
+
+ return NULL;
+}
+
+PyObject *
+_pygi_marshal_out_glist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ GList *list_;
+ gsize length;
+ gsize i;
+
+ PyGIMarshalOutFunc item_out_marshaller;
+ PyGIArgCache *item_arg_cache;
+ PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+
+ PyObject *py_obj = NULL;
+
+ list_ = arg->v_pointer;
+ length = g_list_length (list_);
+
+ py_obj = PyList_New (length);
+ if (py_obj == NULL)
+ return NULL;
+
+ item_arg_cache = seq_cache->item_cache;
+ item_out_marshaller = item_arg_cache->out_marshaller;
+
+ for (i = 0; list_ != NULL; list_ = g_list_next (list_), i++) {
+ GIArgument item_arg;
+ PyObject *py_item;
+
+ item_arg.v_pointer = list_->data;
+ py_item = item_out_marshaller ( state,
+ callable_cache,
+ item_arg_cache,
+ &item_arg);
+
+ if (py_item == NULL) {
+ Py_CLEAR (py_obj);
+ _PyGI_ERROR_PREFIX ("Item %zu: ", i);
+ return NULL;
+ }
+
+ PyList_SET_ITEM (py_obj, i, py_item);
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_gslist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ GSList *list_;
+ gsize length;
+ gsize i;
+
+ PyGIMarshalOutFunc item_out_marshaller;
+ PyGIArgCache *item_arg_cache;
+ PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+
+ PyObject *py_obj = NULL;
+
+ list_ = arg->v_pointer;
+ length = g_slist_length (list_);
+
+ py_obj = PyList_New (length);
+ if (py_obj == NULL)
+ return NULL;
+
+ item_arg_cache = seq_cache->item_cache;
+ item_out_marshaller = item_arg_cache->out_marshaller;
+
+ for (i = 0; list_ != NULL; list_ = g_slist_next (list_), i++) {
+ GIArgument item_arg;
+ PyObject *py_item;
+
+ item_arg.v_pointer = list_->data;
+ py_item = item_out_marshaller ( state,
+ callable_cache,
+ item_arg_cache,
+ &item_arg);
+
+ if (py_item == NULL) {
+ Py_CLEAR (py_obj);
+ _PyGI_ERROR_PREFIX ("Item %zu: ", i);
+ return NULL;
+ }
+
+ PyList_SET_ITEM (py_obj, i, py_item);
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ GHashTable *hash_;
+ GHashTableIter hash_table_iter;
+
+ PyGIMarshalOutFunc key_out_marshaller;
+ PyGIMarshalOutFunc value_out_marshaller;
+
+ PyGIArgCache *key_arg_cache;
+ PyGIArgCache *value_arg_cache;
+ PyGIHashCache *hash_cache = (PyGIHashCache *)arg_cache;
+
+ GIArgument key_arg;
+ GIArgument value_arg;
+
+ PyObject *py_obj = NULL;
+
+ hash_ = arg->v_pointer;
+
+ if (hash_ == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ py_obj = PyDict_New ();
+ if (py_obj == NULL)
+ return NULL;
+
+ key_arg_cache = hash_cache->key_cache;
+ key_out_marshaller = key_arg_cache->out_marshaller;
+
+ value_arg_cache = hash_cache->value_cache;
+ value_out_marshaller = value_arg_cache->out_marshaller;
+
+ g_hash_table_iter_init (&hash_table_iter, hash_);
+ while (g_hash_table_iter_next (&hash_table_iter,
+ &key_arg.v_pointer,
+ &value_arg.v_pointer)) {
+ PyObject *py_key;
+ PyObject *py_value;
+ int retval;
+
+ py_key = key_out_marshaller ( state,
+ callable_cache,
+ key_arg_cache,
+ &key_arg);
+
+ if (py_key == NULL) {
+ Py_CLEAR (py_obj);
+ return NULL;
+ }
+
+ py_value = value_out_marshaller ( state,
+ callable_cache,
+ value_arg_cache,
+ &value_arg);
+
+ if (py_value == NULL) {
+ Py_CLEAR (py_obj);
+ Py_DECREF(py_key);
+ return NULL;
+ }
+
+ retval = PyDict_SetItem (py_obj, py_key, py_value);
+
+ Py_DECREF (py_key);
+ Py_DECREF (py_value);
+
+ if (retval < 0) {
+ Py_CLEAR (py_obj);
+ return NULL;
+ }
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_gerror (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for gerror out is not implemented");
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_callback (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ PyErr_Format (PyExc_NotImplementedError,
+ "Callback out values are not supported");
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ if (iface_cache->g_type == G_TYPE_NONE) {
+ py_obj = PyObject_CallFunction (iface_cache->py_type, "l", arg->v_long);
+ } else {
+ py_obj = pyg_enum_from_gtype (iface_cache->g_type, arg->v_long);
+ }
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+
+ 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 (arg->v_long)) != 0) {
+ Py_DECREF (py_args);
+ Py_DECREF (py_type);
+ return NULL;
+ }
+
+ py_obj = PyObject_CallFunction (py_type, "l", arg->v_long);
+
+ Py_DECREF (py_args);
+ Py_DECREF (py_type);
+ } else {
+ py_obj = pyg_flags_from_gtype (iface_cache->g_type, arg->v_long);
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_struct (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+ PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+ GType type = iface_cache->g_type;
+
+ if (arg->v_pointer == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ if (g_type_is_a (type, G_TYPE_VALUE)) {
+ py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
+ } else if (iface_cache->is_foreign) {
+ py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info,
+ arg->v_pointer);
+ } else if (g_type_is_a (type, G_TYPE_BOXED)) {
+ py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
+ arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+ } else if (g_type_is_a (type, G_TYPE_POINTER)) {
+ if (iface_cache->py_type == NULL ||
+ !PyType_IsSubtype ( (PyTypeObject *)iface_cache->py_type, &PyGIStruct_Type)) {
+ g_warn_if_fail(arg_cache->transfer == GI_TRANSFER_NOTHING);
+ py_obj = pyg_pointer_new (type, arg->v_pointer);
+ } else {
+ py_obj = _pygi_struct_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
+ arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+ }
+ } else if (g_type_is_a (type, G_TYPE_VARIANT)) {
+ g_variant_ref_sink (arg->v_pointer);
+ py_obj = _pygi_struct_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
+ FALSE);
+ } else if (type == G_TYPE_NONE && iface_cache->is_foreign) {
+ py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info, arg->v_pointer);
+ } else if (type == G_TYPE_NONE) {
+ py_obj = _pygi_struct_new ( (PyTypeObject *) iface_cache->py_type, arg->v_pointer,
+ arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+ } else {
+ PyErr_Format (PyExc_NotImplementedError,
+ "structure type '%s' is not supported yet",
+ g_type_name (type));
+ }
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_interface (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for this type is not implemented yet");
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_boxed (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for this type is not implemented yet");
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_object (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj;
+
+ if (arg->v_pointer == NULL) {
+ py_obj = Py_None;
+ Py_INCREF (py_obj);
+ return py_obj;
+ }
+
+ py_obj = pygobject_new (arg->v_pointer);
+
+ if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+ g_object_unref (arg->v_pointer);
+
+ return py_obj;
+}
+
+PyObject *
+_pygi_marshal_out_interface_union (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg)
+{
+ PyObject *py_obj = NULL;
+
+ PyErr_Format (PyExc_NotImplementedError,
+ "Marshalling for this type is not implemented yet");
+ return py_obj;
+}
diff --git a/gi/pygi-marshal-out.h b/gi/pygi-marshal-out.h
new file mode 100644
index 0000000..db6bcfe
--- /dev/null
+++ b/gi/pygi-marshal-out.h
@@ -0,0 +1,144 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2011 John (J5) Palmieri <johnp redhat com>, Red Hat, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_MARSHAL_OUT_H__
+#define __PYGI_MARSHAL_OUT_H__
+
+PyObject *_pygi_marshal_out_void (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_boolean (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_int8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_uint8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_int16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_uint16 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_int32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_uint32 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_int64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_uint64 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_float (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_double (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_unichar (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_gtype (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_utf8 (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_filename (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_array (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_glist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_gslist (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_ghash (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_gerror (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_callback(PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_enum (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_flags (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_struct (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_interface(PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_boxed (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_object (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+PyObject *_pygi_marshal_out_interface_union (PyGIInvokeState *state,
+ PyGICallableCache *callable_cache,
+ PyGIArgCache *arg_cache,
+ GIArgument *arg);
+
+G_END_DECLS
+
+#endif /* __PYGI_MARSHAL_OUT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]