[glib] Add fundamental type and pspec for GVariant
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Add fundamental type and pspec for GVariant
- Date: Thu, 17 Jun 2010 19:01:47 +0000 (UTC)
commit 4708b8ecc3f00e49aa98cb5989b5474a3257906c
Author: Christian Persch <chpe gnome org>
Date: Thu Jun 17 18:03:51 2010 +0200
Add fundamental type and pspec for GVariant
Make G_TYPE_VARIANT a fundamental type instead of boxed, and add
g_variant_{set,get,dup}_variant.
Add GParamSpecVariant.
Bug #610863.
NEWS | 4 +
docs/reference/gobject/gobject-sections.txt | 13 ++-
gobject/gboxed.c | 15 ++--
gobject/gboxed.h | 13 +--
gobject/glib-genmarshal.c | 4 +
gobject/gmarshal.list | 2 +
gobject/gobject.symbols | 6 +-
gobject/gparamspecs.c | 127 +++++++++++++++++++++++-
gobject/gparamspecs.h | 52 ++++++++++
gobject/gtype.h | 13 ++-
gobject/gvaluetypes.c | 148 +++++++++++++++++++++++++++
gobject/gvaluetypes.h | 15 +++
tests/gobject/gvalue-test.c | 38 ++++++--
tests/gobject/paramspec-test.c | 46 +++++++--
14 files changed, 461 insertions(+), 35 deletions(-)
---
diff --git a/NEWS b/NEWS
index 0ba9da1..f2e1d54 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,10 @@ and GApplication. Users of these APIs will need to be adapted.
* GObject
- Introduce g_object_notify_by_pspec
- Add GBinding
+ - The GVariant gtype G_TYPE_VARIANT was changed from boxed
+ to fundamental. We believe there were no existing users
+ of the boxed type, so this should not cause any applications
+ to break.
* Test framework
- Add package and version to the test report XML
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index 4b1bf0f..483c785 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -147,6 +147,7 @@ G_TYPE_BOXED
G_TYPE_PARAM
G_TYPE_OBJECT
G_TYPE_GTYPE
+G_TYPE_VARIANT
<SUBSECTION>
G_TYPE_RESERVED_GLIB_FIRST
@@ -351,7 +352,6 @@ G_TYPE_REGEX
G_TYPE_ARRAY
G_TYPE_BYTE_ARRAY
G_TYPE_PTR_ARRAY
-G_TYPE_VARIANT
G_TYPE_VARIANT_TYPE
G_TYPE_ERROR
GStrv
@@ -698,6 +698,17 @@ g_param_spec_gtype
g_value_get_gtype
g_value_set_gtype
+<SUBSECTION GVariant>
+G_IS_PARAM_SPEC_VARIANT
+G_PARAM_SPEC_VARIANT
+G_VALUE_HOLDS_VARIANT
+G_TYPE_PARAM_VARIANT
+GParamSpecVariant
+g_param_spec_variant
+g_value_get_variant
+g_value_dup_variant
+g_value_set_variant
+
<SUBSECTION Private>
g_value_set_instance
g_param_spec_types
diff --git a/gobject/gboxed.c b/gobject/gboxed.c
index f18ffb5..0685093 100644
--- a/gobject/gboxed.c
+++ b/gobject/gboxed.c
@@ -286,17 +286,16 @@ g_variant_type_get_gtype (void)
return type_id;
}
+/**
+ * g_variant_get_gtype:
+ *
+ * Since: 2.24
+ * Deprecated: 2.26
+ */
GType
g_variant_get_gtype (void)
{
- static GType type_id = 0;
-
- if (!type_id)
- type_id = g_boxed_type_register_static (g_intern_static_string ("GVariant"),
- (GBoxedCopyFunc) g_variant_ref,
- (GBoxedFreeFunc) g_variant_unref);
-
- return type_id;
+ return G_TYPE_VARIANT;
}
GType
diff --git a/gobject/gboxed.h b/gobject/gboxed.h
index f46728b..baac62c 100644
--- a/gobject/gboxed.h
+++ b/gobject/gboxed.h
@@ -195,14 +195,6 @@ GType g_boxed_type_register_static (const gchar *name,
*/
#define G_TYPE_VARIANT_TYPE (g_variant_type_get_gtype ())
/**
- * G_TYPE_VARIANT:
- *
- * The #GType for a boxed type holding a #GVariant reference.
- *
- * Since: 2.24
- */
-#define G_TYPE_VARIANT (g_variant_get_gtype ())
-/**
* G_TYPE_ERROR:
*
* The #GType for a boxed type holding a #GError.
@@ -229,10 +221,13 @@ GType g_array_get_type (void) G_GNUC_CONST;
GType g_byte_array_get_type (void) G_GNUC_CONST;
GType g_ptr_array_get_type (void) G_GNUC_CONST;
GType g_variant_type_get_gtype(void) G_GNUC_CONST;
-GType g_variant_get_gtype (void) G_GNUC_CONST;
GType g_regex_get_type (void) G_GNUC_CONST;
GType g_error_get_type (void) G_GNUC_CONST;
+#ifndef G_DISABLE_DEPRECATED
+GType g_variant_get_gtype (void) G_GNUC_CONST;
+#endif
+
/**
* GStrv:
*
diff --git a/gobject/glib-genmarshal.c b/gobject/glib-genmarshal.c
index f96f466..e382fdc 100644
--- a/gobject/glib-genmarshal.c
+++ b/gobject/glib-genmarshal.c
@@ -151,6 +151,7 @@ put_marshal_value_getters (void)
fputs ("#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)\n", fout);
fputs ("#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)\n", fout);
fputs ("#define g_marshal_value_peek_object(v) g_value_get_object (v)\n", fout);
+ fputs ("#define g_marshal_value_peek_variant(v) g_value_get_variant (v)\n", fout);
fputs ("#else /* !G_ENABLE_DEBUG */\n", fout);
fputs ("/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.\n", fout);
fputs (" * Do not access GValues directly in your code. Instead, use the\n", fout);
@@ -174,6 +175,7 @@ put_marshal_value_getters (void)
fputs ("#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer\n", fout);
fputs ("#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer\n", fout);
fputs ("#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer\n", fout);
+ fputs ("#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer\n", fout);
fputs ("#endif /* !G_ENABLE_DEBUG */\n", fout);
fputs ("\n", fout);
}
@@ -202,6 +204,7 @@ complete_in_arg (InArgument *iarg)
{ "BOXED", "BOXED", "gpointer", "g_marshal_value_peek_boxed", },
{ "POINTER", "POINTER", "gpointer", "g_marshal_value_peek_pointer", },
{ "OBJECT", "OBJECT", "gpointer", "g_marshal_value_peek_object", },
+ { "VARIANT", "VARIANT", "gpointer", "g_marshal_value_peek_variant", },
/* deprecated: */
{ "NONE", "VOID", "void", NULL, },
{ "BOOL", "BOOLEAN", "gboolean", "g_marshal_value_peek_boolean", },
@@ -246,6 +249,7 @@ complete_out_arg (OutArgument *oarg)
{ "BOXED", "BOXED", "gpointer", "g_value_take_boxed", },
{ "POINTER", "POINTER", "gpointer", "g_value_set_pointer", },
{ "OBJECT", "OBJECT", "GObject*", "g_value_take_object", },
+ { "VARIANT", "VARIANT", "GVariant*", "g_value_take_variant", },
/* deprecated: */
{ "NONE", "VOID", "void", NULL, },
{ "BOOL", "BOOLEAN", "gboolean", "g_value_set_boolean", },
diff --git a/gobject/gmarshal.list b/gobject/gmarshal.list
index f3844a1..533307b 100644
--- a/gobject/gmarshal.list
+++ b/gobject/gmarshal.list
@@ -19,6 +19,7 @@
# BOXED for boxed (anonymous but reference counted) types (GBoxed*)
# POINTER for anonymous pointer types (gpointer)
# OBJECT for GObject or derived types (GObject*)
+# VARIANT for variants (GVariant*)
# NONE deprecated alias for VOID
# BOOL deprecated alias for BOOLEAN
@@ -40,6 +41,7 @@ VOID:PARAM
VOID:BOXED
VOID:POINTER
VOID:OBJECT
+VOID:VARIANT
# GRuntime specific marshallers
VOID:UINT,POINTER
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index f47f9e6..0c3dd5b 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -41,7 +41,6 @@ g_error_get_type G_GNUC_CONST
g_ptr_array_get_type G_GNUC_CONST
g_regex_get_type G_GNUC_CONST
g_variant_type_get_gtype G_GNUC_CONST
-g_variant_get_gtype G_GNUC_CONST
g_closure_get_type G_GNUC_CONST
g_value_get_type G_GNUC_CONST
g_value_array_get_type G_GNUC_CONST
@@ -52,6 +51,7 @@ g_value_get_boxed
g_value_set_static_boxed
#ifndef G_DISABLE_DEPRECATED
g_value_set_boxed_take_ownership
+g_variant_get_gtype G_GNUC_CONST
#endif
#endif
#endif
@@ -215,6 +215,7 @@ g_param_spec_uint64
g_param_spec_ulong
g_param_spec_unichar
g_param_spec_value_array
+g_param_spec_variant
#endif
#endif
@@ -294,6 +295,9 @@ g_value_take_string
g_gtype_get_type
g_value_set_gtype
g_value_get_gtype
+g_value_get_variant
+g_value_dup_variant
+g_value_set_variant
#endif
#endif
diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
index 2f49824..3bdfaf7 100644
--- a/gobject/gparamspecs.c
+++ b/gobject/gparamspecs.c
@@ -1,5 +1,6 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
+ * Copyright (C) 2010 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1098,13 +1099,71 @@ param_gtype_values_cmp (GParamSpec *pspec,
return p1 < p2 ? -1 : p1 > p2;
}
+static void
+param_variant_init (GParamSpec *pspec)
+{
+ GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
+
+ vspec->type = NULL;
+ vspec->default_value = NULL;
+}
+
+static void
+param_variant_finalize (GParamSpec *pspec)
+{
+ GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
+ GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
+
+ if (vspec->default_value)
+ g_variant_unref (vspec->default_value);
+ g_variant_type_free (vspec->type);
+
+ parent_class->finalize (pspec);
+}
+
+static void
+param_variant_set_default (GParamSpec *pspec,
+ GValue *value)
+{
+ value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
+ value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
+}
+
+static gboolean
+param_variant_validate (GParamSpec *pspec,
+ GValue *value)
+{
+ GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
+ GVariant *variant = value->data[0].v_pointer;
+
+ if ((variant == NULL && vspec->default_value != NULL) ||
+ (variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
+ {
+ g_param_value_set_default (pspec, value);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gint
+param_variant_values_cmp (GParamSpec *pspec,
+ const GValue *value1,
+ const GValue *value2)
+{
+ GVariant *v1 = value1->data[0].v_pointer;
+ GVariant *v2 = value2->data[0].v_pointer;
+
+ return v1 < v2 ? -1 : v2 > v1;
+}
+
/* --- type initialization --- */
GType *g_param_spec_types = NULL;
void
g_param_spec_types_init (void)
{
- const guint n_types = 22;
+ const guint n_types = 23;
GType type, *spec_types, *spec_types_bound;
g_param_spec_types = g_new0 (GType, n_types);
@@ -1509,6 +1568,24 @@ g_param_spec_types_init (void)
g_assert (type == G_TYPE_PARAM_GTYPE);
}
+ /* G_TYPE_PARAM_VARIANT
+ */
+ {
+ const GParamSpecTypeInfo pspec_info = {
+ sizeof (GParamSpecVariant), /* instance_size */
+ 0, /* n_preallocs */
+ param_variant_init, /* instance_init */
+ G_TYPE_VARIANT, /* value_type */
+ param_variant_finalize, /* finalize */
+ param_variant_set_default, /* value_set_default */
+ param_variant_validate, /* value_validate */
+ param_variant_values_cmp, /* values_cmp */
+ };
+ type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
+ *spec_types++ = type;
+ g_assert (type == G_TYPE_PARAM_VARIANT);
+ }
+
g_assert (spec_types == spec_types_bound);
}
@@ -2393,5 +2470,53 @@ g_param_spec_override (const gchar *name,
return pspec;
}
+/**
+ * g_param_spec_variant:
+ * @name: canonical name of the property specified
+ * @nick: nick name for the property specified
+ * @blurb: description of the property specified
+ * @type: a #GVariantType
+ * @default_value: (allow-none): a #GVariant of type @type to use as the
+ * default value, or %NULL
+ * @flags: flags for the property specified
+ *
+ * Creates a new #GParamSpecVariant instance specifying a #GVariant
+ * property.
+ *
+ * If @default_value is floating, it is consumed.
+ *
+ * See g_param_spec_internal() for details on property names.
+ *
+ * Returns: the newly created #GParamSpec
+ *
+ * Since: 2.26
+ */
+GParamSpec*
+g_param_spec_variant (const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ const GVariantType *type,
+ GVariant *default_value,
+ GParamFlags flags)
+{
+ GParamSpecVariant *vspec;
+
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (default_value == NULL ||
+ g_variant_is_of_type (default_value, type), NULL);
+
+ vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
+ name,
+ nick,
+ blurb,
+ flags);
+
+ vspec->type = g_variant_type_copy (type);
+ if (default_value)
+ vspec->default_value = g_variant_ref_sink (default_value);
+
+ return G_PARAM_SPEC (vspec);
+}
+
#define __G_PARAMSPECS_C__
#include "gobjectaliasdef.c"
diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h
index 345db03..a61d608 100644
--- a/gobject/gparamspecs.h
+++ b/gobject/gparamspecs.h
@@ -549,6 +549,34 @@ G_BEGIN_DECLS
*/
#define G_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType))
+/**
+ * G_TYPE_PARAM_VARIANT:
+ *
+ * The #GType of #GParamSpecVariant.
+ *
+ * Since: 2.26
+ */
+#define G_TYPE_PARAM_VARIANT (g_param_spec_types[22])
+/**
+ * G_IS_PARAM_SPEC_VARIANT:
+ * @pspec: a #GParamSpec
+ *
+ * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_VARIANT.
+ *
+ * Returns: %TRUE on success
+ *
+ * Since: 2.26
+ */
+#define G_IS_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_VARIANT))
+/**
+ * G_PARAM_SPEC_VARIANT:
+ * @pspec: a #GParamSpec
+ *
+ * Casts a #GParamSpec into a #GParamSpecVariant.
+ *
+ * Since: 2.26
+ */
+#define G_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_VARIANT, GParamSpecVariant))
/* --- typedefs & structures --- */
typedef struct _GParamSpecChar GParamSpecChar;
@@ -573,6 +601,7 @@ typedef struct _GParamSpecValueArray GParamSpecValueArray;
typedef struct _GParamSpecObject GParamSpecObject;
typedef struct _GParamSpecOverride GParamSpecOverride;
typedef struct _GParamSpecGType GParamSpecGType;
+typedef struct _GParamSpecVariant GParamSpecVariant;
/**
* GParamSpecChar:
@@ -921,6 +950,23 @@ struct _GParamSpecGType
GParamSpec parent_instance;
GType is_a_type;
};
+/**
+ * GParamSpecVariant:
+ * @parent_instance: private #GParamSpec portion
+ * @type: a #GVariantType, or %NULL
+ * @default_value: a #GVariant, or %NULL
+ *
+ * A #GParamSpec derived structure that contains the meta data for #GVariant properties.
+ *
+ * Since: 2.26
+ */
+struct _GParamSpecVariant
+{
+ GParamSpec parent_instance;
+ GVariantType *type;
+ GVariant *default_value;
+ gpointer padding[4];
+};
/* --- GParamSpec prototypes --- */
GParamSpec* g_param_spec_char (const gchar *name,
@@ -1051,6 +1097,12 @@ GParamSpec* g_param_spec_gtype (const gchar *name,
const gchar *blurb,
GType is_a_type,
GParamFlags flags);
+GParamSpec* g_param_spec_variant (const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ const GVariantType *type,
+ GVariant *default_value,
+ GParamFlags flags);
/* --- internal --- */
/* We prefix variable declarations so they can
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 33a4a8b..d94249d 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -179,6 +179,17 @@ G_BEGIN_DECLS
* The fundamental type for #GObject.
*/
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
+/**
+ * G_TYPE_VARIANT:
+ *
+ * The fundamental type corresponding to #GVariant.
+ *
+ * Note: GLib 2.24 did include a boxed type with this name. It was replaced
+ * with this fundamental type in 2.26.
+ *
+ * Since: 2.26
+ */
+#define G_TYPE_VARIANT G_TYPE_MAKE_FUNDAMENTAL (21)
/* Reserved fundamental type numbers to create new fundamental
@@ -208,7 +219,7 @@ G_BEGIN_DECLS
* First fundamental type number to create a new fundamental type id with
* G_TYPE_MAKE_FUNDAMENTAL() reserved for GLib.
*/
-#define G_TYPE_RESERVED_GLIB_FIRST (21)
+#define G_TYPE_RESERVED_GLIB_FIRST (22)
/**
* G_TYPE_RESERVED_GLIB_LAST:
*
diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c
index 5713e48..925a503 100644
--- a/gobject/gvaluetypes.c
+++ b/gobject/gvaluetypes.c
@@ -1,5 +1,6 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
+ * Copyright © 2010 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -361,6 +362,63 @@ value_lcopy_pointer (const GValue *value,
return NULL;
}
+static void
+value_free_variant (GValue *value)
+{
+ if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) &&
+ value->data[0].v_pointer)
+ g_variant_unref (value->data[0].v_pointer);
+}
+
+static void
+value_copy_variant (const GValue *src_value,
+ GValue *dest_value)
+{
+ if (src_value->data[0].v_pointer)
+ dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer);
+ else
+ dest_value->data[0].v_pointer = NULL;
+}
+
+static gchar*
+value_collect_variant (GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ if (!collect_values[0].v_pointer)
+ value->data[0].v_pointer = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ {
+ value->data[0].v_pointer = collect_values[0].v_pointer;
+ value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
+ }
+ else
+ value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer);
+
+ return NULL;
+}
+
+static gchar*
+value_lcopy_variant (const GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
+{
+ GVariant **variant_p = collect_values[0].v_pointer;
+
+ if (!variant_p)
+ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+
+ if (!value->data[0].v_pointer)
+ *variant_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *variant_p = value->data[0].v_pointer;
+ else
+ *variant_p = g_variant_ref_sink (value->data[0].v_pointer);
+
+ return NULL;
+}
/* --- type initialization --- */
void
@@ -550,6 +608,24 @@ g_value_types_init (void)
type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0);
g_assert (type == G_TYPE_POINTER);
}
+
+ /* G_TYPE_VARIANT
+ */
+ {
+ static const GTypeValueTable value_table = {
+ value_init_pointer, /* value_init */
+ value_free_variant, /* value_free */
+ value_copy_variant, /* value_copy */
+ value_peek_pointer0, /* value_peek_pointer */
+ "p", /* collect_format */
+ value_collect_variant, /* collect_value */
+ "p", /* lcopy_format */
+ value_lcopy_variant, /* lcopy_value */
+ };
+ info.value_table = &value_table;
+ type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0);
+ g_assert (type == G_TYPE_VARIANT);
+ }
}
@@ -1102,6 +1178,78 @@ g_value_get_gtype (const GValue *value)
}
/**
+ * g_value_set_variant:
+ * @value: a valid #GValue of %G_TYPE_VARIANT
+ * @variant: a #GVariant, or %NULL
+ *
+ * Set the contents of a variant #GValue to @variant.
+ * If the variant is floating, it is consumed.
+ *
+ * Since: 2.26
+ */
+void
+g_value_set_variant (GValue *value,
+ GVariant *variant)
+{
+ GVariant *old_variant;
+
+ g_return_if_fail (G_VALUE_HOLDS_VARIANT (value));
+
+ old_variant = value->data[0].v_pointer;
+
+ if (variant)
+ value->data[0].v_pointer = g_variant_ref_sink (variant);
+ else
+ value->data[0].v_pointer = NULL;
+
+ if (old_variant)
+ g_variant_unref (old_variant);
+}
+
+/**
+ * g_value_get_variant:
+ * @value: a valid #GValue of %G_TYPE_VARIANT
+ *
+ * Get the contents of a variant #GValue.
+ *
+ * Returns: variant contents of @value
+ *
+ * Since: 2.26
+ */
+GVariant*
+g_value_get_variant (const GValue *value)
+{
+ g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
+
+ return value->data[0].v_pointer;
+}
+
+/**
+ * g_value_get_variant:
+ * @value: a valid #GValue of %G_TYPE_VARIANT
+ *
+ * Get the contents of a variant #GValue, increasing its refcount.
+ *
+ * Returns: variant contents of @value, should be unrefed using
+ * g_variant_unref() when no longer needed
+ *
+ * Since: 2.26
+ */
+GVariant*
+g_value_dup_variant (const GValue *value)
+{
+ GVariant *variant;
+
+ g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL);
+
+ variant = value->data[0].v_pointer;
+ if (variant)
+ g_variant_ref_sink (variant);
+
+ return variant;
+}
+
+/**
* g_strdup_value_contents:
* @value: #GValue which contents are to be described.
*
diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h
index 6385783..d5e27c9 100644
--- a/gobject/gvaluetypes.h
+++ b/gobject/gvaluetypes.h
@@ -163,6 +163,17 @@ G_BEGIN_DECLS
* Returns: %TRUE on success.
*/
#define G_VALUE_HOLDS_GTYPE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE))
+/**
+ * G_VALUE_HOLDS_VARIANT:
+ * @value: a valid #GValue structure
+ *
+ * Checks whether the given #GValue can hold values of type %G_TYPE_VARIANT.
+ *
+ * Returns: %TRUE on success.
+ *
+ * Since: 2.26
+ */
+#define G_VALUE_HOLDS_VARIANT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_VARIANT))
/* --- prototypes --- */
@@ -212,6 +223,10 @@ GType g_gtype_get_type (void);
void g_value_set_gtype (GValue *value,
GType v_gtype);
GType g_value_get_gtype (const GValue *value);
+void g_value_set_variant (GValue *value,
+ GVariant *variant);
+GVariant* g_value_get_variant (const GValue *value);
+GVariant* g_value_dup_variant (const GValue *value);
/* Convenience for registering new pointer types */
diff --git a/tests/gobject/gvalue-test.c b/tests/gobject/gvalue-test.c
index 2d721e0..516a484 100644
--- a/tests/gobject/gvalue-test.c
+++ b/tests/gobject/gvalue-test.c
@@ -219,6 +219,15 @@ test_collection (void)
error = collect (&value, G_TYPE_BOXED);
g_assert (error == NULL);
g_assert (g_value_get_gtype (&value) == G_TYPE_BOXED);
+
+ g_value_unset (&value);
+ g_value_init (&value, G_TYPE_VARIANT);
+ error = collect (&value, g_variant_new_uint32 (42));
+ g_assert (error == NULL);
+ g_assert (g_variant_is_of_type (g_value_get_variant (&value), G_VARIANT_TYPE ("u")));
+ g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42);
+
+ g_value_unset (&value);
}
static void
@@ -357,18 +366,33 @@ test_copying (void)
g_assert (error == NULL);
g_assert (c == G_TYPE_BOXED);
}
+
+ {
+ GVariant *c = NULL;
+
+ g_value_unset (&value);
+ g_value_init (&value, G_TYPE_VARIANT);
+ g_value_set_variant (&value, g_variant_new_uint32 (42));
+ error = lcopy (&value, &c);
+ g_assert (error == NULL);
+ g_assert (c != NULL);
+ g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u")));
+ g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42);
+ g_variant_unref (c);
+ }
}
int
main (int argc, char *argv[])
{
- g_type_init ();
-
- test_enum_transformation ();
- test_gtype_value ();
- test_collection ();
- test_copying ();
+ g_test_init (&argc, &argv, NULL);
+ g_type_init ();
+
+ g_test_add_func ("/gvalue/enum-transformation", test_enum_transformation);
+ g_test_add_func ("/gvalue/gtype", test_gtype_value);
+ g_test_add_func ("/gvalue/collection", test_collection);
+ g_test_add_func ("/gvalue/copying", test_copying);
- return 0;
+ return g_test_run ();
}
diff --git a/tests/gobject/paramspec-test.c b/tests/gobject/paramspec-test.c
index 498aed0..6de850f 100644
--- a/tests/gobject/paramspec-test.c
+++ b/tests/gobject/paramspec-test.c
@@ -206,15 +206,47 @@ test_param_spec_gtype (void)
g_assert (!modified && g_value_get_gtype (&value) == G_TYPE_PARAM_INT);
}
+static void
+test_param_spec_variant (void)
+{
+ GParamSpec *pspec;
+ GValue value = { 0, };
+ gboolean modified;
+
+ pspec = g_param_spec_variant ("variant", "nick", "blurb",
+ G_VARIANT_TYPE ("i"),
+ g_variant_new_int32 (42),
+ G_PARAM_READWRITE);
+
+ g_value_init (&value, G_TYPE_VARIANT);
+ g_value_set_variant (&value, g_variant_new_int32 (42));
+
+ g_assert (g_param_value_defaults (pspec, &value));
+
+ modified = g_param_value_validate (pspec, &value);
+ g_assert (!modified);
+
+ g_value_reset (&value);
+ g_value_set_variant (&value, g_variant_new_uint32 (41));
+ modified = g_param_value_validate (pspec, &value);
+ g_assert (modified);
+ g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42);
+ g_value_unset (&value);
+
+ g_param_spec_unref (pspec);
+}
+
int
main (int argc, char *argv[])
{
- g_type_init ();
-
- test_param_spec_char ();
- test_param_spec_string ();
- test_param_spec_override ();
- test_param_spec_gtype ();
+ g_test_init (&argc, &argv, NULL);
+ g_type_init ();
+
+ g_test_add_func ("/paramspec/char", test_param_spec_char);
+ g_test_add_func ("/paramspec/string", test_param_spec_string);
+ g_test_add_func ("/paramspec/override", test_param_spec_override);
+ g_test_add_func ("/paramspec/gtype", test_param_spec_gtype);
+ g_test_add_func ("/paramspec/variant", test_param_spec_variant);
- return 0;
+ return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]