soylent r247 - trunk/libsoylent



Author: svenp
Date: Wed Jul 30 09:44:33 2008
New Revision: 247
URL: http://svn.gnome.org/viewvc/soylent?rev=247&view=rev

Log:
attribute-name-to-vCard-attribute-name mapping implemented (back and forth)
loading attributes implemented
attributes are now looked up via hash-table
getting all attributes works
added some more constructors for SlAttribute
many small fixes and improvements

Modified:
   trunk/libsoylent/sl-entity.c
   trunk/libsoylent/sl-entity.h

Modified: trunk/libsoylent/sl-entity.c
==============================================================================
--- trunk/libsoylent/sl-entity.c	(original)
+++ trunk/libsoylent/sl-entity.c	Wed Jul 30 09:44:33 2008
@@ -25,6 +25,7 @@
  * base class), SlEntityEDS. for now this will be misused as SlEntityEDS */
 
 #include "sl-entity.h"
+#include "sl-person.h"
 
 /* private structs and fields */
 
@@ -84,6 +85,9 @@
 static void sl_attribute_get_property (GObject *object, guint property_id,
   GValue *value, GParamSpec *pspec);
 
+static const gchar *sl_attribute_name_to_eattrname (const gchar *name);
+static const gchar *sl_attribute_eattrname_to_name (const gchar *eattrname);
+
 GType
 sl_entity_get_type (void)
 {
@@ -197,7 +201,10 @@
     {
       attrhandler = attrhandler_default;
     }
-  *type = attrhandler->type;
+  if (type != NULL)
+    {
+      *type = attrhandler->type;
+    }
   return attrhandler->reader (attrname, value);
 }
 
@@ -302,7 +309,29 @@
 void
 sl_entity_constr_with_econtact (SlEntity *self, EContact *econtact)
 {
+  self->priv->ebook = NULL;
+  self->priv->attribute_table = g_hash_table_new (NULL, NULL);
+  self->priv->attributes = NULL;
   self->priv->econtact = g_object_ref (econtact);
+  
+  GList *eattributes = e_vcard_get_attributes (E_VCARD (self->priv->econtact));
+  EVCardAttribute *eattr = NULL;
+  SlAttribute *attr = NULL;
+  for (; eattributes != NULL; eattributes = eattributes->next)
+    {
+      eattr = eattributes->data;
+      const gchar *eattrname = e_vcard_attribute_get_name (eattr);
+      if (g_str_equal (eattrname, EVC_VERSION) ||
+          g_str_equal (eattrname, EVC_REV))
+        {
+          continue;
+        }
+      attr = sl_attribute_new_with_eattr (eattr);
+      /* TODO: make one function for the next two calls */
+      self->priv->attributes = g_list_append (self->priv->attributes, g_object_ref (attr));
+      g_hash_table_insert (self->priv->attribute_table, (const gpointer) attr->priv->name, g_object_ref (attr));
+      g_object_unref (attr);
+    }
 }
 
 void
@@ -326,7 +355,11 @@
 gboolean
 sl_entity_commit (SlEntity *self, GError **error)
 {
-  /* TODO: if ebook not set return error */
+  if (self->priv->ebook == NULL)
+    {
+      /* TODO: return error */
+      return FALSE;
+    }
   return e_book_commit_contact (self->priv->ebook, self->priv->econtact, error);
 }
 
