From 8dddf6499e9e8a052a5673fe8771aeaac08cccae Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sun, 25 Apr 2010 22:00:28 -0500 Subject: [PATCH] GSettingsBackend API/ABI change - add list() virtual method - add 'default_value' flag to read() call --- gio/gdelayedsettingsbackend.c | 8 +-- gio/gio.symbols | 1 + gio/gkeyfilesettingsbackend.c | 6 ++- gio/gmemorysettingsbackend.c | 7 ++- gio/gnullsettingsbackend.c | 3 +- gio/gsettings.c | 2 +- gio/gsettingsbackend.c | 91 ++++++++++++++++++++++++---------- gio/gsettingsbackend.h | 10 +++- gio/gsettingsbackendinternal.h | 3 +- 9 files changed, 96 insertions(+), 35 deletions(-) diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c index 644e92e82..c09be7f30 100644 --- a/gio/gdelayedsettingsbackend.c +++ b/gio/gdelayedsettingsbackend.c @@ -42,16 +42,18 @@ G_DEFINE_TYPE (GDelayedSettingsBackend, static GVariant * g_delayed_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type) + const GVariantType *expected_type, + gboolean default_value) { GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); GVariant *result; - if ((result = g_tree_lookup (delayed->priv->delayed, key))) + if (!default_value && + (result = g_tree_lookup (delayed->priv->delayed, key))) return g_variant_ref (result); return g_settings_backend_read (delayed->priv->backend, - key, expected_type); + key, expected_type, default_value); } static gboolean g_delayed_settings_backend_write (GSettingsBackend *backend, diff --git a/gio/gio.symbols b/gio/gio.symbols index 6b729d374..aa2eadf7e 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -1387,6 +1387,7 @@ g_settings_backend_setup_keyfile g_settings_backend_setup g_settings_backend_get_type g_settings_backend_changed +g_settings_backend_flatten_tree g_settings_backend_keys_changed g_settings_backend_path_changed g_settings_backend_path_writable_changed diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c index cfae96fbc..4bb922544 100644 --- a/gio/gkeyfilesettingsbackend.c +++ b/gio/gkeyfilesettingsbackend.c @@ -54,11 +54,15 @@ struct _GKeyfileSettingsBackendPrivate static GVariant * g_keyfile_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type) + const GVariantType *expected_type, + gboolean default_value) { GKeyfileSettingsBackend *kf_backend = G_KEYFILE_SETTINGS_BACKEND (backend); GVariant *value; + if (default_value) + return NULL; + value = g_hash_table_lookup (kf_backend->priv->table, key); if (value != NULL) diff --git a/gio/gmemorysettingsbackend.c b/gio/gmemorysettingsbackend.c index 902bce15e..bb04f39cb 100644 --- a/gio/gmemorysettingsbackend.c +++ b/gio/gmemorysettingsbackend.c @@ -48,11 +48,14 @@ G_DEFINE_TYPE_WITH_CODE (GMemorySettingsBackend, static GVariant * g_memory_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type) + const GVariantType *expected_type, + gboolean default_value) { + GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend); GVariant *value; - GMemorySettingsBackend *memory = G_MEMORY_SETTINGS_BACKEND (backend); + if (default_value) + return NULL; value = g_hash_table_lookup (memory->table, key); diff --git a/gio/gnullsettingsbackend.c b/gio/gnullsettingsbackend.c index 28ffe8203..5fb98e935 100644 --- a/gio/gnullsettingsbackend.c +++ b/gio/gnullsettingsbackend.c @@ -42,7 +42,8 @@ G_DEFINE_TYPE (GNullSettingsBackend, static GVariant * g_null_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type) + const GVariantType *expected_type, + gboolean default_value) { return NULL; } diff --git a/gio/gsettings.c b/gio/gsettings.c index 30450a879..801f57060 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -751,7 +751,7 @@ g_settings_get_value (GSettings *settings, path = g_strconcat (settings->priv->path, key, NULL); type = g_variant_get_type (sval); - value = g_settings_backend_read (settings->priv->backend, path, type); + value = g_settings_backend_read (settings->priv->backend, path, type, FALSE); g_free (path); if (options != NULL) diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c index 7ad048aee..a4e1cbe66 100644 --- a/gio/gsettingsbackend.c +++ b/gio/gsettingsbackend.c @@ -368,17 +368,18 @@ g_settings_backend_path_writable_changed (GSettingsBackend *backend, typedef struct { + const gchar **keys; + GVariant **values; gint prefix_len; gchar *prefix; - gchar **items; -} GetKeysState; +} FlattenState; static gboolean -tree_get_keys (gpointer key, - gpointer value, - gpointer user_data) +g_settings_backend_flatten_one (gpointer key, + gpointer value, + gpointer user_data) { - GetKeysState *state = user_data; + FlattenState *state = user_data; const gchar *skey = key; gint i; @@ -419,11 +420,60 @@ tree_get_keys (gpointer key, /* save the entire item into the array. * the prefixes will be removed later. */ - *state->items++ = key; + *state->keys++ = key; + + if (state->values) + *state->values++ = value; return FALSE; } +/** + * g_settings_backend_flatten_tree: + * @tree: a #GTree containing the changes + * @path: the location to save the path + * @keys: the location to save the relative keys + * @values: the location to save the values, or %NULL + * + * Calculate the longest common prefix of all keys in a tree and write + * out an array of the key names relative to that prefix and, + * optionally, the value to store at each of those keys. + * + * You must free the value returned in @path, @keys and @values using + * g_free(). You should not attempt to free or unref the contents of + * @keys or @values. + * + * Since: 2.26 + **/ +void +g_settings_backend_flatten_tree (GTree *tree, + gchar **path, + const gchar ***keys, + GVariant ***values) +{ + FlattenState state = { 0, }; + gsize nnodes; + gsize i; + + nnodes = g_tree_nnodes (tree); + + *keys = state.keys = g_new (const gchar *, nnodes + 1); + state.keys[nnodes] = NULL; + + if (values != NULL) + { + *values = state.values = g_new (GVariant *, nnodes + 1); + state.values[nnodes] = NULL; + } + + g_tree_foreach (tree, g_settings_backend_flatten_one, &state); + g_return_if_fail (*keys + nnodes == state.keys); + + *path = state.prefix; + for (i = 0; i < nnodes; i++) + state.keys[i] += state.prefix_len; +} + /** * g_settings_backend_changed_tree: * @backend: a #GSettingsBackend implementation @@ -442,28 +492,18 @@ g_settings_backend_changed_tree (GSettingsBackend *backend, gpointer origin_tag) { GSettingsBackendWatch *watch; - GetKeysState state = { 0, }; - gchar **list; + const gchar **keys; + gchar *path; g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); - list = g_new (gchar *, g_tree_nnodes (tree) + 1); - state.items = list; - - g_tree_foreach (tree, tree_get_keys, &state); - g_return_if_fail (list + g_tree_nnodes (tree) == state.items); - *state.items = NULL; - - while (state.items-- != list) - *state.items += state.prefix_len; + g_settings_backend_flatten_tree (tree, &path, &keys, NULL); for (watch = backend->priv->watches; watch; watch = watch->next) - watch->keys_changed (backend, state.prefix, - (const gchar * const *) list, - origin_tag, watch->user_data); + watch->keys_changed (backend, path, keys, origin_tag, watch->user_data); - g_free (list); - g_free (state.prefix); + g_free (path); + g_free (keys); } /*< private > @@ -487,10 +527,11 @@ g_settings_backend_changed_tree (GSettingsBackend *backend, GVariant * g_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type) + const GVariantType *expected_type, + gboolean default_value) { return G_SETTINGS_BACKEND_GET_CLASS (backend) - ->read (backend, key, expected_type); + ->read (backend, key, expected_type, default_value); } /*< private > diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h index 6aa33450d..6adcbe155 100644 --- a/gio/gsettingsbackend.h +++ b/gio/gsettingsbackend.h @@ -69,7 +69,11 @@ struct _GSettingsBackendClass GVariant * (*read) (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type); + const GVariantType *expected_type, + gboolean default_value); + gchar ** (*list) (GSettingsBackend *backend, + const gchar *path, + gsize *length); gboolean (*write) (GSettingsBackend *backend, const gchar *key, GVariant *value, @@ -112,6 +116,10 @@ void g_settings_backend_changed (GSettin void g_settings_backend_path_changed (GSettingsBackend *backend, const gchar *path, gpointer origin_tag); +void g_settings_backend_flatten_tree (GTree *tree, + gchar **path, + const gchar ***keys, + GVariant ***values); void g_settings_backend_keys_changed (GSettingsBackend *backend, const gchar *path, gchar const * const *items, diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h index fbdf15241..b36eaa3bf 100644 --- a/gio/gsettingsbackendinternal.h +++ b/gio/gsettingsbackendinternal.h @@ -67,7 +67,8 @@ GTree * g_settings_backend_create_tree (void); G_GNUC_INTERNAL GVariant * g_settings_backend_read (GSettingsBackend *backend, const gchar *key, - const GVariantType *expected_type); + const GVariantType *expected_type, + gboolean default_value); G_GNUC_INTERNAL gboolean g_settings_backend_write (GSettingsBackend *backend, const gchar *key,