libidav/xml.c

changeset 331
9ca1e4706acc
child 338
c7f3fe4abdb2
equal deleted inserted replaced
330:54819e984a19 331:9ca1e4706acc
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2017 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "xml.h"
34
35 static DavXmlNodeType convert_type(xmlElementType type) {
36 DavXmlNodeType ct;
37 switch(type) {
38 default: ct = DAV_XML_NONE; break;
39 case XML_ELEMENT_NODE: ct = DAV_XML_ELEMENT; break;
40 case XML_TEXT_NODE: ct = DAV_XML_TEXT;
41 }
42 return ct;
43 }
44
45 typedef struct {
46 xmlNode *node;
47 DavXmlNode *parent;
48 } ConvXmlElm;
49
50 DavXmlNode* dav_convert_xml(DavSession *sn, xmlNode *node) {
51 if(!node) {
52 return NULL;
53 }
54 DavXmlNodeType newnt = convert_type(node->type);
55 if(newnt == DAV_XML_NONE) {
56 return NULL;
57 }
58
59 UcxMempool *mp = sn->mp;
60
61 ConvXmlElm *ce = malloc(sizeof(ConvXmlElm));
62 ce->node = node;
63 ce->parent = NULL;
64 UcxList *stack = ucx_list_prepend(NULL, ce);
65
66 DavXmlNode *ret = NULL;
67
68 while(stack) {
69 ConvXmlElm *c = stack->data;
70 stack = ucx_list_remove(stack, stack);
71
72 xmlNode *n = c->node;
73 DavXmlNode *prev = NULL;
74 while(n) {
75 DavXmlNode *newxn = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode));
76 if(!ret) {
77 ret = newxn;
78 }
79 newxn->type = convert_type(n->type);
80 newxn->parent = c->parent;
81 if(c->parent && !c->parent->children) {
82 c->parent->children = newxn;
83 }
84 newxn->prev = prev;
85 if(prev) {
86 prev->next = newxn;
87 }
88
89 if(newxn->type == DAV_XML_ELEMENT) {
90 newxn->name = dav_session_strdup(sn, (char*)n->name);
91 if(n->ns && n->ns->href) {
92 newxn->namespace = dav_session_strdup(sn, (char*)n->ns->href);
93 }
94
95 // TODO: copy attributes
96
97 if(n->children) {
98 ConvXmlElm *convc = malloc(sizeof(ConvXmlElm));
99 convc->node = n->children;
100 convc->parent = newxn;
101 stack = ucx_list_prepend(stack, convc);
102 }
103 } else if(newxn->type == DAV_XML_TEXT) {
104 sstr_t content = sstrdup_a(mp->allocator, sstr((char*)n->content));
105 newxn->content = content.ptr;
106 newxn->contentlength = content.length;
107 }
108
109 prev = newxn;
110 n = n->next;
111 }
112
113 free(c);
114 }
115
116 return ret;
117 }
118
119 void dav_print_xml(DavXmlNode *node) {
120 if(node->type == DAV_XML_ELEMENT) {
121 printf("<%s>", node->name);
122
123 DavXmlNode *child = node->children;
124 if(child) {
125 dav_print_xml(child);
126 }
127
128 printf("</%s>", node->name);
129 } else {
130 fwrite(node->content, 1, node->contentlength, stdout);
131 fflush(stdout);
132 }
133 if(node->next) {
134 dav_print_xml(node->next);
135 }
136 }
137
138 /* ------------------------- public API ------------------------- */
139
140 char* dav_xml_getstring(DavXmlNode *node) {
141 if(node && node->type == DAV_XML_TEXT) {
142 return node->content;
143 } else {
144 return NULL;
145 }
146 }
147
148 DavXmlNode* dav_text_node(DavSession *sn, char *text) {
149 UcxMempool *mp = sn->mp;
150 DavXmlNode *newxn = ucx_mempool_calloc(mp, 1, sizeof(DavXmlNode));
151 newxn->type = DAV_XML_TEXT;
152 sstr_t content = sstrdup_a(mp->allocator, sstr(text));
153 newxn->content = content.ptr;
154 newxn->contentlength = content.length;
155 return newxn;
156 }
157

mercurial