/*
- * Copyright (C) 2007 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ * Copyright (C) 2008 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <atompub/atom.h>
#include <glib.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
struct _atom_entry
{
- char *data;
- size_t len;
+ xmlDocPtr doc;
+ char *id;
+ char *title;
+ GPtrArray *authors;
+ char *summary;
};
-Atom *
-atom_new_data_len (char *data, size_t len)
+void atom_entry_author_add (AtomEntry *, AtomPerson *);
+static void atom_entry_authors_delete (AtomEntry *);
+
+AtomEntry *
+atom_entry_new (char *title, AtomPerson *author)
+{
+ AtomEntry *entry;
+ entry = g_slice_new (AtomEntry);
+ entry->doc = NULL;
+ entry->id = NULL;
+ entry->title = g_strdup (title);
+ entry->authors = NULL;
+ atom_entry_author_add (entry, author);
+ entry->summary = NULL;
+ return entry;
+}
+
+AtomEntry *
+atom_entry_new_data_len (char *data, size_t len)
+{
+ AtomEntry *entry;
+ xmlNodePtr root;
+ xmlNodePtr child;
+ entry = g_slice_new0 (AtomEntry);
+ entry->doc = xmlReadMemory (data, len, NULL, NULL,
+ XML_PARSE_RECOVER | XML_PARSE_NOERROR);
+ if (entry->doc == NULL ||
+ (root = xmlDocGetRootElement (entry->doc)) == NULL)
+ {
+ g_slice_free (AtomEntry, entry);
+ return NULL;
+ }
+ if (xmlStrcmp (root->name, "entry"))
+ {
+ xmlFreeDoc (entry->doc);
+ g_slice_free (AtomEntry, entry);
+ return NULL;
+ }
+ for (child = root->xmlChildrenNode; child != NULL; child = child->next)
+ {
+ char * content;
+ content = xmlNodeGetContent (child->xmlChildrenNode);
+ if (!xmlStrcmp (child->name, "id"))
+ entry->id = content;
+ else if (!xmlStrcmp (child->name, "title"))
+ entry->title = content;
+ else if (!xmlStrcmp (child->name, "summary"))
+ entry->summary = content;
+ else if (!xmlStrcmp (child->name, "author"))
+ atom_entry_author_add (entry, atom_person_new_from_xmlnode (child));
+ else
+ xmlFree (content);
+ }
+ return entry;
+}
+
+void
+atom_entry_delete (AtomEntry *entry)
+{
+ if (entry->doc)
+ xmlFreeDoc (entry->doc);
+ if (entry->id)
+ g_free (entry->id);
+ if (entry->title)
+ g_free (entry->title);
+ if (entry->authors)
+ atom_entry_authors_delete (entry);
+ if (entry->summary)
+ g_free (entry->summary);
+ g_slice_free (AtomEntry, entry);
+}
+
+char *
+atom_entry_id (AtomEntry *entry)
+{
+ return entry->id;
+}
+
+void
+atom_entry_id_set (AtomEntry *entry, char *id)
+{
+ if (entry->id)
+ g_free (entry->id);
+ entry->id = g_strdup (id);
+}
+
+char *
+atom_entry_title (AtomEntry *entry)
+{
+ return entry->title;
+}
+
+void
+atom_entry_title_set (AtomEntry *entry, char *title)
{
- Atom *atom = g_slice_new (Atom);
- atom->data = g_memdup (data, len);
- atom->len = len;
- return atom;
+ if (entry->title)
+ g_free (title);
+ entry->title = g_strdup (title);
}
void
-atom_delete (Atom *atom)
+atom_entry_authors (AtomEntry *entry, AtomPerson *** authors, size_t *len)
{
- g_slice_free (Atom, atom);
+ if (len)
+ *len = entry->authors->len;
+ if (authors)
+ *authors = entry->authors->pdata;
+}
+
+void
+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)
+{
+ 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 *
-atom_string (Atom *atom)
+atom_entry_summary (AtomEntry *entry)
+{
+ return entry->summary;
+}
+
+void
+atom_entry_summary_set (AtomEntry *entry, char *summary)
+{
+ if (entry->summary)
+ g_free (entry->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)
{
- return atom->data;
+ atom_entry_update_xmlnode (entry);
+ xmlDocDumpMemory (entry->doc, buffer, len);
}
-size_t
-atom_len (Atom *atom)
+xmlNodePtr
+atom_entry_to_xmlnode (AtomEntry *entry)
{
- return atom->len;
+ atom_entry_update_xmlnode (entry);
+ return xmlCopyNodeList (xmlDocGetRootElement (entry->doc));
}