[dconf] add support for flattening a dconf db to a GTree
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dconf] add support for flattening a dconf db to a GTree
- Date: Fri, 14 Aug 2009 15:08:35 +0000 (UTC)
commit b0c706ef7da2120936ea6effe3d8166825f4ca8f
Author: Ryan Lortie <desrt desrt ca>
Date: Tue Aug 11 19:40:51 2009 -0400
add support for flattening a dconf db to a GTree
also add a dump() debug function to display the contents of the entire
tree to stderr and wire it up to the dbus "Dump" method.
writer/Makefile.am | 1 +
writer/dconf-dbus-writer.c | 6 ++
writer/dconf-writer-flatten.c | 124 +++++++++++++++++++++++++++++++++++++++++
writer/dconf-writer-private.h | 7 ++
writer/dconf-writer.c | 24 +++++++-
writer/dconf-writer.h | 2 +
6 files changed, 161 insertions(+), 3 deletions(-)
---
diff --git a/writer/Makefile.am b/writer/Makefile.am
index 44f64bc..2027f83 100644
--- a/writer/Makefile.am
+++ b/writer/Makefile.am
@@ -6,6 +6,7 @@ DEFS = -DDCONF_CONF=\"$(sysconfdir)/dconf/dconf.conf\"
noinst_LIBRARIES = libdconf-writer.a
libdconf_writer_a_SOURCES = \
+ dconf-writer-flatten.c \
dconf-writer-file.c \
dconf-writer.c \
dconf-writer-merge.c \
diff --git a/writer/dconf-dbus-writer.c b/writer/dconf-dbus-writer.c
index b4d136e..defdafb 100644
--- a/writer/dconf-dbus-writer.c
+++ b/writer/dconf-dbus-writer.c
@@ -353,6 +353,12 @@ dconf_dbus_writer_handle_message (DConfDBusWriter *writer)
return dconf_dbus_writer_reply (writer, status, &sequence, error);
}
+ if (dconf_dbus_writer_is_call (writer, "Dump", ""))
+ {
+ dconf_writer_dump (writer->writer);
+ return dconf_dbus_writer_reply (writer, TRUE, NULL, NULL);
+ }
+
return NULL;
}
diff --git a/writer/dconf-writer-flatten.c b/writer/dconf-writer-flatten.c
new file mode 100644
index 0000000..ee6fe01
--- /dev/null
+++ b/writer/dconf-writer-flatten.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2009 Codethink Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Authors: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "dconf-writer-private.h"
+
+#include <string.h>
+
+static gboolean
+dconf_writer_check_name (const gchar *name,
+ guint32 namelen,
+ gboolean *is_directory)
+{
+ gint i;
+
+ if (namelen == 0)
+ return FALSE;
+
+ if (namelen == 1 && name[0] == '/')
+ return FALSE;
+
+ for (i = 0; i < namelen - 1; i++)
+ if (name[i] == '/')
+ return FALSE;
+
+ *is_directory = name[i] == '/';
+
+ return TRUE;
+}
+
+static void
+dconf_writer_flatten_index (DConfWriter *writer,
+ GTree *tree,
+ const gchar *prefix,
+ gint prefixlen,
+ guint32 index)
+{
+ const volatile struct dir_entry *entries;
+ gint n_items;
+ gint i;
+
+ entries = dconf_writer_get_dir (writer, index, &n_items);
+
+ for (i = 0; i < n_items; i++)
+ {
+ const volatile struct dir_entry *entry = &entries[i];
+ gboolean is_directory;
+ const gchar *name;
+ guint32 namelen;
+ gint pathlen;
+ gchar *path;
+
+ name = dconf_writer_get_entry_name (writer, entry, &namelen);
+
+ if (!dconf_writer_check_name (name, namelen, &is_directory))
+ continue;
+
+ pathlen = prefixlen + namelen;
+ path = g_malloc (pathlen + 1);
+ memcpy (path, prefix, prefixlen);
+ memcpy (path + prefixlen, name, namelen);
+ path[pathlen] = '\0';
+
+ if (is_directory)
+ {
+ index = dconf_writer_get_index (writer, &entry->data.index, TRUE);
+ dconf_writer_flatten_index (writer, tree, path, pathlen, index);
+ g_free (path);
+ }
+ else
+ {
+ g_tree_insert (tree, path,
+ dconf_writer_get_entry_value (writer, entry));
+ }
+ }
+}
+
+GTree *
+dconf_writer_flatten (DConfWriter *writer)
+{
+ GTree *tree;
+
+ tree = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
+ g_free, (GDestroyNotify) g_variant_unref);
+
+ dconf_writer_flatten_index (writer, tree, "", 0,
+ writer->data.super->root_index);
+
+ return tree;
+}
+
+static gboolean
+dconf_writer_dump_entry (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GString *string;
+
+ string = g_variant_markup_print (value, NULL, 0, 0, 0);
+ g_message (" %s = %s", (const gchar *) key, string->str);
+ g_string_free (string, TRUE);
+
+ return FALSE;
+}
+
+void
+dconf_writer_dump (DConfWriter *writer)
+{
+ GTree *tree;
+
+ tree = dconf_writer_flatten (writer);
+ g_message ("dumping contents of dconf database");
+ g_tree_foreach (tree, dconf_writer_dump_entry, NULL);
+ g_message ("end of output");
+ g_tree_unref (tree);
+}
diff --git a/writer/dconf-writer-private.h b/writer/dconf-writer-private.h
index 20af829..bbdfb60 100644
--- a/writer/dconf-writer-private.h
+++ b/writer/dconf-writer-private.h
@@ -83,4 +83,11 @@ gboolean
dconf_writer_create (DConfWriter *writer,
GError **error);
+GVariant *
+dconf_writer_get_entry_value (DConfWriter *writer,
+ const volatile struct dir_entry *entry);
+
+GTree *
+dconf_writer_flatten (DConfWriter *writer);
+
#endif /* _dconf_writer_private_h_ */
diff --git a/writer/dconf-writer.c b/writer/dconf-writer.c
index cbb3918..022ff63 100644
--- a/writer/dconf-writer.c
+++ b/writer/dconf-writer.c
@@ -58,7 +58,7 @@ dconf_writer_allocate (DConfWriter *writer,
}
static volatile void *
-dconf_writer_get_block (DConfWriter *writer,
+dconf_writer_get_chunk (DConfWriter *writer,
guint32 index,
guint32 *size)
{
@@ -105,7 +105,7 @@ dconf_writer_get_dir (DConfWriter *writer,
volatile struct dir_entry *entries;
guint32 size;
- entries = dconf_writer_get_block (writer, index, &size);
+ entries = dconf_writer_get_chunk (writer, index, &size);
if (size % sizeof (struct dir_entry))
size = 0;
@@ -208,7 +208,7 @@ dconf_writer_get_entry_name (DConfWriter *writer,
guint32 *name_length)
{
if G_UNLIKELY (entry->namelen > sizeof entry->name.direct)
- return (const gchar *) dconf_writer_get_block (writer,
+ return (const gchar *) dconf_writer_get_chunk (writer,
entry->name.index,
name_length);
@@ -249,3 +249,21 @@ dconf_writer_set (DConfWriter *writer,
return dconf_writer_merge (writer, key, &empty_string, &value, 1, error);
}
+
+GVariant *
+dconf_writer_get_entry_value (DConfWriter *writer,
+ const volatile struct dir_entry *entry)
+{
+ const volatile void *data;
+ guint32 index;
+ guint32 size;
+
+ g_assert (entry->type == 'v');
+
+ index = dconf_writer_get_index (writer, &entry->data.index, TRUE);
+ data = dconf_writer_get_chunk (writer, entry->data.index, &size);
+
+ return g_variant_ref_sink (g_variant_from_data (NULL,
+ (gconstpointer) data, size,
+ 0, NULL, NULL));
+}
diff --git a/writer/dconf-writer.h b/writer/dconf-writer.h
index 544ba36..a59b54b 100644
--- a/writer/dconf-writer.h
+++ b/writer/dconf-writer.h
@@ -41,4 +41,6 @@ gboolean dconf_writer_merge (DConfWr
gint n_items,
GError **error);
+void dconf_writer_dump (DConfWriter *writer);
+
#endif /* _dconf_writer_h_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]