[pygobject/invoke-rewrite: 2/3] add marshalling for basic types and add more skeleton code



commit 8b5b3d2bbbbdf5d26c83e9a6fe67121cbd77ebe1
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu Jan 6 17:29:00 2011 -0500

    add marshalling for basic types and add more skeleton code
    
    * still doesn't compile

 gi/pygi-argument.c |  708 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gi/pygi-argument.h |   35 +++-
 gi/pygi-cache.c    |   82 +++++--
 gi/pygi-cache.h    |   41 +++-
 4 files changed, 832 insertions(+), 34 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index ec0fd5f..7d7f003 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1989,3 +1989,711 @@ _pygi_argument_init (void)
     _pygobject_import();
 }
 
+/*** argument marshaling and validating routines ***/
+
+gboolean 
+_pygi_marshal_in_void (PyGIState         *state,
+                       PyGIFunctionCache *function_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 (PyGIState         *state,
+                          PyGIFunctionCache *function_cache, 
+                          PyGIArgCache      *arg_cache,
+                          PyObject          *py_arg,
+                          GIArgument        *arg)
+{
+    arg.v_boolean = PyObject_IsTrue(py_arg);
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_int8 (PyGIState         *state,
+                       PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (long_ < -128 || long_ > 127) {
+        PyErr_Format (PyExc_ValueError, "%i not in range %i to %i", long_, -128, 127);
+        return FALSE;
+    }
+
+    arg.v_long = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_uint8 (PyGIState         *state,
+                        PyGIFunctionCache *function_cache, 
+                        PyGIArgCache      *arg_cache,
+                        PyObject          *py_arg,
+                        GIArgument        *arg)
+{
+    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_ = (long)(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_Occured())
+            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, "%li not in range %i to %i", long_, 0, 255);
+        return FALSE;
+    }
+
+    arg.v_long = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_int16 (PyGIState         *state,
+                        PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (long_ < -32768 || long_ > 32767) {
+        PyErr_Format (PyExc_ValueError, "%li not in range %i to %i", long_, -32768, 32767);
+        return FALSE;
+    }
+
+    arg.v_long = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_uint16 (PyGIState         *state,
+                         PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (long_ < 0 || long_ > 65535) {
+        PyErr_Format (PyExc_ValueError, "%li not in range %i to %i", long_, 0, 65535);
+        return FALSE;
+    }
+
+    arg.v_long = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_int32 (PyGIState         *state,
+                        PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (long_ < G_MININT32 || long_ > G_MAXINT32) {
+        PyErr_Format (PyExc_ValueError, "%i not in range %i to %i", long_, G_MININT32, G_MAXINT32);
+        return FALSE;
+    }
+
+    arg.v_long = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_uint32 (PyGIState         *state,
+                         PyGIFunctionCache *function_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 (number))
+        long_ = PyInt_AS_LONG (number);
+    else
+#endif
+        long_ = PyLong_AsLongLong(py_long);
+
+    Py_DECREF(py_long);
+
+    if (PyErr_Occurred())
+        return FALSE;
+
+    if (long_ < 0 || long_ > G_MAXUINT32) {
+        PyErr_Format (PyExc_ValueError, "%lli not in range %i to %lli", long_, 0, G_MAXUINT32);
+        return FALSE;
+    }
+
+    arg.v_uint64 = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_int64 (PyGIState         *state,
+                        PyGIFunctionCache *function_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 (number))
+        long_ = PyInt_AS_LONG (number);
+    else
+#endif
+        long_ = PyLong_AsLongLong(py_long);
+
+    Py_DECREF(py_long);
+
+    if (PyErr_Occurred())
+        return FALSE;
+
+    if (long_ < G_MININT64 || long_ > G_MAXINT64) {
+        PyErr_Format (PyExc_ValueError, "%lli not in range %lli to %lli", long_, G_MININT64, G_MAXINT64);
+        return FALSE;
+    }
+
+    arg.v_uint64 = long_;
+
+    return TRUE;
+}
+
+gboolean 
+_pygi_marshal_in_uint64 (PyGIState         *state,
+                         PyGIFunctionCache *function_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 (number))
+        long_ = PyInt_AS_LONG (number);
+    else
+#endif
+        long_ = PyLong_AsLongLong(py_long);
+
+    Py_DECREF(py_long);
+
+    if (PyErr_Occurred())
+        return FALSE;
+
+    if (long_ < 0 || long_ > G_MAXUINT64) {
+        PyErr_Format (PyExc_ValueError, "%lli not in range %i to %lli", long_, 0, G_MAXUINT64);
+        return FALSE;
+    }
+
+    arg.v_uint64 = long_;
+
+    return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_float (PyGIState         *state,
+                        PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (double_ < -G_MAXFLOAT || double_ > G_MAXFLOAT) {
+        PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", long_, -G_MAXFLOAT, G_MAXFLOAT);
+        return FALSE;
+    }
+
+    arg.v_double = double_;
+
+    return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_double (PyGIState         *state,
+                         PyGIFunctionCache *function_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())
+        return FALSE;
+
+    if (double_ < -G_MAXDOUBLE || double_ > G_MAXDOUBLE) {
+        PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", long_, -G_MAXDOUBLE, G_MAXDOUBLE);
+        return FALSE;
+    }
+
+    arg.v_double = double_;
+
+    return TRUE;
+}
+
+gboolean
+_pygi_marshal_in_unichar (PyGIState         *state,
+                          PyGIFunctionCache *function_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();
+       _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 (PyGIState         *state,
+                        PyGIFunctionCache *function_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);
+    } 
+
+    arg.v_long = type_;
+    return TRUE;
+}
+gboolean
+_pygi_marshal_in_utf8 (PyGIState         *state,
+                       PyGIFunctionCache *function_cache, 
+                       PyGIArgCache      *arg_cache,
+                       PyObject          *py_arg,
+                       GIArgument        *arg)
+{
+    gchar *string_;
+
+    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 (PyGIState         *state,
+                           PyGIFunctionCache *function_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 (PyGIState         *state,
+                        PyGIFunctionCache *function_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_glist (PyGIState         *state,
+                        PyGIFunctionCache *function_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_gslist (PyGIState         *state,
+                         PyGIFunctionCache *function_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_ghash (PyGIState         *state,
+                        PyGIFunctionCache *function_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_gerror (PyGIState         *state,
+                         PyGIFunctionCache *function_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_callback (PyGIState         *state,
+                                     PyGIFunctionCache *function_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_enum (PyGIState         *state,
+                                 PyGIFunctionCache *function_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_flags (PyGIState         *state,
+                                  PyGIFunctionCache *function_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_struct (PyGIState         *state,
+                                   PyGIFunctionCache *function_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_interface (PyGIState         *state,
+                                      PyGIFunctionCache *function_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_boxed (PyGIState         *state,
+                                  PyGIFunctionCache *function_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 (PyGIState         *state,
+                                   PyGIFunctionCache *function_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_union (PyGIState         *state,
+                                  PyGIFunctionCache *function_cache, 
+                                  PyGIArgCache      *arg_cache,
+                                  PyObject          *py_arg,
+                                  GIArgument        *arg)
+{
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Marshalling for this type is not implemented yet");
+    return FALSE;
+}
+
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
index d932e8f..8848d8c 100644
--- a/gi/pygi-argument.h
+++ b/gi/pygi-argument.h
@@ -26,8 +26,9 @@
 
 #include <girepository.h>
 
-G_BEGIN_DECLS
+#include "pygi-cache.h"
 
+G_BEGIN_DECLS
 
 /* Private */
 gint _pygi_g_type_interface_check_object (GIBaseInfo *info,
@@ -63,6 +64,38 @@ void _pygi_argument_release (GIArgument   *arg,
 
 void _pygi_argument_init (void);
 
+
+/*** argument marshaling and validating routines ***/
+PyGIMarshalInFunc _pygi_marshal_in_void;
+PyGIMarshalInFunc _pygi_marshal_in_int8;
+PyGIMarshalInFunc _pygi_marshal_in_uint8;
+PyGIMarshalInFunc _pygi_marshal_in_int16;
+PyGIMarshalInFunc _pygi_marshal_in_uint16;
+PyGIMarshalInFunc _pygi_marshal_in_int32;
+PyGIMarshalInFunc _pygi_marshal_in_uint32;
+PyGIMarshalInFunc _pygi_marshal_in_int64;
+PyGIMarshalInFunc _pygi_marshal_in_float;
+PyGIMarshalInFunc _pygi_marshal_in_double;
+PyGIMarshalInFunc _pygi_marshal_in_unichar;
+PyGIMarshalInFunc _pygi_marshal_in_gtype;
+PyGIMarshalInFunc _pygi_marshal_in_utf8;
+PyGIMarshalInFunc _pygi_marshal_in_filename;
+PyGIMarshalInFunc _pygi_marshal_in_array;
+PyGIMarshalInFunc _pygi_marshal_in_glist;
+PyGIMarshalInFunc _pygi_marshal_in_gslist;
+PyGIMarshalInFunc _pygi_marshal_in_ghash;
+PyGIMarshalInFunc _pygi_marshal_in_gerror;
+PyGIMarshalInFunc _pygi_marshal_in_interface_callback;
+PyGIMarshalInFunc _pygi_marshal_in_interface_enum;
+PyGIMarshalInFunc _pygi_marshal_in_interface_flags;
+PyGIMarshalInFunc _pygi_marshal_in_interface_struct;
+PyGIMarshalInFunc _pygi_marshal_in_interface_interface;
+PyGIMarshalInFunc _pygi_marshal_in_interface_boxed;
+PyGIMarshalInFunc _pygi_marshal_in_interface_object;
+PyGIMarshalInFunc _pygi_marshal_in_interface_union;
+
+
+
 G_END_DECLS
 
 #endif /* __PYGI_ARGUMENT_H__ */
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 4c73816..f9858e9 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -117,9 +117,7 @@ _arg_cache_generate_metadata_in_void(PyGIArgCache *arg_cache,
                                      PyGIFunctionCache *function_cache,
                                      GIArgInfo *arg_info)
 {
-     ac->in_validator = <type validation function pointer>
-     ac->in_marshaler = <type marshaling function pointer>
-     ac->cleanup = <type cleanup function pointer>
+     arg_cache->in_marshaler = _pygi_marshal_in_void;
 
      return TRUE;
 }
@@ -129,6 +127,7 @@ _arg_cache_generate_metadata_in_boolean(PyGIArgCache *arg_cache,
                                         PyGIFunctionCache *function_cache,
                                         GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_boolean; 
     return TRUE;
 }
 
@@ -137,6 +136,7 @@ _arg_cache_generate_metadata_in_int8(PyGIArgCache *arg_cache,
                                      PyGIFunctionCache *function_cache,
                                      GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_int8;
     return TRUE;
 }
 
@@ -145,6 +145,7 @@ _arg_cache_generate_metadata_in_uint8(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_uint8;
     return TRUE;
 }
 
@@ -153,6 +154,7 @@ _arg_cache_generate_metadata_in_int16(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_int16;
     return TRUE;
 }
 
@@ -161,6 +163,7 @@ _arg_cache_generate_metadata_in_uint16(PyGIArgCache *arg_cache,
                                        PyGIFunctionCache *function_cache,
                                        GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_uint16;
     return TRUE;
 }
 
@@ -169,6 +172,7 @@ _arg_cache_generate_metadata_in_int32(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_int32;
     return TRUE;
 }
 
@@ -177,6 +181,7 @@ _arg_cache_generate_metadata_in_uint32(PyGIArgCache *arg_cache,
                                        PyGIFunctionCache *function_cache,
                                        GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_uint32;
     return TRUE;
 }
 
@@ -185,6 +190,7 @@ _arg_cache_generate_metadata_in_int64(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_int64;
     return TRUE;
 }
 
@@ -193,6 +199,7 @@ _arg_cache_generate_metadata_in_uint64(PyGIArgCache *arg_cache,
                                        PyGIFunctionCache *function_cache,
                                        GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_uint64;
     return TRUE;
 }
 
@@ -201,6 +208,7 @@ _arg_cache_generate_metadata_in_float(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_float;
     return TRUE;
 }
 
@@ -209,6 +217,7 @@ _arg_cache_generate_metadata_in_double(PyGIArgCache *arg_cache,
                                        PyGIFunctionCache *function_cache,
                                        GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_double;
     return TRUE;
 }
 
@@ -217,6 +226,8 @@ _arg_cache_generate_metadata_in_unichar(PyGIArgCache *arg_cache,
                                         PyGIFunctionCache *function_cache,
                                         GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_unichar;
+
     return TRUE;
 }
 
@@ -225,6 +236,7 @@ _arg_cache_generate_metadata_in_gtype(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_gtype;
     return TRUE;
 }
 
@@ -233,6 +245,10 @@ _arg_cache_generate_metadata_in_utf8(PyGIArgCache *arg_cache,
                                      PyGIFunctionCache *function_cache,
                                      GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_utf8;
+    if (arg_cache->transfer == GI_TRANSFER_NOTHING)
+        arg_cache->cleanup = g_free;
+
     return TRUE;
 }
 
@@ -241,6 +257,10 @@ _arg_cache_generate_metadata_in_filename(PyGIArgCache *arg_cache,
                                          PyGIFunctionCache *function_cache,
                                          GIArgInfo *arg_info)
 {
+    arg_cache->in_marshaler = _pygi_marshal_in_filename;
+    if (arg_cache->transfer == GI_TRANSFER_NOTHING)
+        arg_cache->cleanup = g_free;
+
     return TRUE;
 }
 
@@ -249,7 +269,10 @@ _arg_cache_generate_metadata_in_array(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
-    return TRUE;
+    arg_cache->in_marshaler = _pygi_marshal_in_array;
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
@@ -257,7 +280,10 @@ _arg_cache_generate_metadata_in_interface(PyGIArgCache *arg_cache,
                                           PyGIFunctionCache *function_cache,
                                           GIArgInfo *arg_info)
 {
-    return TRUE;
+    /* TODO: Switch on GI_INFO_TYPE_ to determine caching */
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
@@ -265,7 +291,10 @@ _arg_cache_generate_metadata_in_glist(PyGIArgCache *arg_cache,
                                      PyGIFunctionCache *function_cache,
                                      GIArgInfo *arg_info)
 {
-    return TRUE;
+    arg_cache->in_marshaler = _pygi_marshal_in_glist;
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
@@ -273,7 +302,10 @@ _arg_cache_generate_metadata_in_gslist(PyGIArgCache *arg_cache,
                                      PyGIFunctionCache *function_cache,
                                      GIArgInfo *arg_info)
 {
-    return TRUE;
+    arg_cache->in_marshaler = _pygi_marshal_in_gslist;
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
@@ -281,7 +313,10 @@ _arg_cache_generate_metadata_in_ghash(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
-    return TRUE;
+    arg_cache->in_marshaler = _pygi_marshal_in_ghash;
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
@@ -289,19 +324,25 @@ _arg_cache_generate_metadata_in_error(PyGIArgCache *arg_cache,
                                       PyGIFunctionCache *function_cache,
                                       GIArgInfo *arg_info)
 {
-    return TRUE;
+    arg_cache->in_marshaler = _pygi_marshal_in_error;
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
 }
 
 static inline boolean
 _arg_cache_generate_metadata_in(PyGIArgCache *arg_cache,
                                 PyGIFunctionCache *function_cache,
                                 GIArgInfo *arg_info,
-                                GITypeTag type_tag,
-                                gint arg_index)
+                                GITypeTag type_tag)
 {
     gboolean success = True;
 
-    function_info->n_in_args++; 
+    arg_cache->c_arg_index = i + function_cache->is_method;
+    arg_cache->py_arg_index =
+        function_info->n_in_args + function_cache->is_method;
+
+    function_info->n_in_args++;
     switch (type_tag) {
        case GI_TYPE_TAG_VOID:
            success = _arg_cache_generate_metadata_in_void(arg_cache,
@@ -443,21 +484,18 @@ _args_cache_generate(GIFunctionInfo *function_info,
 
         switch(direction) {
             case GI_DIRECTION_IN:
-                function_info->n_in_args++;
-                switch (type_tag) {
-                    case GI_TYPE_TAG_...:
-                        ac->in_validator = <type validation function pointer>
-                        ac->in_marshaler = <type marshaling function pointer>
-                        ac->cleanup = <type cleanup function pointer>
+                _arg_cache_generate_metadata_in(arg_cache,
+                                                function_cache,
+                                                arg_info,
+                                                type_tag);
+
+                break;
 
-                        fc->in_args = g_slist_append(fc->in_args, ac);
-                        break;
-                
             case GI_DIRECTION_OUT:
                 function_info->n_out_args++;
  		    switch (type_tag) {
                     case GI_TYPE_TAG_...:
-                   
+
                         ac->out_marshaler = <type marshaling function pointer>
                         ac->cleanup = <type cleanup function pointer>
                         fc->out_args = g_slist_append(fc->out_args, ac);
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 7f98688..b5538b1 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -19,12 +19,27 @@
  * USA
  */
 
-/* placeholders for now */
-typedef gboolean (*PyGIValidateInFunc) (void);
-typedef gboolean (*PyGIMarshalInFunc) (void);
+#ifndef __PYGI_CACHE_H__
+#define __PYGI_CACHE_H__
+
+#include <Python.h>
+#include <girepository.h>
+
+G_BEGIN_DECLS
+
+typedef struct _PyGIFunctionCache PyGIFunctionCache;
+typedef struct _PyGIArgCache PyGIArgCache;
+
+typedef gboolean (*PyGIMarshalInFunc) (PyGIState         *state,
+                                       PyGIFunctionCache *function_cache, 
+                                       PyGIArgCache      *arg_cache,
+                                       PyObject          *py_arg,
+                                       GIArgument        *arg);
+
 typedef gboolean (*PyGIMarshalOutFunc) (void);
 typedef gboolean (*PyGIArgCleanupFunc) (gpointer data);
 
+
 typedef struct _PyGISequenceCache
 {
     gssize fixed_size; 
@@ -34,7 +49,7 @@ typedef struct _PyGISequenceCache
     gboolean is_zero_terminated; 
     gsize item_size;
     GITypeTag item_tag_type; 
-}
+} PyGISequenceCache;
 
 typedef struct _PyGIInterfaceCache
 {
@@ -61,14 +76,15 @@ typedef struct _PyGICallbackCache
     GScope scope;
 } PyGICallbackCache; 
 
-typedef struct _PyGIArgCache
+struct _PyGIArgCache
 {
     gboolean is_aux; 
     gboolean is_pointer; 
-    GIDirection direction; 
+    GIDirection direction;
+    GITransfer transfer;
     GIArgInfo *arg_info;
+    GIArgument *default_value;
 
-    PyGIValidateInFunc in_validator; 
     PyGIMashalInFunc in_marshaler; 
     PyGIMarshalOutFunc out_marshaler; 
     PyGIArgCleanupFunc cleanup; 
@@ -80,9 +96,9 @@ typedef struct _PyGIArgCache
 
     gint c_arg_index;
     gint py_arg_index;
-} PyGIArgCache;
+};
 
-typedef struct _PyGIFunctionCache
+struct _PyGIFunctionCache
 {
     gboolean is_method;
     gboolean is_constructor;
@@ -95,10 +111,13 @@ typedef struct _PyGIFunctionCache
     guint n_in_args;
     guint n_out_args;
     guint n_args;   
-} PyGIFunctionCache;
+};
 
 void _pygi_arg_cache_clear	(PyGIArgCache *cache);
 void _pygi_function_cache_free	(PyGIFunctionCache *cache);
 
-PyGIFunctionCache *_pygi_generate_function_cache (GIFunctionInfo *function_info);
+PyGIFunctionCache *_pygi_function_cache_new (GIFunctionInfo *function_info);
+
+G_END_DECLS
 
+#endif /* __PYGI_CACHE_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]