travis: Enable caching for sonarcloud scan
[strongswan.git] / src / manager / xml.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <string.h>
17
18 #include "xml.h"
19
20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
22
23
24 typedef struct private_xml_t private_xml_t;
25
26 /**
27 * private data of xml
28 */
29 struct private_xml_t {
30
31 /**
32 * public functions
33 */
34 xml_t public;
35
36 /**
37 * root node of this xml (part)
38 */
39 xmlNode *node;
40
41 /**
42 * document, only for root xml_t
43 */
44 xmlDoc *doc;
45
46 /**
47 * Root xml_t*
48 */
49 private_xml_t *root;
50
51 /**
52 * number of enumerator instances
53 */
54 int enums;
55 };
56
57 /**
58 * child element enumerator
59 */
60 typedef struct {
61 /** enumerator interface */
62 enumerator_t e;
63 /** current child context (returned to enumerate() caller) */
64 private_xml_t child;
65 /** currently processing node */
66 xmlNode *node;
67 } child_enum_t;
68
69 METHOD(enumerator_t, child_enumerate, bool,
70 child_enum_t *e, va_list args)
71 {
72 private_xml_t **child;
73 char **name, **value;
74
75 VA_ARGS_VGET(args, child, name, value);
76
77 while (e->node && e->node->type != XML_ELEMENT_NODE)
78 {
79 e->node = e->node->next;
80 }
81 if (e->node)
82 {
83 xmlNode *text;
84
85 text = e->node->children;
86 *value = NULL;
87
88 while (text && text->type != XML_TEXT_NODE)
89 {
90 text = text->next;
91 }
92 if (text)
93 {
94 *value = text->content;
95 }
96 *name = (char*)e->node->name;
97 *child = &e->child;
98 e->child.node = e->node->children;
99 e->node = e->node->next;
100 return TRUE;
101 }
102 return FALSE;
103 }
104
105 METHOD(xml_t, get_attribute, char*,
106 private_xml_t *this, char *name)
107 {
108 return NULL;
109 }
110
111 METHOD(enumerator_t, child_destroy, void,
112 child_enum_t *this)
113 {
114 if (--this->child.root->enums == 0)
115 {
116 xmlFreeDoc(this->child.root->doc);
117 free(this->child.root);
118 }
119 free(this);
120 }
121
122 METHOD(xml_t, children, enumerator_t*,
123 private_xml_t *this)
124 {
125 child_enum_t *ce;
126 INIT(ce,
127 .e = {
128 .enumerate = enumerator_enumerate_default,
129 .venumerate = _child_enumerate,
130 .destroy = _child_destroy,
131 },
132 .child = {
133 .public = {
134 .get_attribute = _get_attribute,
135 .children = _children,
136 },
137 .doc = this->doc,
138 .root = this->root,
139 },
140 .node = this->node,
141 );
142 this->root->enums++;
143 return &ce->e;
144 }
145
146 /*
147 * see header file
148 */
149 xml_t *xml_create(char *xml)
150 {
151 private_xml_t *this;
152
153 INIT(this,
154 .public = {
155 .get_attribute = _get_attribute,
156 .children = _children,
157 },
158 .doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0),
159 );
160
161 if (!this->doc)
162 {
163 free(this);
164 return NULL;
165 }
166
167 this->node = xmlDocGetRootElement(this->doc);
168 this->root = this;
169
170 return &this->public;
171 }
172