Ticket #4131: 0001-Add-support-for-caller-allocated-GArray-out-argument.patch

File 0001-Add-support-for-caller-allocated-GArray-out-argument.patch, 4.9 KB (added by godiard, 11 years ago)

Backported patch for pygobject

  • gi/pygi-cache.c

    From bbb9823307335d28e121a026b081d845410a6e0d Mon Sep 17 00:00:00 2001
    From: Martin Pitt <martinpitt@gnome.org>
    Date: Mon, 17 Dec 2012 18:02:15 +0100
    Subject: [PATCH] Add support for caller-allocated GArray out arguments to
     3.4.3 branch
    
    Backported from 3.7.3
    
    https://bugzilla.gnome.org/show_bug.cgi?id=690041
    ---
     gi/pygi-cache.c  |  2 +-
     gi/pygi-invoke.c | 57 ++++++++++++++++++++++++++++++--------------------------
     tests/test_gi.py |  3 +++
     3 files changed, 35 insertions(+), 27 deletions(-)
    
    diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
    index 21dd58f..2a44c02 100644
    a b _args_cache_generate (GICallableInfo *callable_info, 
    13701370        type_info = g_arg_info_get_type (arg_info);
    13711371        type_tag = g_type_info_get_tag (type_info);
    13721372
    1373         if (type_tag == GI_TYPE_TAG_INTERFACE)
     1373        if (type_tag == GI_TYPE_TAG_INTERFACE || type_tag == GI_TYPE_TAG_ARRAY)
    13741374            is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
    13751375
    13761376        /* must be an child arg filled in by its owner
  • gi/pygi-invoke.c

    diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
    index c0f7179..195a830 100644
    a b static gboolean _caller_alloc (PyGIInvokeState *state, 
    361361                               gssize arg_count,
    362362                               gssize out_count)
    363363{
    364     PyGIInterfaceCache *iface_cache;
    365 
    366     g_assert (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE);
    367 
    368     iface_cache = (PyGIInterfaceCache *)arg_cache;
    369 
    370     state->out_args[out_count].v_pointer = NULL;
    371     state->args[arg_count] = &state->out_args[out_count];
    372     if (iface_cache->g_type == G_TYPE_BOXED) {
    373         state->args[arg_count]->v_pointer =
    374             _pygi_boxed_alloc (iface_cache->interface_info, NULL);
    375     } else if (iface_cache->g_type == G_TYPE_VALUE) {
    376         state->args[arg_count]->v_pointer = g_slice_new0 (GValue);
    377     } else if (iface_cache->is_foreign) {
    378         PyObject *foreign_struct =
    379             pygi_struct_foreign_convert_from_g_argument (
    380                 iface_cache->interface_info,
    381                 NULL);
    382 
    383             pygi_struct_foreign_convert_to_g_argument (foreign_struct,
    384                                                        iface_cache->interface_info,
    385                                                        GI_TRANSFER_EVERYTHING,
    386                                                        state->args[arg_count]);
     364    if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
     365        PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
     366
     367        state->out_args[out_count].v_pointer = NULL;
     368        state->args[arg_count] = &state->out_args[out_count];
     369        if (iface_cache->g_type == G_TYPE_BOXED) {
     370            state->args[arg_count]->v_pointer =
     371                _pygi_boxed_alloc (iface_cache->interface_info, NULL);
     372        } else if (iface_cache->g_type == G_TYPE_VALUE) {
     373            state->args[arg_count]->v_pointer = g_slice_new0 (GValue);
     374        } else if (iface_cache->is_foreign) {
     375            PyObject *foreign_struct =
     376                pygi_struct_foreign_convert_from_g_argument (
     377                    iface_cache->interface_info,
     378                    NULL);
     379
     380                pygi_struct_foreign_convert_to_g_argument (foreign_struct,
     381                                                           iface_cache->interface_info,
     382                                                           GI_TRANSFER_EVERYTHING,
     383                                                           state->args[arg_count]);
     384        } else {
     385                gssize size = g_struct_info_get_size(
     386                    (GIStructInfo *)iface_cache->interface_info);
     387                state->args[arg_count]->v_pointer = g_malloc0 (size);
     388        }
     389    } else if (arg_cache->type_tag == GI_TYPE_TAG_ARRAY) {
     390        PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
     391
     392        state->out_args[out_count].v_pointer = g_array_new (TRUE, TRUE, seq_cache->item_size);
     393        state->args[arg_count] = &state->out_args[out_count];
    387394    } else {
    388             gssize size = g_struct_info_get_size(
    389                 (GIStructInfo *)iface_cache->interface_info);
    390             state->args[arg_count]->v_pointer = g_malloc0 (size);
     395        return FALSE;
    391396    }
    392397
    393398    if (state->args[arg_count]->v_pointer == NULL)
  • tests/test_gi.py

    diff --git a/tests/test_gi.py b/tests/test_gi.py
    index 315867a..72d6c7c 100644
    a b class TestGArray(unittest.TestCase): 
    864864    def test_garray_utf8_full_out(self):
    865865        self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_out())
    866866
     867    def test_garray_utf8_full_out_caller_allocated(self):
     868        self.assertEqual(['0', '1', '2'], GIMarshallingTests.garray_utf8_full_out_caller_allocated())
     869
    867870    def test_garray_utf8_none_inout(self):
    868871        self.assertEqual(['-2', '-1', '0', '1'], GIMarshallingTests.garray_utf8_none_inout(Sequence(('0', '1', '2'))))
    869872