src/server/webdav/xml.c

branch
webdav
changeset 224
0de1ec82628e
parent 223
bbaec8415c10
child 225
e4f3e1433098
equal deleted inserted replaced
223:bbaec8415c10 224:0de1ec82628e
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 32
33
34 #include "xml.h" 33 #include "xml.h"
35 34
36 typedef struct StackElm { 35 typedef struct StackElm {
37 WSXmlNode *node; // list of nodes 36 WSXmlNode *node; // list of nodes
38 WSXmlNode *parent; // if not NULL, call endcb after node->next is NULL 37 //WSXmlNode *parent; // if not NULL, call endcb after node->next is NULL
38 int endonly;
39 struct StackElm *next; 39 struct StackElm *next;
40 } StackElm; 40 } StackElm;
41 41
42 #define STACK_PUSH(stack, elm) if(stack) { elm->next = stack; } stack = elm; 42 #define STACK_PUSH(stack, elm) if(stack) { elm->next = stack; } stack = elm;
43 43
56 if(!stack) { 56 if(!stack) {
57 return 1; // OOM 57 return 1; // OOM
58 } 58 }
59 stack->next = NULL; 59 stack->next = NULL;
60 stack->node = node; 60 stack->node = node;
61 stack->parent = NULL; 61 stack->endonly = 0;
62 //stack->parent = NULL;
62 63
63 int ret = 0; 64 int ret = 0;
64 int br = 0; 65 int br = 0;
65 while(stack) { 66 while(stack) {
66 StackElm *cur = stack; 67 StackElm *cur = stack;
67 WSXmlNode *xmlnode = cur->node; // get top stack element 68 WSXmlNode *xmlnode = cur->node; // get top stack element
68 stack = cur->next; // and remove it 69 stack = cur->next; // and remove it
69 cur->next = NULL; 70 cur->next = NULL;
70 71
71 while(xmlnode) { 72 while(xmlnode && !cur->endonly) {
72 // element begin callback 73 // element begin callback
73 if(begincb(xmlnode, udata)) { 74 if(begincb(xmlnode, udata)) {
74 br = 1; 75 br = 1;
75 break; // I don't like break with labels - is this wrong? 76 break; // I don't like break with labels - is this wrong?
76 } 77 }
86 } 87 }
87 newelm->next = NULL; 88 newelm->next = NULL;
88 newelm->node = xmlnode->children; 89 newelm->node = xmlnode->children;
89 // setting the parent will make sure endcb will be called 90 // setting the parent will make sure endcb will be called
90 // for the current xmlnode after all children are processed 91 // for the current xmlnode after all children are processed
91 newelm->parent = xmlnode; 92 //newelm->parent = xmlnode;
93 newelm->endonly = 0;
92 94
93 // if xmlnode->next is not NULL, there are still nodes at 95 // if xmlnode->next is not NULL, there are still nodes at
94 // this level, therefore we have to put these also on the 96 // this level, therefore we have to put these also on the
95 // stack 97 // stack
96 // this way, the remaining nodes are processed after all 98 // this way, the remaining nodes are processed after all
97 // children of the current node are processed 99 // children and the end tag are processed
98 if(xmlnode->next) { 100 if(xmlnode->next) {
99 // reuse current StackElm 101 StackElm *nextelm = pool_malloc(pool, sizeof(StackElm));
100 cur->node = xmlnode->next; 102 if(!nextelm) {
101 STACK_PUSH(stack, cur); 103 ret = 1;
102 cur = NULL; 104 br = 1;
105 break;
106 }
107 nextelm->node = xmlnode->next;
108 nextelm->next = NULL;
109 nextelm->endonly = 0;
110 STACK_PUSH(stack, nextelm);
103 } 111 }
112
113 // we have to put the end tag of the current element
114 // on the stack to ensure endcb is called for the current
115 // element, after all children are processed
116 // reuse cur
117 cur->node = xmlnode;
118 cur->endonly = 1;
119 STACK_PUSH(stack, cur);
120
121 cur = NULL;
104 122
105 // now we can put the children on the stack 123 // now we can put the children on the stack
106 STACK_PUSH(stack, newelm); 124 STACK_PUSH(stack, newelm);
107 // break, because we don't want to process xmlnode->next now 125 // break, because we don't want to process xmlnode->next now
108 break; 126 break;
109 } else { 127 } else {
110 // no children means, the end callback can be called directly 128 // no children means, the end callback can be called directly
111 // after the begin callback (no intermediate nodes) 129 // after the begin callback (no intermediate nodes)
130 cur->node = NULL;
112 if(endcb(xmlnode, udata)) { 131 if(endcb(xmlnode, udata)) {
113 br = 1; 132 br = 1;
114 break; 133 break;
115 } 134 }
116 } 135 }
120 } 139 }
121 if(br) { 140 if(br) {
122 break; // break because of an error 141 break; // break because of an error
123 } 142 }
124 143
125 if(cur) { 144 if(cur && cur->node) {
126 if(cur->parent) { 145 //xmlNode *endNode = cur->parent ? cur->parent : cur->node;
127 if(endcb(cur->parent, udata)) { 146 xmlNode *endNode = cur->node;
128 break; 147 if(endcb(endNode, udata)) {
129 } 148 break;
130 } 149 }
131 pool_free(pool, cur); 150 pool_free(pool, cur);
132 } 151 }
133 } 152 }
134 153

mercurial