summaryrefslogtreecommitdiff
path: root/common/dconf-changeset.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/dconf-changeset.c')
-rw-r--r--common/dconf-changeset.c231
1 files changed, 168 insertions, 63 deletions
diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c
index 1dcee39..195841a 100644
--- a/common/dconf-changeset.c
+++ b/common/dconf-changeset.c
@@ -25,12 +25,38 @@
#include <string.h>
#include <stdlib.h>
+/**
+ * SECTION:changeset
+ * @title: DConfChangeset
+ * @Short_description: A set of changes to a dconf database
+ *
+ * #DConfChangeset represents a set of changes that can be made to a
+ * dconf database. Currently supported operations are writing new
+ * values to keys and resetting keys and dirs.
+ *
+ * Create the changeset with dconf_changeset_new() and populate it with
+ * dconf_changeset_set(). Submit it to dconf with
+ * dconf_client_change_fast() or dconf_client_change_sync().
+ * dconf_changeset_new_write() is a convenience constructor for the
+ * common case of writing or resetting a single value.
+ **/
+
+/**
+ * DConfChangeset:
+ *
+ * This is a reference counted opaque structure type. It is not a
+ * #GObject.
+ *
+ * Use dconf_changeset_ref() and dconf_changeset_unref() to manipuate
+ * references.
+ **/
+
struct _DConfChangeset
{
GHashTable *table;
gint ref_count;
- gchar *root;
+ gchar *prefix;
const gchar **paths;
GVariant **values;
};
@@ -52,47 +78,55 @@ unref_gvariant0 (gpointer data)
DConfChangeset *
dconf_changeset_new (void)
{
- DConfChangeset *change;
+ DConfChangeset *changeset;
- change = g_slice_new0 (DConfChangeset);
- change->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, unref_gvariant0);
- change->ref_count = 1;
+ changeset = g_slice_new0 (DConfChangeset);
+ changeset->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, unref_gvariant0);
+ changeset->ref_count = 1;
- return change;
+ return changeset;
}
/**
* dconf_changeset_unref:
- * @change: a #DConfChangeset
+ * @changeset: a #DConfChangeset
*
* Releases a #DConfChangeset reference.
**/
void
-dconf_changeset_unref (DConfChangeset *change)
+dconf_changeset_unref (DConfChangeset *changeset)
{
- if (g_atomic_int_dec_and_test (&change->ref_count))
+ if (g_atomic_int_dec_and_test (&changeset->ref_count))
{
- g_free (change->root);
- g_free (change->paths);
- g_free (change->values);
+ g_free (changeset->prefix);
+ g_free (changeset->paths);
+ g_free (changeset->values);
- g_hash_table_unref (change->table);
+ g_hash_table_unref (changeset->table);
- g_slice_free (DConfChangeset, change);
+ g_slice_free (DConfChangeset, changeset);
}
}
+/**
+ * dconf_changeset_ref:
+ * @changeset: a #DConfChangeset
+ *
+ * Increases the reference count on @changeset
+ *
+ * Returns: @changeset
+ **/
DConfChangeset *
-dconf_changeset_ref (DConfChangeset *change)
+dconf_changeset_ref (DConfChangeset *changeset)
{
- g_atomic_int_inc (&change->ref_count);
+ g_atomic_int_inc (&changeset->ref_count);
- return change;
+ return changeset;
}
/**
* dconf_changeset_set:
- * @change: a #DConfChangeset
+ * @changeset: a #DConfChangeset
* @path: a path to modify
* @value: the value for the key, or %NULL to reset
*
@@ -105,11 +139,11 @@ dconf_changeset_ref (DConfChangeset *change)
* %NULL. It is not permitted to assign a #GVariant value to a dir.
**/
void
-dconf_changeset_set (DConfChangeset *change,
+dconf_changeset_set (DConfChangeset *changeset,
const gchar *path,
GVariant *value)
{
- g_return_if_fail (change->root == NULL);
+ g_return_if_fail (changeset->prefix == NULL);
g_return_if_fail (dconf_is_path (path, NULL));
/* Check if we are performing a path reset */
@@ -123,23 +157,23 @@ dconf_changeset_set (DConfChangeset *change,
/* When we reset a path we must also reset all keys within that
* path.
*/
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
while (g_hash_table_iter_next (&iter, &key, NULL))
if (g_str_has_prefix (key, path))
g_hash_table_iter_remove (&iter);
/* Record the reset itself. */
- g_hash_table_insert (change->table, g_strdup (path), NULL);
+ g_hash_table_insert (changeset->table, g_strdup (path), NULL);
}
/* else, just a normal value write or reset */
else
- g_hash_table_insert (change->table, g_strdup (path), value ? g_variant_ref_sink (value) : NULL);
+ g_hash_table_insert (changeset->table, g_strdup (path), value ? g_variant_ref_sink (value) : NULL);
}
/**
* dconf_changeset_get:
- * @change: a #DConfChangeset
+ * @changeset: a #DConfChangeset
* @key: the key to check
* @value: a return location for the value, or %NULL
*
@@ -156,13 +190,13 @@ dconf_changeset_set (DConfChangeset *change,
* Returns: %TRUE if the key is being modified by the change
*/
gboolean
-dconf_changeset_get (DConfChangeset *change,
+dconf_changeset_get (DConfChangeset *changeset,
const gchar *key,
GVariant **value)
{
gpointer tmp;
- if (!g_hash_table_lookup_extended (change->table, key, NULL, &tmp))
+ if (!g_hash_table_lookup_extended (changeset->table, key, NULL, &tmp))
return FALSE;
if (value)
@@ -173,10 +207,10 @@ dconf_changeset_get (DConfChangeset *change,
/**
* dconf_changeset_is_similar_to:
- * @change: a #DConfChangeset
+ * @changeset: a #DConfChangeset
* @other: another #DConfChangeset
*
- * Checks if @change is similar to @other.
+ * Checks if @changeset is similar to @other.
*
* Two changes are considered similar if they write to the exact same
* set of keys. The values written are not considered.
@@ -193,16 +227,16 @@ dconf_changeset_get (DConfChangeset *change,
* Returns: %TRUE if the changes are similar
**/
gboolean
-dconf_changeset_is_similar_to (DConfChangeset *change,
+dconf_changeset_is_similar_to (DConfChangeset *changeset,
DConfChangeset *other)
{
GHashTableIter iter;
gpointer key;
- if (g_hash_table_size (change->table) != g_hash_table_size (other->table))
+ if (g_hash_table_size (changeset->table) != g_hash_table_size (other->table))
return FALSE;
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
while (g_hash_table_iter_next (&iter, &key, NULL))
if (!g_hash_table_contains (other->table, key))
return FALSE;
@@ -211,9 +245,23 @@ dconf_changeset_is_similar_to (DConfChangeset *change,
}
/**
+ * DConfChangesetPredicate:
+ * @path: a path, as per dconf_is_path()
+ * @value: a #GVariant, or %NULL
+ * @user_data: user data pointer
+ *
+ * Callback function type for predicates over items in a
+ * #DConfChangeset.
+ *
+ * Use with dconf_changeset_all().
+ *
+ * Returns: %TRUE if the predicate is met for the given @path and @value
+ **/
+
+/**
* dconf_changeset_all:
- * @change: a #DConfChangeset
- * @predicate: a #DConfChangePredicate
+ * @changeset: a #DConfChangeset
+ * @predicate: a #DConfChangesetPredicate
* @user_data: user data to pass to @predicate
*
* Checks if all changes in the changeset satisfy @predicate.
@@ -225,17 +273,17 @@ dconf_changeset_is_similar_to (DConfChangeset *change,
* %FALSE. If not (including the case of no items) then this function
* returns %TRUE.
*
- * Returns: %TRUE if all items in @change satisfy @predicate
+ * Returns: %TRUE if all items in @changeset satisfy @predicate
*/
gboolean
-dconf_changeset_all (DConfChangeset *change,
+dconf_changeset_all (DConfChangeset *changeset,
DConfChangesetPredicate predicate,
gpointer user_data)
{
GHashTableIter iter;
gpointer key, value;
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
while (g_hash_table_iter_next (&iter, &key, &value))
if (!(* predicate) (key, value, user_data))
return FALSE;
@@ -254,12 +302,12 @@ dconf_changeset_string_ptr_compare (gconstpointer a_p,
}
static void
-dconf_changeset_build_description (DConfChangeset *change)
+dconf_changeset_build_description (DConfChangeset *changeset)
{
gsize prefix_length;
gint n_items;
- n_items = g_hash_table_size (change->table);
+ n_items = g_hash_table_size (changeset->table);
/* If there are no items then what is there to describe? */
if (n_items == 0)
@@ -291,7 +339,7 @@ dconf_changeset_build_description (DConfChangeset *change)
const gchar *first;
gpointer key;
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
/* We checked above that we have at least one item. */
if (!g_hash_table_iter_next (&iter, &key, NULL))
@@ -329,7 +377,7 @@ dconf_changeset_build_description (DConfChangeset *change)
prefix_length--;
}
- change->root = g_strndup (first, prefix_length);
+ changeset->prefix = g_strndup (first, prefix_length);
}
/* Pass 2: collect the list of keys, dropping the prefix */
@@ -338,63 +386,94 @@ dconf_changeset_build_description (DConfChangeset *change)
gpointer key;
gint i = 0;
- change->paths = g_new (const gchar *, n_items + 1);
+ changeset->paths = g_new (const gchar *, n_items + 1);
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
while (g_hash_table_iter_next (&iter, &key, NULL))
{
const gchar *path = key;
- change->paths[i++] = path + prefix_length;
+ changeset->paths[i++] = path + prefix_length;
}
- change->paths[i] = NULL;
+ changeset->paths[i] = NULL;
g_assert (i == n_items);
/* Sort the list of keys */
- qsort (change->paths, n_items, sizeof (const gchar *), dconf_changeset_string_ptr_compare);
+ qsort (changeset->paths, n_items, sizeof (const gchar *), dconf_changeset_string_ptr_compare);
}
/* Pass 3: collect the list of values */
{
gint i;
- change->values = g_new (GVariant *, n_items);
+ changeset->values = g_new (GVariant *, n_items);
for (i = 0; i < n_items; i++)
/* We dropped the prefix when collecting the array.
* Bring it back temporarily, for the lookup.
*/
- change->values[i] = g_hash_table_lookup (change->table, change->paths[i] - prefix_length);
+ changeset->values[i] = g_hash_table_lookup (changeset->table, changeset->paths[i] - prefix_length);
}
}
+/**
+ * dconf_changeset_describe:
+ * @changeset: a #DConfChangeset
+ * @prefix: the prefix under which changes have been requested
+ * @paths: the list of paths changed, relative to @prefix
+ * @values: the list of values changed
+ *
+ * Describes @changeset.
+ *
+ * @prefix and @paths are presented in the same way as they are for the
+ * DConfClient::changed signal. @values is an array of the same length
+ * as @paths. For each key described by an element in @paths, @values
+ * will contain either a #GVariant (the requested new value of that key)
+ * or %NULL (to reset a reset).
+ *
+ * The @paths array is returned in an order such that dir will always
+ * come before keys contained within those dirs.
+ *
+ * Returns: the number of changes (the length of @changes and @values).
+ **/
guint
-dconf_changeset_describe (DConfChangeset *change,
- const gchar **root,
+dconf_changeset_describe (DConfChangeset *changeset,
+ const gchar **prefix,
const gchar * const **paths,
GVariant * const **values)
{
gint n_items;
- n_items = g_hash_table_size (change->table);
+ n_items = g_hash_table_size (changeset->table);
- if (n_items && !change->root)
- dconf_changeset_build_description (change);
+ if (n_items && !changeset->prefix)
+ dconf_changeset_build_description (changeset);
- if (root)
- *root = change->root;
+ if (prefix)
+ *prefix = changeset->prefix;
if (paths)
- *paths = change->paths;
+ *paths = changeset->paths;
if (values)
- *values = change->values;
+ *values = changeset->values;
return n_items;
}
+/**
+ * dconf_changeset_serialise:
+ * @changeset: a #DConfChangeset
+ *
+ * Serialises a #DConfChangeset.
+ *
+ * The returned value has no particular format and should only be passed
+ * to dconf_changeset_deserialise().
+ *
+ * Returns: a floating #GVariant
+ **/
GVariant *
-dconf_changeset_serialise (DConfChangeset *change)
+dconf_changeset_serialise (DConfChangeset *changeset)
{
GVariantBuilder builder;
GHashTableIter iter;
@@ -402,22 +481,37 @@ dconf_changeset_serialise (DConfChangeset *change)
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{smv}"));
- g_hash_table_iter_init (&iter, change->table);
+ g_hash_table_iter_init (&iter, changeset->table);
while (g_hash_table_iter_next (&iter, &key, &value))
g_variant_builder_add (&builder, "{smv}", key, value);
return g_variant_builder_end (&builder);
}
+/**
+ * dconf_changeset_deserialise:
+ * @serialised: a #GVariant from dconf_changeset_serialise()
+ *
+ * Creates a #DConfChangeset according to a serialised description
+ * returned from an earlier call to dconf_changeset_serialise().
+ *
+ * @serialised has no particular format -- you should only pass a value
+ * that reasulted from an earlier serialise operation.
+ *
+ * This call never fails, even if @serialised is not in the correct
+ * format. Improperly-formatted parts are simply ignored.
+ *
+ * Returns: a new #DConfChangeset
+ **/
DConfChangeset *
dconf_changeset_deserialise (GVariant *serialised)
{
- DConfChangeset *change;
+ DConfChangeset *changeset;
GVariantIter iter;
const gchar *key;
GVariant *value;
- change = dconf_changeset_new ();
+ changeset = dconf_changeset_new ();
g_variant_iter_init (&iter, serialised);
while (g_variant_iter_loop (&iter, "{&smv}", &key, &value))
{
@@ -431,18 +525,29 @@ dconf_changeset_deserialise (GVariant *serialised)
if (value == NULL)
{
if (dconf_is_path (key, NULL))
- g_hash_table_insert (change->table, g_strdup (key), NULL);
+ g_hash_table_insert (changeset->table, g_strdup (key), NULL);
}
else
{
if (dconf_is_key (key, NULL))
- g_hash_table_insert (change->table, g_strdup (key), g_variant_ref (value));
+ g_hash_table_insert (changeset->table, g_strdup (key), g_variant_ref (value));
}
}
- return change;
+ return changeset;
}
+/**
+ * dconf_changeset_new_write:
+ * @path: a dconf path
+ * @value: a #GVariant, or %NULL
+ *
+ * Creates a new #DConfChangeset with one change. This is equivalent to
+ * calling dconf_changeset_new() and then dconf_changeset_set() with
+ * @path and @value.
+ *
+ * Returns: a new #DConfChangeset
+ **/
DConfChangeset *
dconf_changeset_new_write (const gchar *path,
GVariant *value)