[glib/gsettings: 324/327] move GSettingsBackend into gio/
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib/gsettings: 324/327] move GSettingsBackend into gio/
- Date: Thu, 27 Aug 2009 17:49:23 +0000 (UTC)
commit 528b743569c442e4aabffcfca8c7fa207d6428de
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Aug 20 15:07:32 2009 -0400
move GSettingsBackend into gio/
docs/reference/gio/gio-sections.txt | 18 ++
gio/Makefile.am | 2 +
gio/gio-marshal.list | 2 +
gio/gio.symbols | 15 ++
gio/giomodule.c | 4 +
gio/gsettingsbackend.c | 333 +++++++++++++++++++++++++++++++++++
gio/gsettingsbackend.h | 110 ++++++++++++
gio/pltcheck.sh | 2 +-
8 files changed, 485 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index f178a70..fc6fedd 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1912,3 +1912,21 @@ G_UNIX_FD_MESSAGE_GET_CLASS
GUnixFDMessagePrivate
g_unix_fd_message_get_type
</SECTION>
+
+<SECTION>
+<FILE>gsettingsbackend</FILE>
+<TITLE>GSettingsBackend</TITLE>
+GSettingsBackend
+g_settings_backend_get_default
+g_settings_backend_new_tree
+g_settings_backend_read
+g_settings_backend_write
+g_settings_backend_get_writable
+g_settings_backend_subscribe
+g_settings_backend_unsubscribe
+g_settings_backend_changed
+g_settings_backend_changed_tree
+<SUBSECTION Private>
+GSettingsBackendPrivate
+g_settings_backend_get_type
+</SECTION>
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 59d5264..17ef981 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -236,6 +236,7 @@ libgio_2_0_la_SOURCES = \
gpollfilemonitor.h \
gresolver.c \
gseekable.c \
+ gsettingsbackend.c \
gsimpleasyncresult.c \
gsocket.c \
gsocketaddress.c \
@@ -364,6 +365,7 @@ gio_headers = \
goutputstream.h \
gresolver.h \
gseekable.h \
+ gsettingsbackend.h \
gsimpleasyncresult.h \
gsocket.h \
gsocketaddress.h \
diff --git a/gio/gio-marshal.list b/gio/gio-marshal.list
index 269ec35..10db380 100644
--- a/gio/gio-marshal.list
+++ b/gio/gio-marshal.list
@@ -4,3 +4,5 @@ VOID:BOOLEAN,POINTER
VOID:OBJECT,OBJECT,ENUM
BOOLEAN:OBJECT,OBJECT
VOID:STRING,BOXED,BOXED
+VOID:POINTER,INT
+VOID:STRING,POINTER,INT,POINTER
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 166b677..890e1bd 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1257,3 +1257,18 @@ g_unix_fd_message_steal_fds
#endif
#endif
#endif
+
+#if IN_HEADER(_gsettingsbackend_h_)
+#if IN_FILE(_gsettingsbackend_c_)
+g_settings_backend_get_type
+g_settings_backend_get_default
+g_settings_backend_new_tree
+g_settings_backend_read
+g_settings_backend_write
+g_settings_backend_get_writable
+g_settings_backend_unsubscribe
+g_settings_backend_subscribe
+g_settings_backend_changed
+g_settings_backend_changed_tree
+#endif
+#endif
diff --git a/gio/giomodule.c b/gio/giomodule.c
index 68f3b7b..540135f 100644
--- a/gio/giomodule.c
+++ b/gio/giomodule.c
@@ -24,6 +24,7 @@
#include <string.h>
+#include "gsettingsbackend.h"
#include "giomodule.h"
#include "giomodule-priv.h"
#include "glocalfilemonitor.h"
@@ -328,6 +329,9 @@ _g_io_modules_ensure_extension_points_registered (void)
ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
+
+ ep = g_io_extension_point_register (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
+ g_io_extension_point_set_required_type (ep, G_TYPE_SETTINGS_BACKEND);
}
G_UNLOCK (registered_extensions);
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
new file mode 100644
index 0000000..5ef1091
--- /dev/null
+++ b/gio/gsettingsbackend.c
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+#include "gsettingsbackend.h"
+
+#include "giomodule-priv.h"
+#include "gio-marshal.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+
+#include "gioalias.h"
+
+G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
+
+static guint changed_signal;
+
+/**
+ * SECTION:gsettingsbackend
+ * @short_description: an interface for settings backend implementations
+ *
+ * The #GSettingsBackend inteface defines a generic interface for
+ * non-strictly-typed data backend in a hierarchy.
+ *
+ * The interface defines methods for reading and writing values, a
+ * method for determining if writing of certain values will fail
+ * (lockdown) and a change notification signal.
+ *
+ * The semantics of the interface are very precisely defined and
+ * implementations must carefully adhere to the expectations of
+ * callers that are documented on each of the interface methods.
+ **/
+
+/**
+ * g_settings_backend_changed:
+ * @backend: a #GSettingsBackend implementation
+ * @prefix: the longest common prefix
+ * @items: the NULL-terminated list of changed keys
+ * @n_items: the number of items in @items
+ * @origin_tag: the origin tag
+ *
+ * Emits the changed signal on @backend. This function should only be
+ * called by the implementation itself, to indicate that a change has
+ * occurred.
+ *
+ * The list of changed keys, relative to the root of the settings store,
+ * is @prefix prepended to each of the @items. It must either be the
+ * case that @prefix is equal to "" or ends in "/" or that @items
+ * contains exactly one item: "". @prefix need not be the largest
+ * possible prefix.
+ *
+ * The implementation must call this function during any call to
+ * g_settings_backend_write(), before the call returns (except in the
+ * case that no keys are actually changed). It may not rely on the
+ * existence of a mainloop for dispatching the signal later.
+ *
+ * The implementation may call this function at any other time it likes
+ * in response to other events (such as changes occuring outside of the
+ * program). These calls may originate from a mainloop or may originate
+ * in response to any other action (including from calls to
+ * g_settings_backend_write()).
+ *
+ * In the case that this call is in response to a call to
+ * g_settings_backend_write() then @origin_tag must be set to the same
+ * value that was passed to that call.
+ **/
+void
+g_settings_backend_changed (GSettingsBackend *backend,
+ const gchar *prefix,
+ gchar const * const *items,
+ gint n_items,
+ gpointer origin_tag)
+{
+ if (n_items == -1)
+ for (n_items = 0; items[n_items]; n_items++);
+
+ g_assert (items[n_items] == NULL);
+
+ g_signal_emit (backend, changed_signal, 0,
+ prefix, items, n_items, origin_tag);
+}
+
+static gboolean
+g_settings_backend_append_to_list (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ return (*((*((gchar ***) user_data))++) = key, FALSE);
+}
+
+/**
+ * g_settings_backend_changed_tree:
+ * @backend: a #GSettingsBackend implementation
+ * @prefix: the longest common prefix
+ * @tree: a #GTree
+ * @origin_tag: the origin tag
+ *
+ * This call is a convenience wrapper around
+ * g_settings_backend_changed(). It gets the list of changes from
+ * @tree.
+ **/
+void
+g_settings_backend_changed_tree (GSettingsBackend *backend,
+ const gchar *prefix,
+ GTree *tree,
+ gpointer origin_tag)
+{
+ gchar **list;
+
+ list = g_new (gchar *, g_tree_nnodes (tree) + 1);
+
+ {
+ gchar **ptr = list;
+ g_tree_foreach (tree, g_settings_backend_append_to_list, &ptr);
+ *ptr = NULL;
+
+ g_assert (list + g_tree_nnodes (tree) == ptr);
+ }
+
+ g_signal_emit (backend, changed_signal, 0,
+ prefix, list, g_tree_nnodes (tree), origin_tag);
+ g_free (list);
+}
+
+/**
+ * g_settings_backend_read:
+ * @backend: a #GSettingsBackend implementation
+ * @key: the key to read
+ * @expected_type: a #GVariantType hint
+ * @returns: the values that was read, or %NULL
+ *
+ * Reads a keys. This call will never block.
+ *
+ * If the key exists, it will be returned. If the key does not exist,
+ * %NULL will be returned.
+ *
+ * If @expected_type is given, it serves as a type hint to the backend.
+ * If you expect a key of a certain type then you should give
+ * @expected_type to increase your chances of getting it. Some backends
+ * may ignore this argument and return values of a different type; it is
+ * mostly used by backends that don't store strong type information.
+ **/
+GVariant *
+g_settings_backend_read (GSettingsBackend *backend,
+ const gchar *key,
+ const GVariantType *expected_type)
+{
+ return G_SETTINGS_BACKEND_GET_CLASS (backend)
+ ->read (backend, key, expected_type);
+}
+
+/**
+ * g_settings_backend_write:
+ * @backend: a #GSettingsBackend implementation
+ * @prefix: the longest common prefix
+ * @values: a #GTree containing values to write
+ * @origin_tag: the origin tag
+ *
+ * Writes one or more keys. This call will never block.
+ *
+ * For each item in @values, a key is written. The key to be written is
+ * @prefix prepended to the key used in the tree. The value stored in
+ * the tree is expected to be a #GVariant instance. It must either be
+ * the case that @prefix is equal to "" or ends in "/" or that @values
+ * contains exactly one item, with a key of "". @prefix need not be the
+ * largest possible prefix.
+ *
+ * This call does not fail. During this call a "changed" signal will be
+ * emitted if any keys have been changed. The new values of all updated
+ * keys will be visible to any signal callbacks.
+ *
+ * One possible method that an implementation might deal with failures
+ * is to emit a second "backend-changed" signal (either during this
+ * call, or later) to indicate that the affected keys have suddenly
+ * "changed back" to their old values.
+ **/
+void
+g_settings_backend_write (GSettingsBackend *backend,
+ const gchar *prefix,
+ GTree *values,
+ gpointer origin_tag)
+{
+ G_SETTINGS_BACKEND_GET_CLASS (backend)
+ ->write (backend, prefix, values, origin_tag);
+}
+
+/**
+ * g_settings_backend_get_writable:
+ * @backend: a #GSettingsBackend implementation
+ * @name: the name of a key, relative to the root of the backend
+ * @returns: %TRUE if the key is writable
+ *
+ * Ensures that a key is available for writing to. This is the
+ * interface through which 'lockdown' is implemented. Locked down
+ * keys will have %FALSE returned by this call.
+ *
+ * You should not write to locked-down keys, but if you do, the
+ * implementation will deal with it.
+ **/
+gboolean
+g_settings_backend_get_writable (GSettingsBackend *backend,
+ const gchar *name)
+{
+ return G_SETTINGS_BACKEND_GET_CLASS (backend)
+ ->get_writable (backend, name);
+}
+
+/**
+ * g_settings_backend_subscribe:
+ * @backend: a #GSettingsBackend
+ * @name: a key or path to subscribe to
+ *
+ * Reverses the effect of a previous call to
+ * g_settings_backend_subscribe().
+ **/
+void
+g_settings_backend_unsubscribe (GSettingsBackend *backend,
+ const char *name)
+{
+ G_SETTINGS_BACKEND_GET_CLASS (backend)
+ ->unsubscribe (backend, name);
+}
+
+/**
+ * g_settings_backend_subscribe:
+ * @backend: a #GSettingsBackend
+ * @name: a key or path to subscribe to
+ *
+ * Requests that change signals be emitted for events on @name.
+ **/
+void
+g_settings_backend_subscribe (GSettingsBackend *backend,
+ const gchar *name)
+{
+ G_SETTINGS_BACKEND_GET_CLASS (backend)
+ ->subscribe (backend, name);
+}
+
+static void
+g_settings_backend_class_init (GSettingsBackendClass *class)
+{
+ changed_signal =
+ g_signal_new ("changed", G_TYPE_SETTINGS_BACKEND,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GSettingsBackendClass, changed),
+ NULL, NULL,
+ _gio_marshal_VOID__STRING_POINTER_INT_POINTER, G_TYPE_NONE,
+ 4, G_TYPE_STRING, G_TYPE_STRV, G_TYPE_INT, G_TYPE_POINTER);
+}
+
+/**
+ * g_settings_backend_new_tree:
+ * @returns: a new #GTree
+ *
+ * This is a convenience function for creating a tree that is compatible
+ * with g_settings_backend_write(). It merely calls g_tree_new_full()
+ * with strcmp() g_free() and g_variant_unref().
+ **/
+GTree *
+g_settings_backend_new_tree (void)
+{
+ return g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
+ g_free, (GDestroyNotify) g_variant_unref);
+}
+
+static gpointer
+get_default_backend (gpointer user_data)
+{
+ GIOExtension *extension = NULL;
+ GIOExtensionPoint *point;
+ GList *extensions;
+ const gchar *env;
+ GType type;
+
+ _g_io_modules_ensure_loaded ();
+
+ point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
+
+ if ((env = getenv ("GSETTINGS_BACKEND")))
+ {
+ extension = g_io_extension_point_get_extension_by_name (point, env);
+
+ if (extension == NULL)
+ g_warning ("Can't find GSettings backend '%s' given in "
+ "GSETTINGS_BACKEND environment variable", env);
+ }
+
+ if (extension == NULL)
+ {
+ extensions = g_io_extension_point_get_extensions (point);
+
+ if (extensions == NULL)
+ g_error ("No GSettingsBackend implementations exist.");
+
+ extension = extensions->data;
+ }
+
+ type = g_io_extension_get_type (extension);
+
+ return g_object_new (type, NULL);
+}
+
+/**
+ * g_settings_backend_get_default:
+ * @returns: the default #GSettingsBackend
+ *
+ * Returns the default #GSettingsBackend.
+ *
+ * The user does not own the return value and it must not be freed.
+ **/
+GSettingsBackend *
+g_settings_backend_get_default (void)
+{
+ static GOnce once = G_ONCE_INIT;
+
+ return g_once (&once, get_default_backend, NULL);
+}
+
+static void
+g_settings_backend_init (GSettingsBackend *backend)
+{
+}
+
+#define _gsettingsbackend_c_
+#include "gioaliasdef.c"
diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h
new file mode 100644
index 0000000..7f9f394
--- /dev/null
+++ b/gio/gsettingsbackend.h
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#ifndef _gsettingsbackend_h_
+#define _gsettingsbackend_h_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_SETTINGS_BACKEND (g_settings_backend_get_type ())
+#define G_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ G_TYPE_SETTINGS_BACKEND, GSettingsBackend))
+#define G_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ G_TYPE_SETTINGS_BACKEND, GSettingsBackendClass))
+#define G_IS_SETTINGS_BACKEND(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ G_TYPE_SETTINGS_BACKEND))
+#define G_IS_SETTINGS_BACKEND_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ G_TYPE_SETTINGS_BACKEND))
+#define G_SETTINGS_BACKEND_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ G_TYPE_SETTINGS_BACKEND, GSettingsBackendClass))
+
+#define G_SETTINGS_BACKEND_EXTENSION_POINT_NAME "gsettings-backend"
+
+/**
+ * GSettingsBackend:
+ *
+ * An implementation of a settings storage repository.
+ **/
+typedef struct _GSettingsBackendPrivate GSettingsBackendPrivate;
+typedef struct _GSettingsBackendClass GSettingsBackendClass;
+typedef struct _GSettingsBackend GSettingsBackend;
+
+struct _GSettingsBackendClass
+{
+ GObjectClass parent_class;
+
+ void (*destroyed) (GSettingsBackend *backend);
+
+ void (*changed) (GSettingsBackend *backend,
+ const gchar *prefix,
+ gchar const * const *names,
+ gint names_len,
+ gpointer origin_tag);
+
+ GVariant * (*read) (GSettingsBackend *backend,
+ const gchar *key,
+ const GVariantType *expected_type);
+ void (*write) (GSettingsBackend *backend,
+ const gchar *prefix,
+ GTree *tree,
+ gpointer origin_tag);
+ gboolean (*get_writable) (GSettingsBackend *backend,
+ const gchar *name);
+ void (*subscribe) (GSettingsBackend *backend,
+ const gchar *name);
+ void (*unsubscribe) (GSettingsBackend *backend,
+ const gchar *name);
+};
+
+struct _GSettingsBackend
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ GSettingsBackendPrivate *priv;
+};
+
+GType g_settings_backend_get_type (void);
+GSettingsBackend * g_settings_backend_get_default (void);
+void g_settings_backend_set_default (GSettingsBackend *backend);
+GTree * g_settings_backend_new_tree (void);
+
+GVariant * g_settings_backend_read (GSettingsBackend *backend,
+ const gchar *key,
+ const GVariantType *expected_type);
+
+void g_settings_backend_write (GSettingsBackend *backend,
+ const gchar *prefix,
+ GTree *values,
+ gpointer origin_tag);
+
+gboolean g_settings_backend_get_writable (GSettingsBackend *backend,
+ const char *name);
+
+void g_settings_backend_unsubscribe (GSettingsBackend *backend,
+ const char *name);
+void g_settings_backend_subscribe (GSettingsBackend *backend,
+ const char *name);
+
+void g_settings_backend_changed (GSettingsBackend *backend,
+ const gchar *prefix,
+ gchar const * const *items,
+ gint n_items,
+ gpointer origin_tag);
+void g_settings_backend_changed_tree (GSettingsBackend *backend,
+ const gchar *prefix,
+ GTree *tree,
+ gpointer origin_tag);
+
+G_END_DECLS
+
+#endif /* _gsettingsbackend_h_ */
diff --git a/gio/pltcheck.sh b/gio/pltcheck.sh
index 5859443..3e18f3a 100755
--- a/gio/pltcheck.sh
+++ b/gio/pltcheck.sh
@@ -9,7 +9,7 @@ if ! which readelf 2>/dev/null >/dev/null; then
exit 0
fi
-SKIP='\<g_access\|\<g_array_\|\<g_ascii\|\<g_list_\|\<g_assertion_message\|\<g_warn_message\|\<g_atomic\|\<g_bit_\|\<g_boxed\|\<g_build_filename\|\<g_byte_array\|\<g_checksum\|\<g_child_watch\|\<g_clear_error\|\<g_convert\|\<g_dir_\|\<g_enum_\|\<g_error_\|\<g_prefix_error\|\<g_file_error_quark\|\<g_file_get_contents\|\<g_file_set_contents\|\<g_file_test\|\<g_file_read_link\|\<g_filename_\|\<g_find_program_in_path\|\<g_flags_\|\<g_free\|\<g_get_\|\<g_getenv\|\<g_setenv\|\<g_hash_table_\|\<g_hostname_\|\<g_idle_\|\<g_intern_static_string\|\<g_io_add_watch\|\<g_io_channel_\|\<g_io_create_watch\|\<g_key_file_\|\<g_listenv\|\<g_locale_to_utf8\|\<g_log\|\<g_main_context_\|\<g_main_current_source\|\<g_main_loop_\|\<g_malloc\|\<g_markup_\|\<g_mkdir_\|\<g_mkstemp\|\<g_module_\|\<g_object_\|\<g_once_\|\<g_param_spec_\|\<g_path_\|\<g_poll\|\<g_printerr\|\<g_propagate_error\|\<g_ptr_array_\|\<g_qsort_\|\<g_quark_\|\<g_queue_\|\<g_random_int_range\|\<g_realloc\|\<g_return_if_fail\|\<g_se
t_error\|\<g_shell_\|\<g_signal_\|\<g_slice_\|\<g_slist_\|\<g_snprintf\|\<g_source_\|\<g_spawn_\|\<g_static_\|\<g_str\|\<g_thread_pool_\|\<g_time_val_add\|\<g_timeout_\|\<g_type_\|\<g_unlink\|\<g_uri_\|\<g_utf8_\|\<g_value_'
+SKIP='\<g_access\|\<g_array_\|\<g_ascii\|\<g_list_\|\<g_tree_\|\<g_assertion_message\|\<g_warn_message\|\<g_atomic\|\<g_bit_\|\<g_boxed\|\<g_build_filename\|\<g_byte_array\|\<g_checksum\|\<g_child_watch\|\<g_clear_error\|\<g_convert\|\<g_dir_\|\<g_enum_\|\<g_error_\|\<g_prefix_error\|\<g_file_error_quark\|\<g_file_get_contents\|\<g_file_set_contents\|\<g_file_test\|\<g_file_read_link\|\<g_filename_\|\<g_find_program_in_path\|\<g_flags_\|\<g_free\|\<g_get_\|\<g_getenv\|\<g_setenv\|\<g_hash_table_\|\<g_hostname_\|\<g_idle_\|\<g_intern_static_string\|\<g_io_add_watch\|\<g_io_channel_\|\<g_io_create_watch\|\<g_key_file_\|\<g_listenv\|\<g_locale_to_utf8\|\<g_log\|\<g_main_context_\|\<g_main_current_source\|\<g_main_loop_\|\<g_malloc\|\<g_markup_\|\<g_mkdir_\|\<g_mkstemp\|\<g_module_\|\<g_object_\|\<g_once_\|\<g_param_spec_\|\<g_path_\|\<g_poll\|\<g_printerr\|\<g_propagate_error\|\<g_ptr_array_\|\<g_qsort_\|\<g_quark_\|\<g_queue_\|\<g_random_int_range\|\<g_realloc\|\<g_return_if_f
ail\|\<g_set_error\|\<g_shell_\|\<g_signal_\|\<g_slice_\|\<g_slist_\|\<g_snprintf\|\<g_source_\|\<g_spawn_\|\<g_static_\|\<g_str\|\<g_thread_pool_\|\<g_time_val_add\|\<g_timeout_\|\<g_type_\|\<g_unlink\|\<g_uri_\|\<g_utf8_\|\<g_value_'
for so in .libs/lib*.so; do
echo Checking $so for local PLT entries
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]