#define MAX_ITEMS 50
-typedef struct _GeditMetadataManager GeditMetadataManager;
+typedef struct _EvMetadataManager EvMetadataManager;
typedef struct _Item Item;
GHashTable *values;
};
-struct _GeditMetadataManager
+struct _EvMetadataManager
{
gboolean values_loaded; /* It is true if the file
has been read */
static gboolean ev_metadata_manager_save (gpointer data);
-static GeditMetadataManager *ev_metadata_manager = NULL;
+static EvMetadataManager *ev_metadata_manager = NULL;
static void
item_free (gpointer data)
g_free (item);
}
-static gboolean
+void ev_metadata_arm_timeout(void)
+{
+ if (ev_metadata_manager->timeout_id)
+ return;
+ ev_metadata_manager->timeout_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
+ 2000, /* 2 sec */
+ (GSourceFunc)ev_metadata_manager_save,
+ NULL,
+ NULL);
+}
+void
ev_metadata_manager_init (void)
{
- if (ev_metadata_manager != NULL)
- return TRUE;
-
- ev_metadata_manager = g_new0 (GeditMetadataManager, 1);
+ ev_metadata_manager = g_new0 (EvMetadataManager, 1);
ev_metadata_manager->values_loaded = FALSE;
ev_metadata_manager->modified = FALSE;
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);
-
- return TRUE;
}
/* This function must be called before exiting ev */
if (ev_metadata_manager == NULL)
return;
- g_source_remove (ev_metadata_manager->timeout_id);
+ if (ev_metadata_manager->timeout_id)
+ g_source_remove (ev_metadata_manager->timeout_id);
ev_metadata_manager_save (NULL);
ev_metadata_manager = NULL;
}
+static void
+value_free (gpointer data)
+{
+ GValue *value = (GValue *)data;
+
+ g_value_unset (value);
+ g_free (value);
+}
+
static GValue *
parse_value (xmlChar *value, xmlChar *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, atof ((char *)value));
+ 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;
}
item = g_new0 (Item, 1);
- 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);
}
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;
}
+#define LAST_URI "last-used-value"
+
+static gboolean
+ev_metadata_manager_get_last (const gchar *key,
+ GValue *value,
+ gboolean ignore)
+{
+ Item *item;
+ GValue *ret;
+
+ g_assert (ev_metadata_manager->values_loaded);
+
+ if (ignore)
+ return FALSE;
+
+ item = (Item *)g_hash_table_lookup (ev_metadata_manager->items,
+ LAST_URI);
+
+ if (item == NULL)
+ return FALSE;
+
+ item->atime = time (NULL);
+
+ if (item->values == NULL)
+ return FALSE;
+
+ ret = (GValue *)g_hash_table_lookup (item->values, key);
+
+ if (ret != NULL) {
+ g_value_init (value, G_VALUE_TYPE (ret));
+ g_value_copy (ret, value);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+ev_metadata_manager_set_last (const gchar *key,
+ const GValue *value)
+{
+ Item *item;
+
+ g_assert (ev_metadata_manager->values_loaded);
+
+ item = (Item *)g_hash_table_lookup (ev_metadata_manager->items,
+ LAST_URI);
+
+ if (item == NULL)
+ {
+ item = g_new0 (Item, 1);
+
+ g_hash_table_insert (ev_metadata_manager->items,
+ g_strdup (LAST_URI),
+ item);
+ }
+
+ if (item->values == NULL)
+ item->values = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ value_free);
+ if (value != NULL) {
+ GValue *new;
+
+ new = g_new0 (GValue, 1);
+ g_value_init (new, G_VALUE_TYPE (value));
+ g_value_copy (value, new);
+
+ g_hash_table_insert (item->values,
+ g_strdup (key),
+ new);
+ } else {
+ g_hash_table_remove (item->values,
+ key);
+ }
+
+ item->atime = time (NULL);
+ ev_metadata_manager->modified = TRUE;
+ ev_metadata_arm_timeout();
+ return;
+}
+
+/**
+ * ev_metadata_manager_set:
+ * @uri: Uri to set data for, if @NULL, we return default value
+ * @key: Key to set uri
+ * @value: GValue struct filled up with value
+ * @ignore_last: if @TRUE, default value is ignored
+ *
+ * Retrieve value for uri in metadata database
+ *
+ * Returns: @TRUE if value was taken.
+ **/
gboolean
ev_metadata_manager_get (const gchar *uri,
const gchar *key,
- GValue *value)
+ GValue *value,
+ gboolean ignore_last)
{
Item *item;
GValue *ret;
- g_return_val_if_fail (uri != NULL, FALSE);
g_return_val_if_fail (key != NULL, FALSE);
if (ev_metadata_manager == NULL)
- ev_metadata_manager_init ();
+ return FALSE;
if (!ev_metadata_manager->values_loaded)
{
res = load_values ();
if (!res)
- return FALSE;
+ return ev_metadata_manager_get_last (key, value, ignore_last);
}
+ if (uri == NULL)
+ return ev_metadata_manager_get_last (key, value, ignore_last);
+
item = (Item *)g_hash_table_lookup (ev_metadata_manager->items,
uri);
if (item == NULL)
- return FALSE;
+ return ev_metadata_manager_get_last (key, value, ignore_last);
item->atime = time (NULL);
if (item->values == NULL)
- return FALSE;
+ return ev_metadata_manager_get_last (key, value, ignore_last);
ret = (GValue *)g_hash_table_lookup (item->values, key);
- if (ret == NULL) {
- return FALSE;
- } else {
+ if (ret != NULL) {
g_value_init (value, G_VALUE_TYPE (ret));
g_value_copy (ret, value);
-
return TRUE;
}
-}
-static void
-value_free (gpointer data)
-{
- GValue *value = (GValue *)data;
-
- g_value_unset (value);
- g_free (value);
+ return ev_metadata_manager_get_last (key, value, ignore_last);
}
+/**
+ * ev_metadata_manager_set:
+ * @uri: Uri to set data for, if @NULL, we set default value
+ * @key: Key to set uri
+ * @value: GValue struct containing value
+ *
+ * Set value for key in metadata database
+ **/
void
ev_metadata_manager_set (const gchar *uri,
const gchar *key,
{
Item *item;
- g_return_if_fail (uri != NULL);
g_return_if_fail (key != NULL);
if (ev_metadata_manager == NULL)
- ev_metadata_manager_init ();
+ return;
if (!ev_metadata_manager->values_loaded)
{
return;
}
+ if (uri == NULL)
+ {
+ ev_metadata_manager_set_last (key, value);
+ return;
+ }
+
item = (Item *)g_hash_table_lookup (ev_metadata_manager->items,
uri);
g_hash_table_insert (item->values,
g_strdup (key),
new);
+ ev_metadata_manager_set_last (key, value);
} else {
g_hash_table_remove (item->values,
key);
item->atime = time (NULL);
ev_metadata_manager->modified = TRUE;
+ ev_metadata_arm_timeout();
}
static void
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_printf ("%s", 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;
+ ev_metadata_manager->timeout_id = 0;
+
if (!ev_metadata_manager->modified)
- return TRUE;
+ return FALSE;
resize_items ();
ev_metadata_manager->modified = FALSE;
- return TRUE;
+ return FALSE;
}
void