summaryrefslogtreecommitdiff
path: root/service/dconf-gvdb-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'service/dconf-gvdb-utils.c')
-rw-r--r--service/dconf-gvdb-utils.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/service/dconf-gvdb-utils.c b/service/dconf-gvdb-utils.c
new file mode 100644
index 0000000..4e93cc8
--- /dev/null
+++ b/service/dconf-gvdb-utils.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ * Copyright © 2012 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "dconf-gvdb-utils.h"
+
+#include "../gvdb/gvdb-builder.h"
+#include "../gvdb/gvdb-reader.h"
+
+#include <string.h>
+
+DConfChangeset *
+dconf_gvdb_utils_read_file (const gchar *filename,
+ GError **error)
+{
+ DConfChangeset *database;
+ GError *my_error = NULL;
+ GvdbTable *table;
+
+ table = gvdb_table_new (filename, FALSE, &my_error);
+
+ /* It is perfectly fine if the file does not exist -- then it's
+ * just empty.
+ */
+ if (g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_clear_error (&my_error);
+
+ /* Otherwise, we should report errors to prevent ourselves from
+ * overwriting the database in other situations...
+ */
+ if (my_error)
+ {
+ g_propagate_prefixed_error (error, my_error, "Cannot open dconf database: ");
+ return NULL;
+ }
+
+ /* Only allocate once we know we are in a non-error situation */
+ database = dconf_changeset_new_database (NULL);
+
+ /* Fill the table up with the initial state */
+ if (table != NULL)
+ {
+ gchar **names;
+ gint n_names;
+ gint i;
+
+ names = gvdb_table_get_names (table, &n_names);
+ for (i = 0; i < n_names; i++)
+ {
+ if (dconf_is_key (names[i], NULL))
+ {
+ GVariant *value;
+
+ value = gvdb_table_get_value (table, names[i]);
+
+ if (value != NULL)
+ {
+ dconf_changeset_set (database, names[i], value);
+ g_variant_unref (value);
+ }
+ }
+
+ g_free (names[i]);
+ }
+
+ gvdb_table_unref (table);
+ g_free (names);
+ }
+
+ return database;
+}
+
+static GvdbItem *
+dconf_gvdb_utils_get_parent (GHashTable *table,
+ const gchar *key)
+{
+ GvdbItem *grandparent, *parent;
+ gchar *parent_name;
+ gint len;
+
+ if (g_str_equal (key, "/"))
+ return NULL;
+
+ len = strlen (key);
+ if (key[len - 1] == '/')
+ len--;
+
+ while (key[len - 1] != '/')
+ len--;
+
+ parent_name = g_strndup (key, len);
+ parent = g_hash_table_lookup (table, parent_name);
+
+ if (parent == NULL)
+ {
+ parent = gvdb_hash_table_insert (table, parent_name);
+
+ grandparent = dconf_gvdb_utils_get_parent (table, parent_name);
+
+ if (grandparent != NULL)
+ gvdb_item_set_parent (parent, grandparent);
+ }
+
+ g_free (parent_name);
+
+ return parent;
+}
+
+static gboolean
+dconf_gvdb_utils_add_key (const gchar *path,
+ GVariant *value,
+ gpointer user_data)
+{
+ GHashTable *gvdb = user_data;
+ GvdbItem *item;
+
+ g_assert (g_hash_table_lookup (gvdb, path) == NULL);
+ item = gvdb_hash_table_insert (gvdb, path);
+ gvdb_item_set_parent (item, dconf_gvdb_utils_get_parent (gvdb, path));
+ gvdb_item_set_value (item, value);
+
+ return TRUE;
+}
+
+gboolean
+dconf_gvdb_utils_write_file (const gchar *filename,
+ DConfChangeset *database,
+ GError **error)
+{
+ GHashTable *gvdb;
+ gboolean success;
+
+ gvdb = gvdb_hash_table_new (NULL, NULL);
+ dconf_changeset_all (database, dconf_gvdb_utils_add_key, gvdb);
+ success = gvdb_table_write_contents (gvdb, filename, FALSE, error);
+ g_hash_table_unref (gvdb);
+
+ return success;
+}