UPnPsdk 0.1
Universal Plug and Play +, Software Development Kit
 
Loading...
Searching...
No Matches
ixml.cpp
Go to the documentation of this file.
1/**************************************************************************
2 *
3 * Copyright (c) 2000-2003 Intel Corporation
4 * All rights reserved.
5 * Copyright (C) 2022 GPL 3 and higher by Ingo Höft, <Ingo@Hoeft-online.de>
6 * Redistribution only with this Copyright remark. Last modified: 2025-05-29
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * - Neither name of Intel Corporation nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 **************************************************************************/
37#include <ixml/ixmldebug.hpp>
38#include <ixml/ixmlparser.hpp>
39
40#include <cstring>
41
46static void copy_with_escape(
48 ixml_membuf* buf,
50 const char* p) {
51 size_t i;
52 size_t plen;
53
54 if (p == NULL)
55 return;
56 plen = strlen(p);
57 for (i = (size_t)0; i < plen; ++i) {
58 switch (p[i]) {
59 case '<':
60 ixml_membuf_append_str(buf, "&lt;");
61 break;
62 case '>':
63 ixml_membuf_append_str(buf, "&gt;");
64 break;
65 case '&':
66 ixml_membuf_append_str(buf, "&amp;");
67 break;
68 case '\'':
69 ixml_membuf_append_str(buf, "&apos;");
70 break;
71 case '\"':
72 ixml_membuf_append_str(buf, "&quot;");
73 break;
74 default:
75 ixml_membuf_append(buf, &p[i]);
76 break;
77 }
78 }
79}
80
87 IXML_Node* nodeptr,
89 ixml_membuf* buf) {
90 const char* nodeName = NULL;
91 const char* nodeValue = NULL;
92 IXML_Node *child = NULL, *sibling = NULL;
93
94 if (nodeptr != NULL) {
95 nodeName = (const char*)ixmlNode_getNodeName(nodeptr);
96 nodeValue = ixmlNode_getNodeValue(nodeptr);
97
98 switch (ixmlNode_getNodeType(nodeptr)) {
99 case eTEXT_NODE:
100 copy_with_escape(buf, nodeValue);
101 break;
102
103 case eCDATA_SECTION_NODE:
104 ixml_membuf_append_str(buf, "<![CDATA[");
105 ixml_membuf_append_str(buf, nodeValue);
106 ixml_membuf_append_str(buf, "]]>");
107 break;
108
109 case ePROCESSING_INSTRUCTION_NODE:
110 ixml_membuf_append_str(buf, "<?");
111 ixml_membuf_append_str(buf, nodeName);
112 ixml_membuf_append_str(buf, " ");
113 copy_with_escape(buf, nodeValue);
114 ixml_membuf_append_str(buf, "?>\n");
115 break;
116
117 case eDOCUMENT_NODE:
119 break;
120
121 case eATTRIBUTE_NODE:
122 ixml_membuf_append_str(buf, nodeName);
123 ixml_membuf_append_str(buf, "=\"");
124 copy_with_escape(buf, nodeValue);
125 ixml_membuf_append_str(buf, "\"");
126 if (nodeptr->nextSibling != NULL) {
127 ixml_membuf_append_str(buf, " ");
128 ixmlPrintDomTreeRecursive(nodeptr->nextSibling, buf);
129 }
130 break;
131
132 case eELEMENT_NODE:
133 ixml_membuf_append_str(buf, "<");
134 ixml_membuf_append_str(buf, nodeName);
135 if (nodeptr->firstAttr != NULL) {
136 ixml_membuf_append_str(buf, " ");
137 ixmlPrintDomTreeRecursive(nodeptr->firstAttr, buf);
138 }
139 child = ixmlNode_getFirstChild(nodeptr);
140 if (child != NULL && ixmlNode_getNodeType(child) == eELEMENT_NODE) {
141 ixml_membuf_append_str(buf, ">\r\n");
142 } else {
143 ixml_membuf_append_str(buf, ">");
144 }
145 /* output the children */
147
148 /* Done with children. Output the end tag. */
149 ixml_membuf_append_str(buf, "</");
150 ixml_membuf_append_str(buf, nodeName);
151
152 sibling = ixmlNode_getNextSibling(nodeptr);
153 if (sibling != NULL &&
154 ixmlNode_getNodeType(sibling) == eTEXT_NODE) {
155 ixml_membuf_append_str(buf, ">");
156 } else {
157 ixml_membuf_append_str(buf, ">\r\n");
158 }
160 break;
161
162 default:
163 IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTreeRecursive",
164 "Warning, unknown node type %d\n",
165 (int)ixmlNode_getNodeType(nodeptr));
166 break;
167 }
168 }
169}
170
179 IXML_Node* nodeptr,
181 ixml_membuf* buf) {
182 const char* nodeName = NULL;
183 const char* nodeValue = NULL;
184 IXML_Node* child = NULL;
185
186 if (nodeptr == NULL || buf == NULL) {
187 return;
188 }
189
190 nodeName = (const char*)ixmlNode_getNodeName(nodeptr);
191 nodeValue = ixmlNode_getNodeValue(nodeptr);
192 switch (ixmlNode_getNodeType(nodeptr)) {
193 case eTEXT_NODE:
194 case eCDATA_SECTION_NODE:
195 case ePROCESSING_INSTRUCTION_NODE:
196 case eDOCUMENT_NODE:
197 ixmlPrintDomTreeRecursive(nodeptr, buf);
198 break;
199
200 case eATTRIBUTE_NODE:
201 ixml_membuf_append_str(buf, nodeName);
202 ixml_membuf_append_str(buf, "=\"");
203 copy_with_escape(buf, nodeValue);
204 ixml_membuf_append_str(buf, "\"");
205 break;
206
207 case eELEMENT_NODE:
208 ixml_membuf_append_str(buf, "<");
209 ixml_membuf_append_str(buf, nodeName);
210 if (nodeptr->firstAttr != NULL) {
211 ixml_membuf_append_str(buf, " ");
212 ixmlPrintDomTreeRecursive(nodeptr->firstAttr, buf);
213 }
214 child = ixmlNode_getFirstChild(nodeptr);
215 if (child != NULL && ixmlNode_getNodeType(child) == eELEMENT_NODE) {
216 ixml_membuf_append_str(buf, ">\r\n");
217 } else {
218 ixml_membuf_append_str(buf, ">");
219 }
220
221 /* output the children */
223
224 /* Done with children. Output the end tag. */
225 ixml_membuf_append_str(buf, "</");
226 ixml_membuf_append_str(buf, nodeName);
227 ixml_membuf_append_str(buf, ">\r\n");
228 break;
229
230 default:
231 IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTree",
232 "Warning, unknown node type %d\n",
233 (int)ixmlNode_getNodeType(nodeptr));
234 break;
235 }
236}
237
246 IXML_Node* nodeptr,
248 ixml_membuf* buf) {
249 const char* nodeName = NULL;
250 const char* nodeValue = NULL;
251 IXML_Node* child = NULL;
252
253 if (nodeptr == NULL || buf == NULL) {
254 return;
255 }
256
257 nodeName = (const char*)ixmlNode_getNodeName(nodeptr);
258 nodeValue = ixmlNode_getNodeValue(nodeptr);
259
260 switch (ixmlNode_getNodeType(nodeptr)) {
261 case eTEXT_NODE:
262 case eCDATA_SECTION_NODE:
263 case ePROCESSING_INSTRUCTION_NODE:
264 case eDOCUMENT_NODE:
265 ixmlPrintDomTreeRecursive(nodeptr, buf);
266 break;
267
268 case eATTRIBUTE_NODE:
269 ixml_membuf_append_str(buf, nodeName);
270 ixml_membuf_append_str(buf, "=\"");
271 copy_with_escape(buf, nodeValue);
272 ixml_membuf_append_str(buf, "\"");
273 break;
274
275 case eELEMENT_NODE:
276 ixml_membuf_append_str(buf, "<");
277 ixml_membuf_append_str(buf, nodeName);
278 if (nodeptr->firstAttr != NULL) {
279 ixml_membuf_append_str(buf, " ");
280 ixmlPrintDomTreeRecursive(nodeptr->firstAttr, buf);
281 }
282 child = ixmlNode_getFirstChild(nodeptr);
283 if (child != NULL && ixmlNode_getNodeType(child) == eELEMENT_NODE) {
284 ixml_membuf_append_str(buf, ">");
285 } else {
286 ixml_membuf_append_str(buf, ">");
287 }
288
289 /* output the children */
291
292 /* Done with children. Output the end tag. */
293 ixml_membuf_append_str(buf, "</");
294 ixml_membuf_append_str(buf, nodeName);
295 ixml_membuf_append_str(buf, ">");
296 break;
297
298 default:
299 IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTreeRecursive",
300 "Warning, unknown node type %d\n",
301 (int)ixmlNode_getNodeType(nodeptr));
302 break;
303 }
304}
305
306int ixmlLoadDocumentEx(const char* xmlFile, IXML_Document** doc) {
307 if (xmlFile == NULL || doc == NULL) {
308 return IXML_INVALID_PARAMETER;
309 }
310
311 return Parser_LoadDocument(doc, xmlFile, 1);
312}
313
314IXML_Document* ixmlLoadDocument(const char* xmlFile) {
315 IXML_Document* doc = NULL;
316
317 ixmlLoadDocumentEx(xmlFile, &doc);
318
319 return doc;
320}
321
323 IXML_Node* rootNode = (IXML_Node*)doc;
324 ixml_membuf memBuf;
325 ixml_membuf* buf = &memBuf;
326
327 if (rootNode == NULL) {
328 return NULL;
329 }
330
331 ixml_membuf_init(buf);
332 ixml_membuf_append_str(buf, "<?xml version=\"1.0\"?>\r\n");
333 ixmlPrintDomTree(rootNode, buf);
334
335 return buf->buf;
336}
337
339 ixml_membuf memBuf;
340 ixml_membuf* buf = &memBuf;
341
342 if (node == NULL) {
343 return NULL;
344 }
345
346 ixml_membuf_init(buf);
347 ixmlPrintDomTree(node, buf);
348
349 return buf->buf;
350}
351
353 IXML_Node* rootNode = (IXML_Node*)doc;
354 ixml_membuf memBuf;
355 ixml_membuf* buf = &memBuf;
356
357 if (rootNode == NULL) {
358 return NULL;
359 }
360
361 ixml_membuf_init(buf);
362 ixml_membuf_append_str(buf, "<?xml version=\"1.0\"?>\r\n");
363 ixmlDomTreetoString(rootNode, buf);
364
365 return buf->buf;
366}
367
369 ixml_membuf memBuf;
370 ixml_membuf* buf = &memBuf;
371
372 if (node == NULL) {
373 return NULL;
374 }
375
376 ixml_membuf_init(buf);
377 ixmlDomTreetoString(node, buf);
378
379 return buf->buf;
380}
381
382void ixmlRelaxParser(char errorChar) { Parser_setErrorChar(errorChar); }
383
384#ifdef IXML_HAVE_SCRIPTSUPPORT
385void ixmlSetBeforeFree(IXML_BeforeFreeNode_t hndlr) {
386 Parser_setBeforeFree(hndlr);
387}
388#endif
389
390int ixmlParseBufferEx(const char* buffer, IXML_Document** retDoc) {
391 if (buffer == NULL || retDoc == NULL) {
392 return IXML_INVALID_PARAMETER;
393 }
394
395 if (buffer[0] == '\0') {
396 return IXML_INVALID_PARAMETER;
397 }
398
399 return Parser_LoadDocument(retDoc, buffer, 0);
400}
401
402IXML_Document* ixmlParseBuffer(const char* buffer) {
403 IXML_Document* doc = NULL;
404
405 ixmlParseBufferEx(buffer, &doc);
406
407 return doc;
408}
409
411 if (src == NULL) {
412 return NULL;
413 }
414
415 return strdup(src);
416}
417
419 if (buf != NULL) {
420 free(buf);
421 }
422}
Data structure common to all types of nodes.
Definition ixml.hpp:132
Data structure representing the DOM Document.
Definition ixml.hpp:155
DOMString ixmlPrintNode(IXML_Node *node)
Renders a Node and all sub-elements into an XML text representation.
Definition ixml.cpp:338
PUPNP_Api unsigned short ixmlNode_getNodeType(IXML_Node *nodeptr)
Retrieves the type of a Node. Note that not all possible return values are actually implemented.
Definition node.cpp:326
DOMString ixmlNodetoString(IXML_Node *node)
Renders a Node and all sub-elements into an XML text representation. The caller is required to free t...
Definition ixml.cpp:368
int ixmlParseBufferEx(const char *buffer, IXML_Document **retDoc)
Parses an XML text buffer converting it into an IXML DOM representation.
Definition ixml.cpp:390
#define DOMString
The type of DOM strings.
Definition ixml.hpp:47
PUPNP_Api IXML_Node * ixmlNode_getNextSibling(IXML_Node *nodeptr)
Retrieves the sibling Node immediately following this Node.
Definition node.cpp:375
void ixmlRelaxParser(char errorChar)
Makes the XML parser more tolerant to malformed text.
Definition ixml.cpp:382
PUPNP_Api const DOMString ixmlNode_getNodeValue(IXML_Node *nodeptr)
Returns the value of the Node as a string.
Definition node.cpp:296
PUPNP_Api const DOMString ixmlNode_getNodeName(IXML_Node *nodeptr)
Returns the name of the Node, depending on what type of Node it is, in a read-only string.
Definition node.cpp:179
DOMString ixmlPrintDocument(IXML_Document *doc)
Renders a Node and all sub-elements into an XML document representation.
Definition ixml.cpp:322
DOMString ixmlDocumenttoString(IXML_Document *doc)
Renders a Node and all sub-elements into an XML document representation.
Definition ixml.cpp:352
int ixmlLoadDocumentEx(const char *xmlFile, IXML_Document **doc)
Parses an XML text file converting it into an IXML DOM representation.
Definition ixml.cpp:306
IXML_Document * ixmlLoadDocument(const char *xmlFile)
Parses an XML text file converting it into an IXML DOM representation.
Definition ixml.cpp:314
void ixmlFreeDOMString(DOMString buf)
Frees a DOMString.
Definition ixml.cpp:418
DOMString ixmlCloneDOMString(const DOMString src)
Clones an existing DOMString.
Definition ixml.cpp:410
PUPNP_Api IXML_Node * ixmlNode_getFirstChild(IXML_Node *nodeptr)
Retrieves the first child Node of a Node.
Definition node.cpp:342
IXML_Document * ixmlParseBuffer(const char *buffer)
Parses an XML text buffer converting it into an IXML DOM representation.
Definition ixml.cpp:402
static void ixmlPrintDomTree(IXML_Node *nodeptr, ixml_membuf *buf)
Print a DOM tree.
Definition ixml.cpp:177
static void ixmlPrintDomTreeRecursive(IXML_Node *nodeptr, ixml_membuf *buf)
Recursive function to print all the node in a tree. Internal to parser only.
Definition ixml.cpp:85
static void ixmlDomTreetoString(IXML_Node *nodeptr, ixml_membuf *buf)
Converts a DOM tree into a text string.
Definition ixml.cpp:244
static void copy_with_escape(ixml_membuf *buf, const char *p)
Appends a string to a buffer, substituting some characters by escape sequences.
Definition ixml.cpp:46
Auxiliar routines to aid debugging.
void IxmlPrintf(const char *DbgFileName, int DbgLineNo, const char *FunctionName, const char *FmtStr,...)
Prints the debug statement either on the standard output or log file along with the information from ...
Definition ixmldebug.cpp:13
void ixml_membuf_init(ixml_membuf *m)
ixml_membuf initialization routine.
int ixml_membuf_append(ixml_membuf *m, const void *buf)
Appends one byte to the designated ixml_membuffer.
int ixml_membuf_append_str(ixml_membuf *m, const char *c_str)
Appends the contents of a NULL terminated string to the designated ixml_membuf.
The ixml_membuf type.
int Parser_LoadDocument(IXML_Document **retDoc, const char *xmlFile, int file)
Parses a xml file and return the DOM tree.
void Parser_setErrorChar(char c)
Sets the error character.