[perl-Glib-Object-Introspection] Add a GValue wrapper API



commit 4e061e7656cb08f617fdfa6cd6d5411fc76fd7fd
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Tue Aug 23 00:45:33 2011 +0200

    Add a GValue wrapper API
    
    Called Glib::Object::Introspection::GValueWrapper.  This allows you to marshal
    into GValue if you know the required GType.  Can be used in custom overrides.

 GObjectIntrospection.xs |   56 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 55 insertions(+), 1 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 16be028..9d42232 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -59,6 +59,28 @@ call_carp_croak (const char *msg)
 
 /* ------------------------------------------------------------------------- */
 
+/* Semi-private package for marshalling into GValues. */
+#define GVALUE_WRAPPER_PACKAGE "Glib::Object::Introspection::GValueWrapper"
+
+static GValue *
+SvGValueWrapper (SV *sv)
+{
+	return sv_derived_from (sv, GVALUE_WRAPPER_PACKAGE)
+		? INT2PTR (GValue*, SvIV (SvRV (sv)))
+		: NULL;
+}
+
+static SV *
+newSVGValueWrapper (GValue *v)
+{
+	SV *sv;
+	sv = newSV (0);
+	sv_setref_pv (sv, GVALUE_WRAPPER_PACKAGE, v);
+	return sv;
+}
+
+/* ------------------------------------------------------------------------- */
+
 typedef struct {
 	ffi_cif *cif;
 	ffi_closure *closure;
@@ -1236,7 +1258,9 @@ sv_to_interface (GIArgInfo * arg_info,
 			arg->v_pointer = gperl_closure_new (sv, NULL, FALSE);
 		} else if (type == G_TYPE_VALUE) {
 			dwarn ("    value type\n");
-			croak ("Cannot convert SV to GValue");
+			arg->v_pointer = SvGValueWrapper (sv);
+			if (!arg->v_pointer)
+				croak ("Cannot convert arbitrary SV to GValue");
 		} else {
 			dwarn ("    boxed type: %s (%d)\n",
 			       g_type_name (type), type);
@@ -1310,6 +1334,7 @@ interface_to_sv (GITypeInfo* info, GIArgument *arg, gboolean own)
 		} else if (type == G_TYPE_VALUE) {
 			dwarn ("    value type\n");
 			sv = gperl_sv_from_value (arg->v_pointer);
+			/* FIXME: Check 'own'. */
 		} else {
 			dwarn ("    boxed type: %d (%s)\n",
 			       type, g_type_name (type));
@@ -2863,3 +2888,32 @@ _invoke (class, basename, namespace, method, ...)
 		PUTBACK;
 		return;
 	}
+
+# --------------------------------------------------------------------------- #
+
+MODULE = Glib::Object::Introspection	PACKAGE = Glib::Object::Introspection::GValueWrapper
+
+SV *
+new (class, const gchar *type_package, SV *perl_value)
+    PREINIT:
+	GType type;
+	GValue *v;
+    CODE:
+	type = gperl_type_from_package (type_package);
+	if (!type)
+		croak ("Could not find GType for '%s'", type_package);
+	v = g_new0 (GValue, 1);
+	g_value_init (v, type);
+	gperl_value_from_sv (v, perl_value);
+	RETVAL = newSVGValueWrapper (v);
+    OUTPUT:
+	RETVAL
+
+void
+DESTROY (SV *sv)
+    PREINIT:
+	GValue *v;
+    CODE:
+	v = SvGValueWrapper (sv);
+	g_value_unset (v);
+	g_free (v);



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