#include "gsettings-mapping.h"
#include "gsettingsschema-internal.h"
-#include <string.h>
-
-
#include "strinfo.c"
/**
NULL);
}
-/* Internal read/write utilities, enum/flags conversion, validation {{{1 */
-typedef struct
-{
- GSettingsSchema *schema;
- const gchar *name;
-
- guint is_flags : 1;
- guint is_enum : 1;
-
- const guint32 *strinfo;
- gsize strinfo_length;
-
- const gchar *unparsed;
- gchar lc_char;
-
- const GVariantType *type;
- GVariant *minimum, *maximum;
- GVariant *default_value;
-} GSettingsSchemaKey;
-
-static inline void
-endian_fixup (GVariant **value)
-{
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- GVariant *tmp;
-
- tmp = g_variant_byteswap (*value);
- g_variant_unref (*value);
- *value = tmp;
-#endif
-}
-
-static void
-g_settings_schema_key_init (GSettingsSchemaKey *key,
- GSettingsSchema *schema,
- const gchar *name)
-{
- GVariantIter *iter;
- GVariant *data;
- guchar code;
-
- memset (key, 0, sizeof *key);
-
- iter = g_settings_schema_get_value (schema, name);
-
- key->schema = g_settings_schema_ref (schema);
- key->default_value = g_variant_iter_next_value (iter);
- endian_fixup (&key->default_value);
- key->type = g_variant_get_type (key->default_value);
- key->name = g_intern_string (name);
-
- while (g_variant_iter_next (iter, "(y*)", &code, &data))
- {
- switch (code)
- {
- case 'l':
- /* translation requested */
- g_variant_get (data, "(y&s)", &key->lc_char, &key->unparsed);
- break;
-
- case 'e':
- /* enumerated types... */
- key->is_enum = TRUE;
- goto choice;
-
- case 'f':
- /* flags... */
- key->is_flags = TRUE;
- goto choice;
-
- choice: case 'c':
- /* ..., choices, aliases */
- key->strinfo = g_variant_get_fixed_array (data, &key->strinfo_length, sizeof (guint32));
- break;
-
- case 'r':
- g_variant_get (data, "(**)", &key->minimum, &key->maximum);
- endian_fixup (&key->minimum);
- endian_fixup (&key->maximum);
- break;
-
- default:
- g_warning ("unknown schema extension '%c'", code);
- break;
- }
-
- g_variant_unref (data);
- }
-
- g_variant_iter_free (iter);
-}
-
-static void
-g_settings_schema_key_clear (GSettingsSchemaKey *key)
-{
- if (key->minimum)
- g_variant_unref (key->minimum);
-
- if (key->maximum)
- g_variant_unref (key->maximum);
-
- g_variant_unref (key->default_value);
-
- g_settings_schema_unref (key->schema);
-}
-
+/* Internal read/write utilities {{{1 */
static gboolean
g_settings_write_to_backend (GSettings *settings,
GSettingsSchemaKey *key,
return success;
}
-static gboolean
-g_settings_schema_key_type_check (GSettingsSchemaKey *key,
- GVariant *value)
-{
- g_return_val_if_fail (value != NULL, FALSE);
-
- return g_variant_is_of_type (value, key->type);
-}
-
-static gboolean
-g_settings_schema_key_range_check (GSettingsSchemaKey *key,
- GVariant *value)
-{
- if (key->minimum == NULL && key->strinfo == NULL)
- return TRUE;
-
- if (g_variant_is_container (value))
- {
- gboolean ok = TRUE;
- GVariantIter iter;
- GVariant *child;
-
- g_variant_iter_init (&iter, value);
- while (ok && (child = g_variant_iter_next_value (&iter)))
- {
- ok = g_settings_schema_key_range_check (key, child);
- g_variant_unref (child);
- }
-
- return ok;
- }
-
- if (key->minimum)
- {
- return g_variant_compare (key->minimum, value) <= 0 &&
- g_variant_compare (value, key->maximum) <= 0;
- }
-
- return strinfo_is_string_valid (key->strinfo, key->strinfo_length,
- g_variant_get_string (value, NULL));
-}
-
-static GVariant *
-g_settings_schema_key_range_fixup (GSettingsSchemaKey *key,
- GVariant *value)
-{
- const gchar *target;
-
- if (g_settings_schema_key_range_check (key, value))
- return g_variant_ref (value);
-
- if (key->strinfo == NULL)
- return NULL;
-
- if (g_variant_is_container (value))
- {
- GVariantBuilder builder;
- GVariantIter iter;
- GVariant *child;
-
- g_variant_iter_init (&iter, value);
- g_variant_builder_init (&builder, g_variant_get_type (value));
-
- while ((child = g_variant_iter_next_value (&iter)))
- {
- GVariant *fixed;
-
- fixed = g_settings_schema_key_range_fixup (key, child);
- g_variant_unref (child);
-
- if (fixed == NULL)
- {
- g_variant_builder_clear (&builder);
- return NULL;
- }
-
- g_variant_builder_add_value (&builder, fixed);
- g_variant_unref (fixed);
- }
-
- return g_variant_ref_sink (g_variant_builder_end (&builder));
- }
-
- target = strinfo_string_from_alias (key->strinfo, key->strinfo_length,
- g_variant_get_string (value, NULL));
- return target ? g_variant_ref_sink (g_variant_new_string (target)) : NULL;
-}
-
static GVariant *
g_settings_read_from_backend (GSettings *settings,
GSettingsSchemaKey *key)
return fixup;
}
-static GVariant *
-g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key)
-{
- const gchar *translated;
- GError *error = NULL;
- const gchar *domain;
- GVariant *value;
-
- domain = g_settings_schema_get_gettext_domain (key->schema);
-
- if (key->lc_char == '\0')
- /* translation not requested for this key */
- return NULL;
-
- if (key->lc_char == 't')
- translated = g_dcgettext (domain, key->unparsed, LC_TIME);
- else
- translated = g_dgettext (domain, key->unparsed);
-
- if (translated == key->unparsed)
- /* the default value was not translated */
- return NULL;
-
- /* try to parse the translation of the unparsed default */
- value = g_variant_parse (key->type, translated, NULL, NULL, &error);
-
- if (value == NULL)
- {
- g_warning ("Failed to parse translated string `%s' for "
- "key `%s' in schema `%s': %s", key->unparsed, key->name,
- g_settings_schema_get_name (key->schema), error->message);
- g_warning ("Using untranslated default instead.");
- g_error_free (error);
- }
-
- else if (!g_settings_schema_key_range_check (key, value))
- {
- g_warning ("Translated default `%s' for key `%s' in schema `%s' "
- "is outside of valid range", key->unparsed, key->name,
- g_settings_schema_get_name (key->schema));
- g_variant_unref (value);
- value = NULL;
- }
-
- return value;
-}
-
-static gint
-g_settings_schema_key_to_enum (GSettingsSchemaKey *key,
- GVariant *value)
-{
- gboolean it_worked;
- guint result;
-
- it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length,
- g_variant_get_string (value, NULL),
- &result);
-
- /* 'value' can only come from the backend after being filtered for validity,
- * from the translation after being filtered for validity, or from the schema
- * itself (which the schema compiler checks for validity). If this assertion
- * fails then it's really a bug in GSettings or the schema compiler...
- */
- g_assert (it_worked);
-
- return result;
-}
-
-static GVariant *
-g_settings_schema_key_from_enum (GSettingsSchemaKey *key,
- gint value)
-{
- const gchar *string;
-
- string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, value);
-
- if (string == NULL)
- return NULL;
-
- return g_variant_new_string (string);
-}
-
-static guint
-g_settings_schema_key_to_flags (GSettingsSchemaKey *key,
- GVariant *value)
-{
- GVariantIter iter;
- const gchar *flag;
- guint result;
-
- result = 0;
- g_variant_iter_init (&iter, value);
- while (g_variant_iter_next (&iter, "&s", &flag))
- {
- gboolean it_worked;
- guint flag_value;
-
- it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, flag, &flag_value);
- /* as in g_settings_to_enum() */
- g_assert (it_worked);
-
- result |= flag_value;
- }
-
- return result;
-}
-
-static GVariant *
-g_settings_schema_key_from_flags (GSettingsSchemaKey *key,
- guint value)
-{
- GVariantBuilder builder;
- gint i;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
-
- for (i = 0; i < 32; i++)
- if (value & (1u << i))
- {
- const gchar *string;
-
- string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, 1u << i);
-
- if (string == NULL)
- {
- g_variant_builder_clear (&builder);
- return NULL;
- }
-
- g_variant_builder_add (&builder, "s", string);
- }
-
- return g_variant_builder_end (&builder);
-}
-
/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
/**
* g_settings_get_value:
typedef struct _GSettingsSchema GSettingsSchema;
+typedef struct
+{
+ GSettingsSchema *schema;
+ const gchar *name;
+
+ guint is_flags : 1;
+ guint is_enum : 1;
+
+ const guint32 *strinfo;
+ gsize strinfo_length;
+
+ const gchar *unparsed;
+ gchar lc_char;
+
+ const GVariantType *type;
+ GVariant *minimum, *maximum;
+ GVariant *default_value;
+} GSettingsSchemaKey;
+
G_GNUC_INTERNAL
GSettingsSchema * g_settings_schema_new (const gchar *name);
G_GNUC_INTERNAL
const gchar * g_settings_schema_get_string (GSettingsSchema *schema,
const gchar *key);
+G_GNUC_INTERNAL
+void g_settings_schema_key_init (GSettingsSchemaKey *key,
+ GSettingsSchema *schema,
+ const gchar *name);
+G_GNUC_INTERNAL
+void g_settings_schema_key_clear (GSettingsSchemaKey *key);
+G_GNUC_INTERNAL
+gboolean g_settings_schema_key_type_check (GSettingsSchemaKey *key,
+ GVariant *value);
+G_GNUC_INTERNAL
+gboolean g_settings_schema_key_range_check (GSettingsSchemaKey *key,
+ GVariant *value);
+G_GNUC_INTERNAL
+GVariant * g_settings_schema_key_range_fixup (GSettingsSchemaKey *key,
+ GVariant *value);
+G_GNUC_INTERNAL
+GVariant * g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key);
+
+G_GNUC_INTERNAL
+gint g_settings_schema_key_to_enum (GSettingsSchemaKey *key,
+ GVariant *value);
+G_GNUC_INTERNAL
+GVariant * g_settings_schema_key_from_enum (GSettingsSchemaKey *key,
+ gint value);
+G_GNUC_INTERNAL
+guint g_settings_schema_key_to_flags (GSettingsSchemaKey *key,
+ GVariant *value);
+G_GNUC_INTERNAL
+GVariant * g_settings_schema_key_from_flags (GSettingsSchemaKey *key,
+ guint value);
+
#endif /* __G_SETTINGS_SCHEMA_INTERNAL_H__ */
#include "gsettings.h"
#include "gvdb/gvdb-reader.h"
+#include "strinfo.c"
#include <glibintl.h>
+#include <string.h>
struct _GSettingsSchema
{
{
return schema->name;
}
+
+static inline void
+endian_fixup (GVariant **value)
+{
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ GVariant *tmp;
+
+ tmp = g_variant_byteswap (*value);
+ g_variant_unref (*value);
+ *value = tmp;
+#endif
+}
+
+void
+g_settings_schema_key_init (GSettingsSchemaKey *key,
+ GSettingsSchema *schema,
+ const gchar *name)
+{
+ GVariantIter *iter;
+ GVariant *data;
+ guchar code;
+
+ memset (key, 0, sizeof *key);
+
+ iter = g_settings_schema_get_value (schema, name);
+
+ key->schema = g_settings_schema_ref (schema);
+ key->default_value = g_variant_iter_next_value (iter);
+ endian_fixup (&key->default_value);
+ key->type = g_variant_get_type (key->default_value);
+ key->name = g_intern_string (name);
+
+ while (g_variant_iter_next (iter, "(y*)", &code, &data))
+ {
+ switch (code)
+ {
+ case 'l':
+ /* translation requested */
+ g_variant_get (data, "(y&s)", &key->lc_char, &key->unparsed);
+ break;
+
+ case 'e':
+ /* enumerated types... */
+ key->is_enum = TRUE;
+ goto choice;
+
+ case 'f':
+ /* flags... */
+ key->is_flags = TRUE;
+ goto choice;
+
+ choice: case 'c':
+ /* ..., choices, aliases */
+ key->strinfo = g_variant_get_fixed_array (data, &key->strinfo_length, sizeof (guint32));
+ break;
+
+ case 'r':
+ g_variant_get (data, "(**)", &key->minimum, &key->maximum);
+ endian_fixup (&key->minimum);
+ endian_fixup (&key->maximum);
+ break;
+
+ default:
+ g_warning ("unknown schema extension '%c'", code);
+ break;
+ }
+
+ g_variant_unref (data);
+ }
+
+ g_variant_iter_free (iter);
+}
+
+void
+g_settings_schema_key_clear (GSettingsSchemaKey *key)
+{
+ if (key->minimum)
+ g_variant_unref (key->minimum);
+
+ if (key->maximum)
+ g_variant_unref (key->maximum);
+
+ g_variant_unref (key->default_value);
+
+ g_settings_schema_unref (key->schema);
+}
+
+gboolean
+g_settings_schema_key_type_check (GSettingsSchemaKey *key,
+ GVariant *value)
+{
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ return g_variant_is_of_type (value, key->type);
+}
+
+gboolean
+g_settings_schema_key_range_check (GSettingsSchemaKey *key,
+ GVariant *value)
+{
+ if (key->minimum == NULL && key->strinfo == NULL)
+ return TRUE;
+
+ if (g_variant_is_container (value))
+ {
+ gboolean ok = TRUE;
+ GVariantIter iter;
+ GVariant *child;
+
+ g_variant_iter_init (&iter, value);
+ while (ok && (child = g_variant_iter_next_value (&iter)))
+ {
+ ok = g_settings_schema_key_range_check (key, child);
+ g_variant_unref (child);
+ }
+
+ return ok;
+ }
+
+ if (key->minimum)
+ {
+ return g_variant_compare (key->minimum, value) <= 0 &&
+ g_variant_compare (value, key->maximum) <= 0;
+ }
+
+ return strinfo_is_string_valid (key->strinfo, key->strinfo_length,
+ g_variant_get_string (value, NULL));
+}
+
+GVariant *
+g_settings_schema_key_range_fixup (GSettingsSchemaKey *key,
+ GVariant *value)
+{
+ const gchar *target;
+
+ if (g_settings_schema_key_range_check (key, value))
+ return g_variant_ref (value);
+
+ if (key->strinfo == NULL)
+ return NULL;
+
+ if (g_variant_is_container (value))
+ {
+ GVariantBuilder builder;
+ GVariantIter iter;
+ GVariant *child;
+
+ g_variant_iter_init (&iter, value);
+ g_variant_builder_init (&builder, g_variant_get_type (value));
+
+ while ((child = g_variant_iter_next_value (&iter)))
+ {
+ GVariant *fixed;
+
+ fixed = g_settings_schema_key_range_fixup (key, child);
+ g_variant_unref (child);
+
+ if (fixed == NULL)
+ {
+ g_variant_builder_clear (&builder);
+ return NULL;
+ }
+
+ g_variant_builder_add_value (&builder, fixed);
+ g_variant_unref (fixed);
+ }
+
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+ }
+
+ target = strinfo_string_from_alias (key->strinfo, key->strinfo_length,
+ g_variant_get_string (value, NULL));
+ return target ? g_variant_ref_sink (g_variant_new_string (target)) : NULL;
+}
+
+
+GVariant *
+g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key)
+{
+ const gchar *translated;
+ GError *error = NULL;
+ const gchar *domain;
+ GVariant *value;
+
+ domain = g_settings_schema_get_gettext_domain (key->schema);
+
+ if (key->lc_char == '\0')
+ /* translation not requested for this key */
+ return NULL;
+
+ if (key->lc_char == 't')
+ translated = g_dcgettext (domain, key->unparsed, LC_TIME);
+ else
+ translated = g_dgettext (domain, key->unparsed);
+
+ if (translated == key->unparsed)
+ /* the default value was not translated */
+ return NULL;
+
+ /* try to parse the translation of the unparsed default */
+ value = g_variant_parse (key->type, translated, NULL, NULL, &error);
+
+ if (value == NULL)
+ {
+ g_warning ("Failed to parse translated string `%s' for "
+ "key `%s' in schema `%s': %s", key->unparsed, key->name,
+ g_settings_schema_get_name (key->schema), error->message);
+ g_warning ("Using untranslated default instead.");
+ g_error_free (error);
+ }
+
+ else if (!g_settings_schema_key_range_check (key, value))
+ {
+ g_warning ("Translated default `%s' for key `%s' in schema `%s' "
+ "is outside of valid range", key->unparsed, key->name,
+ g_settings_schema_get_name (key->schema));
+ g_variant_unref (value);
+ value = NULL;
+ }
+
+ return value;
+}
+
+gint
+g_settings_schema_key_to_enum (GSettingsSchemaKey *key,
+ GVariant *value)
+{
+ gboolean it_worked;
+ guint result;
+
+ it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length,
+ g_variant_get_string (value, NULL),
+ &result);
+
+ /* 'value' can only come from the backend after being filtered for validity,
+ * from the translation after being filtered for validity, or from the schema
+ * itself (which the schema compiler checks for validity). If this assertion
+ * fails then it's really a bug in GSettings or the schema compiler...
+ */
+ g_assert (it_worked);
+
+ return result;
+}
+
+GVariant *
+g_settings_schema_key_from_enum (GSettingsSchemaKey *key,
+ gint value)
+{
+ const gchar *string;
+
+ string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, value);
+
+ if (string == NULL)
+ return NULL;
+
+ return g_variant_new_string (string);
+}
+
+guint
+g_settings_schema_key_to_flags (GSettingsSchemaKey *key,
+ GVariant *value)
+{
+ GVariantIter iter;
+ const gchar *flag;
+ guint result;
+
+ result = 0;
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "&s", &flag))
+ {
+ gboolean it_worked;
+ guint flag_value;
+
+ it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, flag, &flag_value);
+ /* as in g_settings_to_enum() */
+ g_assert (it_worked);
+
+ result |= flag_value;
+ }
+
+ return result;
+}
+
+GVariant *
+g_settings_schema_key_from_flags (GSettingsSchemaKey *key,
+ guint value)
+{
+ GVariantBuilder builder;
+ gint i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+ for (i = 0; i < 32; i++)
+ if (value & (1u << i))
+ {
+ const gchar *string;
+
+ string = strinfo_string_from_enum (key->strinfo, key->strinfo_length, 1u << i);
+
+ if (string == NULL)
+ {
+ g_variant_builder_clear (&builder);
+ return NULL;
+ }
+
+ g_variant_builder_add (&builder, "s", string);
+ }
+
+ return g_variant_builder_end (&builder);
+}