[virt-tools-list] [PATCH 5/7] Backport GVariantDict code from glib 2.40

Eduardo Lima (Etrunko) etrunko at redhat.com
Fri Dec 11 16:40:34 UTC 2015


Same case as last GApplication patch, but kept split for easier understanding.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko at redhat.com>
---
 src/virt-glib-compat.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/virt-glib-compat.h |  32 ++++++++
 2 files changed, 236 insertions(+)

diff --git a/src/virt-glib-compat.c b/src/virt-glib-compat.c
index 4748993..a61a3a6 100644
--- a/src/virt-glib-compat.c
+++ b/src/virt-glib-compat.c
@@ -399,4 +399,208 @@ g_application_real_local_command_line (GApplication   *application,
 
   return TRUE;
 }
+
+struct stack_dict
+{
+  GHashTable *values;
+  gsize magic;
+};
+
+G_STATIC_ASSERT (sizeof (struct stack_dict) <= sizeof (GVariantDict));
+
+struct heap_dict
+{
+  struct stack_dict dict;
+  gint ref_count;
+  gsize magic;
+};
+
+#define GVSD(d)                 ((struct stack_dict *) (d))
+#define GVHD(d)                 ((struct heap_dict *) (d))
+#define GVSD_MAGIC              ((gsize) 2579507750u)
+#define GVHD_MAGIC              ((gsize) 2450270775u)
+#define is_valid_dict(d)        (d != NULL && \
+                                 GVSD(d)->magic == GVSD_MAGIC)
+#define is_valid_heap_dict(d)   (GVHD(d)->magic == GVHD_MAGIC)
+
+GVariantDict *
+g_variant_dict_new (GVariant *from_asv)
+{
+  GVariantDict *dict;
+
+  dict = g_slice_alloc (sizeof (struct heap_dict));
+  g_variant_dict_init (dict, from_asv);
+  GVHD(dict)->magic = GVHD_MAGIC;
+  GVHD(dict)->ref_count = 1;
+
+  return dict;
+}
+
+void
+g_variant_dict_init (GVariantDict *dict,
+                     GVariant     *from_asv)
+{
+  GVariantIter iter;
+  gchar *key;
+  GVariant *value;
+
+  GVSD(dict)->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
+  GVSD(dict)->magic = GVSD_MAGIC;
+
+  if (from_asv)
+    {
+      g_variant_iter_init (&iter, from_asv);
+      while (g_variant_iter_next (&iter, "{sv}", &key, &value))
+        g_hash_table_insert (GVSD(dict)->values, key, value);
+    }
+}
+
+gboolean
+g_variant_dict_lookup (GVariantDict *dict,
+                       const gchar  *key,
+                       const gchar  *format_string,
+                       ...)
+{
+  GVariant *value;
+  va_list ap;
+
+  g_return_val_if_fail (is_valid_dict (dict), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+  g_return_val_if_fail (format_string != NULL, FALSE);
+
+  value = g_hash_table_lookup (GVSD(dict)->values, key);
+
+  if (value == NULL || !g_variant_check_format_string (value, format_string, FALSE))
+    return FALSE;
+
+  va_start (ap, format_string);
+  g_variant_get_va (value, format_string, NULL, &ap);
+  va_end (ap);
+
+  return TRUE;
+}
+
+GVariant *
+g_variant_dict_lookup_value (GVariantDict       *dict,
+                             const gchar        *key,
+                             const GVariantType *expected_type)
+{
+  GVariant *result;
+
+  g_return_val_if_fail (is_valid_dict (dict), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  result = g_hash_table_lookup (GVSD(dict)->values, key);
+
+  if (result && (!expected_type || g_variant_is_of_type (result, expected_type)))
+    return g_variant_ref (result);
+
+  return NULL;
+}
+
+gboolean
+g_variant_dict_contains (GVariantDict *dict,
+                         const gchar  *key)
+{
+  g_return_val_if_fail (is_valid_dict (dict), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  return g_hash_table_contains (GVSD(dict)->values, key);
+}
+
+void
+g_variant_dict_insert (GVariantDict *dict,
+                       const gchar  *key,
+                       const gchar  *format_string,
+                       ...)
+{
+  va_list ap;
+
+  g_return_if_fail (is_valid_dict (dict));
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (format_string != NULL);
+
+  va_start (ap, format_string);
+  g_variant_dict_insert_value (dict, key, g_variant_new_va (format_string, NULL, &ap));
+  va_end (ap);
+}
+
+void
+g_variant_dict_insert_value (GVariantDict *dict,
+                             const gchar  *key,
+                             GVariant     *value)
+{
+  g_return_if_fail (is_valid_dict (dict));
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (value != NULL);
+
+  g_hash_table_insert (GVSD(dict)->values, g_strdup (key), g_variant_ref_sink (value));
+}
+
+gboolean
+g_variant_dict_remove (GVariantDict *dict,
+                       const gchar  *key)
+{
+  g_return_val_if_fail (is_valid_dict (dict), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  return g_hash_table_remove (GVSD(dict)->values, key);
+}
+
+void
+g_variant_dict_clear (GVariantDict *dict)
+{
+  if (GVSD(dict)->magic == 0)
+    /* all-zeros case */
+    return;
+
+  g_return_if_fail (is_valid_dict (dict));
+
+  g_hash_table_unref (GVSD(dict)->values);
+  GVSD(dict)->values = NULL;
+
+  GVSD(dict)->magic = 0;
+}
+
+GVariant *
+g_variant_dict_end (GVariantDict *dict)
+{
+  GVariantBuilder builder;
+  GHashTableIter iter;
+  gpointer key, value;
+
+  g_return_val_if_fail (is_valid_dict (dict), NULL);
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+
+  g_hash_table_iter_init (&iter, GVSD(dict)->values);
+  while (g_hash_table_iter_next (&iter, &key, &value))
+    g_variant_builder_add (&builder, "{sv}", (const gchar *) key, (GVariant *) value);
+
+  g_variant_dict_clear (dict);
+
+  return g_variant_builder_end (&builder);
+}
+
+GVariantDict *
+g_variant_dict_ref (GVariantDict *dict)
+{
+  g_return_val_if_fail (is_valid_heap_dict (dict), NULL);
+
+  GVHD(dict)->ref_count++;
+
+  return dict;
+}
+
+void
+g_variant_dict_unref (GVariantDict *dict)
+{
+  g_return_if_fail (is_valid_heap_dict (dict));
+
+  if (--GVHD(dict)->ref_count == 0)
+    {
+      g_variant_dict_clear (dict);
+      g_slice_free (struct heap_dict, (struct heap_dict *) dict);
+    }
+}
 #endif
diff --git a/src/virt-glib-compat.h b/src/virt-glib-compat.h
index 29fcdef..26add80 100644
--- a/src/virt-glib-compat.h
+++ b/src/virt-glib-compat.h
@@ -87,6 +87,38 @@ void     g_application_add_option_group (GApplication *application,
 gboolean g_application_real_local_command_line (GApplication   *application,
                                                 gchar        ***arguments,
                                                 int            *exit_status);
+
+typedef struct _GVariantDict GVariantDict;
+struct _GVariantDict {
+  /*< private >*/
+  gsize x[16];
+};
+
+GVariantDict *                  g_variant_dict_new                      (GVariant             *from_asv);
+void                            g_variant_dict_init                     (GVariantDict         *dict,
+                                                                         GVariant             *from_asv);
+gboolean                        g_variant_dict_lookup                   (GVariantDict         *dict,
+                                                                         const gchar          *key,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+GVariant *                      g_variant_dict_lookup_value             (GVariantDict         *dict,
+                                                                         const gchar          *key,
+                                                                         const GVariantType   *expected_type);
+gboolean                        g_variant_dict_contains                 (GVariantDict         *dict,
+                                                                         const gchar          *key);
+void                            g_variant_dict_insert                   (GVariantDict         *dict,
+                                                                         const gchar          *key,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+void                            g_variant_dict_insert_value             (GVariantDict         *dict,
+                                                                         const gchar          *key,
+                                                                         GVariant             *value);
+gboolean                        g_variant_dict_remove                   (GVariantDict         *dict,
+                                                                         const gchar          *key);
+void                            g_variant_dict_clear                    (GVariantDict         *dict);
+GVariant *                      g_variant_dict_end                      (GVariantDict         *dict);
+GVariantDict *                  g_variant_dict_ref                      (GVariantDict         *dict);
+void                            g_variant_dict_unref                    (GVariantDict         *dict);
 #endif
 G_END_DECLS
 
-- 
2.5.0




More information about the virt-tools-list mailing list