Merge Call completion support into trunk.
[asterisk/asterisk.git] / main / xml.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief XML abstraction layer
20  *
21  * \author Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
22  */
23
24 #include "asterisk.h"
25 #include "asterisk/xml.h"
26 #include "asterisk/logger.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #if defined(HAVE_LIBXML2)
31 #include <libxml/parser.h>
32 #include <libxml/tree.h>
33 #include <libxml/xinclude.h>
34 /* libxml2 ast_xml implementation. */
35
36
37 int ast_xml_init(void)
38 {
39         LIBXML_TEST_VERSION
40
41         return 0;
42 }
43
44 int ast_xml_finish(void)
45 {
46         xmlCleanupParser();
47
48         return 0;
49 }
50
51 struct ast_xml_doc *ast_xml_open(char *filename)
52 {
53         xmlDoc *doc;
54
55         if (!filename) {
56                 return NULL;
57         }
58
59         doc = xmlReadFile(filename, NULL, XML_PARSE_RECOVER);
60         if (doc) {
61                 /* process xinclude elements. */
62                 if (xmlXIncludeProcess(doc) < 0) {
63                         xmlFreeDoc(doc);
64                         return NULL;
65                 }
66         }
67
68         return (struct ast_xml_doc *) doc;
69 }
70
71 struct ast_xml_doc *ast_xml_read_memory(char *buffer, size_t size)
72 {
73         xmlDoc *doc;
74
75         if (!buffer) {
76                 return NULL;
77         }
78
79         if (!(doc = xmlParseMemory(buffer, (int) size))) {
80                 /* process xinclude elements. */
81                 if (xmlXIncludeProcess(doc) < 0) {
82                         xmlFreeDoc(doc);
83                         return NULL;
84                 }
85         }
86
87         return (struct ast_xml_doc *) doc;
88 }
89
90 void ast_xml_close(struct ast_xml_doc *doc)
91 {
92         if (!doc) {
93                 return;
94         }
95
96         xmlFreeDoc((xmlDoc *) doc);
97         doc = NULL;
98 }
99
100
101 struct ast_xml_node *ast_xml_get_root(struct ast_xml_doc *doc)
102 {
103         xmlNode *root_node;
104
105         if (!doc) {
106                 return NULL;
107         }
108
109         root_node = xmlDocGetRootElement((xmlDoc *) doc);
110
111         return (struct ast_xml_node *) root_node;
112 }
113
114 void ast_xml_free_node(struct ast_xml_node *node)
115 {
116         if (!node) {
117                 return;
118         }
119
120         xmlFreeNode((xmlNode *) node);
121         node = NULL;
122 }
123
124 void ast_xml_free_attr(const char *attribute)
125 {
126         if (attribute) {
127                 xmlFree((char *) attribute);
128         }
129 }
130
131 void ast_xml_free_text(const char *text)
132 {
133         if (text) {
134                 xmlFree((char *) text);
135         }
136 }
137
138 const char *ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
139 {
140         xmlChar *attrvalue;
141
142         if (!node) {
143                 return NULL;
144         }
145
146         if (!attrname) {
147                 return NULL;
148         }
149
150         attrvalue = xmlGetProp((xmlNode *) node, (xmlChar *) attrname);
151
152         return (const char *) attrvalue;
153 }
154
155 struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
156 {
157         struct ast_xml_node *cur;
158         const char *attr;
159
160         if (!root_node) {
161                 return NULL;
162         }
163
164         for (cur = root_node; cur; cur = ast_xml_node_get_next(cur)) {
165                 /* Check if the name matchs */
166                 if (strcmp(ast_xml_node_get_name(cur), name)) {
167                         continue;
168                 }
169                 /* We need to check for a specific attribute name? */
170                 if (!attrname || !attrvalue) {
171                         return cur;
172                 }
173                 /* Get the attribute, we need to compare it. */
174                 if ((attr = ast_xml_get_attribute(cur, attrname))) {
175                         /* does attribute name/value matches? */
176                         if (!strcmp(attr, attrvalue)) {
177                                 ast_xml_free_attr(attr);
178                                 return cur;
179                         }
180                         ast_xml_free_attr(attr);
181                 }
182         }
183
184         return NULL;
185 }
186
187 struct ast_xml_ns *ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name) {
188         xmlNsPtr ns = xmlSearchNs((xmlDocPtr) doc, (xmlNodePtr) node, (xmlChar *) ns_name);
189         return (struct ast_xml_ns *) ns;
190 }
191
192 const char *ast_xml_get_ns_href(struct ast_xml_ns *ns)
193 {
194         return (const char *) ((xmlNsPtr) ns)->href;
195 }
196
197 const char *ast_xml_get_text(struct ast_xml_node *node)
198 {
199         if (!node) {
200                 return NULL;
201         }
202
203         return (const char *) xmlNodeGetContent((xmlNode *) node);
204 }
205
206 const char *ast_xml_node_get_name(struct ast_xml_node *node)
207 {
208         return (const char *) ((xmlNode *) node)->name;
209 }
210
211 struct ast_xml_node *ast_xml_node_get_children(struct ast_xml_node *node)
212 {
213         return (struct ast_xml_node *) ((xmlNode *) node)->children;
214 }
215
216 struct ast_xml_node *ast_xml_node_get_next(struct ast_xml_node *node)
217 {
218         return (struct ast_xml_node *) ((xmlNode *) node)->next;
219 }
220
221 struct ast_xml_node *ast_xml_node_get_prev(struct ast_xml_node *node)
222 {
223         return (struct ast_xml_node *) ((xmlNode *) node)->prev;
224 }
225
226 struct ast_xml_node *ast_xml_node_get_parent(struct ast_xml_node *node)
227 {
228         return (struct ast_xml_node *) ((xmlNode *) node)->parent;
229 }
230
231 #endif /* defined(HAVE_LIBXML2) */
232