[perl-Glib-Object-Introspection] Add support for marshalling GVariants



commit 8c026e82e3378bb16dcefe2cc1e25c9ffaae9666
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Sun Jan 18 19:40:08 2015 +0100

    Add support for marshalling GVariants

 Makefile.PL                    |    4 +-
 NEWS                           |    5 +++
 README                         |    2 +-
 gperl-i11n-marshal-interface.c |   54 ++++++++++++++++++++++++++++++++++------
 t/variants.t                   |   22 ++++++++++++++++
 5 files changed, 76 insertions(+), 11 deletions(-)
---
diff --git a/Makefile.PL b/Makefile.PL
index 055e5d4..5509153 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -23,7 +23,7 @@ use Config;
 use Cwd;
 
 my %RUNTIME_REQ_PM = (
-  'Glib' => 1.280,
+  'Glib' => 1.310, # FIXME: 1.320
 );
 
 my %CONFIG_REQ_PM = (
@@ -54,7 +54,7 @@ my %meta_merge = (
         },
         author              =>
             ['Glib::Object::Introspection Team <gtk-perl-list at gnome dot org>'],
-        release_status      => 'stable',
+        release_status      => 'unstable', # Until we can depend on Glib 1.320.
         # valid values: https://metacpan.org/module/CPAN::Meta::Spec#license
         license             => 'lgpl_2_1',
         resources => {
diff --git a/NEWS b/NEWS
index 5c760e3..384e589 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Overview of changes in Glib::Object::Introspection <next>
+========================================================
+
+* Add support for marshalling GVariants.
+
 Overview of changes in Glib::Object::Introspection 0.028
 ========================================================
 
diff --git a/README b/README
index 4b3fbcf..fc201d0 100644
--- a/README
+++ b/README
@@ -28,7 +28,7 @@ and these Perl modules:
 
   ExtUtils::Depends   >= 0.300
   ExtUtils::PkgConfig >= 1.000
-  Glib                >= 1.240
+  Glib                >= 1.310 # FIXME: 1.320
 
 
 HOW TO CONTACT US
diff --git a/gperl-i11n-marshal-interface.c b/gperl-i11n-marshal-interface.c
index 43efb6a..dedee79 100644
--- a/gperl-i11n-marshal-interface.c
+++ b/gperl-i11n-marshal-interface.c
@@ -155,9 +155,9 @@ sv_to_interface (GIArgInfo * arg_info,
                if (!type || type == G_TYPE_NONE) {
                        const gchar *namespace, *name, *package;
                        GType parent_type;
-                       dwarn ("    unboxed type\n");
+                       dwarn ("    untyped record\n");
                        g_assert (!need_value_semantics);
-                       /* Find out whether this untyped struct is a member of
+                       /* Find out whether this untyped record is a member of
                         * a boxed union before using raw hash-to-struct
                         * conversion. */
                        name = g_base_info_get_name (interface);
@@ -177,12 +177,16 @@ sv_to_interface (GIArgInfo * arg_info,
                                                               info_type,
                                                               sv);
                        }
-               } else if (type == G_TYPE_CLOSURE) {
+               }
+
+               else if (type == G_TYPE_CLOSURE) {
                        /* FIXME: User cannot supply user data. */
                        dwarn ("    closure type\n");
                        g_assert (!need_value_semantics);
                        arg->v_pointer = gperl_closure_new (sv, NULL, FALSE);
-               } else if (type == G_TYPE_VALUE) {
+               }
+
+               else if (type == G_TYPE_VALUE) {
                        GValue *gvalue = SvGValueWrapper (sv);
                        dwarn ("    value type\n");
                        if (!gvalue)
@@ -199,7 +203,9 @@ sv_to_interface (GIArgInfo * arg_info,
                                        arg->v_pointer = gvalue;
                                }
                        }
-               } else {
+               }
+
+               else if (g_type_is_a (type, G_TYPE_BOXED)) {
                        dwarn ("    boxed type: %s, name=%s, caller-allocates=%d, is-pointer=%d\n",
                               g_type_name (type),
                               g_base_info_get_name (interface),
@@ -224,6 +230,21 @@ sv_to_interface (GIArgInfo * arg_info,
                                }
                        }
                }
+
+#if GLIB_CHECK_VERSION (2, 24, 0)
+               else if (g_type_is_a (type, G_TYPE_VARIANT)) {
+                       dwarn ("    variant type\n");
+                       g_assert (!need_value_semantics);
+                       arg->v_pointer = SvGVariant (sv);
+                       if (GI_TRANSFER_EVERYTHING == transfer)
+                               g_variant_ref (arg->v_pointer);
+               }
+#endif
+
+               else {
+                       ccroak ("Cannot convert SV to record value of unknown type %s (%" G_GSIZE_FORMAT ")",
+                               g_type_name (type), type);
+               }
                break;
            }
 
@@ -300,18 +321,35 @@ interface_to_sv (GITypeInfo* info, GIArgument *arg, gboolean own, GPerlI11nInvoc
                GType type;
                type = get_gtype ((GIRegisteredTypeInfo *) interface);
                if (!type || type == G_TYPE_NONE) {
-                       dwarn ("    unboxed type\n");
+                       dwarn ("    untyped record\n");
                        sv = struct_to_sv (interface, info_type, arg->v_pointer, own);
-               } else if (type == G_TYPE_VALUE) {
+               }
+
+               else if (type == G_TYPE_VALUE) {
                        dwarn ("    value type\n");
                        sv = gperl_sv_from_value (arg->v_pointer);
                        if (own)
                                g_boxed_free (type, arg->v_pointer);
-               } else {
+               }
+
+               else if (g_type_is_a (type, G_TYPE_BOXED)) {
                        dwarn ("    boxed type: %"G_GSIZE_FORMAT" (%s)\n",
                               type, g_type_name (type));
                        sv = gperl_new_boxed (arg->v_pointer, type, own);
                }
+
+#if GLIB_CHECK_VERSION (2, 24, 0)
+               else if (g_type_is_a (type, G_TYPE_VARIANT)) {
+                       dwarn ("    variant type\n");
+                       sv = own ? newSVGVariant_noinc (arg->v_pointer)
+                                : newSVGVariant (arg->v_pointer);
+               }
+#endif
+
+               else {
+                       ccroak ("Cannot convert record value of unknown type %s (%" G_GSIZE_FORMAT ") to SV",
+                               g_type_name (type), type);
+               }
                break;
            }
 
diff --git a/t/variants.t b/t/variants.t
new file mode 100644
index 0000000..234919c
--- /dev/null
+++ b/t/variants.t
@@ -0,0 +1,22 @@
+#!/usr/bin/env perl
+
+BEGIN { require './t/inc/setup.pl' };
+
+use strict;
+use warnings;
+use utf8;
+
+plan tests => 6;
+
+my $v1 = Glib::Variant->new ("i", 27);
+my $v2 = Glib::Variant->new ("s", "Hello");
+
+check_variants (GI::array_gvariant_none_in ([$v1, $v2]));
+check_variants (GI::array_gvariant_container_in ([$v1, $v2]));
+check_variants (GI::array_gvariant_full_in ([$v1, $v2]));
+
+sub check_variants {
+  my ($v1, $v2) = @{$_[0]};
+  is ($v1->get ("i"), 27);
+  is ($v2->get ("s"), "Hello");
+}


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