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