[gjs] Support marshalling arguments that are GVariants
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Support marshalling arguments that are GVariants
- Date: Tue, 21 Jun 2011 14:33:57 +0000 (UTC)
commit 6dca0dde9c2d3a0dfc7b353cf6ad118d6cc48b26
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Tue Mar 29 18:05:25 2011 +0200
Support marshalling arguments that are GVariants
Initial GVariant support, includes only obtaining a GVariant from
a method that returns one and passing it around mantaining a correct
reference count.
Has some basic unit tests, will add more alongside the JS convenience
layer.
https://bugzilla.gnome.org/show_bug.cgi?id=622344
gi/arg.c | 5 +++++
gi/boxed.c | 25 ++++++++++++++++++++-----
gi/value.c | 25 +++++++++++++++++++++++--
test/js/testEverythingBasic.js | 22 ++++++++++++++++++++++
4 files changed, 70 insertions(+), 7 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index 0205266..667a177 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -1154,6 +1154,8 @@ gjs_value_to_g_argument(JSContext *context,
if (transfer != GI_TRANSFER_NOTHING) {
if (g_type_is_a(gtype, G_TYPE_BOXED))
arg->v_pointer = g_boxed_copy (gtype, arg->v_pointer);
+ else if (g_type_is_a(gtype, G_TYPE_VARIANT))
+ g_variant_ref (arg->v_pointer);
else {
gjs_throw(context,
"Can't transfer ownership of a structure type not registered as boxed");
@@ -2519,6 +2521,9 @@ gjs_g_arg_release_internal(JSContext *context,
} else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
if (transfer != TRANSFER_IN_NOTHING)
g_boxed_free(gtype, arg->v_pointer);
+ } else if (g_type_is_a(gtype, G_TYPE_VARIANT)) {
+ if (transfer != TRANSFER_IN_NOTHING)
+ g_variant_unref (arg->v_pointer);
} else if (gtype == G_TYPE_NONE) {
if (transfer != TRANSFER_IN_NOTHING) {
gjs_throw(context, "Don't know how to release GArgument: not an object or boxed type");
diff --git a/gi/boxed.c b/gi/boxed.c
index 11297e9..53a68f8 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -503,19 +503,27 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(boxed)
if (unthreadsafe_template_for_constructor.gboxed == NULL) {
Boxed *source_priv;
+ GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
/* Short-circuit copy-construction in the case where we can use g_boxed_copy */
if (argc == 1 &&
boxed_get_copy_source(context, priv, argv[0], &source_priv)) {
- GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
- if (gtype != G_TYPE_NONE) {
+ if (gtype != G_TYPE_NONE && g_type_is_a (gtype, G_TYPE_BOXED)) {
priv->gboxed = g_boxed_copy(gtype, source_priv->gboxed);
GJS_NATIVE_CONSTRUCTOR_FINISH(boxed);
return JS_TRUE;
}
}
+ /* Short-circuit construction for GVariants (simply cannot construct here,
+ the constructor should be overridden) */
+ if (g_type_is_a(gtype, G_TYPE_VARIANT)) {
+ gjs_throw(context,
+ "Can't create instance of GVariant directly, use GVariant.new_*");
+ return JS_FALSE;
+ }
+
if (!boxed_new(context, object, priv))
return JS_FALSE;
@@ -548,9 +556,11 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(boxed)
GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
JSBool retval;
- if (gtype != G_TYPE_NONE) {
+ if (gtype != G_TYPE_NONE && g_type_is_a (gtype, G_TYPE_BOXED)) {
priv->gboxed = g_boxed_copy(gtype,
unthreadsafe_template_for_constructor.gboxed);
+ } else if (g_type_is_a(gtype, G_TYPE_VARIANT)) {
+ priv->gboxed = g_variant_ref_sink (unthreadsafe_template_for_constructor.gboxed);
} else if (priv->can_allocate_directly) {
if (!boxed_new_direct(context, object, priv))
return JS_FALSE;
@@ -597,7 +607,12 @@ boxed_finalize(JSContext *context,
GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
g_assert(gtype != G_TYPE_NONE);
- g_boxed_free(gtype, priv->gboxed);
+ if (g_type_is_a (gtype, G_TYPE_BOXED))
+ g_boxed_free (gtype, priv->gboxed);
+ else if (g_type_is_a (gtype, G_TYPE_VARIANT))
+ g_variant_unref (priv->gboxed);
+ else
+ g_assert_not_reached ();
}
priv->gboxed = NULL;
@@ -1020,7 +1035,7 @@ gjs_lookup_boxed_constructor(JSContext *context,
JSObject*
gjs_lookup_boxed_prototype(JSContext *context,
- GIBoxedInfo *info)
+ GIBoxedInfo *info)
{
JSObject *ns;
JSObject *proto;
diff --git a/gi/value.c b/gi/value.c
index 28b8d3d..2de1401 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -403,6 +403,23 @@ gjs_value_to_g_value_internal(JSContext *context,
g_value_set_static_boxed(gvalue, gboxed);
else
g_value_set_boxed(gvalue, gboxed);
+ } else if (g_type_is_a(gtype, G_TYPE_VARIANT)) {
+ GVariant *variant = NULL;
+
+ if (JSVAL_IS_NULL(value)) {
+ /* nothing to do */
+ } else if (JSVAL_IS_OBJECT(value)) {
+ JSObject *obj = JSVAL_TO_OBJECT(value);
+ variant = gjs_c_struct_from_boxed(context, obj);
+ } else {
+ gjs_throw(context,
+ "Wrong type %s; boxed type %s expected",
+ gjs_get_type_name(value),
+ g_type_name(gtype));
+ return JS_FALSE;
+ }
+
+ g_value_set_variant (gvalue, variant);
} else if (g_type_is_a(gtype, G_TYPE_ENUM)) {
gint64 value_int64;
@@ -627,13 +644,17 @@ gjs_value_from_g_value_internal(JSContext *context,
gjs_throw(context,
"Unable to introspect element-type of container in GValue");
return JS_FALSE;
- } else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
+ } else if (g_type_is_a(gtype, G_TYPE_BOXED) ||
+ g_type_is_a(gtype, G_TYPE_VARIANT)) {
GjsBoxedCreationFlags boxed_flags;
GIBaseInfo *info;
void *gboxed;
JSObject *obj;
- gboxed = g_value_get_boxed(gvalue);
+ if (g_type_is_a(gtype, G_TYPE_BOXED))
+ gboxed = g_value_get_boxed(gvalue);
+ else
+ gboxed = g_value_get_variant(gvalue);
boxed_flags = GJS_BOXED_CREATION_NONE;
/* The only way to differentiate unions and structs is from
diff --git a/test/js/testEverythingBasic.js b/test/js/testEverythingBasic.js
index f74e4f6..264b216 100644
--- a/test/js/testEverythingBasic.js
+++ b/test/js/testEverythingBasic.js
@@ -7,6 +7,7 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
}
// We use Gio to have some objects that we know exist
+const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
@@ -462,4 +463,25 @@ function testStrvInGValue() {
assertEquals(v[2], "three");
}
+function testVariant() {
+ // Cannot access the variant contents, for now
+ let ivar = Everything.test_gvariant_i();
+ assertEquals('i', ivar.get_type_string());
+ assertTrue(ivar.equal(GLib.Variant.new_int32(1)));
+
+ let svar = Everything.test_gvariant_s();
+ assertEquals('s', String.fromCharCode(svar.classify()));
+ assertEquals('one', svar.get_string()[0]);
+
+ let asvvar = Everything.test_gvariant_asv();
+ assertEquals(2, asvvar.n_children());
+
+ let asvar = Everything.test_gvariant_as();
+ let as = asvar.get_strv();
+ assertEquals('one', as[0]);
+ assertEquals('two', as[1]);
+ assertEquals('three', as[2]);
+ assertEquals(3, as.length);
+}
+
gjstestRun();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]