@@ -335,7 +368,7 @@
 {
   /* TODO: what if attribute already exists? add values?*/
   self->priv->attributes = g_list_append (self->priv->attributes, g_object_ref (attr));
-  g_hash_table_insert (self->priv->attribute_table, (const gpointer) attr->priv->name, attr);
+  g_hash_table_insert (self->priv->attribute_table, (const gpointer) attr->priv->name, g_object_ref (attr));
   attr->priv->entity = self;
   
   e_vcard_add_attribute (E_VCARD (self->priv->econtact), attr->priv->eattr);
@@ -368,30 +401,23 @@
 
 SlAttribute *sl_entity_get_attribute (SlEntity *self, gchar *attrname)
 {
-  /* TODO: use hashtable? I think yes... */
-  GList *iter = self->priv->attributes;
-  for (; iter != NULL; iter = iter->next)
-    {
-      SlAttribute *attr = iter->data;
-      if (g_str_equal (sl_attribute_get_name (attr), attrname))
-        {
-          return attr;
-        }
-    }
-  return NULL;
+  return g_hash_table_lookup (self->priv->attribute_table, attrname);
 }
 
 GList *sl_entity_get_attributes (SlEntity *self)
 {
-  g_warning("%s not implemented", __FUNCTION__);
-  return NULL;
+  return self->priv->attributes;
 }
 
 void
 sl_entity_set (SlEntity *self, gchar *attrname, gpointer value)
 {
   SlAttribute *attr = sl_entity_get_attribute (self, attrname);
-  if (!attr) return;
+  if (attr == NULL) 
+    {
+      attr = sl_attribute_new_empty (attrname);
+      sl_entity_add_attribute (self, attr);
+    }
   sl_attribute_set (attr, value);
 }
 
@@ -399,7 +425,10 @@
 sl_entity_get (SlEntity *self, gchar *attrname)
 {
   SlAttribute *attr = sl_entity_get_attribute (self, attrname);
-  if (!attr) return NULL;
+  if (attr == NULL) 
+    {
+      return NULL;
+    }
   return sl_attribute_get (attr);
 }
 
@@ -495,41 +524,176 @@
   g_warning("%s not implemented", __FUNCTION__);
 }
 
+static const gchar *
+sl_attribute_name_to_eattrname (const gchar *name)
+{
+  static GHashTable *name_to_eattrname_map = NULL;
+  if (name_to_eattrname_map == NULL)
+    {
+      name_to_eattrname_map = g_hash_table_new (g_str_hash, g_str_equal);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_ID, EVC_UID);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_NAME, EVC_N);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_FAMILY_NAME, EVC_FN);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_NICK, EVC_NICKNAME);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_GROUP, EVC_CATEGORIES);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_ADDRESS, EVC_ADR);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_EMAIL, EVC_EMAIL);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_TELEPHONE, EVC_TEL);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_BIRTHDAY, EVC_BDAY);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_URL, EVC_URL);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_BLOG, EVC_X_BLOG_URL);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_CALENDAR_URL, EVC_CALURI);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_FREE_BUSY_URL, EVC_FBURL);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_NOTE, EVC_NOTE);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_PHOTO, EVC_PHOTO);
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_ICON, EVC_LOGO); 
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_JOB_ROLE, EVC_ROLE); 
+      g_hash_table_insert (name_to_eattrname_map, SL_ATTR_JOB_TITLE, EVC_TITLE);
+    }
+  
+  const gchar *eattrname = g_hash_table_lookup (name_to_eattrname_map, name);
+  if (eattrname == NULL)
+    {
+      GString *str = g_string_new (NULL);
+      g_string_printf (str, "X-%s", name);
+      eattrname = str->str;
+    }
+  return eattrname;
+}
+
+static const gchar *
+sl_attribute_eattrname_to_name (const gchar *eattrname)
+{
+  static GHashTable *eattrname_to_name_map = NULL;
+  if (eattrname_to_name_map == NULL)
+    {
+      eattrname_to_name_map = g_hash_table_new (g_str_hash, g_str_equal);
+      g_hash_table_insert (eattrname_to_name_map, EVC_UID, SL_ATTR_ID);
+      g_hash_table_insert (eattrname_to_name_map, EVC_N, SL_ATTR_NAME);
+      g_hash_table_insert (eattrname_to_name_map, EVC_FN, SL_ATTR_FAMILY_NAME);
+      g_hash_table_insert (eattrname_to_name_map, EVC_NICKNAME, SL_ATTR_NICK);
+      g_hash_table_insert (eattrname_to_name_map, EVC_CATEGORIES, SL_ATTR_GROUP);
+      g_hash_table_insert (eattrname_to_name_map, EVC_ADR, SL_ATTR_ADDRESS);
+      g_hash_table_insert (eattrname_to_name_map, EVC_EMAIL, SL_ATTR_EMAIL);
+      g_hash_table_insert (eattrname_to_name_map, EVC_TEL, SL_ATTR_TELEPHONE);
+      g_hash_table_insert (eattrname_to_name_map, EVC_BDAY, SL_ATTR_BIRTHDAY);
+      g_hash_table_insert (eattrname_to_name_map, EVC_URL, SL_ATTR_URL);
+      g_hash_table_insert (eattrname_to_name_map, EVC_X_BLOG_URL, SL_ATTR_BLOG);
+      g_hash_table_insert (eattrname_to_name_map, EVC_CALURI, SL_ATTR_CALENDAR_URL);
+      g_hash_table_insert (eattrname_to_name_map, EVC_FBURL, SL_ATTR_FREE_BUSY_URL);
+      g_hash_table_insert (eattrname_to_name_map, EVC_NOTE, SL_ATTR_NOTE);
+      g_hash_table_insert (eattrname_to_name_map, EVC_PHOTO, SL_ATTR_PHOTO);
+      g_hash_table_insert (eattrname_to_name_map, EVC_LOGO, SL_ATTR_ICON);
+      g_hash_table_insert (eattrname_to_name_map, EVC_ROLE, SL_ATTR_JOB_ROLE);
+      g_hash_table_insert (eattrname_to_name_map, EVC_TITLE, SL_ATTR_JOB_TITLE);
+    }
+  
+  const gchar *name = g_hash_table_lookup (eattrname_to_name_map, eattrname);
+  if (name == NULL)
+    {
+      /* TODO: this leaks, cause name must be freed somehow */
+      g_assert (g_str_has_prefix (eattrname, "X-"));
+      name = g_utf8_strdown (&eattrname[2], -1);
+    }
+  return name;
+}
+
 void
