#include <libxml/xmlreader.h>
#include "ev-metadata-manager.h"
+#include "ev-application.h"
#include "ev-file-helpers.h"
#define METADATA_FILE "ev-metadata.xml"
gboolean values_loaded; /* It is true if the file
has been read */
- gboolean modified; /* It is true if the file
- has top be written */
-
guint timeout_id;
GHashTable *items;
static EvMetadataManager *ev_metadata_manager = NULL;
+/**
+ * item_free:
+ * @data: a pointer to a #Item data
+ *
+ * It does free the values on the #GHashTable where data points.
+ */
static void
item_free (gpointer data)
{
- Item *item;
-
- g_return_if_fail (data != NULL);
-
- item = (Item *)data;
+ Item *item = (Item *) data;
if (item->values != NULL)
g_hash_table_destroy (item->values);
- g_free (item);
+ g_slice_free (Item, item);
+}
+
+/**
+ * ev_metadata_arm_timeout
+ *
+ * Setup a timeout for saving the metadata to disk.
+ */
+static void
+ev_metadata_arm_timeout(void)
+{
+ if (ev_metadata_manager->timeout_id)
+ return;
+
+ ev_metadata_manager->timeout_id =
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
+ 2,
+ (GSourceFunc)ev_metadata_manager_save,
+ NULL,
+ NULL);
}
+/**
+ * ev_metadata_manager_init:
+ *
+ * Creates an EvMetadataManager with default values.
+ *
+ * values_loaded -> %FALSE.
+ * timeout_id -> the id of the event source.
+ * items -> a new full empty #GHashTable.
+ */
void
ev_metadata_manager_init (void)
{
- ev_metadata_manager = g_new0 (EvMetadataManager, 1);
+ ev_metadata_manager = g_slice_new0 (EvMetadataManager);
ev_metadata_manager->values_loaded = FALSE;
- ev_metadata_manager->modified = FALSE;
ev_metadata_manager->items =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
item_free);
-
- ev_metadata_manager->timeout_id =
- g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
- 2000, /* 2 sec */
- (GSourceFunc)ev_metadata_manager_save,
- NULL,
- NULL);
}
/* This function must be called before exiting ev */
if (ev_metadata_manager == NULL)
return;
- g_source_remove (ev_metadata_manager->timeout_id);
-
- ev_metadata_manager_save (NULL);
+ if (ev_metadata_manager->timeout_id) {
+ g_source_remove (ev_metadata_manager->timeout_id);
+ ev_metadata_manager->timeout_id = 0;
+ ev_metadata_manager_save (NULL);
+ }
if (ev_metadata_manager->items != NULL)
g_hash_table_destroy (ev_metadata_manager->items);
- g_free (ev_metadata_manager);
+ g_slice_free (EvMetadataManager, ev_metadata_manager);
ev_metadata_manager = NULL;
}
+static void
+value_free (gpointer data)
+{
+ GValue *value = (GValue *)data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
static GValue *
parse_value (xmlChar *value, xmlChar *type)
{
GValue *ret;
ret_type = g_type_from_name ((char *)type);
- ret = g_new0 (GValue, 1);
+ ret = g_slice_new0 (GValue);
g_value_init (ret, ret_type);
switch (ret_type) {
g_value_set_string (ret, (char *)value);
break;
case G_TYPE_INT:
- g_value_set_int (ret, atoi ((char *)value));
+ g_value_set_int (ret, g_ascii_strtoull ((char *)value, NULL, 0));
break;
case G_TYPE_DOUBLE:
g_value_set_double (ret, g_ascii_strtod ((char *)value, NULL));
break;
case G_TYPE_BOOLEAN:
- g_value_set_boolean (ret, atoi ((char *)value));
+ g_value_set_boolean (ret, g_ascii_strtoull ((char *)value, NULL, 0));
break;
}
return;
}
- item = g_new0 (Item, 1);
+ item = g_slice_new0 (Item);
- item->atime = atol ((char *)atime);
+ item->atime = g_ascii_strtoull((char*)atime, NULL, 0);
item->values = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
- g_free);
+ value_free);
cur = cur->xmlChildrenNode;
xmlChar *key;
xmlChar *xml_value;
xmlChar *type;
- GValue *value;
+ GValue *value;
key = xmlGetProp (cur, (const xmlChar *)"key");
xml_value = xmlGetProp (cur, (const xmlChar *)"value");
if (key != NULL)
xmlFree (key);
+ if (type != NULL)
+ xmlFree (type);
if (xml_value != NULL)
xmlFree (xml_value);
}
xmlKeepBlanksDefault (0);
/* FIXME: file locking - Paolo */
- file_name = g_build_filename (ev_dot_dir (), METADATA_FILE, NULL);
+ file_name = g_build_filename (ev_application_get_dot_dir (EV_APP), METADATA_FILE, NULL);
if (!g_file_test (file_name, G_FILE_TEST_EXISTS))
{
g_free (file_name);
cur = xmlDocGetRootElement (doc);
if (cur == NULL)
{
- g_message ("The metadata file '%s' is empty", METADATA_FILE);
+ g_message ("The metadata file ā%sā is empty", METADATA_FILE);
xmlFreeDoc (doc);
return FALSE;
if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
{
- g_message ("File '%s' is of the wrong type", METADATA_FILE);
+ g_message ("File ā%sā is of the wrong type", METADATA_FILE);
xmlFreeDoc (doc);
return FALSE;
return TRUE;
}
-static void
-value_free (gpointer data)
-{
- GValue *value = (GValue *)data;
-
- g_value_unset (value);
- g_free (value);
-}
-
-
#define LAST_URI "last-used-value"
static gboolean
if (item == NULL)
{
- item = g_new0 (Item, 1);
+ item = g_slice_new0 (Item);
g_hash_table_insert (ev_metadata_manager->items,
g_strdup (LAST_URI),
if (value != NULL) {
GValue *new;
- new = g_new0 (GValue, 1);
+ new = g_slice_new0 (GValue);
g_value_init (new, G_VALUE_TYPE (value));
g_value_copy (value, new);
}
item->atime = time (NULL);
- ev_metadata_manager->modified = TRUE;
+ ev_metadata_arm_timeout ();
return;
}
/**
- * ev_metadata_manager_set:
+ * ev_metadata_manager_get:
* @uri: Uri to set data for, if @NULL, we return default value
* @key: Key to set uri
* @value: GValue struct filled up with value
if (item == NULL)
{
- item = g_new0 (Item, 1);
+ item = g_slice_new0 (Item);
g_hash_table_insert (ev_metadata_manager->items,
g_strdup (uri),
if (value != NULL) {
GValue *new;
- new = g_new0 (GValue, 1);
+ new = g_slice_new0 (GValue);
g_value_init (new, G_VALUE_TYPE (value));
g_value_copy (value, new);
item->atime = time (NULL);
- ev_metadata_manager->modified = TRUE;
+ ev_metadata_arm_timeout ();
}
static void
switch (G_VALUE_TYPE (value)) {
case G_TYPE_STRING:
- string_value = g_strdup (g_value_get_string (value));
+ string_value = g_value_dup_string (value);
break;
case G_TYPE_INT:
string_value = g_strdup_printf ("%d", g_value_get_int (value));
break;
case G_TYPE_DOUBLE:
- string_value = g_strdup_printf ("%f", g_value_get_double (value));
- break;
+ {
+ gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
+ g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, g_value_get_double (value));
+ string_value = g_strdup (buf);
+ }
+ break;
case G_TYPE_BOOLEAN:
string_value = g_strdup_printf ("%d", g_value_get_boolean (value));
break;
xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
- /* FIXME: is the cast right? - Paolo */
- atime = g_strdup_printf ("%d", (int)item->atime);
- xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
-
+ atime = g_strdup_printf ("%ld", item->atime);
+ xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
g_free (atime);
g_hash_table_foreach (item->values,
xmlNodePtr root;
gchar *file_name;
- if (!ev_metadata_manager->modified)
- return TRUE;
+ ev_metadata_manager->timeout_id = 0;
resize_items ();
(GHFunc)save_item, root);
/* FIXME: lock file - Paolo */
- file_name = g_build_filename (ev_dot_dir (), METADATA_FILE, NULL);
+ file_name = g_build_filename (ev_application_get_dot_dir (EV_APP), METADATA_FILE, NULL);
xmlSaveFormatFile (file_name, doc, 1);
g_free (file_name);
xmlFreeDoc (doc);
- ev_metadata_manager->modified = FALSE;
-
- return TRUE;
+ return FALSE;
}
void
GValue val = { 0, };
g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, value);
+ g_value_set_static_string (&val, value);
ev_metadata_manager_set (uri, key, &val);