summaryrefslogtreecommitdiff
path: root/tests/dconf-mock-gvdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/dconf-mock-gvdb.c')
-rw-r--r--tests/dconf-mock-gvdb.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/tests/dconf-mock-gvdb.c b/tests/dconf-mock-gvdb.c
new file mode 100644
index 0000000..cb639e3
--- /dev/null
+++ b/tests/dconf-mock-gvdb.c
@@ -0,0 +1,195 @@
+#include "../gvdb/gvdb-reader.h"
+#include "dconf-mock.h"
+
+/* The global dconf_mock_gvdb_tables hashtable is modified all the time
+ * so we need to hold the lock while we access it.
+ *
+ * The hashtables contained within it are never modified, however. They
+ * can be safely accessed without a lock.
+ */
+
+static GHashTable *dconf_mock_gvdb_tables;
+static GMutex dconf_mock_gvdb_lock;
+
+typedef struct
+{
+ GVariant *value;
+ GvdbTable *table;
+} DConfMockGvdbItem;
+
+struct _GvdbTable
+{
+ GHashTable *table;
+ gboolean is_valid;
+ gboolean top_level;
+ gint ref_count;
+};
+
+static void
+dconf_mock_gvdb_item_free (gpointer data)
+{
+ DConfMockGvdbItem *item = data;
+
+ if (item->value)
+ g_variant_unref (item->value);
+
+ if (item->table)
+ gvdb_table_unref (item->table);
+
+ g_slice_free (DConfMockGvdbItem, item);
+}
+
+static void
+dconf_mock_gvdb_init (void)
+{
+ if (dconf_mock_gvdb_tables == NULL)
+ dconf_mock_gvdb_tables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gvdb_table_unref);
+}
+
+GvdbTable *
+dconf_mock_gvdb_table_new (void)
+{
+ GvdbTable *table;
+
+ table = g_slice_new (GvdbTable);
+ table->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, dconf_mock_gvdb_item_free);
+ table->ref_count = 1;
+ table->is_valid = TRUE;
+
+ return table;
+}
+
+void
+dconf_mock_gvdb_table_insert (GvdbTable *table,
+ const gchar *name,
+ GVariant *value,
+ GvdbTable *subtable)
+{
+ DConfMockGvdbItem *item;
+
+ g_assert (value == NULL || subtable == NULL);
+
+ if (subtable)
+ subtable->top_level = FALSE;
+
+ item = g_slice_new (DConfMockGvdbItem);
+ item->value = value ? g_variant_ref_sink (value) : NULL;
+ item->table = subtable;
+
+ g_hash_table_insert (table->table, g_strdup (name), item);
+}
+
+void
+dconf_mock_gvdb_install (const gchar *filename,
+ GvdbTable *table)
+{
+ g_mutex_lock (&dconf_mock_gvdb_lock);
+ dconf_mock_gvdb_init ();
+
+ if (table)
+ {
+ table->top_level = TRUE;
+ g_hash_table_insert (dconf_mock_gvdb_tables, g_strdup (filename), table);
+ }
+ else
+ g_hash_table_remove (dconf_mock_gvdb_tables, filename);
+
+ g_mutex_unlock (&dconf_mock_gvdb_lock);
+}
+
+void
+gvdb_table_unref (GvdbTable *table)
+{
+ if (g_atomic_int_dec_and_test (&table->ref_count))
+ {
+ g_hash_table_unref (table->table);
+ g_slice_free (GvdbTable, table);
+ }
+}
+
+GvdbTable *
+gvdb_table_ref (GvdbTable *table)
+{
+ g_atomic_int_inc (&table->ref_count);
+
+ return table;
+}
+
+GvdbTable *
+gvdb_table_get_table (GvdbTable *table,
+ const gchar *key)
+{
+ DConfMockGvdbItem *item;
+ GvdbTable *subtable;
+
+ item = g_hash_table_lookup (table->table, key);
+
+ if (item && item->table)
+ subtable = gvdb_table_ref (item->table);
+ else
+ subtable = NULL;
+
+ return subtable;
+}
+
+gboolean
+gvdb_table_has_value (GvdbTable *table,
+ const gchar *key)
+{
+ DConfMockGvdbItem *item;
+
+ item = g_hash_table_lookup (table->table, key);
+
+ return item && item->value;
+}
+
+GVariant *
+gvdb_table_get_value (GvdbTable *table,
+ const gchar *key)
+{
+ GHashTable *hash_table = (GHashTable *) table;
+ DConfMockGvdbItem *item;
+
+ item = g_hash_table_lookup (hash_table, key);
+
+ return item ? g_variant_ref (item->value) : NULL;
+}
+
+gchar **
+gvdb_table_list (GvdbTable *table,
+ const gchar *key)
+{
+ g_assert_not_reached ();
+}
+
+GvdbTable *
+gvdb_table_new (const gchar *filename,
+ gboolean trusted,
+ GError **error)
+{
+ GvdbTable *table;
+
+ g_mutex_lock (&dconf_mock_gvdb_lock);
+ dconf_mock_gvdb_init ();
+ table = g_hash_table_lookup (dconf_mock_gvdb_tables, filename);
+ if (table)
+ gvdb_table_ref (table);
+ g_mutex_unlock (&dconf_mock_gvdb_lock);
+
+ if (table == NULL)
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, "this gvdb does not exist");
+
+ return table;
+}
+
+gboolean
+gvdb_table_is_valid (GvdbTable *table)
+{
+ return table->is_valid;
+}
+
+void
+dconf_mock_gvdb_table_invalidate (GvdbTable *table)
+{
+ table->is_valid = FALSE;
+}