summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-09-03 10:32:06 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-09-03 10:32:06 -0400
commit55c898db3c434252540431ed61afe6be3ef51bc1 (patch)
tree5ceff8e3346f41834e816dbe05f2152aa778fd8c
parentb82eaa2860c596d59e3b46891ce0f813feab0239 (diff)
Add persist filesexpanding-window
-rw-r--r--persist.c258
-rw-r--r--persist.h32
2 files changed, 290 insertions, 0 deletions
diff --git a/persist.c b/persist.c
new file mode 100644
index 0000000..d2c26af
--- /dev/null
+++ b/persist.c
@@ -0,0 +1,258 @@
+/* persist.c - Simple routines for storing key/values persistently
+ * Copyright (C) 2008, 2009 Soren Sandmann
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include "persist.h"
+
+typedef struct group_t group_t;
+
+struct group_t
+{
+ char * name;
+
+ GHashTable *values;
+};
+
+struct persist_t
+{
+ char * filename;
+
+ GHashTable *groups;
+};
+
+static group_t *
+group_new (const char *name)
+{
+ group_t *group = g_new0 (group_t, 1);
+
+ group->name = g_strdup (name);
+ group->values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ return group;
+}
+
+static void
+group_free (gpointer data)
+{
+ group_t *group = data;
+
+ g_free (group->name);
+ g_hash_table_destroy (group->values);
+
+ g_free (group);
+}
+
+static gboolean
+get_int (GKeyFile *keyfile, const char *group, const char *key, int *result)
+{
+ GError *err = NULL;
+ int d;
+
+ d = g_key_file_get_integer (keyfile, group, key, &err);
+
+ if (err)
+ {
+ g_error_free (err);
+ return FALSE;
+ }
+
+ if (result)
+ *result = d;
+
+ return TRUE;
+}
+
+static void
+load_from_file (persist_t *persist)
+{
+ GKeyFile *keyfile = g_key_file_new ();
+
+ if (g_key_file_load_from_file (keyfile, persist->filename, G_KEY_FILE_NONE, NULL))
+ {
+ char **group_names;
+ gsize n_groups;
+ int i;
+
+ group_names = g_key_file_get_groups (keyfile, &n_groups);
+ for (i = 0; i < n_groups; ++i)
+ {
+ char *group_name = group_names[i];
+ char **key_names;
+ guint n_keys;
+
+ key_names = g_key_file_get_keys (keyfile, group_name, &n_keys, NULL);
+ if (key_names)
+ {
+ int j;
+
+ for (j = 0; j < n_keys; ++j)
+ {
+ char *key = key_names[j];
+ int value;
+
+ if (get_int (keyfile, group_name, key, &value))
+ persist_set_int (persist, group_name, key, value);
+ }
+
+ g_strfreev (key_names);
+ }
+ }
+
+ g_strfreev (group_names);
+ }
+
+ g_key_file_free (keyfile);
+
+}
+
+typedef struct
+{
+ group_t *group;
+ GKeyFile *key_file;
+} info_t;
+
+static void
+foreach_value (gpointer key, gpointer value, gpointer user_data)
+{
+ const info_t *info = user_data;
+
+ g_key_file_set_integer (info->key_file, info->group->name, key, GPOINTER_TO_INT (value));
+}
+
+static void
+foreach_group (gpointer key, gpointer value, gpointer user_data)
+{
+ info_t info;
+
+ info.group = value;
+ info.key_file = user_data;
+
+ g_hash_table_foreach (info.group->values, foreach_value, &info);
+}
+
+static void
+save_to_file (persist_t *persist)
+{
+ GKeyFile *key_file = g_key_file_new ();
+ char *output;
+
+ g_hash_table_foreach (persist->groups, foreach_group, key_file);
+ output = g_key_file_to_data (key_file, NULL, NULL);
+
+ if (output)
+ {
+ g_file_set_contents (persist->filename, output, -1, NULL);
+ g_free (output);
+ }
+
+ g_key_file_free (key_file);
+}
+
+static gchar *
+encode (const char *group_name)
+{
+ GString *result = g_string_new (NULL);
+ int i;
+
+ for (i = 0; group_name[i] != '\0'; ++i)
+ {
+ char c = group_name[i];
+
+ if (!g_ascii_isprint (c) || c == '@' || c == '[' || c == ']')
+ g_string_append_printf (result, "@%x", c);
+ else
+ g_string_append_c (result, c);
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+persist_t *
+persist_new (const char *filename)
+{
+ persist_t *persist;
+
+ persist = g_new0 (persist_t, 1);
+ persist->filename = g_strdup (filename);
+ persist->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, group_free);
+
+ load_from_file (persist);
+
+ return persist;
+}
+
+void
+persist_free (persist_t *persist)
+{
+ g_free (persist->filename);
+
+ g_hash_table_destroy (persist->groups);
+
+ g_free (persist);
+}
+
+void
+persist_set_int (persist_t *persist,
+ const char *group_name,
+ const char *name,
+ int value)
+{
+ char *group_name_enc = encode (group_name);
+ group_t *group = g_hash_table_lookup (persist->groups, group_name_enc);
+
+ if (!group)
+ {
+ group = group_new (group_name_enc);
+
+ g_hash_table_insert (
+ persist->groups, g_strdup (group_name_enc), group);
+ }
+
+ g_hash_table_insert (group->values, g_strdup (name), GINT_TO_POINTER (value));
+
+ g_free (group_name_enc);
+}
+
+gboolean
+persist_get_int (persist_t *persist,
+ const char *group_name,
+ const char *name,
+ int *value)
+{
+ char *group_name_enc = encode (group_name);
+ group_t *group;
+ gboolean retval;
+
+ retval = FALSE;
+
+ group = g_hash_table_lookup (persist->groups, group_name_enc);
+ if (group && g_hash_table_lookup_extended (group->values, name, NULL, (gpointer *)value))
+ retval = TRUE;
+
+ g_free (group_name_enc);
+
+ return retval;
+}
+
+void
+persist_save (persist_t *persist)
+{
+ save_to_file (persist);
+}
diff --git a/persist.h b/persist.h
new file mode 100644
index 0000000..433778d
--- /dev/null
+++ b/persist.h
@@ -0,0 +1,32 @@
+/* persist.c - Simple routines for storing key/values persistently
+ * Copyright (C) 2008, 2009 Soren Sandmann
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+typedef struct persist_t persist_t;
+
+persist_t *persist_new (const char *filename);
+void persist_set_int (persist_t *persist,
+ const char *group,
+ const char *name,
+ int value);
+gboolean persist_get_int (persist_t *persist,
+ const char *group,
+ const char *name,
+ int *value);
+void persist_save (persist_t *);