mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 10:16:17 +01:00
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.
This commit is contained in:
parent
f2ae621777
commit
4708b8ecc3
4
NEWS
4
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -194,14 +194,6 @@ GType g_boxed_type_register_static (const gchar *name,
|
||||
* Since: 2.24
|
||||
*/
|
||||
#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:
|
||||
*
|
||||
@ -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:
|
||||
*
|
||||
|
@ -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", },
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1101,6 +1177,78 @@ g_value_get_gtype (const GValue *value)
|
||||
return value->data[0].v_long;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -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 */
|
||||
|
@ -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 ();
|
||||
|
||||
return 0;
|
||||
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 g_test_run ();
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
||||
return 0;
|
||||
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 g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user