adds initial support for xml properties in libidav

Sun, 22 Oct 2017 12:58:07 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 22 Oct 2017 12:58:07 +0200
changeset 331
9ca1e4706acc
parent 330
54819e984a19
child 332
5587282ebe1c

adds initial support for xml properties in libidav

dav/main.c file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
docs/src/index.html file | annotate | diff | comparison | revisions
libidav/Makefile file | annotate | diff | comparison | revisions
libidav/davqlexec.c file | annotate | diff | comparison | revisions
libidav/methods.c file | annotate | diff | comparison | revisions
libidav/resource.c file | annotate | diff | comparison | revisions
libidav/resource.h file | annotate | diff | comparison | revisions
libidav/webdav.h file | annotate | diff | comparison | revisions
libidav/xml.c file | annotate | diff | comparison | revisions
libidav/xml.h file | annotate | diff | comparison | revisions
--- a/dav/main.c	Thu Oct 12 20:37:46 2017 +0200
+++ b/dav/main.c	Sun Oct 22 12:58:07 2017 +0200
@@ -550,7 +550,7 @@
         flags[0] = 'd';
         type = "";
     }
-    char *keyprop = dav_get_property_ns(
+    char *keyprop = dav_get_string_property_ns(
             res,
             DAV_NS,
             "crypto-key");
@@ -560,10 +560,10 @@
     
     if(cmd_getoption(a, "extended")) {
         flags[6] = '\0';
-        if(dav_get_property(res, "D:lockdiscovery")) {
+        if(dav_get_string_property(res, "D:lockdiscovery")) {
             flags[2] = 'l';
         }
-        char *executable = dav_get_property_ns(
+        char *executable = dav_get_string_property_ns(
                 res,
                 "http://apache.org/dav/props/",
                 "executable");
@@ -1216,7 +1216,9 @@
         break;
     }
     
-    char *value = dav_get_property_ns(res, propname.ns, propname.name);
+    // TODO: show xml
+    //DavXmlNode *x = dav_get_property_ns(res, propname.ns, propname.name);
+    char *value = dav_get_string_property_ns(res, propname.ns, propname.name);
     if(!value) {
         fprintf(stderr, "Error: no property value.\n");
         return -1;
@@ -1511,7 +1513,7 @@
                     last_ns = p.ns;
                 }
 
-                sstr_t value = sstr(dav_get_property_ns(res, p.ns, p.name));
+                sstr_t value = sstr(dav_get_string_property_ns(res, p.ns, p.name));
                 value = sstrtrim(value);
                 printf("  %s: %.*s\n", p.name, (int)value.length, value.ptr);
             }
--- a/dav/sync.c	Thu Oct 12 20:37:46 2017 +0200
+++ b/dav/sync.c	Sun Oct 22 12:58:07 2017 +0200
@@ -376,7 +376,7 @@
                 continue;
             }
             
-            char *status = dav_get_property(res, "idav:status");
+            char *status = dav_get_string_property(res, "idav:status");
             if(status && !strcmp(status, "broken")) {
                 res = res->next;
                 continue;
@@ -498,7 +498,7 @@
     LocalResource *local = ucx_map_cstr_get(db->resources, res->path);
     char *local_path = util_concat_path(dir->path, res->path);
     
-    char *etag = dav_get_property(res, "D:getetag");
+    char *etag = dav_get_string_property(res, "D:getetag");
     struct stat s;
     memset(&s, 0, sizeof(struct stat));
     if(local && !res->iscollection) {
@@ -1180,7 +1180,7 @@
     DavResource *remote = dav_get(sn, res->path, "D:getetag");
     int ret = 0;
     if(remote) {
-        char *etag = dav_get_property(remote, "D:getetag");
+        char *etag = dav_get_string_property(remote, "D:getetag");
         if(!res->etag) {
             // the resource is on the server and the client has no etag
             ret = 1;
@@ -1274,7 +1274,7 @@
                 sync_set_status(res, "broken");
             } else {
                 // everything seems fine, we can update the local resource
-                char *etag = dav_get_property(up_res, "D:getetag");
+                char *etag = dav_get_string_property(up_res, "D:getetag");
                 if(etag) {
                     if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
                         etag = etag + 2;
@@ -1291,7 +1291,7 @@
                     local->etag = NULL;
                 }
                 
-                if(dav_get_property(up_res, "idav:status")) {
+                if(dav_get_string_property(up_res, "idav:status")) {
                     sync_remove_status(up_res);
                 }
                 
@@ -1340,7 +1340,7 @@
             fprintf(stderr, "Cannot delete resource %s\n", res->path);
         }
     } else {
-        char *etag = dav_get_property(res, "D:getetag");
+        char *etag = dav_get_string_property(res, "D:getetag");
         if(etag) {
             if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
                 etag = etag + 2;
--- a/docs/src/index.html	Thu Oct 12 20:37:46 2017 +0200
+++ b/docs/src/index.html	Sun Oct 22 12:58:07 2017 +0200
@@ -28,6 +28,7 @@
 						<li><a href="move.html">move</a></li>
 						<li><a href="get-property.html">get-property</a></li>
 						<li><a href="set-property.html">set-property</a></li>
+						<li><a href="remove-property.html">remove-property</a></li>
 						<li><a href="lock.html">lock</a></li>
 						<li><a href="unlock.html">unlock</a></li>
 						<li><a href="info.html">info</a></li>
--- a/libidav/Makefile	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/Makefile	Sun Oct 22 12:58:07 2017 +0200
@@ -39,6 +39,7 @@
 SRC += davqlparser.c
 SRC += davqlexec.c
 SRC += crypto.c
+SRC += xml.c
 
 OBJ = $(SRC:%.c=../build/libidav/%$(OBJ_EXT))
 
--- a/libidav/davqlexec.c	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/davqlexec.c	Sun Oct 22 12:58:07 2017 +0200
@@ -1056,7 +1056,7 @@
             }
             case DAVQL_CMD_PROP_IDENTIFIER: {
                 //printf("property %s:%s\n", cmd.data.property.ns, cmd.data.property.name);
-                char *value = dav_get_property_ns(res, cmd.data.property.ns, cmd.data.property.name);
+                char *value = dav_get_string_property_ns(res, cmd.data.property.ns, cmd.data.property.name);
                 obj.type = 1;
                 obj.length = value ? strlen(value) : 0;
                 obj.data.string = value;
--- a/libidav/methods.c	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/methods.c	Sun Oct 22 12:58:07 2017 +0200
@@ -34,6 +34,7 @@
 #include "methods.h"
 #include "crypto.h"
 #include "session.h"
+#include "xml.h"
 
 #include <ucx/utils.h>
 
@@ -107,7 +108,7 @@
     util_capture_header(handle, NULL);
     ucx_map_free_content(respheaders, free);
     ucx_map_free(respheaders);
-    
+       
     return ret;
 }
 
@@ -530,12 +531,7 @@
     // add properties
     UCX_FOREACH(elm, response->properties) {
         xmlNode *prop = elm->data;
-        
-        // TODO: add xml data instead of a string
-        char *text = util_xml_get_text(prop);
-        if(text) {
-            resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, text);
-        }
+        resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, prop->children);
     }
     
     set_davprops(res);
@@ -667,12 +663,7 @@
     // add properties
     UCX_FOREACH(elm, properties) {
         xmlNode *prop = elm->data;
-        
-        // TODO: add xml data instead of a string
-        char *text = util_xml_get_text(prop);
-        if(text) {
-            resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, text);
-        }
+        resource_add_property(res, (char*)prop->ns->href, (char*)prop->name, prop->children);
     }
     ucx_list_free(properties);
     
@@ -685,10 +676,10 @@
 }
 
 void set_davprops(DavResource *res) {
-    char *cl = dav_get_property_ns(res, "DAV:", "getcontentlength");
-    char *ct = dav_get_property_ns(res, "DAV:", "getcontenttype");
-    char *cd = dav_get_property_ns(res, "DAV:", "creationdate");
-    char *lm = dav_get_property_ns(res, "DAV:", "getlastmodified");
+    char *cl = dav_get_string_property_ns(res, "DAV:", "getcontentlength");
+    char *ct = dav_get_string_property_ns(res, "DAV:", "getcontenttype");
+    char *cd = dav_get_string_property_ns(res, "DAV:", "creationdate");
+    char *lm = dav_get_string_property_ns(res, "DAV:", "getlastmodified");
     
     res->contenttype = ct;
     if(cl) {
@@ -807,6 +798,7 @@
                 prefix = "D";
             }
             
+            // begin tag
             s = S("<");
             ucx_buffer_write(s.ptr, 1, s.length, buf);
             s = sstr(prefix);
@@ -817,8 +809,16 @@
             ucx_buffer_write(s.ptr, 1, s.length, buf);
             s = S(">");
             ucx_buffer_write(s.ptr, 1, s.length, buf);
-            s = sstr(property->value);
-            ucx_buffer_write(s.ptr, 1, s.length, buf);
+            
+            // content
+            DavXmlNode *content = property->value;
+            if(content->type == DAV_XML_TEXT) {
+                ucx_buffer_write(content->content, 1, content->contentlength, buf);
+            } else {
+                // TODO: implement
+            }
+            
+            // end tag
             s = S("</");
             ucx_buffer_write(s.ptr, 1, s.length, buf);
             s = sstr(prefix);
--- a/libidav/resource.c	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/resource.c	Sun Oct 22 12:58:07 2017 +0200
@@ -40,6 +40,7 @@
 #include "ucx/utils.h"
 
 #include "resource.h"
+#include "xml.h"
 #include "davqlexec.h"
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
@@ -236,25 +237,36 @@
     return resource->href;
 }
 
-void resource_add_property(DavResource *res, char *ns, char *name, char *val) {
+void resource_add_property(DavResource *res, char *ns, char *name, xmlNode *val) {
     if(!val) {
         return;
     }
     
     UcxKey key = dav_property_key(ns, name);
-    sstr_t v = sstrdup_a(res->session->mp->allocator, sstr(val));
-    ucx_map_put(((DavResourceData*)res->data)->properties, key, v.ptr);
+    DavXmlNode *v = dav_convert_xml(res->session, val);
+    ucx_map_put(((DavResourceData*)res->data)->properties, key, v);
     free(key.data);
 }
 
-char* resource_get_property(DavResource *res, char *ns, char *name) {
+void resource_add_string_property(DavResource *res, char *ns, char *name, char *val) {
+    if(!val) {
+        return;
+    }
+    
     UcxKey key = dav_property_key(ns, name);
-    char *property = resource_get_property_k(res, key);
+    DavXmlNode *v = dav_text_node(res->session, val);
+    ucx_map_put(((DavResourceData*)res->data)->properties, key, v);
+    free(key.data);
+}
+
+DavXmlNode* resource_get_property(DavResource *res, char *ns, char *name) {
+    UcxKey key = dav_property_key(ns, name);
+    DavXmlNode *property = resource_get_property_k(res, key);
     free(key.data);
     return property;
 }
 
-char* resource_get_property_k(DavResource *res, UcxKey key) {
+DavXmlNode* resource_get_property_k(DavResource *res, UcxKey key) {
     DavResourceData *data = (DavResourceData*)res->data;
     return ucx_map_get(data->properties, key);
 }
@@ -339,8 +351,10 @@
             default: ret = 0;
         }
     } else if(cr->type == 1) {
-        char *value1 = resource_get_property_k(res1, cr->column.property);
-        char *value2 = resource_get_property_k(res2, cr->column.property);
+        DavXmlNode *xvalue1 = resource_get_property_k(res1, cr->column.property);
+        DavXmlNode *xvalue2 = resource_get_property_k(res2, cr->column.property);
+        char *value1 = dav_xml_getstring(xvalue1);
+        char *value2 = dav_xml_getstring(xvalue2);
         if(!value1) {
             ret = value2 ? -1 : 0;
         } else if(!value2) {
@@ -403,7 +417,25 @@
     }
 }
 
-char* dav_get_property(DavResource *res, char *name) {
+char* dav_get_string_property(DavResource *res, char *name) {
+    char *pns;
+    char *pname;
+    dav_get_property_namespace_str(res->session->context, name, &pns, &pname);
+    if(!pns || !pname) {
+        return NULL;
+    }
+    return dav_get_string_property_ns(res, pns, pname);
+}
+
+char* dav_get_string_property_ns(DavResource *res, char *ns, char *name) {
+    DavXmlNode *prop = dav_get_property_ns(res, ns, name);
+    if(!prop) {
+        return NULL;
+    }
+    return dav_xml_getstring(prop);
+}
+
+DavXmlNode* dav_get_property(DavResource *res, char *name) {
     char *pns;
     char *pname;
     dav_get_property_namespace_str(res->session->context, name, &pns, &pname);
@@ -413,11 +445,11 @@
     return dav_get_property_ns(res, pns, pname);
 }
 
-char* dav_get_property_ns(DavResource *res, char *ns, char *name) {
+DavXmlNode* dav_get_property_ns(DavResource *res, char *ns, char *name) {
     if(!ns || !name) {
         return NULL;
     }
-    char *property = resource_get_property(res, ns, name);
+    DavXmlNode *property = resource_get_property(res, ns, name);
     DavResourceData *data = res->data;
     // resource_get_property only returns persistent properties
     // check the remove and set list
@@ -435,7 +467,7 @@
     UCX_FOREACH(elm, data->set) {
         DavProperty *p = elm->data;
         if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
-            return p->value;
+            return p->value; // TODO: fix
         }
     }
     // no property update
@@ -457,7 +489,7 @@
             res->session,
             sizeof(DavProperty));
     property->name = dav_session_strdup(res->session, name);
-    property->value = dav_session_strdup(res->session, value);
+    property->value = dav_text_node(res->session, value);
     
     DavNamespace *namespace = dav_session_malloc(
             res->session,
@@ -646,7 +678,7 @@
                 free(enc_hash);
                 return 1;
             }
-            resource_add_property(res, DAV_NS, "crypto-hash", enc_hash);
+            resource_add_string_property(res, DAV_NS, "crypto-hash", enc_hash);
             free(enc_hash);
         } else {
             ret = do_put_request(
@@ -713,7 +745,7 @@
     AESDecrypter *dec = NULL;
     DavKey *key = NULL;
     if(DAV_DECRYPT_CONTENT(sn)) {
-        char *keyname = dav_get_property_ns(res, DAV_NS, "crypto-key");
+        char *keyname = dav_get_string_property_ns(res, DAV_NS, "crypto-key");
         if(keyname) {
             key = dav_context_get_key(sn->context, keyname);
             if(key) {
@@ -752,7 +784,7 @@
         int verify_failed = 0;
         if(DAV_DECRYPT_CONTENT(sn) && key) {
             // try to verify the content
-            char *res_hash = dav_get_property_ns(res, DAV_NS, "crypto-hash");
+            char *res_hash = dav_get_string_property_ns(res, DAV_NS, "crypto-hash");
 
             if(res_hash) {
                 size_t len = 0;
--- a/libidav/resource.h	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/resource.h	Sun Oct 22 12:58:07 2017 +0200
@@ -70,9 +70,9 @@
 
 void resource_set_info(DavResource *res, char *href_str);
 DavResourceData* resource_data_new(DavSession *sn);
-void resource_add_property(DavResource *res, char *ns, char *name, char *val);
-char* resource_get_property(DavResource *res, char *ns, char *name);
-char* resource_get_property_k(DavResource *res, UcxKey key);
+void resource_add_property(DavResource *res, char *ns, char *name, xmlNode *val);
+DavXmlNode* resource_get_property(DavResource *res, char *ns, char *name);
+DavXmlNode* resource_get_property_k(DavResource *res, UcxKey key);
 void resource_add_child(DavResource *parent, DavResource *child);
 void resource_add_ordered_child(DavResource *parent, DavResource *child, UcxList *ordercr);
 int resource_add_crypto_info(DavSession *sn, char *href, char *name, char *hash);
--- a/libidav/webdav.h	Thu Oct 12 20:37:46 2017 +0200
+++ b/libidav/webdav.h	Sun Oct 22 12:58:07 2017 +0200
@@ -53,11 +53,12 @@
 typedef struct DavProxy      DavProxy;
 typedef struct DavSession    DavSession;
 typedef struct DavResource   DavResource;
-typedef struct DavResult   DavResult;
+typedef struct DavResult     DavResult;
 typedef struct DavNamespace  DavNamespace;
 typedef struct DavProperty   DavProperty;
 typedef struct DavPropName   DavPropName;
 typedef struct DavKey        DavKey;
+typedef struct DavXmlNode    DavXmlNode;
 
 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*);
 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*);
@@ -87,6 +88,14 @@
 
 typedef enum DavError DavError;
 
+enum DavXmlNodeType {
+    DAV_XML_NONE = 0,
+    DAV_XML_ELEMENT,
+    DAV_XML_TEXT
+};
+
+typedef enum DavXmlNodeType DavXmlNodeType;
+
 #define DAV_SESSION_ENCRYPT_CONTENT     0x0001
 #define DAV_SESSION_ENCRYPT_NAME        0x0002
 #define DAV_SESSION_DECRYPT_CONTENT     0x0004
@@ -151,7 +160,7 @@
 struct DavProperty {
     DavNamespace *ns;
     char         *name;
-    char         *value;
+    DavXmlNode   *value;
 };
 
 struct DavPropName {
@@ -174,6 +183,23 @@
     size_t  length;
 };
 
+struct DavXmlNode {
+    DavXmlNodeType type;
+    
+    char           *namespace;
+    char           *name;
+    
+    DavXmlNode     *prev;
+    DavXmlNode     *next;
+    DavXmlNode     *children;
+    DavXmlNode     *parent;
+    
+    // TODO: attributes
+    
+    char           *content;
+    size_t         contentlength;
+};
+
 DavContext* dav_context_new();
 void dav_context_destroy(DavContext *ctx);
 
@@ -245,8 +271,10 @@
 int dav_lock_t(DavResource *res, time_t timeout);
 int dav_unlock(DavResource *res);
 
-char* dav_get_property(DavResource *res, char *name);
-char* dav_get_property_ns(DavResource *res, char *ns, char *name);
+DavXmlNode* dav_get_property(DavResource *res, char *name);
+DavXmlNode* dav_get_property_ns(DavResource *res, char *ns, char *name);
+char* dav_get_string_property(DavResource *res, char *name);
+char* dav_get_string_property_ns(DavResource *res, char *ns, char *name);
 void dav_set_property(DavResource *res, char *name, char *value);
 void dav_set_property_ns(DavResource *res, char *ns, char *name, char *value);
 void dav_remove_property(DavResource *res, char *name);
@@ -266,6 +294,9 @@
 // private
 int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf);
 
+char* dav_xml_getstring(DavXmlNode *node);
+DavXmlNode* dav_text_node(DavSession *sn, char *text);
+
 #ifdef	__cplusplus
 }
 #endif
--- /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;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/xml.h	Sun Oct 22 12:58:07 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+#ifndef DAV_XML_H
+#define DAV_XML_H
+
+#include "webdav.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DavXmlNode* dav_convert_xml(DavSession *sn, xmlNode *node);
+
+void dav_print_xml(DavXmlNode *node);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DAV_XML_H */
+

mercurial