1*a1157835SDaniel Fojt /*
2*a1157835SDaniel Fojt * XML wrapper for libxml2
3*a1157835SDaniel Fojt * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
4*a1157835SDaniel Fojt *
5*a1157835SDaniel Fojt * This software may be distributed under the terms of the BSD license.
6*a1157835SDaniel Fojt * See README for more details.
7*a1157835SDaniel Fojt */
8*a1157835SDaniel Fojt
9*a1157835SDaniel Fojt #include "includes.h"
10*a1157835SDaniel Fojt #define LIBXML_VALID_ENABLED
11*a1157835SDaniel Fojt #include <libxml/tree.h>
12*a1157835SDaniel Fojt #include <libxml/xmlschemastypes.h>
13*a1157835SDaniel Fojt
14*a1157835SDaniel Fojt #include "common.h"
15*a1157835SDaniel Fojt #include "base64.h"
16*a1157835SDaniel Fojt #include "xml-utils.h"
17*a1157835SDaniel Fojt
18*a1157835SDaniel Fojt
19*a1157835SDaniel Fojt struct xml_node_ctx {
20*a1157835SDaniel Fojt void *ctx;
21*a1157835SDaniel Fojt };
22*a1157835SDaniel Fojt
23*a1157835SDaniel Fojt
24*a1157835SDaniel Fojt struct str_buf {
25*a1157835SDaniel Fojt char *buf;
26*a1157835SDaniel Fojt size_t len;
27*a1157835SDaniel Fojt };
28*a1157835SDaniel Fojt
29*a1157835SDaniel Fojt #define MAX_STR 1000
30*a1157835SDaniel Fojt
add_str(void * ctx_ptr,const char * fmt,...)31*a1157835SDaniel Fojt static void add_str(void *ctx_ptr, const char *fmt, ...)
32*a1157835SDaniel Fojt {
33*a1157835SDaniel Fojt struct str_buf *str = ctx_ptr;
34*a1157835SDaniel Fojt va_list ap;
35*a1157835SDaniel Fojt char *n;
36*a1157835SDaniel Fojt int len;
37*a1157835SDaniel Fojt
38*a1157835SDaniel Fojt n = os_realloc(str->buf, str->len + MAX_STR + 2);
39*a1157835SDaniel Fojt if (n == NULL)
40*a1157835SDaniel Fojt return;
41*a1157835SDaniel Fojt str->buf = n;
42*a1157835SDaniel Fojt
43*a1157835SDaniel Fojt va_start(ap, fmt);
44*a1157835SDaniel Fojt len = vsnprintf(str->buf + str->len, MAX_STR, fmt, ap);
45*a1157835SDaniel Fojt va_end(ap);
46*a1157835SDaniel Fojt if (len >= MAX_STR)
47*a1157835SDaniel Fojt len = MAX_STR - 1;
48*a1157835SDaniel Fojt str->len += len;
49*a1157835SDaniel Fojt str->buf[str->len] = '\0';
50*a1157835SDaniel Fojt }
51*a1157835SDaniel Fojt
52*a1157835SDaniel Fojt
xml_validate(struct xml_node_ctx * ctx,xml_node_t * node,const char * xml_schema_fname,char ** ret_err)53*a1157835SDaniel Fojt int xml_validate(struct xml_node_ctx *ctx, xml_node_t *node,
54*a1157835SDaniel Fojt const char *xml_schema_fname, char **ret_err)
55*a1157835SDaniel Fojt {
56*a1157835SDaniel Fojt xmlDocPtr doc;
57*a1157835SDaniel Fojt xmlNodePtr n;
58*a1157835SDaniel Fojt xmlSchemaParserCtxtPtr pctx;
59*a1157835SDaniel Fojt xmlSchemaValidCtxtPtr vctx;
60*a1157835SDaniel Fojt xmlSchemaPtr schema;
61*a1157835SDaniel Fojt int ret;
62*a1157835SDaniel Fojt struct str_buf errors;
63*a1157835SDaniel Fojt
64*a1157835SDaniel Fojt if (ret_err)
65*a1157835SDaniel Fojt *ret_err = NULL;
66*a1157835SDaniel Fojt
67*a1157835SDaniel Fojt doc = xmlNewDoc((xmlChar *) "1.0");
68*a1157835SDaniel Fojt if (doc == NULL)
69*a1157835SDaniel Fojt return -1;
70*a1157835SDaniel Fojt n = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
71*a1157835SDaniel Fojt if (n == NULL) {
72*a1157835SDaniel Fojt xmlFreeDoc(doc);
73*a1157835SDaniel Fojt return -1;
74*a1157835SDaniel Fojt }
75*a1157835SDaniel Fojt xmlDocSetRootElement(doc, n);
76*a1157835SDaniel Fojt
77*a1157835SDaniel Fojt os_memset(&errors, 0, sizeof(errors));
78*a1157835SDaniel Fojt
79*a1157835SDaniel Fojt pctx = xmlSchemaNewParserCtxt(xml_schema_fname);
80*a1157835SDaniel Fojt xmlSchemaSetParserErrors(pctx, (xmlSchemaValidityErrorFunc) add_str,
81*a1157835SDaniel Fojt (xmlSchemaValidityWarningFunc) add_str,
82*a1157835SDaniel Fojt &errors);
83*a1157835SDaniel Fojt schema = xmlSchemaParse(pctx);
84*a1157835SDaniel Fojt xmlSchemaFreeParserCtxt(pctx);
85*a1157835SDaniel Fojt
86*a1157835SDaniel Fojt vctx = xmlSchemaNewValidCtxt(schema);
87*a1157835SDaniel Fojt xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc) add_str,
88*a1157835SDaniel Fojt (xmlSchemaValidityWarningFunc) add_str,
89*a1157835SDaniel Fojt &errors);
90*a1157835SDaniel Fojt
91*a1157835SDaniel Fojt ret = xmlSchemaValidateDoc(vctx, doc);
92*a1157835SDaniel Fojt xmlSchemaFreeValidCtxt(vctx);
93*a1157835SDaniel Fojt xmlFreeDoc(doc);
94*a1157835SDaniel Fojt xmlSchemaFree(schema);
95*a1157835SDaniel Fojt
96*a1157835SDaniel Fojt if (ret == 0) {
97*a1157835SDaniel Fojt os_free(errors.buf);
98*a1157835SDaniel Fojt return 0;
99*a1157835SDaniel Fojt } else if (ret > 0) {
100*a1157835SDaniel Fojt if (ret_err)
101*a1157835SDaniel Fojt *ret_err = errors.buf;
102*a1157835SDaniel Fojt else
103*a1157835SDaniel Fojt os_free(errors.buf);
104*a1157835SDaniel Fojt return -1;
105*a1157835SDaniel Fojt } else {
106*a1157835SDaniel Fojt if (ret_err)
107*a1157835SDaniel Fojt *ret_err = errors.buf;
108*a1157835SDaniel Fojt else
109*a1157835SDaniel Fojt os_free(errors.buf);
110*a1157835SDaniel Fojt return -1;
111*a1157835SDaniel Fojt }
112*a1157835SDaniel Fojt }
113*a1157835SDaniel Fojt
114*a1157835SDaniel Fojt
xml_validate_dtd(struct xml_node_ctx * ctx,xml_node_t * node,const char * dtd_fname,char ** ret_err)115*a1157835SDaniel Fojt int xml_validate_dtd(struct xml_node_ctx *ctx, xml_node_t *node,
116*a1157835SDaniel Fojt const char *dtd_fname, char **ret_err)
117*a1157835SDaniel Fojt {
118*a1157835SDaniel Fojt xmlDocPtr doc;
119*a1157835SDaniel Fojt xmlNodePtr n;
120*a1157835SDaniel Fojt xmlValidCtxt vctx;
121*a1157835SDaniel Fojt xmlDtdPtr dtd;
122*a1157835SDaniel Fojt int ret;
123*a1157835SDaniel Fojt struct str_buf errors;
124*a1157835SDaniel Fojt
125*a1157835SDaniel Fojt if (ret_err)
126*a1157835SDaniel Fojt *ret_err = NULL;
127*a1157835SDaniel Fojt
128*a1157835SDaniel Fojt doc = xmlNewDoc((xmlChar *) "1.0");
129*a1157835SDaniel Fojt if (doc == NULL)
130*a1157835SDaniel Fojt return -1;
131*a1157835SDaniel Fojt n = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
132*a1157835SDaniel Fojt if (n == NULL) {
133*a1157835SDaniel Fojt xmlFreeDoc(doc);
134*a1157835SDaniel Fojt return -1;
135*a1157835SDaniel Fojt }
136*a1157835SDaniel Fojt xmlDocSetRootElement(doc, n);
137*a1157835SDaniel Fojt
138*a1157835SDaniel Fojt os_memset(&errors, 0, sizeof(errors));
139*a1157835SDaniel Fojt
140*a1157835SDaniel Fojt dtd = xmlParseDTD(NULL, (const xmlChar *) dtd_fname);
141*a1157835SDaniel Fojt if (dtd == NULL) {
142*a1157835SDaniel Fojt xmlFreeDoc(doc);
143*a1157835SDaniel Fojt return -1;
144*a1157835SDaniel Fojt }
145*a1157835SDaniel Fojt
146*a1157835SDaniel Fojt os_memset(&vctx, 0, sizeof(vctx));
147*a1157835SDaniel Fojt vctx.userData = &errors;
148*a1157835SDaniel Fojt vctx.error = add_str;
149*a1157835SDaniel Fojt vctx.warning = add_str;
150*a1157835SDaniel Fojt ret = xmlValidateDtd(&vctx, doc, dtd);
151*a1157835SDaniel Fojt xmlFreeDoc(doc);
152*a1157835SDaniel Fojt xmlFreeDtd(dtd);
153*a1157835SDaniel Fojt
154*a1157835SDaniel Fojt if (ret == 1) {
155*a1157835SDaniel Fojt os_free(errors.buf);
156*a1157835SDaniel Fojt return 0;
157*a1157835SDaniel Fojt } else {
158*a1157835SDaniel Fojt if (ret_err)
159*a1157835SDaniel Fojt *ret_err = errors.buf;
160*a1157835SDaniel Fojt else
161*a1157835SDaniel Fojt os_free(errors.buf);
162*a1157835SDaniel Fojt return -1;
163*a1157835SDaniel Fojt }
164*a1157835SDaniel Fojt }
165*a1157835SDaniel Fojt
166*a1157835SDaniel Fojt
xml_node_free(struct xml_node_ctx * ctx,xml_node_t * node)167*a1157835SDaniel Fojt void xml_node_free(struct xml_node_ctx *ctx, xml_node_t *node)
168*a1157835SDaniel Fojt {
169*a1157835SDaniel Fojt xmlFreeNode((xmlNodePtr) node);
170*a1157835SDaniel Fojt }
171*a1157835SDaniel Fojt
172*a1157835SDaniel Fojt
xml_node_get_parent(struct xml_node_ctx * ctx,xml_node_t * node)173*a1157835SDaniel Fojt xml_node_t * xml_node_get_parent(struct xml_node_ctx *ctx, xml_node_t *node)
174*a1157835SDaniel Fojt {
175*a1157835SDaniel Fojt return (xml_node_t *) ((xmlNodePtr) node)->parent;
176*a1157835SDaniel Fojt }
177*a1157835SDaniel Fojt
178*a1157835SDaniel Fojt
xml_node_from_buf(struct xml_node_ctx * ctx,const char * buf)179*a1157835SDaniel Fojt xml_node_t * xml_node_from_buf(struct xml_node_ctx *ctx, const char *buf)
180*a1157835SDaniel Fojt {
181*a1157835SDaniel Fojt xmlDocPtr doc;
182*a1157835SDaniel Fojt xmlNodePtr node;
183*a1157835SDaniel Fojt
184*a1157835SDaniel Fojt doc = xmlParseMemory(buf, strlen(buf));
185*a1157835SDaniel Fojt if (doc == NULL)
186*a1157835SDaniel Fojt return NULL;
187*a1157835SDaniel Fojt node = xmlDocGetRootElement(doc);
188*a1157835SDaniel Fojt node = xmlCopyNode(node, 1);
189*a1157835SDaniel Fojt xmlFreeDoc(doc);
190*a1157835SDaniel Fojt
191*a1157835SDaniel Fojt return (xml_node_t *) node;
192*a1157835SDaniel Fojt }
193*a1157835SDaniel Fojt
194*a1157835SDaniel Fojt
xml_node_get_localname(struct xml_node_ctx * ctx,xml_node_t * node)195*a1157835SDaniel Fojt const char * xml_node_get_localname(struct xml_node_ctx *ctx,
196*a1157835SDaniel Fojt xml_node_t *node)
197*a1157835SDaniel Fojt {
198*a1157835SDaniel Fojt return (const char *) ((xmlNodePtr) node)->name;
199*a1157835SDaniel Fojt }
200*a1157835SDaniel Fojt
201*a1157835SDaniel Fojt
xml_node_to_str(struct xml_node_ctx * ctx,xml_node_t * node)202*a1157835SDaniel Fojt char * xml_node_to_str(struct xml_node_ctx *ctx, xml_node_t *node)
203*a1157835SDaniel Fojt {
204*a1157835SDaniel Fojt xmlChar *buf;
205*a1157835SDaniel Fojt int bufsiz;
206*a1157835SDaniel Fojt char *ret, *pos;
207*a1157835SDaniel Fojt xmlNodePtr n = (xmlNodePtr) node;
208*a1157835SDaniel Fojt xmlDocPtr doc;
209*a1157835SDaniel Fojt
210*a1157835SDaniel Fojt doc = xmlNewDoc((xmlChar *) "1.0");
211*a1157835SDaniel Fojt n = xmlDocCopyNode(n, doc, 1);
212*a1157835SDaniel Fojt xmlDocSetRootElement(doc, n);
213*a1157835SDaniel Fojt xmlDocDumpFormatMemory(doc, &buf, &bufsiz, 0);
214*a1157835SDaniel Fojt xmlFreeDoc(doc);
215*a1157835SDaniel Fojt if (!buf)
216*a1157835SDaniel Fojt return NULL;
217*a1157835SDaniel Fojt pos = (char *) buf;
218*a1157835SDaniel Fojt if (strncmp(pos, "<?xml", 5) == 0) {
219*a1157835SDaniel Fojt pos = strchr(pos, '>');
220*a1157835SDaniel Fojt if (pos)
221*a1157835SDaniel Fojt pos++;
222*a1157835SDaniel Fojt while (pos && (*pos == '\r' || *pos == '\n'))
223*a1157835SDaniel Fojt pos++;
224*a1157835SDaniel Fojt }
225*a1157835SDaniel Fojt if (pos)
226*a1157835SDaniel Fojt ret = os_strdup(pos);
227*a1157835SDaniel Fojt else
228*a1157835SDaniel Fojt ret = NULL;
229*a1157835SDaniel Fojt xmlFree(buf);
230*a1157835SDaniel Fojt
231*a1157835SDaniel Fojt if (ret) {
232*a1157835SDaniel Fojt pos = ret;
233*a1157835SDaniel Fojt if (pos[0]) {
234*a1157835SDaniel Fojt while (pos[1])
235*a1157835SDaniel Fojt pos++;
236*a1157835SDaniel Fojt }
237*a1157835SDaniel Fojt while (pos >= ret && *pos == '\n')
238*a1157835SDaniel Fojt *pos-- = '\0';
239*a1157835SDaniel Fojt }
240*a1157835SDaniel Fojt
241*a1157835SDaniel Fojt return ret;
242*a1157835SDaniel Fojt }
243*a1157835SDaniel Fojt
244*a1157835SDaniel Fojt
xml_node_detach(struct xml_node_ctx * ctx,xml_node_t * node)245*a1157835SDaniel Fojt void xml_node_detach(struct xml_node_ctx *ctx, xml_node_t *node)
246*a1157835SDaniel Fojt {
247*a1157835SDaniel Fojt xmlUnlinkNode((xmlNodePtr) node);
248*a1157835SDaniel Fojt }
249*a1157835SDaniel Fojt
250*a1157835SDaniel Fojt
xml_node_add_child(struct xml_node_ctx * ctx,xml_node_t * parent,xml_node_t * child)251*a1157835SDaniel Fojt void xml_node_add_child(struct xml_node_ctx *ctx, xml_node_t *parent,
252*a1157835SDaniel Fojt xml_node_t *child)
253*a1157835SDaniel Fojt {
254*a1157835SDaniel Fojt xmlAddChild((xmlNodePtr) parent, (xmlNodePtr) child);
255*a1157835SDaniel Fojt }
256*a1157835SDaniel Fojt
257*a1157835SDaniel Fojt
xml_node_create_root(struct xml_node_ctx * ctx,const char * ns_uri,const char * ns_prefix,xml_namespace_t ** ret_ns,const char * name)258*a1157835SDaniel Fojt xml_node_t * xml_node_create_root(struct xml_node_ctx *ctx, const char *ns_uri,
259*a1157835SDaniel Fojt const char *ns_prefix,
260*a1157835SDaniel Fojt xml_namespace_t **ret_ns, const char *name)
261*a1157835SDaniel Fojt {
262*a1157835SDaniel Fojt xmlNodePtr node;
263*a1157835SDaniel Fojt xmlNsPtr ns = NULL;
264*a1157835SDaniel Fojt
265*a1157835SDaniel Fojt node = xmlNewNode(NULL, (const xmlChar *) name);
266*a1157835SDaniel Fojt if (node == NULL)
267*a1157835SDaniel Fojt return NULL;
268*a1157835SDaniel Fojt if (ns_uri) {
269*a1157835SDaniel Fojt ns = xmlNewNs(node, (const xmlChar *) ns_uri,
270*a1157835SDaniel Fojt (const xmlChar *) ns_prefix);
271*a1157835SDaniel Fojt xmlSetNs(node, ns);
272*a1157835SDaniel Fojt }
273*a1157835SDaniel Fojt
274*a1157835SDaniel Fojt if (ret_ns)
275*a1157835SDaniel Fojt *ret_ns = (xml_namespace_t *) ns;
276*a1157835SDaniel Fojt
277*a1157835SDaniel Fojt return (xml_node_t *) node;
278*a1157835SDaniel Fojt }
279*a1157835SDaniel Fojt
280*a1157835SDaniel Fojt
xml_node_create(struct xml_node_ctx * ctx,xml_node_t * parent,xml_namespace_t * ns,const char * name)281*a1157835SDaniel Fojt xml_node_t * xml_node_create(struct xml_node_ctx *ctx, xml_node_t *parent,
282*a1157835SDaniel Fojt xml_namespace_t *ns, const char *name)
283*a1157835SDaniel Fojt {
284*a1157835SDaniel Fojt xmlNodePtr node;
285*a1157835SDaniel Fojt node = xmlNewChild((xmlNodePtr) parent, (xmlNsPtr) ns,
286*a1157835SDaniel Fojt (const xmlChar *) name, NULL);
287*a1157835SDaniel Fojt return (xml_node_t *) node;
288*a1157835SDaniel Fojt }
289*a1157835SDaniel Fojt
290*a1157835SDaniel Fojt
xml_node_create_text(struct xml_node_ctx * ctx,xml_node_t * parent,xml_namespace_t * ns,const char * name,const char * value)291*a1157835SDaniel Fojt xml_node_t * xml_node_create_text(struct xml_node_ctx *ctx,
292*a1157835SDaniel Fojt xml_node_t *parent, xml_namespace_t *ns,
293*a1157835SDaniel Fojt const char *name, const char *value)
294*a1157835SDaniel Fojt {
295*a1157835SDaniel Fojt xmlNodePtr node;
296*a1157835SDaniel Fojt node = xmlNewTextChild((xmlNodePtr) parent, (xmlNsPtr) ns,
297*a1157835SDaniel Fojt (const xmlChar *) name, (const xmlChar *) value);
298*a1157835SDaniel Fojt return (xml_node_t *) node;
299*a1157835SDaniel Fojt }
300*a1157835SDaniel Fojt
301*a1157835SDaniel Fojt
xml_node_create_text_ns(struct xml_node_ctx * ctx,xml_node_t * parent,const char * ns_uri,const char * name,const char * value)302*a1157835SDaniel Fojt xml_node_t * xml_node_create_text_ns(struct xml_node_ctx *ctx,
303*a1157835SDaniel Fojt xml_node_t *parent, const char *ns_uri,
304*a1157835SDaniel Fojt const char *name, const char *value)
305*a1157835SDaniel Fojt {
306*a1157835SDaniel Fojt xmlNodePtr node;
307*a1157835SDaniel Fojt xmlNsPtr ns;
308*a1157835SDaniel Fojt
309*a1157835SDaniel Fojt node = xmlNewTextChild((xmlNodePtr) parent, NULL,
310*a1157835SDaniel Fojt (const xmlChar *) name, (const xmlChar *) value);
311*a1157835SDaniel Fojt ns = xmlNewNs(node, (const xmlChar *) ns_uri, NULL);
312*a1157835SDaniel Fojt xmlSetNs(node, ns);
313*a1157835SDaniel Fojt return (xml_node_t *) node;
314*a1157835SDaniel Fojt }
315*a1157835SDaniel Fojt
316*a1157835SDaniel Fojt
xml_node_set_text(struct xml_node_ctx * ctx,xml_node_t * node,const char * value)317*a1157835SDaniel Fojt void xml_node_set_text(struct xml_node_ctx *ctx, xml_node_t *node,
318*a1157835SDaniel Fojt const char *value)
319*a1157835SDaniel Fojt {
320*a1157835SDaniel Fojt /* TODO: escape XML special chars in value */
321*a1157835SDaniel Fojt xmlNodeSetContent((xmlNodePtr) node, (xmlChar *) value);
322*a1157835SDaniel Fojt }
323*a1157835SDaniel Fojt
324*a1157835SDaniel Fojt
xml_node_add_attr(struct xml_node_ctx * ctx,xml_node_t * node,xml_namespace_t * ns,const char * name,const char * value)325*a1157835SDaniel Fojt int xml_node_add_attr(struct xml_node_ctx *ctx, xml_node_t *node,
326*a1157835SDaniel Fojt xml_namespace_t *ns, const char *name, const char *value)
327*a1157835SDaniel Fojt {
328*a1157835SDaniel Fojt xmlAttrPtr attr;
329*a1157835SDaniel Fojt
330*a1157835SDaniel Fojt if (ns) {
331*a1157835SDaniel Fojt attr = xmlNewNsProp((xmlNodePtr) node, (xmlNsPtr) ns,
332*a1157835SDaniel Fojt (const xmlChar *) name,
333*a1157835SDaniel Fojt (const xmlChar *) value);
334*a1157835SDaniel Fojt } else {
335*a1157835SDaniel Fojt attr = xmlNewProp((xmlNodePtr) node, (const xmlChar *) name,
336*a1157835SDaniel Fojt (const xmlChar *) value);
337*a1157835SDaniel Fojt }
338*a1157835SDaniel Fojt
339*a1157835SDaniel Fojt return attr ? 0 : -1;
340*a1157835SDaniel Fojt }
341*a1157835SDaniel Fojt
342*a1157835SDaniel Fojt
xml_node_get_attr_value(struct xml_node_ctx * ctx,xml_node_t * node,char * name)343*a1157835SDaniel Fojt char * xml_node_get_attr_value(struct xml_node_ctx *ctx, xml_node_t *node,
344*a1157835SDaniel Fojt char *name)
345*a1157835SDaniel Fojt {
346*a1157835SDaniel Fojt return (char *) xmlGetNoNsProp((xmlNodePtr) node,
347*a1157835SDaniel Fojt (const xmlChar *) name);
348*a1157835SDaniel Fojt }
349*a1157835SDaniel Fojt
350*a1157835SDaniel Fojt
xml_node_get_attr_value_ns(struct xml_node_ctx * ctx,xml_node_t * node,const char * ns_uri,char * name)351*a1157835SDaniel Fojt char * xml_node_get_attr_value_ns(struct xml_node_ctx *ctx, xml_node_t *node,
352*a1157835SDaniel Fojt const char *ns_uri, char *name)
353*a1157835SDaniel Fojt {
354*a1157835SDaniel Fojt return (char *) xmlGetNsProp((xmlNodePtr) node, (const xmlChar *) name,
355*a1157835SDaniel Fojt (const xmlChar *) ns_uri);
356*a1157835SDaniel Fojt }
357*a1157835SDaniel Fojt
358*a1157835SDaniel Fojt
xml_node_get_attr_value_free(struct xml_node_ctx * ctx,char * val)359*a1157835SDaniel Fojt void xml_node_get_attr_value_free(struct xml_node_ctx *ctx, char *val)
360*a1157835SDaniel Fojt {
361*a1157835SDaniel Fojt if (val)
362*a1157835SDaniel Fojt xmlFree((xmlChar *) val);
363*a1157835SDaniel Fojt }
364*a1157835SDaniel Fojt
365*a1157835SDaniel Fojt
xml_node_first_child(struct xml_node_ctx * ctx,xml_node_t * parent)366*a1157835SDaniel Fojt xml_node_t * xml_node_first_child(struct xml_node_ctx *ctx,
367*a1157835SDaniel Fojt xml_node_t *parent)
368*a1157835SDaniel Fojt {
369*a1157835SDaniel Fojt return (xml_node_t *) ((xmlNodePtr) parent)->children;
370*a1157835SDaniel Fojt }
371*a1157835SDaniel Fojt
372*a1157835SDaniel Fojt
xml_node_next_sibling(struct xml_node_ctx * ctx,xml_node_t * node)373*a1157835SDaniel Fojt xml_node_t * xml_node_next_sibling(struct xml_node_ctx *ctx,
374*a1157835SDaniel Fojt xml_node_t *node)
375*a1157835SDaniel Fojt {
376*a1157835SDaniel Fojt return (xml_node_t *) ((xmlNodePtr) node)->next;
377*a1157835SDaniel Fojt }
378*a1157835SDaniel Fojt
379*a1157835SDaniel Fojt
xml_node_is_element(struct xml_node_ctx * ctx,xml_node_t * node)380*a1157835SDaniel Fojt int xml_node_is_element(struct xml_node_ctx *ctx, xml_node_t *node)
381*a1157835SDaniel Fojt {
382*a1157835SDaniel Fojt return ((xmlNodePtr) node)->type == XML_ELEMENT_NODE;
383*a1157835SDaniel Fojt }
384*a1157835SDaniel Fojt
385*a1157835SDaniel Fojt
xml_node_get_text(struct xml_node_ctx * ctx,xml_node_t * node)386*a1157835SDaniel Fojt char * xml_node_get_text(struct xml_node_ctx *ctx, xml_node_t *node)
387*a1157835SDaniel Fojt {
388*a1157835SDaniel Fojt if (xmlChildElementCount((xmlNodePtr) node) > 0)
389*a1157835SDaniel Fojt return NULL;
390*a1157835SDaniel Fojt return (char *) xmlNodeGetContent((xmlNodePtr) node);
391*a1157835SDaniel Fojt }
392*a1157835SDaniel Fojt
393*a1157835SDaniel Fojt
xml_node_get_text_free(struct xml_node_ctx * ctx,char * val)394*a1157835SDaniel Fojt void xml_node_get_text_free(struct xml_node_ctx *ctx, char *val)
395*a1157835SDaniel Fojt {
396*a1157835SDaniel Fojt if (val)
397*a1157835SDaniel Fojt xmlFree((xmlChar *) val);
398*a1157835SDaniel Fojt }
399*a1157835SDaniel Fojt
400*a1157835SDaniel Fojt
xml_node_get_base64_text(struct xml_node_ctx * ctx,xml_node_t * node,int * ret_len)401*a1157835SDaniel Fojt char * xml_node_get_base64_text(struct xml_node_ctx *ctx, xml_node_t *node,
402*a1157835SDaniel Fojt int *ret_len)
403*a1157835SDaniel Fojt {
404*a1157835SDaniel Fojt char *txt;
405*a1157835SDaniel Fojt unsigned char *ret;
406*a1157835SDaniel Fojt size_t len;
407*a1157835SDaniel Fojt
408*a1157835SDaniel Fojt txt = xml_node_get_text(ctx, node);
409*a1157835SDaniel Fojt if (txt == NULL)
410*a1157835SDaniel Fojt return NULL;
411*a1157835SDaniel Fojt
412*a1157835SDaniel Fojt ret = base64_decode((unsigned char *) txt, strlen(txt), &len);
413*a1157835SDaniel Fojt if (ret_len)
414*a1157835SDaniel Fojt *ret_len = len;
415*a1157835SDaniel Fojt xml_node_get_text_free(ctx, txt);
416*a1157835SDaniel Fojt if (ret == NULL)
417*a1157835SDaniel Fojt return NULL;
418*a1157835SDaniel Fojt txt = os_malloc(len + 1);
419*a1157835SDaniel Fojt if (txt == NULL) {
420*a1157835SDaniel Fojt os_free(ret);
421*a1157835SDaniel Fojt return NULL;
422*a1157835SDaniel Fojt }
423*a1157835SDaniel Fojt os_memcpy(txt, ret, len);
424*a1157835SDaniel Fojt txt[len] = '\0';
425*a1157835SDaniel Fojt return txt;
426*a1157835SDaniel Fojt }
427*a1157835SDaniel Fojt
428*a1157835SDaniel Fojt
xml_node_copy(struct xml_node_ctx * ctx,xml_node_t * node)429*a1157835SDaniel Fojt xml_node_t * xml_node_copy(struct xml_node_ctx *ctx, xml_node_t *node)
430*a1157835SDaniel Fojt {
431*a1157835SDaniel Fojt if (node == NULL)
432*a1157835SDaniel Fojt return NULL;
433*a1157835SDaniel Fojt return (xml_node_t *) xmlCopyNode((xmlNodePtr) node, 1);
434*a1157835SDaniel Fojt }
435*a1157835SDaniel Fojt
436*a1157835SDaniel Fojt
xml_node_init_ctx(void * upper_ctx,const void * env)437*a1157835SDaniel Fojt struct xml_node_ctx * xml_node_init_ctx(void *upper_ctx,
438*a1157835SDaniel Fojt const void *env)
439*a1157835SDaniel Fojt {
440*a1157835SDaniel Fojt struct xml_node_ctx *xctx;
441*a1157835SDaniel Fojt
442*a1157835SDaniel Fojt xctx = os_zalloc(sizeof(*xctx));
443*a1157835SDaniel Fojt if (xctx == NULL)
444*a1157835SDaniel Fojt return NULL;
445*a1157835SDaniel Fojt xctx->ctx = upper_ctx;
446*a1157835SDaniel Fojt
447*a1157835SDaniel Fojt LIBXML_TEST_VERSION
448*a1157835SDaniel Fojt
449*a1157835SDaniel Fojt return xctx;
450*a1157835SDaniel Fojt }
451*a1157835SDaniel Fojt
452*a1157835SDaniel Fojt
xml_node_deinit_ctx(struct xml_node_ctx * ctx)453*a1157835SDaniel Fojt void xml_node_deinit_ctx(struct xml_node_ctx *ctx)
454*a1157835SDaniel Fojt {
455*a1157835SDaniel Fojt xmlSchemaCleanupTypes();
456*a1157835SDaniel Fojt xmlCleanupParser();
457*a1157835SDaniel Fojt xmlMemoryDump();
458*a1157835SDaniel Fojt os_free(ctx);
459*a1157835SDaniel Fojt }
460