[pygobject] Fix various endianess errors



commit 1c5d497d3c354f4d02f1d4570df2c61d6f47300c
Author: David Malcolm <dmalcolm redhat com>
Date:   Mon Aug 20 11:19:27 2012 +0200

    Fix various endianess errors
    
    Fix code which assumed little endian behaviour when mixing different types of
    ints, putting ints into pointers, etc.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=680692
    https://bugzilla.redhat.com/show_bug.cgi?id=841596

 gi/pygi-argument.c        |   64 +++++++++++++--
 gi/pygi-argument.h        |    6 ++
 gi/pygi-cache.c           |    2 +
 gi/pygi-closure.c         |   57 ++++++++++++-
 gi/pygi-marshal-from-py.c |  203 +++++++++++++++++++++++++++++++++++----------
 gi/pygi-marshal-from-py.h |    3 +
 gi/pygi-marshal-to-py.c   |  137 ++++++++++++++++++++++++-------
 7 files changed, 391 insertions(+), 81 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 737342a..db97a86 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -31,6 +31,56 @@
 #include <pyglib-python-compat.h>
 #include <pyglib.h>
 
+void
+_pygi_hash_pointer_to_arg (GIArgument *arg,
+                           GITypeTag  type_tag)
+{
+    switch (type_tag) {
+        case GI_TYPE_TAG_INT8:
+            arg->v_int8 = GPOINTER_TO_INT (arg->v_pointer);
+            break;
+        case GI_TYPE_TAG_INT16:
+            arg->v_int16 = GPOINTER_TO_INT (arg->v_pointer);
+            break;
+        case GI_TYPE_TAG_INT32:
+            arg->v_int32 = GPOINTER_TO_INT (arg->v_pointer);
+            break;
+        case GI_TYPE_TAG_UTF8:
+        case GI_TYPE_TAG_FILENAME:
+        case GI_TYPE_TAG_INTERFACE:
+            break;
+        default:
+            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
+    }
+}
+
+gpointer
+_pygi_arg_to_hash_pointer (const GIArgument *arg,
+                           GITypeTag        type_tag)
+{
+    switch (type_tag) {
+        case GI_TYPE_TAG_INT8:
+            return GINT_TO_POINTER (arg->v_int8);
+        case GI_TYPE_TAG_UINT8:
+            return GINT_TO_POINTER (arg->v_uint8);
+        case GI_TYPE_TAG_INT16:
+            return GINT_TO_POINTER (arg->v_int16);
+        case GI_TYPE_TAG_UINT16:
+            return GINT_TO_POINTER (arg->v_uint16);
+        case GI_TYPE_TAG_INT32:
+            return GINT_TO_POINTER (arg->v_int32);
+        case GI_TYPE_TAG_UINT32:
+            return GINT_TO_POINTER (arg->v_uint32);
+        case GI_TYPE_TAG_UTF8:
+        case GI_TYPE_TAG_FILENAME:
+        case GI_TYPE_TAG_INTERFACE:
+            return arg->v_pointer;
+        default:
+            g_critical ("Unsupported type %s", g_type_tag_to_string(type_tag));
+            return arg->v_pointer;
+    }
+}
+
 static void
 _pygi_g_type_tag_py_bounds (GITypeTag   type_tag,
                             PyObject  **lower,
@@ -1196,7 +1246,7 @@ array_success:
                         break;
                     }
 
-                    arg.v_long = PYGLIB_PyLong_AsLong (int_);
+                    arg.v_int = PYGLIB_PyLong_AsLong (int_);
 
                     Py_DECREF (int_);
 
@@ -1369,7 +1419,8 @@ list_item_error:
                     goto hash_table_item_error;
                 }
 
-                g_hash_table_insert (hash_table, key.v_pointer, value.v_pointer);
+                g_hash_table_insert (hash_table, key.v_pointer,
+                                     _pygi_arg_to_hash_pointer (&value, g_type_info_get_tag (value_type_info)));
                 continue;
 
 hash_table_item_error:
@@ -1713,21 +1764,21 @@ _pygi_argument_to_object (GIArgument  *arg,
                             return NULL;
 
                         py_args = PyTuple_New (1);
-                        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_long)) != 0) {
+                        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_int)) != 0) {
                             Py_DECREF (py_args);
                             Py_DECREF (py_type);
                             return NULL;
                         }
 
