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