src/server/webdav/saxhandler.cpp

changeset 30
27c7511c0e34
parent 29
e8619defde14
child 44
3da1f7b6847f
--- a/src/server/webdav/saxhandler.cpp	Wed May 16 12:47:28 2012 +0200
+++ b/src/server/webdav/saxhandler.cpp	Thu May 24 12:51:52 2012 +0200
@@ -38,6 +38,22 @@
 
 using namespace std;
 
+void xstack_push(UcxDlist **stack, XmlElement *elm) {
+    *stack = ucx_dlist_prepend(*stack, elm);
+}
+
+XmlElement* xstack_pop(UcxDlist **stack) {
+    if(*stack == NULL) {
+        return NULL;
+    }
+    XmlElement* ret = (XmlElement*)(*stack)->data;
+    UcxDlist *newstack = ucx_dlist_remove(*stack, *stack);
+    *stack = newstack;
+    return ret;
+}
+
+
+
 PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) {
     davrq = rq;
     pool  = p;
@@ -132,6 +148,13 @@
 ProppatchHandler::ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p) {
     davrq = rq;
     pool  = p;
+    
+    davPropTag = false;
+    rootElement = NULL;
+    xmlStack = NULL;
+    newElement = NULL;
+    
+    updateMode = -1;
 }
 
 ProppatchHandler::~ProppatchHandler() {
@@ -147,10 +170,34 @@
     char *ns  = XMLString::transcode(uri);
     char *name = XMLString::transcode(localname);
     
-    if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
+    if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) {
+        updateMode = 0;
+    } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) {
+        updateMode = 1;
+    } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
         davPropTag = true;
     } else if(davPropTag) {
+        newElement = (XmlElement*)pool_calloc(pool, 1, sizeof(XmlElement));
+        newElement->name = sstr(pool_strdup(pool, name));
+        newElement->xmlns = xmlnsmap_put(davrq->nsmap, ns);
         
+        /*
+         * the xml stack manages the xml hierarchy
+         * new elements will be added to the top element on the stack
+         */
+        
+        XmlElement *currentElm = XSTACK_CUR();
+        if(currentElm) {
+            xmlelm_add_child(currentElm, newElement);
+        }
+        
+        /* newElement is now the parent for future elements */
+        XSTACK_PUSH(newElement);
+        
+        /* if the root element isn't set, the first new element is the root */
+        if(!rootElement) {
+            rootElement = newElement;
+        }
     }
 
     XMLString::release(&ns);
@@ -167,11 +214,42 @@
     char *name = XMLString::transcode(localname);
 
     if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) {
-        updateMode = 0;
+        updateMode = -1;
     } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) {
-        updateMode = 1;
+        updateMode = -1;
     } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
-        
+        davPropTag = false;
+    } else if(davPropTag) {
+        XmlElement *elm = XSTACK_POP();
+        if(xmlStack == NULL) {
+            /* property complete */
+            
+            /*
+            XmlElement *r = rootElement;
+            printf("<%s>\n", sstrdup(r->name).ptr);
+            printf("%s\n", r->content);
+            printf("</%s>\n", sstrdup(r->name).ptr);
+            */
+            
+            /* add the property to the proppatch request */
+            switch(updateMode) {
+                case 0: {
+                    davrq->setProps = ucx_dlist_append(
+                            davrq->setProps,
+                            rootElement);
+                    break;
+                }
+                case 1: {
+                    davrq->removeProps = ucx_dlist_append(
+                            davrq->removeProps,
+                            rootElement);
+                    break;
+                }
+            }
+            
+            rootElement = NULL;
+            
+        }
     }
     
 
@@ -184,6 +262,21 @@
         const XMLSize_t length)
 {
     
+    XMLString::trim((XMLCh *const)chars);
+    if(chars[0] == 0) {
+        return;
+    }
+    
+    XmlElement *currentElm = XSTACK_CUR();
+    if(currentElm) {
+        xmlch_t *str = (xmlch_t*)pool_calloc(pool, sizeof(xmlch_t), length + 1);
+        for(int i=0;i<length;i++) {
+            str[i] = chars[i];
+        }
+        
+        currentElm->content = str;
+        currentElm->ctlen = length;
+    }
 }
 
 void ProppatchHandler::startDocument() {

mercurial