diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-09-03 10:32:06 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-09-03 10:32:06 -0400 |
commit | 55c898db3c434252540431ed61afe6be3ef51bc1 (patch) | |
tree | 5ceff8e3346f41834e816dbe05f2152aa778fd8c | |
parent | b82eaa2860c596d59e3b46891ce0f813feab0239 (diff) |
Add persist filesexpanding-window
-rw-r--r-- | persist.c | 258 | ||||
-rw-r--r-- | persist.h | 32 |
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 *); |