UPnPsdk 0.1
Universal Plug and Play +, Software Development Kit
 
Loading...
Searching...
No Matches
document.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (c) 2000-2003 Intel Corporation
4 * All rights reserved.
5 * Copyright (c) 2012 France Telecom All rights reserved.
6 * Copyright (C) 2022 GPL 3 and higher by Ingo Höft, <Ingo@Hoeft-online.de>
7 * Redistribution only with this Copyright remark. Last modified: 2026-03-31
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * - Neither name of Intel Corporation nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 ******************************************************************************/
34// Last compare with ./Pupnp source file, based on 2026-03-16, ver 1.14.30
35
40#include <ixml/ixmldebug.hpp>
41#include <ixml/ixmlparser.hpp>
42
43#include <cstring>
44
46 memset(doc, 0, sizeof(IXML_Document));
47}
48
50 if (doc) {
52 }
53}
54
63 IXML_Document* doc,
65 IXML_Node* nodeptr) {
66 if (nodeptr) {
67 nodeptr->ownerDocument = doc;
70 }
71}
72
73int ixmlDocument_importNode(IXML_Document* doc, IXML_Node* importNode, int deep,
74 IXML_Node** rtNode) {
75 unsigned short nodeType;
76 IXML_Node* newNode;
77
78 *rtNode = NULL;
79
80 if (!doc || !importNode) {
81 return IXML_INVALID_PARAMETER;
82 }
83
84 nodeType = ixmlNode_getNodeType(importNode);
85 if (nodeType == eDOCUMENT_NODE) {
86 return IXML_NOT_SUPPORTED_ERR;
87 }
88
89 newNode = ixmlNode_cloneNode(importNode, deep);
90 if (!newNode) {
91 return IXML_FAILED;
92 }
93
95 *rtNode = newNode;
96
97 return IXML_SUCCESS;
98}
99
101 IXML_Element** rtElement) {
102 int errCode = IXML_SUCCESS;
103 IXML_Element* newElement = NULL;
104
105 if (!doc || !tagName) {
106 errCode = IXML_INVALID_PARAMETER;
107 goto ErrorHandler;
108 }
109
110 newElement = (IXML_Element*)malloc(sizeof(IXML_Element));
111 if (!newElement) {
112 errCode = IXML_INSUFFICIENT_MEMORY;
113 goto ErrorHandler;
114 }
115
116 ixmlElement_init(newElement);
117 newElement->tagName = strdup(tagName);
118 if (!newElement->tagName) {
119 ixmlElement_free(newElement);
120 newElement = NULL;
121 errCode = IXML_INSUFFICIENT_MEMORY;
122 goto ErrorHandler;
123 }
124 /* set the node fields */
125 newElement->n.nodeType = eELEMENT_NODE;
126 newElement->n.nodeName = strdup(tagName);
127 if (!newElement->n.nodeName) {
128 free(newElement->tagName);
129 ixmlElement_free(newElement);
130 newElement = NULL;
131 errCode = IXML_INSUFFICIENT_MEMORY;
132 goto ErrorHandler;
133 }
134
135 newElement->n.ownerDocument = doc;
136
137ErrorHandler:
138 *rtElement = newElement;
139
140 return errCode;
141}
142
144 const DOMString tagName) {
145 IXML_Element* newElement = NULL;
146 int ret = IXML_SUCCESS;
147
148 ret = ixmlDocument_createElementEx(doc, tagName, &newElement);
149 if (ret != IXML_SUCCESS) {
150 IxmlPrintf(__FILE__, __LINE__, "ixmlDocument_createElement",
151 "Error %d\n", ret);
152 return NULL;
153 }
154 return newElement;
155}
156
158 IXML_Document* doc;
159 int errCode = IXML_SUCCESS;
160
161 doc = NULL;
162 doc = (IXML_Document*)malloc(sizeof(IXML_Document));
163 if (!doc) {
164 errCode = IXML_INSUFFICIENT_MEMORY;
165 goto ErrorHandler;
166 }
167
169
170 doc->n.nodeName = strdup((const char*)DOCUMENTNODENAME);
171 if (!doc->n.nodeName) {
173 doc = NULL;
174 errCode = IXML_INSUFFICIENT_MEMORY;
175 goto ErrorHandler;
176 }
177
178 doc->n.nodeType = eDOCUMENT_NODE;
179 doc->n.ownerDocument = doc;
180
181ErrorHandler:
182 /* doc is NULL on failure */
183 *rtDoc = doc;
184 return errCode;
185}
186
188 IXML_Document* doc = NULL;
189
191
192 return doc;
193}
194
196 IXML_Node** textNode) {
197 IXML_Node* returnNode;
198 int rc = IXML_SUCCESS;
199
200 returnNode = NULL;
201 if (!doc || !data) {
202 rc = IXML_INVALID_PARAMETER;
203 goto ErrorHandler;
204 }
205
206 returnNode = (IXML_Node*)malloc(sizeof(IXML_Node));
207 if (!returnNode) {
208 rc = IXML_INSUFFICIENT_MEMORY;
209 goto ErrorHandler;
210 }
211 /* initialize the node */
212 ixmlNode_init(returnNode);
213
214 returnNode->nodeName = strdup((const char*)TEXTNODENAME);
215 if (!returnNode->nodeName) {
216 ixmlNode_free(returnNode);
217 returnNode = NULL;
218 rc = IXML_INSUFFICIENT_MEMORY;
219 goto ErrorHandler;
220 }
221 /* add in node value */
222 if (data) {
223 returnNode->nodeValue = strdup(data);
224 if (!returnNode->nodeValue) {
225 ixmlNode_free(returnNode);
226 returnNode = NULL;
227 rc = IXML_INSUFFICIENT_MEMORY;
228 goto ErrorHandler;
229 }
230 }
231
232 returnNode->nodeType = eTEXT_NODE;
233 returnNode->ownerDocument = doc;
234
235ErrorHandler:
236 *textNode = returnNode;
237 return rc;
238}
239
241 const DOMString data) {
242 IXML_Node* returnNode = NULL;
243
244 ixmlDocument_createTextNodeEx(doc, data, &returnNode);
245
246 return returnNode;
247}
248
250 IXML_Attr** rtAttr) {
251 int errCode = IXML_SUCCESS;
252 IXML_Attr* attrNode = NULL;
253
254 if (!doc || !name) {
255 errCode = IXML_INVALID_PARAMETER;
256 goto ErrorHandler;
257 }
258 attrNode = (IXML_Attr*)malloc(sizeof(IXML_Attr));
259 if (!attrNode) {
260 errCode = IXML_INSUFFICIENT_MEMORY;
261 goto ErrorHandler;
262 }
263 ixmlAttr_init(attrNode);
264 attrNode->n.nodeType = eATTRIBUTE_NODE;
265 /* set the node fields */
266 attrNode->n.nodeName = strdup(name);
267 if (!attrNode->n.nodeName) {
268 ixmlAttr_free(attrNode);
269 attrNode = NULL;
270 errCode = IXML_INSUFFICIENT_MEMORY;
271 goto ErrorHandler;
272 }
273 attrNode->n.ownerDocument = doc;
274
275ErrorHandler:
276 *rtAttr = attrNode;
277 return errCode;
278}
279
281 const DOMString name) {
282 IXML_Attr* attrNode = NULL;
283
284 if (ixmlDocument_createAttributeEx(doc, name, &attrNode) != IXML_SUCCESS)
285 return NULL;
286
287 return attrNode;
288}
289
291 const DOMString namespaceURI,
292 const DOMString qualifiedName,
293 IXML_Attr** rtAttr) {
294 int errCode = IXML_SUCCESS;
295 IXML_Attr* attrNode = NULL;
296
297 if (!doc || !namespaceURI || !qualifiedName) {
298 errCode = IXML_INVALID_PARAMETER;
299 goto ErrorHandler;
300 }
301
302 errCode = ixmlDocument_createAttributeEx(doc, qualifiedName, &attrNode);
303 if (errCode != IXML_SUCCESS) {
304 goto ErrorHandler;
305 }
306 /* set the namespaceURI field */
307 attrNode->n.namespaceURI = strdup(namespaceURI);
308 if (!attrNode->n.namespaceURI) {
309 ixmlAttr_free(attrNode);
310 attrNode = NULL;
311 errCode = IXML_INSUFFICIENT_MEMORY;
312 goto ErrorHandler;
313 }
314 /* set the localName and prefix */
315 errCode = ixmlNode_setNodeName((IXML_Node*)attrNode, qualifiedName);
316 if (errCode != IXML_SUCCESS) {
317 ixmlAttr_free(attrNode);
318 attrNode = NULL;
319 goto ErrorHandler;
320 }
321
322ErrorHandler:
323 *rtAttr = attrNode;
324 return errCode;
325}
326
328 const DOMString namespaceURI,
329 const DOMString qualifiedName) {
330 IXML_Attr* attrNode = NULL;
331
332 ixmlDocument_createAttributeNSEx(doc, namespaceURI, qualifiedName,
333 &attrNode);
334
335 return attrNode;
336}
337
339 IXML_CDATASection** rtCD) {
340 int errCode = IXML_SUCCESS;
341 IXML_CDATASection* cDSectionNode = NULL;
342
343 if (!doc || !data) {
344 errCode = IXML_INVALID_PARAMETER;
345 goto ErrorHandler;
346 }
347
348 cDSectionNode = (IXML_CDATASection*)malloc(sizeof(IXML_CDATASection));
349 if (!cDSectionNode) {
350 errCode = IXML_INSUFFICIENT_MEMORY;
351 goto ErrorHandler;
352 }
353
354 ixmlCDATASection_init(cDSectionNode);
355 cDSectionNode->n.nodeType = eCDATA_SECTION_NODE;
356 cDSectionNode->n.nodeName = strdup((const char*)CDATANODENAME);
357 if (!cDSectionNode->n.nodeName) {
358 ixmlCDATASection_free(cDSectionNode);
359 cDSectionNode = NULL;
360 errCode = IXML_INSUFFICIENT_MEMORY;
361 goto ErrorHandler;
362 }
363
364 cDSectionNode->n.nodeValue = strdup(data);
365 if (!cDSectionNode->n.nodeValue) {
366 ixmlCDATASection_free(cDSectionNode);
367 cDSectionNode = NULL;
368 errCode = IXML_INSUFFICIENT_MEMORY;
369 goto ErrorHandler;
370 }
371
372 cDSectionNode->n.ownerDocument = doc;
373
374ErrorHandler:
375 *rtCD = cDSectionNode;
376 return errCode;
377}
378
380 const DOMString data) {
381 IXML_CDATASection* cDSectionNode = NULL;
382
383 ixmlDocument_createCDATASectionEx(doc, data, &cDSectionNode);
384
385 return cDSectionNode;
386}
387
389 const DOMString namespaceURI,
390 const DOMString qualifiedName,
391 IXML_Element** rtElement) {
392 IXML_Element* newElement = NULL;
393 int ret = IXML_SUCCESS;
394 int line = 0;
395
396 if (!doc || !namespaceURI || !qualifiedName) {
397 line = __LINE__;
398 ret = IXML_INVALID_PARAMETER;
399 goto ErrorHandler;
400 }
401
402 ret = ixmlDocument_createElementEx(doc, qualifiedName, &newElement);
403 if (ret != IXML_SUCCESS) {
404 line = __LINE__;
405 goto ErrorHandler;
406 }
407 /* set the namespaceURI field */
408 newElement->n.namespaceURI = strdup(namespaceURI);
409 if (!newElement->n.namespaceURI) {
410 line = __LINE__;
411 ixmlElement_free(newElement);
412 newElement = NULL;
413 ret = IXML_INSUFFICIENT_MEMORY;
414 goto ErrorHandler;
415 }
416 /* set the localName and prefix */
417 ret = ixmlNode_setNodeName((IXML_Node*)newElement, qualifiedName);
418 if (ret != IXML_SUCCESS) {
419 line = __LINE__;
420 ixmlElement_free(newElement);
421 newElement = NULL;
422 ret = IXML_INSUFFICIENT_MEMORY;
423 goto ErrorHandler;
424 }
425
426 newElement->n.nodeValue = NULL;
427
428ErrorHandler:
429 *rtElement = newElement;
430 if (ret != IXML_SUCCESS) {
431 IxmlPrintf(__FILE__, line, "ixmlDocument_createElementNSEx",
432 "Error %d\n", ret);
433 }
434
435 return ret;
436}
437
439 const DOMString namespaceURI,
440 const DOMString qualifiedName) {
441 IXML_Element* newElement = NULL;
442
443 ixmlDocument_createElementNSEx(doc, namespaceURI, qualifiedName,
444 &newElement);
445
446 return newElement;
447}
448
450 const DOMString tagName) {
451 IXML_NodeList* returnNodeList = NULL;
452
453 if (!doc || !tagName) {
454 return NULL;
455 }
456
457 ixmlNode_getElementsByTagName((IXML_Node*)doc, tagName, &returnNodeList);
458
459 return returnNodeList;
460}
461
463 const DOMString namespaceURI,
464 const DOMString localName) {
465 IXML_NodeList* returnNodeList = NULL;
466
467 if (!doc || !namespaceURI || !localName) {
468 return NULL;
469 }
470
471 ixmlNode_getElementsByTagNameNS((IXML_Node*)doc, namespaceURI, localName,
472 &returnNodeList);
473
474 return returnNodeList;
475}
476
478 const DOMString tagName) {
479 IXML_Element* rtElement = NULL;
480 IXML_Node* nodeptr = (IXML_Node*)doc;
481 const char* name;
482
483 if (!nodeptr || !tagName) {
484 return rtElement;
485 }
486
487 if (ixmlNode_getNodeType(nodeptr) == eELEMENT_NODE) {
488 name = ixmlNode_getNodeName(nodeptr);
489 if (!name) {
490 return rtElement;
491 }
492
493 if (strcmp(tagName, name) == 0) {
494 rtElement = (IXML_Element*)nodeptr;
495 return rtElement;
496 } else {
497 rtElement = ixmlDocument_getElementById(
498 (IXML_Document*)ixmlNode_getFirstChild(nodeptr), tagName);
499 if (!rtElement) {
500 rtElement = ixmlDocument_getElementById(
501 (IXML_Document*)ixmlNode_getNextSibling(nodeptr), tagName);
502 }
503 }
504 } else {
505 rtElement = ixmlDocument_getElementById(
506 (IXML_Document*)ixmlNode_getFirstChild(nodeptr), tagName);
507 if (!rtElement) {
508 rtElement = ixmlDocument_getElementById(
509 (IXML_Document*)ixmlNode_getNextSibling(nodeptr), tagName);
510 }
511 }
512
513 return rtElement;
514}
static void ixmlDocument_setOwnerDocument(IXML_Document *doc, IXML_Node *nodeptr)
Definition document.cpp:61
Data structure representing a CDATA section node.
Definition ixml.hpp:162
Data structure common to all types of nodes.
Definition ixml.hpp:132
Data structure representing an Attribute node.
Definition ixml.hpp:177
Data structure representing a list of nodes.
Definition ixml.hpp:193
Data structure representing an Element node.
Definition ixml.hpp:169
Data structure representing the DOM Document.
Definition ixml.hpp:155
IXML_Element * ixmlDocument_getElementById(IXML_Document *doc, const DOMString tagName)
Returns the Element whose ID matches that given id.
Definition document.cpp:477
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:322
int ixmlDocument_createTextNodeEx(IXML_Document *doc, const DOMString data, IXML_Node **textNode)
Creates a new Text node with the given data.
Definition document.cpp:195
IXML_Element * ixmlDocument_createElementNS(IXML_Document *doc, const DOMString namespaceURI, const DOMString qualifiedName)
Creates a new Element node in the given qualified name and namespace URI.
Definition document.cpp:438
IXML_Element * ixmlDocument_createElement(IXML_Document *doc, const DOMString tagName)
Creates a new Element node with the given tag name.
Definition document.cpp:143
PUPNP_Api void ixmlAttr_free(IXML_Attr *attrNode)
Frees an Attr node.
Definition attr.cpp:46
IXML_CDATASection * ixmlDocument_createCDATASection(IXML_Document *doc, const DOMString data)
Creates a new CDATASection node with given data.
Definition document.cpp:379
int ixmlDocument_createAttributeNSEx(IXML_Document *doc, const DOMString namespaceURI, const DOMString qualifiedName, IXML_Attr **rtAttr)
Creates a new Attr node with the given qualified name and namespace URI.
Definition document.cpp:290
PUPNP_Api void ixmlCDATASection_init(IXML_CDATASection *nodeptr)
Initializes a CDATASection node.
Definition node.cpp:53
int ixmlDocument_createAttributeEx(IXML_Document *doc, const DOMString name, IXML_Attr **rtAttr)
Creates a new Attr node with the given name.
Definition document.cpp:249
#define DOMString
The type of DOM strings.
Definition ixml.hpp:47
IXML_NodeList * ixmlDocument_getElementsByTagNameNS(IXML_Document *doc, const DOMString namespaceURI, const DOMString localName)
Returns a NodeList of Elements that match the given local name and namespace URI in the order they ar...
Definition document.cpp:462
PUPNP_Api void ixmlNode_free(IXML_Node *nodeptr)
Frees a Node and all Nodes in its subtree.
Definition node.cpp:124
PUPNP_Api void ixmlCDATASection_free(IXML_CDATASection *nodeptr)
Frees a CDATASection node.
Definition node.cpp:57
IXML_Attr * ixmlDocument_createAttributeNS(IXML_Document *doc, const DOMString namespaceURI, const DOMString qualifiedName)
Creates a new Attribute node with the given qualified name and namespace URI.
Definition document.cpp:327
PUPNP_Api IXML_Node * ixmlNode_cloneNode(IXML_Node *nodeptr, int deep)
Clones a Node.
Definition node.cpp:1056
IXML_Node * ixmlDocument_createTextNode(IXML_Document *doc, const DOMString data)
Creates a new Text node with the given data.
Definition document.cpp:240
PUPNP_Api IXML_Node * ixmlNode_getNextSibling(IXML_Node *nodeptr)
Retrieves the sibling Node immediately following this Node.
Definition node.cpp:371
PUPNP_Api void ixmlElement_init(IXML_Element *element)
Initializes a IXML_Element node.
Definition element.cpp:46
IXML_NodeList * ixmlDocument_getElementsByTagName(IXML_Document *doc, const DOMString tagName)
Returns a NodeList of all Elements that match the given tag name in the order in which they were enco...
Definition document.cpp:449
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:182
void ixmlDocument_init(IXML_Document *doc)
Initializes a Document node.
Definition document.cpp:45
#define CDATANODENAME
The type of the DOM node.
Definition ixml.hpp:116
int ixmlDocument_createCDATASectionEx(IXML_Document *doc, const DOMString data, IXML_CDATASection **rtCD)
Creates a new CDATASection node with given data.
Definition document.cpp:338
#define TEXTNODENAME
The type of the DOM node.
Definition ixml.hpp:115
int ixmlDocument_createElementEx(IXML_Document *doc, const DOMString tagName, IXML_Element **rtElement)
Creates a new Element node with the given tag name.
Definition document.cpp:100
int ixmlDocument_importNode(IXML_Document *doc, IXML_Node *importNode, int deep, IXML_Node **rtNode)
Imports a Node from another Document into this Document.
Definition document.cpp:73
PUPNP_Api void ixmlElement_free(IXML_Element *element)
Frees the given Element and any subtree of the Element.
Definition element.cpp:646
IXML_Document * ixmlDocument_createDocument(void)
Creates a new empty Document node.
Definition document.cpp:187
#define DOCUMENTNODENAME
The type of the DOM node.
Definition ixml.hpp:114
IXML_Attr * ixmlDocument_createAttribute(IXML_Document *doc, const DOMString name)
Creates a new Attr node with the given name.
Definition document.cpp:280
PUPNP_Api IXML_Node * ixmlNode_getFirstChild(IXML_Node *nodeptr)
Retrieves the first child Node of a Node.
Definition node.cpp:338
int ixmlDocument_createDocumentEx(IXML_Document **rtDoc)
Creates a new empty Document node.
Definition document.cpp:157
int ixmlDocument_createElementNSEx(IXML_Document *doc, const DOMString namespaceURI, const DOMString qualifiedName, IXML_Element **rtElement)
Creates a new Element node in the given qualified name and namespace URI.
Definition document.cpp:388
void ixmlDocument_free(IXML_Document *doc)
Frees a Document object and all Nodes associated with it.
Definition document.cpp:49
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:18
void ixmlNode_getElementsByTagName(IXML_Node *n, const char *tagname, IXML_NodeList **list)
Returns a nodeList of all descendant Elements with a given tagName, in the order in which they are en...
Definition node.cpp:1184
void ixmlNode_init(IXML_Node *nodeptr)
Intializes a node.
Definition node.cpp:47
int ixmlNode_setNodeName(IXML_Node *node, const DOMString qualifiedName)
Definition node.cpp:1257
void ixmlAttr_init(IXML_Attr *attrNode)
ixmlAttr_init
Definition attr.cpp:40
void ixmlNode_getElementsByTagNameNS(IXML_Node *n, const char *namespaceURI, const char *localName, IXML_NodeList **list)
Returns a nodeList of all the descendant Elements with a given local name and namespace URI in the or...
Definition node.cpp:1234