-sl_attribute_constr (SlAttribute *self, const gchar *name)
+sl_attribute_constr (SlAttribute *self, const gchar *name, gpointer value)
 {
   self->priv->entity = NULL;
   self->priv->name = name;
+  self->priv->eattr = e_vcard_attribute_new (NULL, sl_attribute_name_to_eattrname (name));
   self->priv->values = NULL;
-  self->priv->eattr = e_vcard_attribute_new (NULL, name);
+  if (value != NULL)
+    {
+      self->priv->values = g_list_append (self->priv->values, value);
+    }
+}
+
+void
+sl_attribute_constr_with_values (SlAttribute *self, const gchar *name, 
+                                 GList *values)
+{
+  sl_attribute_constr (self, name, NULL);
+  self->priv->values = values;
+}
+
+void
+sl_attribute_constr_with_eattr (SlAttribute *self, EVCardAttribute *eattr)
+{
+  /* TODO: all attributes twice in memory, once in their "vcard form" and once
+   * in their "runtime form". This is clearly not optimal. */
+  self->priv->entity = NULL;
+  self->priv->eattr = eattr;
+  self->priv->values = NULL;
+  self->priv->name = sl_attribute_eattrname_to_name (e_vcard_attribute_get_name (eattr));
+
+  GList *evalues = e_vcard_attribute_get_values (eattr);
+  gpointer evalue = NULL;
+  for (; evalues != NULL; evalues = evalues->next)
+    {
+      evalue = evalues->data;
+      gpointer value = sl_attribute_handler_read (self->priv->name, evalue, NULL);
+      self->priv->values = g_list_append (self->priv->values, value);
+    }
+}
+
+SlAttribute *
+sl_attribute_new (const gchar *name, gpointer value)
+{
+  SlAttribute *self = g_object_new (SL_ATTRIBUTE_TYPE, NULL);
+  sl_attribute_constr (self, name, value);
+  return self;
+}
+
+SlAttribute *
+sl_attribute_new_empty (const gchar *name)
+{
+  SlAttribute *self = g_object_new (SL_ATTRIBUTE_TYPE, NULL);
+  sl_attribute_constr (self, name, NULL);
+  return self;
+}
+
+SlAttribute *
+sl_attribute_new_with_values (const gchar *name, GList *values)
+{
+  SlAttribute *self = g_object_new (SL_ATTRIBUTE_TYPE, NULL);
+  sl_attribute_constr_with_values (self, name, values);
+  return self;
 }
 
 SlAttribute *
