[evolution-data-server/meego-eds] Implement lazy contact vCard parsing
- From: Christophe Dumez <cdumez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/meego-eds] Implement lazy contact vCard parsing
- Date: Tue, 21 Jun 2011 18:16:34 +0000 (UTC)
commit 29a413cd18759449f3ce68eeaa3e42b50b5d8c7e
Author: Christophe Dumez <christophe dumez intel com>
Date: Tue Jun 21 20:40:15 2011 +0300
Implement lazy contact vCard parsing
Lazily construct contacts from vCards. This means that the vCard
will only be parsed if needed (i.e. a vCard field is queried).
This helps a lot with performance because it avoids double vCard
parsing. Calling e_contact_new_from_vcard() and then
e_vcard_to_string() directly after is now really fast since this
involves no parsing at all.
addressbook/libebook/e-vcard.c | 50 ++++++++++++++++++++++++++++++++-------
1 files changed, 41 insertions(+), 9 deletions(-)
---
diff --git a/addressbook/libebook/e-vcard.c b/addressbook/libebook/e-vcard.c
index 8fae7f0..77bfe47 100644
--- a/addressbook/libebook/e-vcard.c
+++ b/addressbook/libebook/e-vcard.c
@@ -47,6 +47,7 @@ typedef enum {
struct _EVCardPrivate {
GList *attributes;
+ gchar *vcard;
};
struct _EVCardAttribute {
@@ -72,10 +73,12 @@ e_vcard_dispose (GObject *object)
EVCard *evc = E_VCARD (object);
if (evc->priv) {
-
+ /* Directly access priv->attributes and don't call e_vcard_ensure_attributes(),
+ * since it is pointless to start vCard parsing that late. */
g_list_foreach (evc->priv->attributes, (GFunc)e_vcard_attribute_free, NULL);
g_list_free (evc->priv->attributes);
+ g_free (evc->priv->vcard);
g_free (evc->priv);
evc->priv = NULL;
}
@@ -653,6 +656,24 @@ parse (EVCard *evc, const gchar *str)
evc->priv->attributes = g_list_reverse (evc->priv->attributes);
}
+static GList*
+e_vcard_ensure_attributes (EVCard *evc)
+{
+ if (evc->priv->vcard) {
+ gchar *vcs = evc->priv->vcard;
+
+ /* detach vCard to avoid loops */
+ evc->priv->vcard = NULL;
+
+ /* Parse the vCard */
+ parse (evc, vcs);
+ g_free (vcs);
+ }
+
+ return evc->priv->attributes;
+}
+
+
/**
* e_vcard_escape_string:
* @s: the string to escape
@@ -747,9 +768,12 @@ e_vcard_construct (EVCard *evc, const gchar *str)
{
g_return_if_fail (E_IS_VCARD (evc));
g_return_if_fail (str != NULL);
+ g_return_if_fail (evc->priv->vcard == NULL);
+ g_return_if_fail (evc->priv->attributes == NULL);
+ /* Lazy construction */
if (*str)
- parse (evc, str);
+ evc->priv->vcard = g_strdup (str);
}
/**
@@ -810,7 +834,7 @@ e_vcard_to_string_vcard_30 (EVCard *evc)
vcard might contain */
g_string_append (str, "VERSION:3.0" CRLF);
- for (l = evc->priv->attributes; l; l = l->next) {
+ for (l = e_vcard_ensure_attributes (evc); l; l = l->next) {
GList *list;
EVCardAttribute *attr = l->data;
GString *attr_str;
@@ -950,6 +974,12 @@ e_vcard_to_string (EVCard *evc, EVCardFormat format)
{
g_return_val_if_fail (E_IS_VCARD (evc), NULL);
+ /* If the vcard is not parsed yet, return it directly */
+ /* XXX: The format is ignored but it does not really matter
+ since only 3.0 is supported at the moment */
+ if (evc->priv->vcard)
+ return g_strdup (evc->priv->vcard);
+
switch (format) {
case EVC_FORMAT_VCARD_21:
return e_vcard_to_string_vcard_21 (evc);
@@ -978,7 +1008,7 @@ e_vcard_dump_structure (EVCard *evc)
g_return_if_fail (E_IS_VCARD (evc));
printf ("vCard\n");
- for (a = evc->priv->attributes; a; a = a->next) {
+ for (a = e_vcard_ensure_attributes (evc); a; a = a->next) {
GList *p;
EVCardAttribute *attr = a->data;
printf ("+-- %s\n", attr->name);
@@ -1097,7 +1127,7 @@ e_vcard_remove_attributes (EVCard *evc, const gchar *attr_group, const gchar *at
g_return_if_fail (E_IS_VCARD (evc));
g_return_if_fail (attr_name != NULL);
- attr = evc->priv->attributes;
+ attr = e_vcard_ensure_attributes (evc);
while (attr) {
GList *next_attr;
EVCardAttribute *a = attr->data;
@@ -1131,6 +1161,8 @@ e_vcard_remove_attribute (EVCard *evc, EVCardAttribute *attr)
g_return_if_fail (E_IS_VCARD (evc));
g_return_if_fail (attr != NULL);
+ /* No need to call e_vcard_ensure_attributes() here. It has already been
+ called if this is a valid call and attr is among our attributes */
evc->priv->attributes = g_list_remove (evc->priv->attributes, attr);
e_vcard_attribute_free (attr);
}
@@ -1150,7 +1182,7 @@ e_vcard_append_attribute (EVCard *evc, EVCardAttribute *attr)
g_return_if_fail (E_IS_VCARD (evc));
g_return_if_fail (attr != NULL);
- evc->priv->attributes = g_list_append (evc->priv->attributes, attr);
+ evc->priv->attributes = g_list_append (e_vcard_ensure_attributes (evc), attr);
}
/**
@@ -1220,7 +1252,7 @@ e_vcard_add_attribute (EVCard *evc, EVCardAttribute *attr)
g_return_if_fail (E_IS_VCARD (evc));
g_return_if_fail (attr != NULL);
- evc->priv->attributes = g_list_prepend (evc->priv->attributes, attr);
+ evc->priv->attributes = g_list_prepend (e_vcard_ensure_attributes (evc), attr);
}
/**
@@ -1769,7 +1801,7 @@ e_vcard_get_attributes (EVCard *evcard)
{
g_return_val_if_fail (E_IS_VCARD (evcard), NULL);
- return evcard->priv->attributes;
+ return e_vcard_ensure_attributes (evcard);
}
/**
@@ -1792,7 +1824,7 @@ e_vcard_get_attribute (EVCard *evc,
g_return_val_if_fail (E_IS_VCARD (evc), NULL);
g_return_val_if_fail (name != NULL, NULL);
- attrs = e_vcard_get_attributes (evc);
+ attrs = e_vcard_ensure_attributes (evc);
for (l = attrs; l; l = l->next) {
EVCardAttribute *attr;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]