src/server/webdav/xml.c

branch
webdav
changeset 319
a9b9344875aa
parent 318
60870dbac94f
child 324
44cf877b3d9f
--- a/src/server/webdav/xml.c	Sat Apr 30 20:44:38 2022 +0200
+++ b/src/server/webdav/xml.c	Sun May 01 10:48:20 2022 +0200
@@ -35,6 +35,7 @@
 #include <ucx/buffer.h>
 
 #include "../util/util.h"
+#include "../util/pool.h"
 
 #include "xml.h"
 
@@ -314,7 +315,7 @@
 }
 
 
-static ssize_t buf_writefunc(void *buf, const void *s, size_t len) {
+static ssize_t buf_writefunc(void *buf, const char *s, size_t len) {
     int w = ucx_buffer_write(s, 1, len, buf);
     return w == 0 ? IO_ERROR : w;
 }
@@ -357,6 +358,131 @@
     return data;
 }
 
+char* wsxml_nslist2string(pool_handle_t *pool, WebdavNSList *nslist) {
+    if(!nslist) return NULL;
+    
+    // get required string length
+    size_t len = 0;
+    WebdavNSList *elm = nslist;
+    while(elm) {
+        WSNamespace *ns = elm->namespace;
+        if(ns) {
+            if(ns->prefix) len += strlen((const char*)ns->prefix);
+            if(ns->href) len += strlen((const char*)ns->href);
+            len += 2; // 1 char for ':', 1 char for \n or \0
+        }
+        elm = elm->next;
+    }
+    
+    // alloc string
+    char *str = pool_malloc(pool, len);
+    if(!str) {
+        return NULL;
+    }
+    char *pos = str;
+    
+    // copy namespace definitions to the string
+    elm = nslist;
+    while(elm) {
+        WSNamespace *ns = elm->namespace;
+        if(ns) {
+            if(ns->prefix) {
+                size_t prefixlen = strlen((const char*)ns->prefix);
+                memcpy(pos, ns->prefix, prefixlen);
+                pos[prefixlen] = ':';
+                pos += prefixlen + 1;
+            } else {
+                pos[0] = ':';
+                pos++;
+            }
+            if(ns->href) {
+                size_t hreflen = strlen((const char*)ns->href);
+                memcpy(pos, ns->href, hreflen);
+                pos[hreflen] = elm->next ? '\n' : '\0';
+                pos += hreflen + 1;
+            } else {
+                pos[0] = elm->next ? '\n' : '\0';
+                pos++;
+            }      
+        }
+        elm = elm->next;
+    }
+    
+    return str;
+}
+
+WebdavNSList* wsxml_string2nslist(pool_handle_t *pool, char *nsliststr) {
+    if(!nsliststr) return NULL;
+    size_t len = strlen(nsliststr);
+    WebdavNSList *list_start = NULL;
+    WebdavNSList *list_current = NULL;
+    
+    char *prefix = nsliststr;
+    size_t prefix_start = 0;
+    size_t prefix_len = 0;
+    char *href = NULL;
+    size_t href_start = len;
+    size_t i;
+    for(i=0;i<=len;i++) {
+        char c = nsliststr[i];
+        if(c == '\n' || c == '\0') {
+            if(i > href_start) {
+                WebdavNSList *elm = pool_malloc(pool, sizeof(WebdavNSList));
+                if(!elm) {
+                    break;
+                }
+                elm->prev = list_current;
+                elm->next = NULL;
+                WSNamespace *ns = pool_malloc(pool, sizeof(WSNamespace));
+                elm->namespace = ns;
+                if(!ns) {
+                    break;
+                }
+                memset(ns, 0, sizeof(WSNamespace));
+                ns->prefix = prefix_len > 0 ? (xmlChar*)sstrdup_pool(pool, sstrn(prefix, prefix_len)).ptr : NULL;
+                ns->href = (xmlChar*)sstrdup_pool(pool, sstrn(href, i-href_start)).ptr;
+                if(list_current) {
+                    list_current->next = elm;
+                } else {
+                    list_start = elm; 
+                }
+                list_current = elm;
+            }
+            prefix_start = i + 1;
+            prefix = nsliststr + prefix_start;
+            prefix_len = 0;
+            href_start = len;
+            href = NULL;
+        } else if(!href && c == ':') {
+            prefix_len = i - prefix_start;
+            href_start = i + 1;
+            href = nsliststr + href_start;
+        }
+    }
+    
+    if(i < len) {
+        // error, cleanup
+        while(list_start) {
+            if(list_start->namespace) {
+                WSNamespace *ns = list_start->namespace;
+                if(ns->prefix) {
+                    pool_free(pool, (char*)ns->prefix);
+                }
+                if(ns->href) {
+                    pool_free(pool, (char*)ns->href);
+                }
+                pool_free(pool, ns);
+            }
+            WebdavNSList *next = list_start->next;
+            pool_free(pool, list_start);
+            list_start = next;
+        }
+        list_start = NULL;
+    }
+    
+    return list_start;
+}
+
 /*****************************************************************************
  *    Non public functions
  *****************************************************************************/

mercurial