From a47c2a895d1302b012ff1ec1fe016cd573b96527 Mon Sep 17 00:00:00 2001 From: Ali Abdallah Date: Sun, 24 Apr 2016 21:27:37 +0200 Subject: Implement gvalue to gvariant conversion functions to convert GHashTable key,value pairs to GVariant(av) and vice versa. --- common/xfconf-gvaluefuncs.c | 264 +++++++++++++++++++++++++++++++++++++++++++- common/xfconf-gvaluefuncs.h | 12 ++ 2 files changed, 275 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/xfconf-gvaluefuncs.c b/common/xfconf-gvaluefuncs.c index a6d3e07..8a19c98 100644 --- a/common/xfconf-gvaluefuncs.c +++ b/common/xfconf-gvaluefuncs.c @@ -40,7 +40,7 @@ #include #endif -#include +#include #include "xfconf-gvaluefuncs.h" #include "xfconf/xfconf-types.h" @@ -363,3 +363,265 @@ _xfconf_gvalue_free(GValue *value) g_value_unset(value); g_free(value); } + + +GVariant * +xfconf_basic_gvalue_to_gvariant (const GValue *value) { + + const GVariantType *type = NULL; + + switch (G_VALUE_TYPE(value)){ + case G_TYPE_UINT: + type = G_VARIANT_TYPE_UINT32; + break; + case G_TYPE_INT: + type = G_VARIANT_TYPE_INT32; + break; + case G_TYPE_BOOLEAN: + type = G_VARIANT_TYPE_BOOLEAN; + break; + case G_TYPE_INT64: + type = G_VARIANT_TYPE_INT64; + break; + case G_TYPE_UINT64: + type = G_VARIANT_TYPE_UINT64; + break; + case G_TYPE_DOUBLE: + type = G_VARIANT_TYPE_DOUBLE; + break; + case G_TYPE_STRING: + type = G_VARIANT_TYPE_STRING; + break; + default: + if (G_VALUE_TYPE(value) == XFCONF_TYPE_INT16) + type = G_VARIANT_TYPE_INT16; + else if (G_VALUE_TYPE(value) == XFCONF_TYPE_UINT16) + type = G_VARIANT_TYPE_UINT16; + break; + } + + + if (type) { + return g_dbus_gvalue_to_gvariant (value, type); + } + + g_warning ("Unable toconvert GType '%s' to GVariant", _xfconf_string_from_gtype(G_VALUE_TYPE(value))); + + return NULL; +} + +void xfconf_basic_gvariant_to_gvalue (GVariant *variant, GValue *value) +{ + switch (g_variant_classify (variant)){ + case G_VARIANT_CLASS_UINT16: + g_value_init(value, G_TYPE_UINT); + g_value_set_uint (value, g_variant_get_uint16 (variant)); + break; + case G_VARIANT_CLASS_INT16: + g_value_init(value, G_TYPE_INT); + g_value_set_int (value, g_variant_get_int16 (variant)); + break; + case G_VARIANT_CLASS_UINT32: + g_value_init(value, G_TYPE_UINT); + g_value_set_uint (value, g_variant_get_uint32 (variant)); + break; + case G_VARIANT_CLASS_INT32: + g_value_init(value, G_TYPE_INT); + g_value_set_int (value, g_variant_get_int32 (variant)); + break; + case G_VARIANT_CLASS_UINT64: + g_value_init(value, G_TYPE_UINT64); + g_value_set_uint64 (value, g_variant_get_uint64 (variant)); + break; + case G_VARIANT_CLASS_INT64: + g_value_init(value, G_TYPE_INT64); + g_value_set_int64 (value, g_variant_get_int64 (variant)); + break; + case G_VARIANT_CLASS_BOOLEAN: + g_value_init(value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, g_variant_get_boolean (variant)); + break; + case G_VARIANT_CLASS_STRING: + g_value_init(value, G_TYPE_STRING); + g_value_set_string (value, g_variant_get_string (variant, NULL)); + break; + case G_VARIANT_CLASS_DOUBLE: + g_value_init(value, G_TYPE_DOUBLE); + g_value_set_double (value, g_variant_get_double (variant)); + break; + default: + g_warn_if_reached (); + break; + } +} + +GVariant * +xfconf_gvalue_to_gvariant (const GValue *value) +{ + GVariant *variant = NULL; + + if (G_VALUE_TYPE(value) == G_TYPE_PTR_ARRAY) { + GPtrArray *arr; + GVariantBuilder builder; + guint i = 0; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + + arr = (GPtrArray*)g_value_get_boxed (value); + + for (i=0; i < arr->len; ++i) { + GValue *v = g_ptr_array_index (arr, i); + GVariant *var = NULL; + + var = xfconf_basic_gvalue_to_gvariant (v); + if (var) + g_variant_builder_add (&builder, "v", var, NULL); + } + + variant = g_variant_builder_end (&builder); + } + else if (G_VALUE_TYPE(value) == G_TYPE_STRV) { + gchar **strlist; + + strlist = g_value_get_boxed(value); + variant = g_variant_new_strv ((const gchar**)strlist, g_strv_length(strlist)); + } + else + variant = xfconf_basic_gvalue_to_gvariant(value); + + return variant; +} + +GVariant *xfconf_hash_to_gvariant (GHashTable *hash) +{ + GHashTableIter iter; + GVariantBuilder builder; + GVariant *variant; + const gchar *key; + const GValue *value; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + g_hash_table_iter_init (&iter, hash); + + while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value)) { + GVariant *v; + + if (G_VALUE_TYPE (value) == G_TYPE_PTR_ARRAY) { + GPtrArray *arr; + GVariantBuilder arr_builder; + uint i; + + arr = g_value_get_boxed(value); + + g_variant_builder_init (&arr_builder, G_VARIANT_TYPE ("av")); + + for (i = 0; i < arr->len; ++i) { + GValue *item_value = g_ptr_array_index(arr, i); + + if(item_value) + { + v = xfconf_basic_gvalue_to_gvariant(item_value); + g_variant_builder_add (&arr_builder, "v", v); + } + } + + v = g_variant_builder_end (&arr_builder); + g_variant_builder_add (&builder, "{sv}", key, v); + } + else if (G_VALUE_TYPE (value) == G_TYPE_STRV) { + gchar **strlist; + + strlist = g_value_get_boxed(value); + variant = g_variant_new_strv ((const gchar**)strlist, g_strv_length(strlist)); + } + else { + + v = xfconf_basic_gvalue_to_gvariant(value); + g_variant_builder_add (&builder, "{sv}", key, v); + } + } + + variant = g_variant_builder_end (&builder); + return variant; +} + +GValue * xfconf_gvariant_to_gvalue (GVariant *in_variant) +{ + GValue *value; + GVariant *variant; + value = g_new0(GValue, 1); + + if (g_variant_is_of_type(in_variant, G_VARIANT_TYPE ("v"))) + variant = g_variant_get_variant (in_variant); + else + variant = in_variant; + + if (g_variant_is_of_type (variant, G_VARIANT_TYPE("av"))) { + GPtrArray *arr; + GVariant *var; + gsize nchild; + gsize idx = 0; + + nchild = g_variant_n_children (variant); + + if (nchild > 0) { + arr = g_ptr_array_sized_new(nchild); + + while (idx < nchild ) { + GVariant *v; + GValue *arr_val; + + arr_val = g_new0(GValue, 1); + + var = g_variant_get_child_value (variant, idx); + v = g_variant_get_variant (var); + xfconf_basic_gvariant_to_gvalue (v, arr_val); + + g_variant_unref (v); + g_variant_unref (var); + g_ptr_array_add (arr, arr_val); + idx++; + } + + g_value_init(value, G_TYPE_PTR_ARRAY); + g_value_set_boxed(value, arr); + } + } + else if (g_variant_is_of_type (variant, G_VARIANT_TYPE("as"))) { + g_value_init(value, G_TYPE_STRV); + g_value_set_boxed (value, g_variant_get_strv (variant, NULL)); + } + else {/* Should be a basic type */ + xfconf_basic_gvariant_to_gvalue(variant, value); + } + + return value; +} + +GHashTable *xfconf_gvariant_to_hash (GVariant *variant) +{ + GHashTable *properties; + GVariantIter iter; + GVariant *v; + gchar *key; + + g_return_val_if_fail (g_variant_is_of_type(variant, G_VARIANT_TYPE ("a{sv}")), NULL); + + properties = g_hash_table_new_full(g_str_hash, g_str_equal, + (GDestroyNotify)g_free,(GDestroyNotify)_xfconf_gvalue_free); + + g_variant_iter_init (&iter, variant); + + while (g_variant_iter_next (&iter, "{&sv}", &key, &v)) { + GValue *value; + + value = xfconf_gvariant_to_gvalue (v); + g_hash_table_insert (properties, + g_strdup(key), + value); + g_variant_unref (v); + g_free(key); + } + return properties; +} diff --git a/common/xfconf-gvaluefuncs.h b/common/xfconf-gvaluefuncs.h index d891516..3293c58 100644 --- a/common/xfconf-gvaluefuncs.h +++ b/common/xfconf-gvaluefuncs.h @@ -38,6 +38,18 @@ G_GNUC_INTERNAL gboolean _xfconf_gvalue_is_equal(const GValue *value1, G_GNUC_INTERNAL void _xfconf_gvalue_free(GValue *value); +G_GNUC_INTERNAL GVariant *xfconf_basic_gvalue_to_gvariant (const GValue *value); + +G_GNUC_INTERNAL GVariant *xfconf_gvalue_to_gvariant (const GValue *value); + +G_GNUC_INTERNAL void xfconf_basic_gvariant_to_gvalue (GVariant *variant, GValue *value); + +G_GNUC_INTERNAL GValue * xfconf_gvariant_to_gvalue (GVariant *variant); + +G_GNUC_INTERNAL GVariant *xfconf_hash_to_gvariant (GHashTable *hash); + +G_GNUC_INTERNAL GHashTable *xfconf_gvariant_to_hash (GVariant *variant); + G_END_DECLS #endif /* __XFCONF_GVALUEFUNCS_H__ */ -- cgit v1.2.1