-                        object = PyObject_CallFunction (py_type, "l", arg->v_long);
+                        object = PyObject_CallFunction (py_type, "i", arg->v_int);
 
                         Py_DECREF (py_args);
                         Py_DECREF (py_type);
 
                     } else if (info_type == GI_INFO_TYPE_ENUM) {
-                        object = pyg_enum_from_gtype (type, arg->v_long);
+                        object = pyg_enum_from_gtype (type, arg->v_int);
                     } else {
-                        object = pyg_flags_from_gtype (type, arg->v_long);
+                        object = pyg_flags_from_gtype (type, arg->v_int);
                     }
 
                     break;
@@ -1840,6 +1891,7 @@ _pygi_argument_to_object (GIArgument  *arg,
                     break;
                 }
 
+                _pygi_hash_pointer_to_arg (&value, g_type_info_get_tag (value_type_info));
                 py_value = _pygi_argument_to_object (&value, value_type_info, item_transfer);
                 if (py_value == NULL) {
                     Py_DECREF (py_key);
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
index 668fabb..32f263b 100644
--- a/gi/pygi-argument.h
+++ b/gi/pygi-argument.h
@@ -30,6 +30,12 @@ G_BEGIN_DECLS
 
 
 /* Private */
+gpointer _pygi_arg_to_hash_pointer (const GIArgument *arg,
+                                    GITypeTag         type_tag);
+
+void _pygi_hash_pointer_to_arg (GIArgument *arg,
+                                GITypeTag   type_tag);
+
 gint _pygi_g_type_interface_check_object (GIBaseInfo *info,
                                           PyObject   *object);
 
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index f42aa64..d6531ed 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -1393,6 +1393,8 @@ _args_cache_generate (GICallableInfo *callable_info,
                 callable_cache->n_to_py_child_args++;
             }
 
+            arg_cache->type_tag = g_type_info_get_tag (type_info);
+
             g_base_info_unref ( (GIBaseInfo *)arg_info);
             continue;
         }
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 1fab07f..bec0bc4 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -28,6 +28,57 @@
 static GSList* async_free_list;
 
 static void
+_pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object,
+                                      GITypeInfo *type_info,
+                                      GITransfer transfer)
+{
+    GIArgument arg = _pygi_argument_from_object (object, type_info, transfer);
+    GITypeTag type_tag = g_type_info_get_tag (type_info);
+
+    if (retval == NULL)
+        return;
+
+    switch (type_tag) {
+        case GI_TYPE_TAG_BOOLEAN:
+           *((ffi_sarg *) retval) = arg.v_boolean;
+           break;
+        case GI_TYPE_TAG_INT8:
+           *((ffi_sarg *) retval) = arg.v_int8;
+           break;
+        case GI_TYPE_TAG_UINT8:
+           *((ffi_arg *) retval) = arg.v_uint8;
+           break;
+        case GI_TYPE_TAG_INT16:
+           *((ffi_sarg *) retval) = arg.v_int16;
+           break;
+        case GI_TYPE_TAG_UINT16:
+           *((ffi_arg *) retval) = arg.v_uint16;
+           break;
+        case GI_TYPE_TAG_INT32:
+           *((ffi_sarg *) retval) = arg.v_int32;
+           break;
+        case GI_TYPE_TAG_UINT32:
+           *((ffi_arg *) retval) = arg.v_uint32;
+           break;
+        case GI_TYPE_TAG_INT64:
+           *((ffi_sarg *) retval) = arg.v_int64;
+           break;
+        case GI_TYPE_TAG_UINT64:
+           *((ffi_arg *) retval) = arg.v_uint64;
+           break;
+        case GI_TYPE_TAG_FLOAT:
+           *((gfloat *) retval) = arg.v_float;
+           break;
+        case GI_TYPE_TAG_DOUBLE:
+           *((gdouble *) retval) = arg.v_double;
+           break;
+        default:
+           *((GIArgument *) retval) = arg;
+           break;
+      }
+}
+
+static void
 _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg, PyObject *object,
                                             GITypeInfo *type_info,
                                             GITransfer transfer)
@@ -299,7 +350,7 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
                     arg = (GIArgument*) g_args[i].v_pointer;
                 
                 if (g_type_info_get_tag (arg_type) == GI_TYPE_TAG_ARRAY)
