libidav/xml.c

changeset 331
9ca1e4706acc
child 338
c7f3fe4abdb2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/xml.c	Sun Oct 22 12:58:07 2017 +0200
@@ -0,0 +1,157 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2017 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "xml.h"
+
+static DavXmlNodeType convert_type(xmlElementType type) {
+    DavXmlNodeType ct;
+    switch(type) {
+        default: ct = DAV_XML_NONE; break;
+        case XML_ELEMENT_NODE: ct = DAV_XML_ELEMENT; break;
+        case XML_TEXT_NODE: ct = DAV_XML_TEXT;
+    }
+    return ct;
+}
+
+typedef struct {
+    xmlNode    *node;
+    DavXmlNode *parent;
+} ConvXmlElm;
+
+DavXmlNode* dav_convert_xml(DavSession *sn, xmlNode *node) {
+    if(!node) {
+        return NULL;
+    }
+    DavXmlNodeType newnt = convert_type(node->type);
+    if(newnt == DAV_XML_NONE) {
+        return NULL;
+    }
+    
+    UcxMempool *mp = sn->mp;
+    
+    ConvXmlElm *ce = malloc(sizeof(ConvXmlElm));
+    ce->node = node;
+    ce->parent = NULL;
+    UcxList *stack = ucx_list_prepend(NULL, ce);
+    
+    DavXmlNode *ret = NULL;
+    
+    while(stack) {
+        ConvXmlElm *c = stack->data;
+        stack = ucx_list_remove(stack, stack);
+        
+        xmlNode *n = c->node;
+        DavXmlNode *prev = NULL;
+        while(n) {
+            DavXmlNode *newxn = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode));
+            if(!ret) {
+                ret = newxn;
+            }
+            newxn->type = convert_type(n->type);
+            newxn->parent = c->parent;
+            if(c->parent && !c->parent->children) {
+                c->parent->children = newxn;
+            }
+            newxn->prev = prev;
+            if(prev) {
+                prev->next = newxn;
+            }
+            
+            if(newxn->type == DAV_XML_ELEMENT) {
+                newxn->name = dav_session_strdup(sn, (char*)n->name);
+                if(n->ns && n->ns->href) {
+                    newxn->namespace = dav_session_strdup(sn, (char*)n->ns->href);
+                }
+                
+                // TODO: copy attributes
+                
+                if(n->children) {
+                    ConvXmlElm *convc = malloc(sizeof(ConvXmlElm));
+                    convc->node = n->children;
+                    convc->parent = newxn;
+                    stack = ucx_list_prepend(stack, convc);
+                }
+            } else if(newxn->type == DAV_XML_TEXT) {
+                sstr_t content = sstrdup_a(mp->allocator, sstr((char*)n->content));
+                newxn->content = content.ptr;
+                newxn->contentlength = content.length;
+            }
+            
+            prev = newxn;
+            n = n->next;
+        }
+        
+        free(c);
+    }
+    
+    return ret;
+}
+
+void dav_print_xml(DavXmlNode *node) {
+    if(node->type == DAV_XML_ELEMENT) {
+        printf("<%s>", node->name);
+        
+        DavXmlNode *child = node->children;
+        if(child) {
+            dav_print_xml(child);
+        }
+        
+        printf("</%s>", node->name);
+    } else {
+        fwrite(node->content, 1, node->contentlength, stdout);
+        fflush(stdout);
+    }
+    if(node->next) {
+        dav_print_xml(node->next);
+    }
+}
+
+/* ------------------------- public API ------------------------- */
+
+char* dav_xml_getstring(DavXmlNode *node) {
+    if(node && node->type == DAV_XML_TEXT) {
+        return node->content;
+    } else {
+        return NULL;
+    }
+}
+
+DavXmlNode* dav_text_node(DavSession *sn, char *text) {
+    UcxMempool *mp = sn->mp; 
+    DavXmlNode *newxn = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode));
+    newxn->type = DAV_XML_TEXT;
+    sstr_t content = sstrdup_a(mp->allocator, sstr(text));
+    newxn->content = content.ptr;
+    newxn->contentlength = content.length;
+    return newxn;
+}
+

mercurial