removing svn keyword $Id$ from all files
[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 "xml.h"
17
18 #include <libxml/parser.h>
19 #include <libxml/tree.h>
20
21
22 typedef struct private_xml_t private_xml_t;
23
24 /**
25 * private data of xml
26 */
27 struct private_xml_t {
28
29 /**
30 * public functions
31 */
32 xml_t public;
33
34 /**
35 * root node of this xml (part)
36 */
37 xmlNode *node;
38
39 /**
40 * document, only for root xml_t
41 */
42 xmlDoc *doc;
43
44 /**
45 * Root xml_t*
46 */
47 private_xml_t *root;
48
49 /**
50 * number of enumerator instances
51 */
52 int enums;
53 };
54
55 /**
56 * child element enumerator
57 */
58 typedef struct {
59 /** enumerator interface */
60 enumerator_t e;
61 /** current child context (returned to enumerate() caller) */
62 private_xml_t child;
63 /** currently processing node */
64 xmlNode *node;
65 } child_enum_t;
66
67 /**
68 * Implementation of xml_t.children().enumerate().
69 */
70 static bool child_enumerate(child_enum_t *e, private_xml_t **child,
71 char **name, char **value)
72 {
73 while (e->node && e->node->type != XML_ELEMENT_NODE)
74 {
75 e->node = e->node->next;
76 }
77 if (e->node)
78 {
79 xmlNode *text;
80
81 text = e->node->children;
82 *value = NULL;
83
84 while (text && text->type != XML_TEXT_NODE)
85 {
86 text = text->next;
87 }
88 if (text)
89 {
90 *value = text->content;
91 }
92 *name = (char*)e->node->name;
93 *child = &e->child;
94 e->child.node = e->node->children;
95 e->node = e->node->next;
96 return TRUE;
97 }
98 return FALSE;
99 }
100
101 /**
102 * Implementation of xml_t.get_attribute.
103 */
104 static char* get_attribute(private_xml_t *this, char *name)
105 {
106 return NULL;
107 }
108
109 /**
110 * destroy enumerator, and complete tree if this was the last enumerator
111 */
112 static void child_destroy(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 /**
123 * Implementation of xml_t.children.
124 */
125 static enumerator_t* children(private_xml_t *this)
126 {
127 child_enum_t *ce = malloc_thing(child_enum_t);
128 ce->e.enumerate = (void*)child_enumerate;
129 ce->e.destroy = (void*)child_destroy;
130 ce->node = this->node;
131 ce->child.public.children = (void*)children;
132 ce->child.public.get_attribute = (void*)get_attribute;
133 ce->child.node = NULL;
134 ce->child.doc = this->doc;
135 ce->child.root = this->root;
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 = malloc_thing(private_xml_t);
146
147 this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute;
148 this->public.children = (enumerator_t*(*)(xml_t*))children;
149
150 this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
151 if (this->doc == NULL)
152 {
153 free(this);
154 return NULL;
155 }
156 this->node = xmlDocGetRootElement(this->doc);
157 this->root = this;
158 this->enums = 0;
159
160 return &this->public;
161 }
162