-                    arg->v_pointer = _pygi_argument_to_array (arg, args, 
+                    arg->v_pointer = _pygi_argument_to_array (arg, (GIArgument **) args, 
                                                               arg_type, &free_array);
 
                 value = _pygi_argument_to_object (arg, arg_type, transfer);
@@ -358,10 +409,10 @@ _pygi_closure_set_out_arguments (GICallableInfo *callable_info,
         GITransfer transfer = g_callable_info_get_caller_owns (callable_info);
         if (PyTuple_Check (py_retval)) {
             PyObject *item = PyTuple_GET_ITEM (py_retval, 0);
-            _pygi_closure_assign_pyobj_to_out_argument (resp, item,
+            _pygi_closure_assign_pyobj_to_retval (resp, item,
                 return_type_info, transfer);
         } else {
-            _pygi_closure_assign_pyobj_to_out_argument (resp, py_retval,
+            _pygi_closure_assign_pyobj_to_retval (resp, py_retval,
                 return_type_info, transfer);
         }
         i_py_retval++;
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index 5437e33..a6572ef 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -32,6 +32,119 @@
 #include "pygi-marshal-cleanup.h"
 #include "pygi-marshal-from-py.h"
 
+gboolean
+gi_argument_from_py_ssize_t (GIArgument   *arg_out,
+                             Py_ssize_t    size_in,
+                             GITypeTag     type_tag)                             
+{
+    switch (type_tag) {
+    case GI_TYPE_TAG_VOID:
+    case GI_TYPE_TAG_BOOLEAN:
+    case GI_TYPE_TAG_INT8:
+    case GI_TYPE_TAG_UINT8:
+    case GI_TYPE_TAG_INT16:
+    case GI_TYPE_TAG_UINT16:
+        goto unhandled_type;
+
+        /* Ranges assume two's complement */
+    case GI_TYPE_TAG_INT32:
+        if (size_in >= G_MININT32 && size_in <= G_MAXINT32) {
+            arg_out->v_int32 = size_in;
+            return TRUE;
+        } else {
+            goto overflow;
+        }
+
+    case GI_TYPE_TAG_UINT32:
+        if (size_in >= 0 && size_in <= G_MAXUINT32) {
+            arg_out->v_uint32 = size_in;
+            return TRUE;
+        } else {
+            goto overflow;
+        }
+
+    case GI_TYPE_TAG_INT64:
+        arg_out->v_int64 = size_in;
+        return TRUE;
+
+    case GI_TYPE_TAG_UINT64:
+        if (size_in >= 0) {
+            arg_out->v_uint64 = size_in;
+            return TRUE;
+        } else {
+            goto overflow;
+        }
+            
+    case GI_TYPE_TAG_FLOAT:
+    case GI_TYPE_TAG_DOUBLE:
+    case GI_TYPE_TAG_GTYPE:
+    case GI_TYPE_TAG_UTF8:
+    case GI_TYPE_TAG_FILENAME:
+    case GI_TYPE_TAG_ARRAY:
+    case GI_TYPE_TAG_INTERFACE:
+    case GI_TYPE_TAG_GLIST:
+    case GI_TYPE_TAG_GSLIST:
+    case GI_TYPE_TAG_GHASH:
+    case GI_TYPE_TAG_ERROR:
+    case GI_TYPE_TAG_UNICHAR:
+    default:
+        goto unhandled_type;
+    }
+
+ overflow:
+    PyErr_Format (PyExc_OverflowError,
+                  "Unable to marshal C Py_ssize_t %zd to %s",
+                  size_in,
+                  g_type_tag_to_string (type_tag));
+    return FALSE;
+
+ unhandled_type:
+    PyErr_Format (PyExc_TypeError,
+                  "Unable to marshal C Py_ssize_t %zd to %s",
+                  size_in,
+                  g_type_tag_to_string (type_tag));
+    return FALSE;
+}
+
+gboolean
+gi_argument_from_c_long (GIArgument *arg_out,
+                         long        c_long_in,
+                         GITypeTag   type_tag)
+{
+    switch (type_tag) {
+      case GI_TYPE_TAG_INT8:
+          arg_out->v_int8 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_UINT8:
+          arg_out->v_uint8 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_INT16:
+          arg_out->v_int16 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_UINT16:
+          arg_out->v_uint16 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_INT32:
+          arg_out->v_int32 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_UINT32:
+          arg_out->v_uint32 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_INT64:
+          arg_out->v_int64 = c_long_in;
+          return TRUE;
+      case GI_TYPE_TAG_UINT64:
+          arg_out->v_uint64 = c_long_in;
+          return TRUE;
+      default:
+          PyErr_Format (PyExc_TypeError,
+                        "Unable to marshal C long %ld to %s",
+                        c_long_in,
+                        g_type_tag_to_string (type_tag));
+          return FALSE;
+    }
+}
+
 /*
  * _is_union_member - check to see if the py_arg is actually a member of the
  * expected C union
@@ -736,33 +849,6 @@ _pygi_marshal_from_py_filename (PyGIInvokeState   *state,
     return TRUE;
 }
 
-static gpointer
-_pygi_arg_to_hash_pointer (const GIArgument *arg,
-                           GITypeTag        type_tag)
-{
-    switch (type_tag) {
-        case GI_TYPE_TAG_INT8:
-            return GINT_TO_POINTER(arg->v_int8);
-        case GI_TYPE_TAG_UINT8:
-            return GINT_TO_POINTER(arg->v_uint8);
-        case GI_TYPE_TAG_INT16:
-            return GINT_TO_POINTER(arg->v_int16);
-        case GI_TYPE_TAG_UINT16:
-            return GINT_TO_POINTER(arg->v_uint16);
-        case GI_TYPE_TAG_INT32:
-            return GINT_TO_POINTER(arg->v_int32);
-        case GI_TYPE_TAG_UINT32:
-            return GINT_TO_POINTER(arg->v_uint32);
-        case GI_TYPE_TAG_UTF8:
-        case GI_TYPE_TAG_FILENAME:
-        case GI_TYPE_TAG_INTERFACE:
-            return arg->v_pointer;
-        default:
-            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
-            return arg->v_pointer;
-    }
-}
-
 gboolean
 _pygi_marshal_from_py_array (PyGIInvokeState   *state,
                              PyGICallableCache *callable_cache,
@@ -942,12 +1028,21 @@ array_success:
         if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) {
             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
+            if (len_arg == NULL) {
+                if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
+                                                  length,
+                                                  child_cache->type_tag)) {
+                    goto err;
+                }
+            } else {
                 *len_arg = length;
+            }
         } else {
-            state->in_args[child_cache->c_arg_index].v_long = length;
+            if (!gi_argument_from_py_ssize_t (&state->in_args[child_cache->c_arg_index],
+                                              length,
+                                              child_cache->type_tag)) {
+                goto err;
+            }
         }
     }
 
@@ -1291,20 +1386,32 @@ _pygi_marshal_from_py_interface_enum (PyGIInvokeState   *state,
                                       PyObject          *py_arg,
                                       GIArgument        *arg)
 {
-    PyObject *int_;
+    PyObject *py_long;
+    long c_long;
     gint is_instance;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+    GIBaseInfo *interface;
 
     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
 
-    int_ = PYGLIB_PyNumber_Long (py_arg);
-    if (int_ == NULL) {
+    py_long = PYGLIB_PyNumber_Long (py_arg);
+    if (py_long == NULL) {
         PyErr_Clear();
         goto err;
     }
 
-    arg->v_long = PYGLIB_PyLong_AsLong (int_);
-    Py_DECREF (int_);
+    c_long = PYGLIB_PyLong_AsLong (py_long);
+    Py_DECREF (py_long);
+
+    /* Write c_long into arg */
+    interface = g_type_info_get_interface (arg_cache->type_info);
+    assert(g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
+    if (!gi_argument_from_c_long(arg,
+                                 c_long,
+                                 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+          g_assert_not_reached();
+          return FALSE;
+    }
 
     /* If this is not an instance of the Enum type that we want
      * we need to check if the value is equivilant to one of the
@@ -1318,7 +1425,7 @@ _pygi_marshal_from_py_interface_enum (PyGIInvokeState   *state,
                 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) {
+            if (c_long == enum_value) {
                 is_found = TRUE;
                 break;
             }
@@ -1343,25 +1450,35 @@ _pygi_marshal_from_py_interface_flags (PyGIInvokeState   *state,
                                        PyObject          *py_arg,
                                        GIArgument        *arg)
 {
-    PyObject *int_;
+    PyObject *py_long;
+    long c_long;
     gint is_instance;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+    GIBaseInfo *interface;
 
     is_instance = PyObject_IsInstance (py_arg, iface_cache->py_type);
 
-    int_ = PYGLIB_PyNumber_Long (py_arg);
-    if (int_ == NULL) {
+    py_long = PYGLIB_PyNumber_Long (py_arg);
+    if (py_long == NULL) {
         PyErr_Clear ();
         goto err;
     }
 
-    arg->v_long = PYGLIB_PyLong_AsLong (int_);
-    Py_DECREF (int_);
+    c_long = PYGLIB_PyLong_AsLong (py_long);
+    Py_DECREF (py_long);
 
     /* only 0 or argument of type Flag is allowed */
-    if (!is_instance && arg->v_long != 0)
+    if (!is_instance && c_long != 0)
         goto err;
 
+    /* Write c_long into arg */
+    interface = g_type_info_get_interface (arg_cache->type_info);
+    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
+    if (!gi_argument_from_c_long(arg, c_long,
+                                 g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+        return FALSE;
+    }
+
     return TRUE;
 
 err:
diff --git a/gi/pygi-marshal-from-py.h b/gi/pygi-marshal-from-py.h
index 34511db..b82f890 100644
--- a/gi/pygi-marshal-from-py.h
+++ b/gi/pygi-marshal-from-py.h
@@ -30,6 +30,9 @@
 
 G_BEGIN_DECLS
 
+gboolean _pygi_marshal_from_py_ssize_t     (PyGIArgCache      *arg_cache,
+                                            Py_ssize_t         size,
+                                            GIArgument        *arg);
 gboolean _pygi_marshal_from_py_void        (PyGIInvokeState   *state,
                                             PyGICallableCache *callable_cache,
                                             PyGIArgCache      *arg_cache,
diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
index b906aa2..a80036a 100644
--- a/gi/pygi-marshal-to-py.c
+++ b/gi/pygi-marshal-to-py.c
@@ -34,6 +34,83 @@
 #include "pygi-marshal-cleanup.h"
 #include "pygi-marshal-to-py.h"
 
+gboolean
+gi_argument_to_c_long (GIArgument *arg_in,
+                       long *c_long_out,
+                       GITypeTag type_tag)
+{
+    switch (type_tag) {
+      case GI_TYPE_TAG_INT8:
+          *c_long_out = arg_in->v_int8;
+          return TRUE;
+      case GI_TYPE_TAG_UINT8:
+          *c_long_out = arg_in->v_uint8;
+          return TRUE;
+      case GI_TYPE_TAG_INT16:
+          *c_long_out = arg_in->v_int16;
+          return TRUE;
+      case GI_TYPE_TAG_UINT16:
+          *c_long_out = arg_in->v_uint16;
+          return TRUE;
+      case GI_TYPE_TAG_INT32:
+          *c_long_out = arg_in->v_int32;
+          return TRUE;
+      case GI_TYPE_TAG_UINT32:
+          *c_long_out = arg_in->v_uint32;
+          return TRUE;
+      case GI_TYPE_TAG_INT64:
+          *c_long_out = arg_in->v_int64;
+          return TRUE;
+      case GI_TYPE_TAG_UINT64:
+          *c_long_out = arg_in->v_uint64;
+          return TRUE;
+      default:
+          PyErr_Format (PyExc_TypeError,
+                        "Unable to marshal %s to C long",
+                        g_type_tag_to_string (type_tag));
+          return FALSE;
+    }
+}
+
+gboolean
+gi_argument_to_gsize (GIArgument *arg_in,
+                      gsize      *gsize_out,
+                      GITypeTag   type_tag)
+{
+    switch (type_tag) {
+      case GI_TYPE_TAG_INT8:
+          *gsize_out = arg_in->v_int8;
+          return TRUE;
+      case GI_TYPE_TAG_UINT8:
+          *gsize_out = arg_in->v_uint8;
+          return TRUE;
+      case GI_TYPE_TAG_INT16:
+          *gsize_out = arg_in->v_int16;
+          return TRUE;
+      case GI_TYPE_TAG_UINT16:
+          *gsize_out = arg_in->v_uint16;
+          return TRUE;
+      case GI_TYPE_TAG_INT32:
+          *gsize_out = arg_in->v_int32;
+          return TRUE;
+      case GI_TYPE_TAG_UINT32:
+          *gsize_out = arg_in->v_uint32;
+          return TRUE;
+      case GI_TYPE_TAG_INT64:
+          *gsize_out = arg_in->v_int64;
+          return TRUE;
+      case GI_TYPE_TAG_UINT64:
+          *gsize_out = arg_in->v_uint64;
+          return TRUE;
+      default:
+          PyErr_Format (PyExc_TypeError,
+                        "Unable to marshal %s to gsize",
+                        g_type_tag_to_string (type_tag));
+          return FALSE;
+    }
+}
+
+
 PyObject *
 _pygi_marshal_to_py_void (PyGIInvokeState   *state,
                           PyGICallableCache *callable_cache,
@@ -284,7 +361,12 @@ _pygi_marshal_to_py_array (PyGIInvokeState   *state,
             }
         } else {
             GIArgument *len_arg = state->args[seq_cache->len_arg_index];
-            len = len_arg->v_long;
+
+            if (!gi_argument_to_gsize (len_arg,
+                                       &len,
+                                       callable_cache->args_cache[seq_cache->len_arg_index]->type_tag)) {
+                return NULL;
+            }
         }
 
         array_ = g_array_new (FALSE,
@@ -415,29 +497,6 @@ err:
     return NULL;
 }
 
-static void
-_pygi_hash_pointer_to_arg (GIArgument *arg,
-                           GITypeTag  type_tag)
-{
-    switch (type_tag) {
-        case GI_TYPE_TAG_INT8:
-            arg->v_int8 = GPOINTER_TO_INT(arg->v_pointer);
-            break;
-        case GI_TYPE_TAG_INT16:
-            arg->v_int16 = GPOINTER_TO_INT(arg->v_pointer);
-            break;
-        case GI_TYPE_TAG_INT32:
-            arg->v_int32 = GPOINTER_TO_INT(arg->v_pointer);
-            break;
-        case GI_TYPE_TAG_UTF8:
-        case GI_TYPE_TAG_FILENAME:
-        case GI_TYPE_TAG_INTERFACE:
-            break;
-        default:
-            g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
-    }
-}
-
 PyObject *
 _pygi_marshal_to_py_glist (PyGIInvokeState   *state,
                            PyGICallableCache *callable_cache,
@@ -664,11 +723,21 @@ _pygi_marshal_to_py_interface_enum (PyGIInvokeState   *state,
 {
     PyObject *py_obj = NULL;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+    GIBaseInfo *interface;
+    long c_long;
+
+    interface = g_type_info_get_interface (arg_cache->type_info);
+    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_ENUM);
+
+    if (!gi_argument_to_c_long(arg, &c_long,
+                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+        return NULL;
+    }
 
     if (iface_cache->g_type == G_TYPE_NONE) {
-        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", arg->v_long);
+        py_obj = PyObject_CallFunction (iface_cache->py_type, "l", c_long);
     } else {
-        py_obj = pyg_enum_from_gtype (iface_cache->g_type, arg->v_long);
+        py_obj = pyg_enum_from_gtype (iface_cache->g_type, c_long);
     }
     return py_obj;
 }
@@ -681,6 +750,16 @@ _pygi_marshal_to_py_interface_flags (PyGIInvokeState   *state,
 {
     PyObject *py_obj = NULL;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+    GIBaseInfo *interface;
+    long c_long;
+
+    interface = g_type_info_get_interface (arg_cache->type_info);
+    g_assert (g_base_info_get_type (interface) == GI_INFO_TYPE_FLAGS);
+
+    if (!gi_argument_to_c_long(arg, &c_long,
+                               g_enum_info_get_storage_type ((GIEnumInfo *)interface))) {
+        return NULL;
+    }
 
     if (iface_cache->g_type == G_TYPE_NONE) {
         /* An enum with a GType of None is an enum without GType */
@@ -692,18 +771,18 @@ _pygi_marshal_to_py_interface_flags (PyGIInvokeState   *state,
             return NULL;
 
         py_args = PyTuple_New (1);
-        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_long)) != 0) {
+        if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (c_long)) != 0) {
             Py_DECREF (py_args);
             Py_DECREF (py_type);
             return NULL;
         }
 
-        py_obj = PyObject_CallFunction (py_type, "l", arg->v_long);
+        py_obj = PyObject_CallFunction (py_type, "l", c_long);
 
         Py_DECREF (py_args);
         Py_DECREF (py_type);
     } else {
-        py_obj = pyg_flags_from_gtype (iface_cache->g_type, arg->v_long);
+        py_obj = pyg_flags_from_gtype (iface_cache->g_type, c_long);
     }
 
     return py_obj;



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