libidav/xml.c

changeset 361
b6f2462ee055
parent 338
c7f3fe4abdb2
child 371
604e7e335b3b
--- a/libidav/xml.c	Mon Dec 18 16:24:32 2017 +0100
+++ b/libidav/xml.c	Mon Jan 01 19:53:36 2018 +0100
@@ -30,6 +30,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <ucx/utils.h>
+
 #include "xml.h"
 
 static DavXmlNodeType convert_type(xmlElementType type) {
@@ -135,6 +137,40 @@
     }
 }
 
+void dav_print_node(void *stream, write_func writef, UcxMap *nsmap, DavXmlNode *node) {
+    while(node) {
+        if(node->type == DAV_XML_ELEMENT) {
+            char *prefix = ucx_map_cstr_get(nsmap, node->namespace);
+            char *tagend = node->children ? ">" : " />";
+            if(!prefix) {
+                sstr_t newpre = ucx_sprintf("x%d", (int)nsmap->count);
+                ucx_map_cstr_put(nsmap, node->namespace, newpre.ptr);
+                prefix = newpre.ptr;
+                ucx_fprintf(
+                        stream,
+                        writef,
+                        "<%s:%s xmlns:%s=\"%s\"%s",
+                        prefix,
+                        node->name,
+                        prefix,
+                        node->namespace,
+                        tagend);
+            } else {
+                ucx_fprintf(stream, writef, "<%s:%s%s", prefix, node->name, tagend);
+            }
+            
+            if(node->children) {
+                dav_print_node(stream, writef, nsmap, node->children);
+                ucx_fprintf(stream, writef, "</%s:%s>", prefix, node->name);
+            }
+        } else if(node->type == DAV_XML_TEXT) {
+            writef(node->content, 1, node->contentlength, stream);
+        }
+        
+        node = node->next;
+    }
+}
+
 /* ------------------------- public API ------------------------- */
 
 char* dav_xml_getstring(DavXmlNode *node) {
@@ -163,3 +199,79 @@
     return newxn;
 }
 
+
+
+
+DavXmlNode* dav_copy_node(DavXmlNode *node) {
+    DavXmlNode *ret = NULL;
+    DavXmlNode *prev = NULL;
+    while(node) {
+        DavXmlNode *copy = calloc(1, sizeof(DavXmlNode));
+        copy->type = node->type;
+        if(node->type == DAV_XML_ELEMENT) {
+            copy->namespace = strdup(node->namespace);
+            copy->name = strdup(node->name);
+            copy->children = dav_copy_node(node->children);
+        } else {
+            copy->contentlength = node->contentlength;
+            copy->content = malloc(node->contentlength+1);
+            memcpy(copy->content, node->content, node->contentlength);
+            copy->content[copy->contentlength] = 0;
+        }
+        if(!ret) {
+            ret = copy;
+        }
+        if(prev) {
+            prev->next = copy;
+            copy->prev = prev;
+        }
+        prev = copy;
+        node = node->next;
+    }
+    return ret;
+}
+
+
+DavXmlNode* dav_xml_createnode(const char *ns, const char *name) {
+    DavXmlNode *node = calloc(1, sizeof(DavXmlNode));
+    node->type = DAV_XML_ELEMENT;
+    node->namespace = strdup(ns);
+    node->name = strdup(name);
+    return node;
+}
+
+DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text) {
+    DavXmlNode *node = calloc(1, sizeof(DavXmlNode));
+    node->type = DAV_XML_ELEMENT;
+    node->namespace = strdup(ns);
+    node->name = strdup(name);
+    
+    DavXmlNode *textnode = dav_xml_createtextnode(text);
+    node->children = textnode;
+    
+    return node;
+}
+
+DavXmlNode* dav_xml_createtextnode(const char *text) {
+    DavXmlNode *node = calloc(1, sizeof(DavXmlNode));
+    node->type = DAV_XML_TEXT;
+    sstr_t content = sstrdup(sstr((char*)text));
+    node->content = content.ptr;
+    node->contentlength = content.length;
+    return node;
+}
+
+void dav_xml_add_child(DavXmlNode *node, DavXmlNode *child) {
+    DavXmlNode *last_child = NULL;
+    DavXmlNode *c = node->children;
+    while(c) {
+        last_child = c;
+        c = c->next;
+    }
+    if(last_child) {
+        last_child->next = child;
+        child->prev = last_child;
+    } else {
+        node->children = child;
+    }
+}

mercurial