[glib] Bug 622127 - GSettings extended key validation



commit 168cfc592283c992d6a6803a91528f87cec2d902
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Jun 28 10:18:45 2010 -0400

    Bug 622127 - GSettings extended key validation
    
    First shot at attempting to implement this in a reasonable way.  See
    the bug for more information about why this is needed.

 docs/reference/gio/gio-sections.txt |    4 ++
 gio/gio.symbols                     |    1 +
 gio/gsettings.c                     |   83 ++++++++++++++++++++++++++++++++++-
 gio/gsettings.h                     |   27 +++++++++++
 4 files changed, 114 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index b1d86d1..e6dbac0 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -2169,6 +2169,10 @@ g_settings_set_strv
 g_settings_get_enum
 g_settings_set_enum
 
+<SUBSECTION MappedGet>
+GSettingsGetMapping
+g_settings_get_mapped
+
 <SUBSECTION Binding>
 GSettingsBindFlags
 g_settings_bind
diff --git a/gio/gio.symbols b/gio/gio.symbols
index e2bb8da..3e03011 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1479,6 +1479,7 @@ g_settings_get_enum
 g_settings_set_enum
 g_settings_sync
 g_settings_list_keys
+g_settings_get_mapped
 #endif
 #endif
 
diff --git a/gio/gsettings.c b/gio/gsettings.c
index b517237..54b66ed 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -1126,7 +1126,7 @@ g_settings_from_enum (GSettingsKeyInfo *info,
   return g_variant_ref_sink (g_variant_new_string (string));
 }
 
-/* Public Get/Set API {{{1 (get, get_value, set, set_value) */
+/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
 /**
  * g_settings_get_value:
  * @settings: a #GSettings object
@@ -1384,6 +1384,87 @@ g_settings_set (GSettings   *settings,
   return g_settings_set_value (settings, key, value);
 }
 
+/**
+ * g_settings_get_mapped:
+ * @settings: a #GSettings object
+ * @key: the key to get the value for
+ * @mapping: the function to map the value in the settings database to
+ *           the value used by the application
+ * @user_data: user data for @mapping
+ *
+ * Gets the value that is stored at @key in @settings, subject to
+ * application-level validation/mapping.
+ *
+ * You should use this function when the application needs to perform
+ * some processing on the value of the key (for example, parsing).  The
+ * @mapping function performs that processing.  If the function
+ * indicates that the processing was unsuccessful (due to a parse error,
+ * for example) then the mapping is tried again with another value.
+
+ * This allows a robust 'fall back to defaults' behaviour to be
+ * implemented somewhat automatically.
+ *
+ * The first value that is tried is the user's setting for the key.  If
+ * the mapping function fails to map this value, other values may be
+ * tried in an unspecified order (system or site defaults, translated
+ * schema default values, untranslated schema default values, etc).
+ *
+ * If the mapping function fails for all possible values, one additional
+ * attempt is made: the mapping function is called with a %NULL value.
+ * If the mapping function still indicates failure at this point then
+ * the application will be aborted.
+ *
+ * The result parameter for the @mapping function is pointed to a
+ * #gpointer which is initially set to %NULL.  The same pointer is given
+ * to each invocation of @mapping.  The final value of that #gpointer is
+ * what is returned by this function.  %NULL is valid; it is returned
+ * just as any other value would be.
+ **/
+gpointer
+g_settings_get_mapped (GSettings           *settings,
+                       const gchar         *key,
+                       GSettingsGetMapping  mapping,
+                       gpointer             user_data)
+{
+  gpointer result = NULL;
+  GSettingsKeyInfo info;
+  GVariant *value;
+  gboolean okay;
+
+  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+  g_return_val_if_fail (mapping != NULL, NULL);
+
+  g_settings_get_key_info (&info, settings, key);
+
+  if ((value = g_settings_read_from_backend (&info)))
+    {
+      okay = mapping (value, &result, user_data);
+      g_variant_unref (value);
+      if (okay) goto okay;
+    }
+
+  if ((value = g_settings_get_translated_default (&info)))
+    {
+      okay = mapping (value, &result, user_data);
+      g_variant_unref (value);
+      if (okay) goto okay;
+    }
+
+  if (mapping (info.default_value, &result, user_data))
+    goto okay;
+
+  if (!mapping (NULL, &result, user_data))
+    g_error ("The mapping function given to g_settings_get_mapped() for key "
+             "`%s' in schema `%s' returned FALSE when given a NULL value.",
+             key, settings->priv->schema_name);
+
+ okay:
+  g_settings_free_key_info (&info);
+
+  return result;
+}
+
 /* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
 /**
  * g_settings_get_string:
diff --git a/gio/gsettings.h b/gio/gsettings.h
index c3cbb48..40d0cbf 100644
--- a/gio/gsettings.h
+++ b/gio/gsettings.h
@@ -169,6 +169,28 @@ typedef gboolean      (*GSettingsBindGetMapping)                        (GValue
                                                                          gpointer            user_data);
 
 /**
+ * GSettingsGetMapping:
+ * @value: the #GVariant to map, or %NULL
+ * @result: the result of the mapping
+ * @user_data: the user data that was passed to g_settings_get_mapped()
+ * Returns: %TRUE if the conversion succeeded, %FALSE in case of an error
+ *
+ * The type of the function that is used to convert from a value stored
+ * in a #GSettings to a value that is useful to the application.
+ *
+ * If the value is successfully mapped, the result should be stored at
+ * @result and %TRUE returned.  If mapping fails (for example, if @value
+ * is not in the right format) then %FALSE should be returned.
+ *
+ * If @value is %NULL then it means that the mapping function is being
+ * given a "last chance" to successfully return a valid value.  %TRUE
+ * must be returned in this case.
+ **/
+typedef gboolean      (*GSettingsGetMapping)                            (GVariant           *value,
+                                                                         gpointer           *result,
+                                                                         gpointer            user_data);
+
+/**
  * GSettingsBindFlags:
  * @G_SETTINGS_BIND_DEFAULT: Equivalent to <literal>G_SETTINGS_BIND_GET|G_SETTINGS_BIND_SET</literal>
  * @G_SETTINGS_BIND_GET: Update the #GObject property when the setting changes.
@@ -214,6 +236,11 @@ void                    g_settings_bind_writable                        (GSettin
 void                    g_settings_unbind                               (gpointer                 object,
                                                                          const gchar             *property);
 
+gpointer                g_settings_get_mapped                           (GSettings               *settings,
+                                                                         const gchar             *key,
+                                                                         GSettingsGetMapping      mapping,
+                                                                         gpointer                 user_data);
+
 G_END_DECLS
 
 #endif  /* __G_SETTINGS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]