Migrated control_controller_t to INIT/METHOD macros.
[strongswan.git] / src / manager / xml.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * 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, private_xml_t **child, char **name, char **value)
71 {
72 while (e->node && e->node->type != XML_ELEMENT_NODE)
73 {
74 e->node = e->node->next;
75 }
76 if (e->node)
77 {
78 xmlNode *text;
79
80 text = e->node->children;
81 *value = NULL;
82
83 while (text && text->type != XML_TEXT_NODE)
84 {
85 text = text->next;
86 }
87 if (text)
88 {
89 *value = text->content;
90 }
91 *name = (char*)e->node->name;
92 *child = &e->child;
93 e->child.node = e->node->children;
94 e->node = e->node->next;
95 return TRUE;
96 }
97 return FALSE;
98 }
99
100 METHOD(xml_t, get_attribute, char*,
101 private_xml_t *this, char *name)
102 {
103 return NULL;
104 }
105
106 METHOD(enumerator_t, child_destroy, void,
107 child_enum_t *this)
108 {
109 if (--this->child.root->enums == 0)
110 {
111 xmlFreeDoc(this->child.root->doc);
112 free(this->child.root);
113 }
114 free(this);
115 }
116
117 METHOD(xml_t, children, enumerator_t*,
118 private_xml_t *this)
119 {
120 child_enum_t *ce;
121 INIT(ce,
122 .e = {
123 .enumerate = (void*)_child_enumerate,
124 .destroy = _child_destroy,
125 },
126 .child = {
127 .public = {
128 .get_attribute = _get_attribute,
129 .children = _children,
130 },
131 .doc = this->doc,
132 .root = this->root,
133 },
134 .node = this->node,
135 );
136 this->root->enums++;
137 return &ce->e;
138 }
139
140 /*
141 * see header file
142 */
143 xml_t *xml_create(char *xml)
144 {
145 private_xml_t *this;
146
147 INIT(this,
148 .public = {
149 .get_attribute = _get_attribute,
150 .children = _children,
151 },
152 .doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0),
153 );
154
155 if (!this->doc)
156 {
157 free(this);
158 return NULL;
159 }
160
161 this->node = xmlDocGetRootElement(this->doc);
162 this->root = this;
163
164 return &this->public;
165 }
166