More implementation of atom:content.
authorThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Sun, 8 Feb 2009 23:41:02 +0000 (21:41 -0200)
committerThadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Mon, 9 Feb 2009 01:54:08 +0000 (23:54 -0200)
Decoding and encoding into a string or xmlNode is now done. And there
can be only one between src, text content or xml content.

atom/content.c

index 01e3ab0..8dfbdd0 100644 (file)
@@ -58,9 +58,45 @@ atom_content_new_src (char *type, char *src)
 AtomContent *
 atom_content_new_data_len (char *buffer, size_t len)
 {
-  /* TODO: Here we decode the XML to find content type, possible
-     source and data */
-  return NULL;
+  AtomContent *content;
+  xmlDocPtr doc;
+  xmlNodePtr root;
+  xmlNodePtr child;
+  doc = xmlReadMemory (buffer, len, NULL, NULL,
+                      XML_PARSE_RECOVER | XML_PARSE_NOERROR);
+  if (doc == NULL || (root = xmlDocGetRootElement (doc)) == NULL)
+    return NULL;
+  if (xmlStrcmp (root->name, "content"))
+    {
+      xmlFreeDoc (doc);
+      return NULL;
+    }
+  content = g_slice_new0 (AtomContent);
+  if ((content->type = xmlGetProp (root, "type")) == NULL)
+    {
+      g_slice_free (AtomContent, content);
+      xmlFreeDoc (doc);
+      return NULL;
+    }
+  content->src = xmlGetProp (root, "src");
+  if (content->src == NULL)
+    {
+      /* libxml2 does not help a lot here. We must decide between a
+        XML child or a content child. Using the type attribute might
+        be a good idead. Let's just ask that the current method
+        works. */
+      if (root->children && root->children->type == XML_ELEMENT_NODE)
+       {
+         content->xmlcontent = xmlCopyNodeList (root->children);
+       }
+      else
+       {
+         content->content = xmlNodeGetContent (root);
+         content->content_len = xmlStrlen (content->content);
+       }
+    }
+  xmlFreeDoc (doc);
+  return content;
 }
 
 void
@@ -102,13 +138,33 @@ atom_content_src_set (AtomContent *content, char *src)
 {
   if (content->src)
     g_free (content->src);
+  if (content->content)
+    g_free (content->content);
+  if (content->xmlcontent)
+    xmlFreeNode (content->xmlcontent);
   content->src = g_strdup (src);
 }
 
 void
 atom_content_content (AtomContent *content, char **buffer, size_t *len)
 {
-  /* TODO: Copy the content or allocated the buffer? */
+  if (content->content == NULL)
+    {
+      if (buffer)
+       *buffer = NULL;
+      if (len)
+       *len = 0;
+    }
+  else
+    {
+      if (buffer)
+       {
+         *buffer = g_malloc (content->content_len);
+         memcpy (*buffer, content->content, content->content_len);
+       }
+      if (len)
+       *len = content->content_len;
+    }
 }
 
 void
@@ -116,6 +172,10 @@ atom_content_content_set (AtomContent *content, char *buffer, size_t len)
 {
   if (content->content)
     g_free (content->content);
+  if (content->src)
+    g_free (content->src);
+  if (content->xmlcontent)
+    xmlFreeNode (content->xmlcontent);
   content->content = g_malloc (len);
   memcpy (content->content, buffer, len);
 }
@@ -123,8 +183,21 @@ atom_content_content_set (AtomContent *content, char *buffer, size_t len)
 void
 atom_content_string (AtomContent *content, char **buffer, size_t *len)
 {
-  /* TODO: convert everything into a string, like
-     "<content type="html">&lt;br&gt;</content>" */
+  xmlDocPtr doc;
+  xmlNodePtr node;
+  node = atom_content_to_xmlnode (content);
+  if (node == NULL)
+    {
+      if (buffer)
+       *buffer = NULL;
+      if (len)
+       *len = 0;
+      return;
+    }
+  doc = xmlNewDoc ("1.0");
+  xmlDocSetRootElement (doc, node);
+  xmlDocDumpMemory (doc, buffer, len);
+  xmlFreeDoc (doc);
 }
 
 AtomContent *
@@ -140,8 +213,25 @@ atom_content_new_xmlnode (char *type, xmlNodePtr node)
 xmlNodePtr
 atom_content_to_xmlnode (AtomContent *content)
 {
-  /* TODO: Convert everything into a xmlnode */
-  return NULL;
+  xmlNodePtr node;
+  node = xmlNewNode (NULL, "content");
+  xmlNewProp (node, "type", content->type);
+  if (content->src)
+    {
+      xmlNewProp (node, "src", content->src);
+      return node;
+    }
+  else if (content->content)
+    {
+      xmlNodeSetContentLen (node, content->content, content->content_len);
+      return node;
+    }
+  else if (content->xmlcontent)
+    {
+      xmlAddChild (node, xmlCopyNodeList (content->xmlcontent));
+      return node;
+    }
+  return node;
 }
 
 xmlNodePtr
@@ -155,5 +245,9 @@ atom_content_content_set_xmlnode (AtomContent *content, xmlNodePtr node)
 {
   if (content->xmlcontent)
     xmlFreeNode (content->xmlcontent);
+  if (content->content)
+    g_free (content->content);
+  if (content->src)
+    g_free (content->src);
   content->xmlcontent = xmlCopyNodeList (node);
 }