-sl_attribute_new (const gchar *name)
+sl_attribute_new_with_eattr (EVCardAttribute *eattr)
 {
   SlAttribute *self = g_object_new (SL_ATTRIBUTE_TYPE, NULL);
-  sl_attribute_constr (self, name);
+  sl_attribute_constr_with_eattr (self, eattr);
   return self;
 }
 
 void sl_attribute_set (SlAttribute *self, gpointer value)
 {
-  g_warning("%s not implemented", __FUNCTION__);
+  /* TODO: temporary add, but should be set_at (0) */
+  sl_attribute_add (self, value);
 }
 
 gpointer sl_attribute_get (SlAttribute *self)
 {
-  g_warning("%s not implemented", __FUNCTION__);
-  return NULL;
+  if (self->priv->values == NULL)
+    {
+      return NULL;
+    }
+  return self->priv->values->data;
 }
 
 void sl_attribute_add (SlAttribute *self, gpointer value)
 {
   SlAttributeHandlerType type = 0;
-  gpointer result = sl_attribute_handler_write (self->priv->name, value, &type);
+  gpointer evalue = sl_attribute_handler_write (self->priv->name, value, &type);
   
+  /* TODO: encode value if binary */
   self->priv->values = g_list_append (self->priv->values, value);
-  e_vcard_attribute_add_value (self->priv->eattr, result);
+  e_vcard_attribute_add_value (self->priv->eattr, evalue);
 }
 
 gboolean sl_attribute_set_at (SlAttribute *self, gint index, gpointer value)
@@ -580,8 +744,7 @@
 
 GList *sl_attribute_get_all (SlAttribute *self)
 {
-  g_warning("%s not implemented", __FUNCTION__);
-  return NULL;
+  return self->priv->values;
 }
 
 void sl_attribute_remove_all (SlAttribute *self)
@@ -591,6 +754,5 @@
 
 const gchar *sl_attribute_get_name (SlAttribute *self)
 {
-  g_warning("%s not implemented", __FUNCTION__);
-  return NULL;
+  return self->priv->name;
 }

Modified: trunk/libsoylent/sl-entity.h
==============================================================================
--- trunk/libsoylent/sl-entity.h	(original)
+++ trunk/libsoylent/sl-entity.h	Wed Jul 30 09:44:33 2008
@@ -57,6 +57,9 @@
 #define SL_ATTRIBUTE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, \
   SL_ATTRIBUTE_TYPE))
 
+#define SL_ATTRIBUTE_WRITER_FUNC(func)  ((SlAttributeWriterFunc) (func))
+#define SL_ATTRIBUTE_READER_FUNC(func)  ((SlAttributeReaderFunc) (func))
+
 typedef struct _SlEntity      SlEntity;
 typedef struct _SlEntityClass SlEntityClass;
 typedef struct _SlEntityPriv  SlEntityPriv;
@@ -158,8 +161,15 @@
 /* TODO: perhaps gboolean instead of void to indicate that an attrname doesn't
  * exist */
 
-void sl_attribute_constr (SlAttribute *self, const gchar *name);
-SlAttribute *sl_attribute_new (const gchar *name);
+void sl_attribute_constr (SlAttribute *self, const gchar *name, gpointer value);
+void sl_attribute_constr_with_values (SlAttribute *self, const gchar *name,
+                                      GList *values);
+void sl_attribute_constr_with_eattr (SlAttribute *self, EVCardAttribute *eattr);
+SlAttribute *sl_attribute_new (const gchar *name, gpointer value);
+SlAttribute *sl_attribute_new_empty (const gchar *name);
+SlAttribute *sl_attribute_new_with_values (const gchar *name, GList *values);
+SlAttribute *sl_attribute_new_with_eattr (EVCardAttribute *eattr);
+
 void sl_attribute_set (SlAttribute *self, gpointer value);
 gpointer sl_attribute_get (SlAttribute *self);
 gboolean sl_attribute_set_at (SlAttribute *self, gint index, gpointer value);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]