[pygobject/invoke-rewrite] [gi] make caller allocates work again



commit d57500537014b3da624be33b40401ba289fa22b8
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu Feb 3 09:02:16 2011 -0500

    [gi] make caller allocates work again

 gi/pygi-cache.c  |   18 +++---------------
 gi/pygi-invoke.c |   37 ++++++++++++++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 18 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index cbc54f4..230017f 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -31,7 +31,6 @@ PyGIArgCache * _arg_cache_new_from_type_info (GITypeInfo *type_info,
                                               GITypeTag type_tag,
                                               GITransfer transfer,
                                               GIDirection direction,
-                                              gboolean is_caller_allocates,
                                               gint c_arg_index,
                                               gint py_arg_index);
 
@@ -190,7 +189,6 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info,
                                                    item_type_tag,
                                                    item_transfer,
                                                    direction,
-                                                   FALSE,
                                                    0, 0);
 
     if (sc->item_cache == NULL) {
@@ -232,7 +230,6 @@ _hash_cache_new_from_type_info(GITypeInfo *type_info,
                                                   key_type_tag,
                                                   item_transfer,
                                                   direction,
-                                                  FALSE,
                                                   0, 0);
 
     if (hc->key_cache == NULL) {
@@ -246,7 +243,6 @@ _hash_cache_new_from_type_info(GITypeInfo *type_info,
                                                     value_type_tag,
                                                     item_transfer,
                                                     direction,
-                                                    FALSE,
                                                     0, 0);
 
     if (hc->value_cache == NULL) {
@@ -866,7 +862,6 @@ _arg_cache_new_from_type_info (GITypeInfo *type_info,
                                GITypeTag type_tag,
                                GITransfer transfer,
                                GIDirection direction,
-                               gboolean is_caller_allocates,
                                gint c_arg_index,
                                gint py_arg_index)
 {
@@ -1241,7 +1236,6 @@ _args_cache_generate(GIFunctionInfo *function_info,
                                       return_type_tag,
                                       return_transfer,
                                       GI_DIRECTION_OUT,
-                                      FALSE,
                                       -1,
                                       -1);
 
@@ -1297,6 +1291,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
         transfer = g_arg_info_get_ownership_transfer(arg_info);
         type_info = g_arg_info_get_type(arg_info);
         type_tag = g_type_info_get_tag(type_info);
+        is_caller_allocates = g_arg_info_is_caller_allocates(arg_info);
 
         /* must be an aux arg filled in by its owner
          * fill in it's c_arg_index, add to the in count
@@ -1336,24 +1331,17 @@ _args_cache_generate(GIFunctionInfo *function_info,
                                           type_tag,
                                           transfer,
                                           direction,
-                                          FALSE,
                                           arg_index,
                                           py_arg_index);
 
         if (arg_cache == NULL)
             goto arg_err;
 
-        arg_cache->allow_none = g_arg_info_may_be_null (arg_info);
+        arg_cache->allow_none = g_arg_info_may_be_null(arg_info);
+        arg_cache->is_caller_allocates = is_caller_allocates;
 
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
             function_cache->n_out_args++;
-            is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
-            if (is_caller_allocates) {
-                PyErr_Format(PyExc_NotImplementedError,
-                             "Caller allocates is not fully implemented yet");
-
-                goto arg_err;
-            }
 
             if (arg_cache == NULL)
                 goto arg_err;
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 15b9c7b..f88965a 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -1021,8 +1021,39 @@ _invoke_marshal_in_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
                                          arg_cache->py_arg_index);
                 }
             case GI_DIRECTION_OUT:
-                state->out_args[out_count].v_pointer = &state->out_values[out_count];
-                state->args[i] = &state->out_values[out_count];
+                if (arg_cache->is_caller_allocates) {
+                    PyGIInterfaceCache *iface_cache =
+                        (PyGIInterfaceCache *)arg_cache;
+
+                    g_assert(arg_cache->type_tag == GI_TYPE_TAG_INTERFACE);
+
+                    state->out_args[out_count].v_pointer = NULL;
+                    state->args[i] = &state->out_args[out_count];
+                    if (iface_cache->g_type == G_TYPE_BOXED) {
+                        state->args[i]->v_pointer =
+                            _pygi_boxed_alloc(iface_cache->interface_info, NULL);
+                    } else if (iface_cache->is_foreign) {
+                        PyObject *foreign_struct =
+                            pygi_struct_foreign_convert_from_g_argument(
+                                iface_cache->interface_info,
+                                NULL);
+
+                        pygi_struct_foreign_convert_to_g_argument(
+                            foreign_struct,
+                            iface_cache->interface_info,
+                            GI_TRANSFER_EVERYTHING,
+                            state->args[i]);
+                    } else {
+                        gssize size =
+                            g_struct_info_get_size(
+                                (GIStructInfo *)iface_cache->interface_info);
+                        state->args[i]->v_pointer = g_malloc0(size);
+                    }
+
+                } else {
+                    state->out_args[out_count].v_pointer = &state->out_values[out_count];
+                    state->args[i] = &state->out_values[out_count];
+                }
                 out_count++;
                 break;
         }
@@ -1089,7 +1120,7 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
         py_out = arg_cache->out_marshaller(state,
                                            cache,
                                            arg_cache,
-                                           &(state->out_values[0]));
+                                           state->args[arg_cache->c_arg_index]);
     } else {
         int out_cache_index = 0;
         int py_arg_index = 0;



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