Added functions to convert AtomID from and to frontend and backend requests
[cascardo/atompub.git] / atom / entry.c
index 21eae78..99ab439 100644 (file)
@@ -28,10 +28,13 @@ struct _atom_entry
   xmlDocPtr doc;
   char *id;
   char *title;
-  AtomPerson *author;
+  GPtrArray *authors;
   char *summary;
 };
 
+void atom_entry_author_add (AtomEntry *, AtomPerson *);
+static void atom_entry_authors_delete (AtomEntry *);
+
 AtomEntry *
 atom_entry_new (char *title, AtomPerson *author)
 {
@@ -40,7 +43,8 @@ atom_entry_new (char *title, AtomPerson *author)
   entry->doc = NULL;
   entry->id = NULL;
   entry->title = g_strdup (title);
-  entry->author = author;
+  entry->authors = NULL;
+  atom_entry_author_add (entry, author);
   entry->summary = NULL;
   return entry;
 }
@@ -52,7 +56,8 @@ atom_entry_new_data_len (char *data, size_t len)
   xmlNodePtr root;
   xmlNodePtr child;
   entry = g_slice_new0 (AtomEntry);
-  entry->doc = xmlReadMemory (data, len, NULL, NULL, XML_PARSE_RECOVER);
+  entry->doc = xmlReadMemory (data, len, NULL, NULL,
+                              XML_PARSE_RECOVER | XML_PARSE_NOERROR);
   if (entry->doc == NULL ||
       (root = xmlDocGetRootElement (entry->doc)) == NULL)
     {
@@ -76,7 +81,7 @@ atom_entry_new_data_len (char *data, size_t len)
       else if (!xmlStrcmp (child->name, "summary"))
        entry->summary = content;
       else if (!xmlStrcmp (child->name, "author"))
-       entry->author = atom_person_new_from_xmlnode (child);
+       atom_entry_author_add (entry, atom_person_new_from_xmlnode (child));
       else
        xmlFree (content);
     }
@@ -92,8 +97,8 @@ atom_entry_delete (AtomEntry *entry)
     g_free (entry->id);
   if (entry->title)
     g_free (entry->title);
-  if (entry->author)
-    atom_person_delete (entry->author);
+  if (entry->authors)
+    atom_entry_authors_delete (entry);
   if (entry->summary)
     g_free (entry->summary);
   g_slice_free (AtomEntry, entry);
@@ -124,21 +129,36 @@ atom_entry_title_set (AtomEntry *entry, char *title)
 {
   if (entry->title)
     g_free (title);
-  entry->title = g_strdup (entry);
+  entry->title = g_strdup (title);
 }
 
-AtomPerson *
-atom_entry_author (AtomEntry *entry)
+void
+atom_entry_authors (AtomEntry *entry, AtomPerson *** authors, size_t *len)
 {
-  return entry->author;
+  if (len)
+    *len = entry->authors->len;
+  if (authors)
+    *authors = entry->authors->pdata;
 }
 
 void
-atom_entry_author_set (AtomEntry *entry, AtomPerson *author)
+atom_entry_author_add (AtomEntry *entry, AtomPerson *author)
+{
+  if (entry->authors == NULL)
+    {
+      entry->authors = g_ptr_array_new ();
+    }
+  g_ptr_array_add (entry->authors, author);
+}
+
+static void
+atom_entry_authors_delete (AtomEntry *entry)
 {
-  if (entry->author)
-    atom_person_delete (entry->author);
-  entry->author = author;
+  size_t len = entry->authors->len;
+  int i;
+  for (i = 0; i < len; i++)
+    atom_person_delete (g_ptr_array_index (entry->authors, i));
+  g_ptr_array_free (entry->authors, TRUE);
 }
 
 char *
@@ -155,16 +175,65 @@ atom_entry_summary_set (AtomEntry *entry, char *summary)
   entry->summary = g_strdup (summary);
 }
 
+static void
+atom_entry_update_xmlnode (AtomEntry *entry)
+{
+  xmlNodePtr root;
+  xmlNodePtr id;
+  xmlNodePtr title;
+  xmlNodePtr summary;
+  xmlNodePtr author;
+  int i;
+  if (entry->doc == NULL)
+    {
+      entry->doc = xmlNewDoc ("1.0");
+      root = xmlNewNode (NULL, "entry");
+      xmlNewNs (root, ATOM_NAMESPACE, NULL);
+      xmlDocSetRootElement (entry->doc, root);
+    }
+  else
+    {
+      xmlNodePtr child;
+      xmlNodePtr next;
+      root = xmlDocGetRootElement (entry->doc);
+      child = root->xmlChildrenNode;
+      while (child != NULL)
+        {
+          next = child->next;
+          if (!xmlStrcmp (child->name, "id") ||
+              !xmlStrcmp (child->name, "title") ||
+              !xmlStrcmp (child->name, "summary") ||
+              !xmlStrcmp (child->name, "author"))
+            {
+              xmlUnlinkNode (child);
+              xmlFreeNode (child);
+            }
+          child = next;
+        }
+    }
+  id = xmlNewTextChild (root, NULL, "id", entry->id);
+  title = xmlNewTextChild (root, NULL, "title", entry->title);
+  if (entry->summary)
+    summary = xmlNewTextChild (root, NULL, "summary", entry->summary);
+  for (i = 0; i < entry->authors->len; i++)
+    {
+      AtomPerson *person;
+      person = g_ptr_array_index (entry->authors, i);
+      author = atom_person_to_xmlnode (person, "author");
+      xmlAddChild (root, author);
+    }
+}
+
 void
 atom_entry_string (AtomEntry *entry, char **buffer, size_t *len)
 {
+  atom_entry_update_xmlnode (entry);
   xmlDocDumpMemory (entry->doc, buffer, len);
 }
 
 xmlNodePtr
 atom_entry_to_xmlnode (AtomEntry *entry)
 {
-  if (entry->doc)
-    return xmlCopyNodeList (xmlDocGetRootElement (entry->doc));
-  return NULL;
+  atom_entry_update_xmlnode (entry);
+  return xmlCopyNodeList (xmlDocGetRootElement (entry->doc));
 }