1 /*******************************************************************************
2 *
3 * Copyright (c) 2000-2003 Intel Corporation
4 * All rights reserved.
5 * Copyright (c) 2012 France Telecom All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 * - Neither name of Intel Corporation nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 ******************************************************************************/
32
33
34 /*!
35 * \file
36 */
37
38
39 #include "ixmlparser.h"
40
41
42 #include <assert.h>
43 #include <stdlib.h> /* for free(), malloc() */
44 #include <string.h>
45
46
ixmlNode_init(IXML_Node * nodeptr)47 void ixmlNode_init(IXML_Node *nodeptr)
48 {
49 assert(nodeptr != NULL);
50
51 memset(nodeptr, 0, sizeof (IXML_Node));
52 }
53
54
ixmlCDATASection_init(IXML_CDATASection * nodeptr)55 void ixmlCDATASection_init(IXML_CDATASection *nodeptr)
56 {
57 memset(nodeptr, 0, sizeof (IXML_CDATASection));
58 }
59
60
ixmlCDATASection_free(IXML_CDATASection * nodeptr)61 void ixmlCDATASection_free(IXML_CDATASection *nodeptr)
62 {
63 if (nodeptr != NULL) {
64 ixmlNode_free((IXML_Node *)nodeptr);
65 }
66 }
67
68
69 /*!
70 * \brief Frees a node content.
71 */
ixmlNode_freeSingleNode(IXML_Node * nodeptr)72 static void ixmlNode_freeSingleNode(
73 /*! [in] The node to free. */
74 IXML_Node *nodeptr)
75 {
76 IXML_Element *element = NULL;
77
78 if (nodeptr != NULL) {
79 if (nodeptr->nodeName != NULL) {
80 free(nodeptr->nodeName);
81 }
82 if (nodeptr->nodeValue != NULL) {
83 free(nodeptr->nodeValue);
84 }
85 if (nodeptr->namespaceURI != NULL) {
86 free(nodeptr->namespaceURI);
87 }
88 if (nodeptr->prefix != NULL) {
89 free(nodeptr->prefix);
90 }
91 if (nodeptr->localName != NULL) {
92 free(nodeptr->localName);
93 }
94 switch (nodeptr->nodeType ) {
95 case eELEMENT_NODE:
96 element = (IXML_Element *)nodeptr;
97 free(element->tagName);
98 break;
99 default:
100 break;
101 }
102 free(nodeptr);
103 }
104 }
105
106 #if 0
107 /*
108 * Old implementation of ixmlNode_free(). Due to its recursive nature, it was
109 * succeptible to attacks overflowing the stack.
110 *
111 * void ixmlNode_free(IXML_Node *nodeptr)
112 */
113 void ixmlNode_recursive_free(IXML_Node *nodeptr)
114 {
115 if (nodeptr != NULL) {
116 #ifdef IXML_HAVE_SCRIPTSUPPORT
117 IXML_BeforeFreeNode_t hndlr = Parser_getBeforeFree();
118 if (hndlr != NULL) hndlr(nodeptr);
119 #endif
120 ixmlNode_free(nodeptr->firstChild);
121 ixmlNode_free(nodeptr->nextSibling);
122 ixmlNode_free(nodeptr->firstAttr);
123 ixmlNode_freeSingleNode(nodeptr);
124 }
125 }
126 #endif
127
128 /*
129 * void ixmlNode_non_recursive_free(IXML_Node *nodeptr)
130 */
ixmlNode_free(IXML_Node * nodeptr)131 void ixmlNode_free(IXML_Node *nodeptr)
132 {
133 IXML_Node *curr_child;
134 IXML_Node *prev_child;
135 IXML_Node *next_child;
136 IXML_Node *curr_attr;
137 IXML_Node *next_attr;
138
139 if (nodeptr) {
140 #ifdef IXML_HAVE_SCRIPTSUPPORT
141 IXML_BeforeFreeNode_t hndlr = Parser_getBeforeFree();
142 #endif
143 prev_child = nodeptr;
144 next_child = nodeptr->firstChild;
145 do {
146 curr_child = next_child;
147 do {
148 while (curr_child) {
149 prev_child = curr_child;
150 curr_child = curr_child->firstChild;
151 }
152 curr_child = prev_child;
153 while (curr_child) {
154 prev_child = curr_child;
155 curr_child = curr_child->nextSibling;
156 }
157 curr_child = prev_child;
158 next_child = curr_child->firstChild;
159 } while (next_child);
160 curr_child = prev_child;
161 /* current is now the last sibling of the last child. */
162 /* Delete the attribute nodes of this child */
163 /* Attribute nodes only have siblings. */
164 curr_attr = curr_child->firstAttr;
165 while (curr_attr) {
166 next_attr = curr_attr->nextSibling;
167 ixmlNode_freeSingleNode(curr_attr);
168 curr_attr = next_attr;
169 }
170 curr_child->firstAttr = 0;
171 /* Return */
172 if (curr_child != nodeptr) {
173 if (curr_child->prevSibling) {
174 next_child = curr_child->prevSibling;
175 next_child->nextSibling = 0;
176 } else {
177 next_child = curr_child->parentNode;
178 next_child->firstChild = 0;
179 }
180 }
181 #ifdef IXML_HAVE_SCRIPTSUPPORT
182 if (hndlr) {
183 hndlr(curr_child);
184 }
185 #endif
186 ixmlNode_freeSingleNode(curr_child);
187 } while (curr_child != nodeptr);
188 }
189 }
190
191
ixmlNode_getNodeName(IXML_Node * nodeptr)192 const DOMString ixmlNode_getNodeName(IXML_Node *nodeptr)
193 {
194 if(nodeptr != NULL) {
195 return nodeptr->nodeName;
196 }
197
198 return NULL;
199 }
200
201
ixmlNode_getLocalName(IXML_Node * nodeptr)202 const DOMString ixmlNode_getLocalName(IXML_Node *nodeptr)
203 {
204 if (nodeptr != NULL) {
205 return nodeptr->localName;
206 }
207
208 return NULL;
209 }
210
211
212 /*!
213 * \brief Sets the namespace URI of the node.
214 */
ixmlNode_setNamespaceURI(IXML_Node * nodeptr,const char * namespaceURI)215 static int ixmlNode_setNamespaceURI(
216 /*! [in] The \b Node on which to operate. */
217 IXML_Node *nodeptr,
218 /*! [in] The name space string to set. */
219 const char *namespaceURI)
220 {
221 if (nodeptr == NULL) {
222 return IXML_INVALID_PARAMETER;
223 }
224
225 if (nodeptr->namespaceURI != NULL) {
226 free(nodeptr->namespaceURI);
227 nodeptr->namespaceURI = NULL;
228 }
229
230 if (namespaceURI != NULL) {
231 nodeptr->namespaceURI = strdup(namespaceURI);
232 if (nodeptr->namespaceURI == NULL) {
233 return IXML_INSUFFICIENT_MEMORY;
234 }
235 }
236
237 return IXML_SUCCESS;
238 }
239
240
241 /*
242 * \brief Set the prefix of the node.
243 */
ixmlNode_setPrefix(IXML_Node * nodeptr,const char * prefix)244 static int ixmlNode_setPrefix(
245 /*! [in] The \b Node on which to operate. */
246 IXML_Node *nodeptr,
247 /*! [in] The prefix string to set. */
248 const char *prefix)
249 {
250 if (nodeptr == NULL) {
251 return IXML_INVALID_PARAMETER;
252 }
253
254 if (nodeptr->prefix != NULL) {
255 free(nodeptr->prefix);
256 nodeptr->prefix = NULL;
257 }
258
259 if (prefix != NULL) {
260 nodeptr->prefix = strdup(prefix);
261 if(nodeptr->prefix == NULL) {
262 return IXML_INSUFFICIENT_MEMORY;
263 }
264 }
265
266 return IXML_SUCCESS;
267 }
268
269
270 /*!
271 * \brief Set the localName of the node.
272 *
273 * \return IXML_SUCCESS or failure.
274 */
ixmlNode_setLocalName(IXML_Node * nodeptr,const char * localName)275 static int ixmlNode_setLocalName(
276 /*! [in] The pointer to the node. */
277 IXML_Node *nodeptr,
278 /*! [in] The local name to set. */
279 const char *localName)
280 {
281 assert(nodeptr != NULL);
282
283 if (nodeptr->localName != NULL) {
284 free(nodeptr->localName);
285 nodeptr->localName = NULL;
286 }
287
288 if (localName != NULL) {
289 nodeptr->localName = strdup(localName);
290 if (nodeptr->localName == NULL) {
291 return IXML_INSUFFICIENT_MEMORY;
292 }
293 }
294
295 return IXML_SUCCESS;
296 }
297
298
ixmlNode_getNamespaceURI(IXML_Node * nodeptr)299 const DOMString ixmlNode_getNamespaceURI(IXML_Node *nodeptr)
300 {
301 DOMString retNamespaceURI = NULL;
302
303 if (nodeptr != NULL) {
304 retNamespaceURI = nodeptr->namespaceURI;
305 }
306
307 return retNamespaceURI;
308 }
309
310
ixmlNode_getPrefix(IXML_Node * nodeptr)311 const DOMString ixmlNode_getPrefix(IXML_Node *nodeptr)
312 {
313 const DOMString prefix = NULL;
314
315 if (nodeptr != NULL) {
316 prefix = nodeptr->prefix;
317 }
318
319 return prefix;
320 }
321
322
ixmlNode_getNodeValue(IXML_Node * nodeptr)323 const DOMString ixmlNode_getNodeValue(IXML_Node *nodeptr)
324 {
325 if ( nodeptr != NULL ) {
326 return nodeptr->nodeValue;
327 }
328
329 return NULL;
330 }
331
332
ixmlNode_setNodeValue(IXML_Node * nodeptr,const char * newNodeValue)333 int ixmlNode_setNodeValue(IXML_Node *nodeptr, const char *newNodeValue)
334 {
335 int rc = IXML_SUCCESS;
336
337 if (nodeptr == NULL) {
338 return IXML_INVALID_PARAMETER;
339 }
340
341 if (nodeptr->nodeValue != NULL) {
342 free(nodeptr->nodeValue);
343 nodeptr->nodeValue = NULL;
344 }
345
346 if (newNodeValue != NULL) {
347 nodeptr->nodeValue = strdup(newNodeValue);
348 if (nodeptr->nodeValue == NULL) {
349 return IXML_INSUFFICIENT_MEMORY;
350 }
351 }
352
353 return rc;
354 }
355
356
ixmlNode_getNodeType(IXML_Node * nodeptr)357 unsigned short ixmlNode_getNodeType(IXML_Node *nodeptr)
358 {
359 if (nodeptr != NULL) {
360 return nodeptr->nodeType;
361 } else {
362 return (unsigned short)eINVALID_NODE;
363 }
364 }
365
366
ixmlNode_getParentNode(IXML_Node * nodeptr)367 IXML_Node *ixmlNode_getParentNode(IXML_Node *nodeptr)
368 {
369 if (nodeptr != NULL) {
370 return nodeptr->parentNode;
371 } else {
372 return NULL;
373 }
374 }
375
376
ixmlNode_getFirstChild(IXML_Node * nodeptr)377 IXML_Node *ixmlNode_getFirstChild(IXML_Node *nodeptr)
378 {
379 if (nodeptr != NULL) {
380 return nodeptr->firstChild;
381 } else {
382 return NULL;
383 }
384 }
385
386
ixmlNode_getLastChild(IXML_Node * nodeptr)387 IXML_Node *ixmlNode_getLastChild(IXML_Node *nodeptr)
388 {
389 IXML_Node *prev;
390 IXML_Node *next;
391
392 if (nodeptr != NULL) {
393 prev = nodeptr;
394 next = nodeptr->firstChild;
395 while (next != NULL) {
396 prev = next;
397 next = next->nextSibling;
398 }
399 return prev;
400 } else {
401 return NULL;
402 }
403 }
404
405
ixmlNode_getPreviousSibling(IXML_Node * nodeptr)406 IXML_Node *ixmlNode_getPreviousSibling(IXML_Node *nodeptr)
407 {
408 if (nodeptr != NULL) {
409 return nodeptr->prevSibling;
410 } else {
411 return NULL;
412 }
413 }
414
415
ixmlNode_getNextSibling(IXML_Node * nodeptr)416 IXML_Node *ixmlNode_getNextSibling(IXML_Node *nodeptr)
417 {
418 if (nodeptr != NULL) {
419 return nodeptr->nextSibling;
420 } else {
421 return NULL;
422 }
423 }
424
425
ixmlNode_getOwnerDocument(IXML_Node * nodeptr)426 IXML_Document *ixmlNode_getOwnerDocument(IXML_Node *nodeptr)
427 {
428 if (nodeptr != NULL) {
429 return (IXML_Document *)nodeptr->ownerDocument;
430 } else {
431 return NULL;
432 }
433 }
434
435 /*!
436 * \brief Check if ancestorNode is ancestor of toFind.
437 *
438 * \return 1 or 0.
439 */
ixmlNode_isAncestor(IXML_Node * ancestorNode,IXML_Node * toFind)440 static int ixmlNode_isAncestor(
441 /*! [in] The candidate to ancestor \b Node. */
442 IXML_Node *ancestorNode,
443 /*! [in] The \b Node to check for an ancestor. */
444 IXML_Node *toFind)
445 {
446 int found = 0;
447
448 if (ancestorNode != NULL && toFind != NULL) {
449 if (toFind->parentNode == ancestorNode) {
450 return 1;
451 } else {
452 found = ixmlNode_isAncestor(
453 ancestorNode->firstChild, toFind);
454 if (found == 0) {
455 found = ixmlNode_isAncestor(
456 ancestorNode->nextSibling, toFind);
457 }
458 }
459 }
460
461 return found;
462 }
463
464 /*!
465 * \brief Check whether toFind is a children of nodeptr.
466 *
467 * \return 1 or 0.
468 */
ixmlNode_isParent(IXML_Node * nodeptr,IXML_Node * toFind)469 static int ixmlNode_isParent(
470 /*! [in] The candidate to parent \b Node. */
471 IXML_Node *nodeptr,
472 /*! [in] The \b Node to check for his parent. */
473 IXML_Node *toFind)
474 {
475 int found = 0;
476
477 assert(nodeptr != NULL && toFind != NULL);
478
479 if (nodeptr != NULL && toFind != NULL)
480 found = toFind->parentNode == nodeptr;
481
482 return found;
483 }
484
485 /*!
486 * \brief Check to see whether nodeptr allows children of type newChild.
487 *
488 * \return
489 * \li 1, if nodeptr can have newChild as children.
490 * \li 0, if nodeptr cannot have newChild as children.
491 */
ixmlNode_allowChildren(IXML_Node * nodeptr,IXML_Node * newChild)492 static int ixmlNode_allowChildren(
493 /*! [in] The \b Node to check. */
494 IXML_Node *nodeptr,
495 /*! [in] The child \b Node to check. */
496 IXML_Node *newChild)
497 {
498 assert(nodeptr != NULL && newChild != NULL);
499
500 switch (nodeptr->nodeType) {
501 case eATTRIBUTE_NODE:
502 case eTEXT_NODE:
503 case eCDATA_SECTION_NODE:
504 return 0;
505
506 case eELEMENT_NODE:
507 switch (newChild->nodeType) {
508 case eATTRIBUTE_NODE:
509 case eDOCUMENT_NODE:
510 return 0;
511 default:
512 break;
513 }
514 break;
515
516 case eDOCUMENT_NODE:
517 switch (newChild->nodeType) {
518 case eELEMENT_NODE:
519 break;
520 default:
521 return 0;
522 }
523
524 default:
525 break;
526 }
527
528 return 1;
529 }
530
531
532 /*!
533 * \brief Compare two nodes to see whether they are the same node.
534 * Parent, sibling and children node are ignored.
535 *
536 * \return
537 * \li 1, the two nodes are the same.
538 * \li 0, the two nodes are not the same.
539 */
ixmlNode_compare(IXML_Node * srcNode,IXML_Node * destNode)540 int ixmlNode_compare(
541 /*! [in] The first \b Node. */
542 IXML_Node *srcNode,
543 /*! [in] The second \b Node. */
544 IXML_Node *destNode)
545 {
546 assert(srcNode != NULL && destNode != NULL);
547
548 return
549 srcNode == destNode ||
550 (strcmp(srcNode->nodeName, destNode->nodeName) == 0 &&
551 strcmp(srcNode->nodeValue, destNode->nodeValue) == 0 &&
552 srcNode->nodeType == destNode->nodeType &&
553 strcmp(srcNode->namespaceURI, destNode->namespaceURI) == 0 &&
554 strcmp(srcNode->prefix, destNode->prefix) == 0 &&
555 strcmp(srcNode->localName, destNode->localName) == 0);
556 }
557
558
ixmlNode_insertBefore(IXML_Node * nodeptr,IXML_Node * newChild,IXML_Node * refChild)559 int ixmlNode_insertBefore(
560 IXML_Node *nodeptr,
561 IXML_Node *newChild,
562 IXML_Node *refChild)
563 {
564 int ret = IXML_SUCCESS;
565
566 if (nodeptr == NULL || newChild == NULL) {
567 return IXML_INVALID_PARAMETER;
568 }
569 /* whether nodeptr allow children of the type of newChild */
570 if (ixmlNode_allowChildren(nodeptr, newChild) == 0) {
571 return IXML_HIERARCHY_REQUEST_ERR;
572 }
573 /* or if newChild is one of nodeptr's ancestors */
574 if (ixmlNode_isAncestor(newChild, nodeptr)) {
575 return IXML_HIERARCHY_REQUEST_ERR;
576 }
577 /* if newChild was created from a different document */
578 if (nodeptr->ownerDocument != newChild->ownerDocument) {
579 return IXML_WRONG_DOCUMENT_ERR;
580 }
581 /* if refChild is not a child of nodeptr */
582 if (ixmlNode_isParent(nodeptr, refChild) == 0) {
583 return IXML_NOT_FOUND_ERR;
584 }
585
586 if (refChild != NULL) {
587 if (ixmlNode_isParent(nodeptr, newChild)) {
588 ixmlNode_removeChild(nodeptr, newChild, &newChild);
589 newChild->nextSibling = NULL;
590 newChild->prevSibling = NULL;
591 }
592 newChild->nextSibling = refChild;
593 if (refChild->prevSibling != NULL) {
594 refChild->prevSibling->nextSibling = newChild;
595 newChild->prevSibling = refChild->prevSibling;
596 }
597 refChild->prevSibling = newChild;
598 if (newChild->prevSibling == NULL) {
599 nodeptr->firstChild = newChild;
600 }
601 newChild->parentNode = nodeptr;
602 } else {
603 ret = ixmlNode_appendChild( nodeptr, newChild );
604 }
605
606 return ret;
607 }
608
609
ixmlNode_replaceChild(IXML_Node * nodeptr,IXML_Node * newChild,IXML_Node * oldChild,IXML_Node ** returnNode)610 int ixmlNode_replaceChild(
611 IXML_Node *nodeptr,
612 IXML_Node *newChild,
613 IXML_Node *oldChild,
614 IXML_Node **returnNode)
615 {
616 int ret = IXML_SUCCESS;
617
618 if (nodeptr == NULL || newChild == NULL || oldChild == NULL) {
619 return IXML_INVALID_PARAMETER;
620 }
621 /* if nodetype of nodeptr does not allow children of the type of newChild
622 * needs to add later or if newChild is one of nodeptr's ancestors */
623 if (ixmlNode_isAncestor(newChild, nodeptr)) {
624 return IXML_HIERARCHY_REQUEST_ERR;
625 }
626
627 if (ixmlNode_allowChildren(nodeptr, newChild) == 0) {
628 return IXML_HIERARCHY_REQUEST_ERR;
629 }
630 /* if newChild was created from a different document */
631 if (nodeptr->ownerDocument != newChild->ownerDocument) {
632 return IXML_WRONG_DOCUMENT_ERR;
633 }
634 /* if refChild is not a child of nodeptr */
635 if (ixmlNode_isParent(nodeptr, oldChild) != 1) {
636 return IXML_NOT_FOUND_ERR;
637 }
638
639 ret = ixmlNode_insertBefore(nodeptr, newChild, oldChild);
640 if (ret != IXML_SUCCESS) {
641 return ret;
642 }
643
644 ret = ixmlNode_removeChild(nodeptr, oldChild, returnNode);
645 return ret;
646 }
647
648
ixmlNode_removeChild(IXML_Node * nodeptr,IXML_Node * oldChild,IXML_Node ** returnNode)649 int ixmlNode_removeChild(
650 IXML_Node *nodeptr,
651 IXML_Node *oldChild,
652 IXML_Node **returnNode)
653 {
654 if (!nodeptr || !oldChild)
655 return IXML_INVALID_PARAMETER;
656 if (!ixmlNode_isParent(nodeptr, oldChild))
657 return IXML_NOT_FOUND_ERR;
658 if (oldChild->prevSibling)
659 oldChild->prevSibling->nextSibling = oldChild->nextSibling;
660 if (nodeptr->firstChild == oldChild)
661 nodeptr->firstChild = oldChild->nextSibling;
662 if (oldChild->nextSibling)
663 oldChild->nextSibling->prevSibling = oldChild->prevSibling;
664 oldChild->nextSibling = NULL;
665 oldChild->prevSibling = NULL;
666 oldChild->parentNode = NULL;
667 if (returnNode)
668 *returnNode = oldChild;
669 else
670 ixmlNode_free(oldChild);
671
672 return IXML_SUCCESS;
673 }
674
675
ixmlNode_appendChild(IXML_Node * nodeptr,IXML_Node * newChild)676 int ixmlNode_appendChild(IXML_Node *nodeptr, IXML_Node *newChild)
677 {
678 IXML_Node *prev = NULL;
679 IXML_Node *next = NULL;
680
681 if (nodeptr == NULL || newChild == NULL) {
682 return IXML_INVALID_PARAMETER;
683 }
684 /* if newChild was created from a different document */
685 if (newChild->ownerDocument != NULL &&
686 nodeptr->ownerDocument != newChild->ownerDocument) {
687 return IXML_WRONG_DOCUMENT_ERR;
688 }
689 /* if newChild is an ancestor of nodeptr */
690 if (ixmlNode_isAncestor(newChild, nodeptr)) {
691 return IXML_HIERARCHY_REQUEST_ERR;
692 }
693 /* if nodeptr does not allow to have newChild as children */
694 if (ixmlNode_allowChildren(nodeptr, newChild) == 0) {
695 return IXML_HIERARCHY_REQUEST_ERR;
696 }
697
698 if (ixmlNode_isParent(nodeptr, newChild)) {
699 ixmlNode_removeChild(nodeptr, newChild, &newChild);
700 }
701 /* set the parent node pointer */
702 newChild->parentNode = nodeptr;
703 newChild->ownerDocument = nodeptr->ownerDocument;
704
705 /* if the first child */
706 if (nodeptr->firstChild == NULL) {
707 nodeptr->firstChild = newChild;
708 } else {
709 prev = nodeptr->firstChild;
710 next = prev->nextSibling;
711 while (next != NULL) {
712 prev = next;
713 next = prev->nextSibling;
714 }
715 prev->nextSibling = newChild;
716 newChild->prevSibling = prev;
717 }
718
719 return IXML_SUCCESS;
720 }
721
722 /*!
723 * \brief Returns a clone of nodeptr.
724 *
725 * \return A cloned node of nodeptr.
726 */
ixmlNode_cloneTextNode(IXML_Node * nodeptr)727 static IXML_Node *ixmlNode_cloneTextNode(
728 /*! [in] The \b Node to clone. */
729 IXML_Node *nodeptr)
730 {
731 IXML_Node *newNode = NULL;
732 int rc;
733
734 assert(nodeptr != NULL);
735
736 newNode = (IXML_Node *)malloc(sizeof (IXML_Node));
737 if (newNode == NULL) {
738 return NULL;
739 } else {
740 ixmlNode_init(newNode);
741 rc = ixmlNode_setNodeName(newNode, nodeptr->nodeName);
742 if (rc != IXML_SUCCESS) {
743 ixmlNode_free(newNode);
744 return NULL;
745 }
746 rc = ixmlNode_setNodeValue(newNode, nodeptr->nodeValue);
747 if (rc != IXML_SUCCESS) {
748 ixmlNode_free(newNode);
749 return NULL;
750 }
751 newNode->nodeType = eTEXT_NODE;
752 }
753
754 return newNode;
755 }
756
757 /*!
758 * \brief Return a clone of CDATASection node.
759 *
760 * \return A clone of CDATASection node.
761 */
ixmlNode_cloneCDATASect(IXML_CDATASection * nodeptr)762 static IXML_CDATASection *ixmlNode_cloneCDATASect(
763 /*! [in] The \b Node to clone. */
764 IXML_CDATASection *nodeptr)
765 {
766 IXML_CDATASection *newCDATA = NULL;
767 IXML_Node *newNode;
768 IXML_Node *srcNode;
769 int rc;
770
771 assert(nodeptr != NULL);
772 newCDATA = (IXML_CDATASection *)malloc(sizeof (IXML_CDATASection));
773 if (newCDATA != NULL) {
774 newNode = (IXML_Node *)newCDATA;
775 ixmlCDATASection_init(newCDATA);
776 srcNode = (IXML_Node *)nodeptr;
777 rc = ixmlNode_setNodeName(newNode, srcNode->nodeName);
778 if (rc != IXML_SUCCESS) {
779 ixmlCDATASection_free(newCDATA);
780 return NULL;
781 }
782 rc = ixmlNode_setNodeValue(newNode, srcNode->nodeValue);
783 if (rc != IXML_SUCCESS) {
784 ixmlCDATASection_free(newCDATA);
785 return NULL;
786 }
787 newNode->nodeType = eCDATA_SECTION_NODE;
788 }
789
790 return newCDATA;
791 }
792
793
794 /*!
795 * \brief Returns a clone of element node.
796 *
797 * \return A clone of element node.
798 */
ixmlNode_cloneElement(IXML_Element * nodeptr)799 static IXML_Element *ixmlNode_cloneElement(
800 /*! [in] The \b Node to clone. */
801 IXML_Element *nodeptr)
802 {
803 IXML_Element *newElement;
804 IXML_Node *elementNode;
805 IXML_Node *srcNode;
806 int rc;
807
808 assert(nodeptr != NULL);
809
810 newElement = (IXML_Element *)malloc(sizeof (IXML_Element));
811 if (newElement == NULL) {
812 return NULL;
813 }
814
815 ixmlElement_init(newElement);
816 rc = ixmlElement_setTagName(newElement, nodeptr->tagName);
817 if (rc != IXML_SUCCESS) {
818 ixmlElement_free(newElement);
819 return NULL;
820 }
821
822 elementNode = (IXML_Node *)newElement;
823 srcNode = (IXML_Node *)nodeptr;
824 rc = ixmlNode_setNodeName(elementNode, srcNode->nodeName);
825 if (rc != IXML_SUCCESS) {
826 ixmlElement_free(newElement);
827 return NULL;
828 }
829
830 rc = ixmlNode_setNodeValue(elementNode, srcNode->nodeValue);
831 if (rc != IXML_SUCCESS) {
832 ixmlElement_free(newElement);
833 return NULL;
834 }
835
836 rc = ixmlNode_setNamespaceURI(elementNode, srcNode->namespaceURI);
837 if (rc != IXML_SUCCESS) {
838 ixmlElement_free(newElement);
839 return NULL;
840 }
841
842 rc = ixmlNode_setPrefix(elementNode, srcNode->prefix);
843 if (rc != IXML_SUCCESS) {
844 ixmlElement_free(newElement);
845 return NULL;
846 }
847
848 rc = ixmlNode_setLocalName(elementNode, srcNode->localName);
849 if (rc != IXML_SUCCESS) {
850 ixmlElement_free(newElement);
851 return NULL;
852 }
853
854 elementNode->nodeType = eELEMENT_NODE;
855
856 return newElement;
857 }
858
859
860 /*!
861 * \brief Returns a new document node.
862 *
863 * Currently, the IXML_Document struct is just a node, so this function
864 * just mallocs the IXML_Document, sets the node type and name.
865 *
866 * \return A new document node.
867 */
ixmlNode_newDoc(void)868 static IXML_Document *ixmlNode_newDoc(void)
869 {
870 IXML_Document *newDoc;
871 IXML_Node *docNode;
872 int rc;
873
874 newDoc = (IXML_Document *)malloc(sizeof (IXML_Document));
875 if (!newDoc)
876 return NULL;
877 ixmlDocument_init(newDoc);
878 docNode = (IXML_Node *)newDoc;
879 rc = ixmlNode_setNodeName(docNode, DOCUMENTNODENAME);
880 if (rc != IXML_SUCCESS) {
881 ixmlDocument_free(newDoc);
882 return NULL;
883 }
884 newDoc->n.nodeType = eDOCUMENT_NODE;
885
886 return newDoc;
887 }
888
889 /*!
890 * \brief Returns a clone of an attribute node.
891 *
892 * \return A clone of an attribute node.
893 */
ixmlNode_cloneAttr(IXML_Attr * nodeptr)894 static IXML_Attr *ixmlNode_cloneAttr(
895 /*! [in] The \b Node to clone. */
896 IXML_Attr *nodeptr)
897 {
898 IXML_Attr *newAttr;
899 IXML_Node *attrNode;
900 IXML_Node *srcNode;
901 int rc;
902
903 assert(nodeptr != NULL);
904
905 newAttr = (IXML_Attr *)malloc(sizeof (IXML_Attr));
906 if (newAttr == NULL) {
907 return NULL;
908 }
909
910 ixmlAttr_init(newAttr);
911 attrNode = (IXML_Node *)newAttr;
912 srcNode = (IXML_Node *)nodeptr;
913
914 rc = ixmlNode_setNodeName(attrNode, srcNode->nodeName);
915 if (rc != IXML_SUCCESS) {
916 ixmlAttr_free(newAttr);
917 return NULL;
918 }
919
920 rc = ixmlNode_setNodeValue(attrNode, srcNode->nodeValue);
921 if (rc != IXML_SUCCESS) {
922 ixmlAttr_free(newAttr);
923 return NULL;
924 }
925
926 /* Check to see whether we need to split prefix and localname for attribute */
927 rc = ixmlNode_setNamespaceURI(attrNode, srcNode->namespaceURI);
928 if (rc != IXML_SUCCESS) {
929 ixmlAttr_free(newAttr);
930 return NULL;
931 }
932
933 rc = ixmlNode_setPrefix(attrNode, srcNode->prefix);
934 if (rc != IXML_SUCCESS) {
935 ixmlAttr_free(newAttr);
936 return NULL;
937 }
938
939 rc = ixmlNode_setLocalName(attrNode, srcNode->localName);
940 if (rc != IXML_SUCCESS) {
941 ixmlAttr_free(newAttr);
942 return NULL;
943 }
944
945 attrNode->nodeType = eATTRIBUTE_NODE;
946
947 return newAttr;
948 }
949
950 /*!
951 * \brief Return a clone of attribute node, with specified field set to 1.
952 *
953 * \return A clone of attribute node, with specified field set to 1.
954 */
ixmlNode_cloneAttrDirect(IXML_Attr * nodeptr)955 static IXML_Attr *ixmlNode_cloneAttrDirect(
956 /*! [in] The \b Node to clone. */
957 IXML_Attr *nodeptr)
958 {
959 IXML_Attr *newAttr;
960
961 assert(nodeptr != NULL);
962
963 newAttr = ixmlNode_cloneAttr(nodeptr);
964 if (newAttr != NULL) {
965 newAttr->specified = 1;
966 }
967
968 return newAttr;
969 }
970
971
972 /*!
973 * \brief Sets siblings nodes parent to be the same as this node's.
974 */
ixmlNode_setSiblingNodesParent(IXML_Node * nodeptr)975 static void ixmlNode_setSiblingNodesParent(
976 /*! [in] The node to operate on. */
977 IXML_Node *nodeptr)
978 {
979 IXML_Node *parentNode = nodeptr->parentNode;
980 IXML_Node *nextptr = nodeptr->nextSibling;
981
982 while (nextptr != NULL) {
983 nextptr->parentNode = parentNode;
984 nextptr = nextptr->nextSibling;
985 }
986 }
987
988
989 /*!
990 * \brief Recursive function that clones a node tree of nodeptr.
991 *
992 * \returns The cloned node/tree.
993 */
ixmlNode_cloneNodeTreeRecursive(IXML_Node * nodeptr,int deep)994 static IXML_Node *ixmlNode_cloneNodeTreeRecursive(
995 /*! [in] Node tree to clone. */
996 IXML_Node *nodeptr,
997 /*! [in] 1 if you want to clone the tree. */
998 int deep)
999 {
1000 IXML_Node *newNode = NULL;
1001 IXML_Element *newElement = NULL;
1002 IXML_Attr *newAttr = NULL;
1003 IXML_CDATASection *newCDATA = NULL;
1004 IXML_Document *newDoc = NULL;
1005 IXML_Node *nextSib = NULL;
1006
1007 if (nodeptr != NULL) {
1008 switch (nodeptr->nodeType) {
1009 case eELEMENT_NODE:
1010 newElement = ixmlNode_cloneElement((IXML_Element *)nodeptr);
1011 if (newElement == NULL)
1012 return NULL;
1013 newElement->n.firstAttr = ixmlNode_cloneNodeTreeRecursive(
1014 nodeptr->firstAttr, deep);
1015 if (deep) {
1016 newElement->n.firstChild =
1017 ixmlNode_cloneNodeTreeRecursive(nodeptr->firstChild, deep);
1018 if (newElement->n.firstChild != NULL) {
1019 newElement->n.firstChild->parentNode = (IXML_Node *)newElement;
1020 ixmlNode_setSiblingNodesParent(newElement->n.firstChild);
1021 }
1022 nextSib = ixmlNode_cloneNodeTreeRecursive(nodeptr->nextSibling, deep);
1023 newElement->n.nextSibling = nextSib;
1024 if (nextSib != NULL) {
1025 nextSib->prevSibling = (IXML_Node *)newElement;
1026 }
1027 }
1028 newNode = (IXML_Node *)newElement;
1029 break;
1030
1031 case eATTRIBUTE_NODE:
1032 newAttr = ixmlNode_cloneAttr((IXML_Attr *)nodeptr);
1033 if (newAttr == NULL)
1034 return NULL;
1035 nextSib = ixmlNode_cloneNodeTreeRecursive(nodeptr->nextSibling, deep);
1036 newAttr->n.nextSibling = nextSib;
1037 if (nextSib != NULL) {
1038 nextSib->prevSibling = (IXML_Node *)newAttr;
1039 }
1040 newNode = (IXML_Node *)newAttr;
1041 break;
1042
1043 case eTEXT_NODE:
1044 newNode = ixmlNode_cloneTextNode(nodeptr);
1045 break;
1046
1047 case eCDATA_SECTION_NODE:
1048 newCDATA = ixmlNode_cloneCDATASect((IXML_CDATASection *)nodeptr);
1049 newNode = (IXML_Node *)newCDATA;
1050 break;
1051
1052 case eDOCUMENT_NODE:
1053 newDoc = ixmlNode_newDoc();
1054 if (newDoc == NULL)
1055 return NULL;
1056 newNode = (IXML_Node *)newDoc;
1057 if (deep) {
1058 newNode->firstChild = ixmlNode_cloneNodeTreeRecursive(
1059 nodeptr->firstChild, deep);
1060 if (newNode->firstChild != NULL) {
1061 newNode->firstChild->parentNode = newNode;
1062 }
1063 }
1064 break;
1065
1066 case eINVALID_NODE:
1067 case eENTITY_REFERENCE_NODE:
1068 case eENTITY_NODE:
1069 case ePROCESSING_INSTRUCTION_NODE:
1070 case eCOMMENT_NODE:
1071 case eDOCUMENT_TYPE_NODE:
1072 case eDOCUMENT_FRAGMENT_NODE:
1073 case eNOTATION_NODE:
1074 break;
1075 }
1076 }
1077
1078 return newNode;
1079 }
1080
1081
1082 /*!
1083 * \brief Function that clones a node tree of nodeptr.
1084 *
1085 * \returns The cloned node/tree.
1086 */
ixmlNode_cloneNodeTree(IXML_Node * nodeptr,int deep)1087 static IXML_Node *ixmlNode_cloneNodeTree(
1088 /*! [in] Node tree to clone. */
1089 IXML_Node *nodeptr,
1090 /*! [in] 1 if you want to clone the tree. */
1091 int deep)
1092 {
1093 IXML_Node *newNode = NULL;
1094 IXML_Element *newElement;
1095 IXML_Node *childNode;
1096
1097 assert(nodeptr != NULL);
1098
1099 switch (nodeptr->nodeType) {
1100 case eELEMENT_NODE:
1101 newElement = ixmlNode_cloneElement((IXML_Element *)nodeptr);
1102 if (newElement == NULL)
1103 return NULL;
1104 newElement->n.firstAttr = ixmlNode_cloneNodeTreeRecursive(nodeptr->firstAttr, deep);
1105 if (deep) {
1106 newElement->n.firstChild = ixmlNode_cloneNodeTreeRecursive(
1107 nodeptr->firstChild, deep);
1108 childNode = newElement->n.firstChild;
1109 while (childNode != NULL) {
1110 childNode->parentNode = (IXML_Node *)newElement;
1111 childNode = childNode->nextSibling;
1112 }
1113 newElement->n.nextSibling = NULL;
1114 }
1115 newNode = ( IXML_Node * ) newElement;
1116 break;
1117
1118 case eATTRIBUTE_NODE:
1119 case eTEXT_NODE:
1120 case eCDATA_SECTION_NODE:
1121 case eDOCUMENT_NODE:
1122 newNode = ixmlNode_cloneNodeTreeRecursive(nodeptr, deep);
1123 break;
1124
1125 case eINVALID_NODE:
1126 case eENTITY_REFERENCE_NODE:
1127 case eENTITY_NODE:
1128 case ePROCESSING_INSTRUCTION_NODE:
1129 case eCOMMENT_NODE:
1130 case eDOCUMENT_TYPE_NODE:
1131 case eDOCUMENT_FRAGMENT_NODE:
1132 case eNOTATION_NODE:
1133 #if 0
1134 /* create a new node here? */
1135 newNode = (IXML_Node *)malloc(sizeof(IXML_Node));
1136 if (newNode == NULL) {
1137 return NULL;
1138 }
1139 #endif
1140 break;
1141 }
1142
1143 /* by spec, the duplicate node has no parent */
1144 if (newNode != NULL)
1145 newNode->parentNode = NULL;
1146
1147 return newNode;
1148 }
1149
1150
1151
ixmlNode_cloneNode(IXML_Node * nodeptr,int deep)1152 IXML_Node *ixmlNode_cloneNode(IXML_Node *nodeptr, int deep)
1153 {
1154 IXML_Node *newNode;
1155 IXML_Attr *newAttrNode;
1156
1157 if (nodeptr == NULL) {
1158 return NULL;
1159 }
1160
1161 switch (nodeptr->nodeType) {
1162 case eATTRIBUTE_NODE:
1163 newAttrNode = ixmlNode_cloneAttrDirect((IXML_Attr *)nodeptr);
1164 return (IXML_Node *)newAttrNode;
1165 break;
1166
1167 default:
1168 newNode = ixmlNode_cloneNodeTree(nodeptr, deep);
1169 return newNode;
1170 break;
1171 }
1172 }
1173
1174
ixmlNode_getChildNodes(IXML_Node * nodeptr)1175 IXML_NodeList *ixmlNode_getChildNodes(IXML_Node *nodeptr)
1176 {
1177 IXML_Node *tempNode;
1178 IXML_NodeList *newNodeList;
1179 int rc;
1180
1181 if (nodeptr == NULL) {
1182 return NULL;
1183 }
1184
1185 newNodeList = (IXML_NodeList *)malloc(sizeof(IXML_NodeList));
1186 if (newNodeList == NULL) {
1187 return NULL;
1188 }
1189
1190 ixmlNodeList_init(newNodeList);
1191 tempNode = nodeptr->firstChild;
1192 while (tempNode != NULL) {
1193 rc = ixmlNodeList_addToNodeList(&newNodeList, tempNode);
1194 if (rc != IXML_SUCCESS) {
1195 ixmlNodeList_free(newNodeList);
1196 return NULL;
1197 }
1198
1199 tempNode = tempNode->nextSibling;
1200 }
1201
1202 return newNodeList;
1203 }
1204
1205
ixmlNode_getAttributes(IXML_Node * nodeptr)1206 IXML_NamedNodeMap *ixmlNode_getAttributes(IXML_Node *nodeptr)
1207 {
1208 IXML_NamedNodeMap *returnNamedNodeMap = NULL;
1209 IXML_Node *tempNode;
1210 int rc;
1211
1212 if(nodeptr == NULL) {
1213 return NULL;
1214 }
1215
1216 switch(nodeptr->nodeType) {
1217 case eELEMENT_NODE:
1218 returnNamedNodeMap = (IXML_NamedNodeMap *)malloc(sizeof(IXML_NamedNodeMap));
1219 if(returnNamedNodeMap == NULL) {
1220 return NULL;
1221 }
1222
1223 ixmlNamedNodeMap_init(returnNamedNodeMap);
1224 tempNode = nodeptr->firstAttr;
1225 while( tempNode != NULL ) {
1226 rc = ixmlNamedNodeMap_addToNamedNodeMap(&returnNamedNodeMap, tempNode);
1227 if(rc != IXML_SUCCESS) {
1228 ixmlNamedNodeMap_free(returnNamedNodeMap);
1229 return NULL;
1230 }
1231
1232 tempNode = tempNode->nextSibling;
1233 }
1234 return returnNamedNodeMap;
1235 default:
1236 /* if not an ELEMENT_NODE */
1237 return NULL;
1238 }
1239 }
1240
1241
ixmlNode_hasChildNodes(IXML_Node * nodeptr)1242 int ixmlNode_hasChildNodes(IXML_Node *nodeptr)
1243 {
1244 if (nodeptr == NULL) {
1245 return 0;
1246 }
1247
1248 return nodeptr->firstChild != NULL;
1249 }
1250
1251
ixmlNode_hasAttributes(IXML_Node * nodeptr)1252 int ixmlNode_hasAttributes(IXML_Node *nodeptr)
1253 {
1254 if (nodeptr != NULL) {
1255 switch (nodeptr->nodeType) {
1256 case eELEMENT_NODE:
1257 if (nodeptr->firstAttr != NULL)
1258 return 1;
1259 break;
1260 default:
1261 break;
1262 }
1263 }
1264
1265 return 0;
1266 }
1267
1268
1269 /*!
1270 * \brief Recursively traverse the whole tree, search for element with the
1271 * given tagname.
1272 */
ixmlNode_getElementsByTagNameRecursive(IXML_Node * n,const char * tagname,IXML_NodeList ** list)1273 static void ixmlNode_getElementsByTagNameRecursive(
1274 /*! [in] The \b Node tree. */
1275 IXML_Node *n,
1276 /*! [in] The tag name to match. */
1277 const char *tagname,
1278 /*! [out] The output \b NodeList. */
1279 IXML_NodeList **list)
1280 {
1281 const char *name;
1282
1283 if (n != NULL) {
1284 if (ixmlNode_getNodeType(n) == eELEMENT_NODE) {
1285 name = ixmlNode_getNodeName(n);
1286 if (strcmp(tagname, name) == 0 || strcmp(tagname, "*") == 0) {
1287 ixmlNodeList_addToNodeList(list, n);
1288 }
1289 }
1290 ixmlNode_getElementsByTagNameRecursive(ixmlNode_getFirstChild(n), tagname, list);
1291 ixmlNode_getElementsByTagNameRecursive(ixmlNode_getNextSibling(n), tagname, list);
1292 }
1293 }
1294
1295
ixmlNode_getElementsByTagName(IXML_Node * n,const char * tagname,IXML_NodeList ** list)1296 void ixmlNode_getElementsByTagName(
1297 IXML_Node *n,
1298 const char *tagname,
1299 IXML_NodeList **list)
1300 {
1301 const char *name;
1302
1303 assert(n != NULL && tagname != NULL);
1304
1305 if (ixmlNode_getNodeType(n) == eELEMENT_NODE) {
1306 name = ixmlNode_getNodeName(n);
1307 if (strcmp(tagname, name) == 0 || strcmp(tagname, "*") == 0) {
1308 ixmlNodeList_addToNodeList(list, n);
1309 }
1310 }
1311 ixmlNode_getElementsByTagNameRecursive(ixmlNode_getFirstChild(n), tagname, list);
1312 }
1313
1314
1315 /*!
1316 * \brief
1317 */
ixmlNode_getElementsByTagNameNSRecursive(IXML_Node * n,const char * namespaceURI,const char * localName,IXML_NodeList ** list)1318 static void ixmlNode_getElementsByTagNameNSRecursive(
1319 /*! [in] . */
1320 IXML_Node *n,
1321 /*! [in] . */
1322 const char *namespaceURI,
1323 /*! [in] . */
1324 const char *localName,
1325 /*! [out] . */
1326 IXML_NodeList **list)
1327 {
1328 const DOMString nsURI;
1329 const DOMString name;
1330
1331 if (n != NULL) {
1332 if (ixmlNode_getNodeType(n) == eELEMENT_NODE) {
1333 name = ixmlNode_getLocalName(n);
1334 nsURI = ixmlNode_getNamespaceURI(n);
1335
1336 if (name != NULL && nsURI != NULL &&
1337 (strcmp(namespaceURI, nsURI) == 0 ||
1338 strcmp(namespaceURI, "*") == 0 ) &&
1339 (strcmp(name, localName) == 0 ||
1340 strcmp(localName, "*") == 0)) {
1341 ixmlNodeList_addToNodeList(list, n);
1342 }
1343 }
1344 ixmlNode_getElementsByTagNameNSRecursive(
1345 ixmlNode_getFirstChild(n), namespaceURI, localName, list);
1346 ixmlNode_getElementsByTagNameNSRecursive(
1347 ixmlNode_getNextSibling(n), namespaceURI, localName, list);
1348 }
1349 }
1350
1351
ixmlNode_getElementsByTagNameNS(IXML_Node * n,const char * namespaceURI,const char * localName,IXML_NodeList ** list)1352 void ixmlNode_getElementsByTagNameNS(
1353 IXML_Node *n,
1354 const char *namespaceURI,
1355 const char *localName,
1356 IXML_NodeList **list)
1357 {
1358 const DOMString nsURI;
1359 const DOMString name;
1360
1361 assert(n != NULL && namespaceURI != NULL && localName != NULL);
1362
1363 if (ixmlNode_getNodeType(n) == eELEMENT_NODE) {
1364 name = ixmlNode_getLocalName(n);
1365 nsURI = ixmlNode_getNamespaceURI(n);
1366 if (name != NULL && nsURI != NULL &&
1367 (strcmp(namespaceURI, nsURI) == 0 ||
1368 strcmp(namespaceURI, "*") == 0) &&
1369 (strcmp(name, localName) == 0 ||
1370 strcmp(localName, "*") == 0)) {
1371 ixmlNodeList_addToNodeList(list, n);
1372 }
1373 }
1374
1375 ixmlNode_getElementsByTagNameNSRecursive(
1376 ixmlNode_getFirstChild(n), namespaceURI, localName, list);
1377 }
1378
1379
ixmlNode_setNodeName(IXML_Node * node,const DOMString qualifiedName)1380 int ixmlNode_setNodeName(
1381 IXML_Node *node,
1382 const DOMString qualifiedName)
1383 {
1384 int rc = IXML_SUCCESS;
1385
1386 assert( node != NULL );
1387
1388 if (node->nodeName != NULL) {
1389 free(node->nodeName);
1390 node->nodeName = NULL;
1391 }
1392
1393 if (qualifiedName != NULL) {
1394 /* set the name part */
1395 node->nodeName = strdup(qualifiedName);
1396 if (node->nodeName == NULL) {
1397 return IXML_INSUFFICIENT_MEMORY;
1398 }
1399
1400 rc = Parser_setNodePrefixAndLocalName(node);
1401 if (rc != IXML_SUCCESS) {
1402 free(node->nodeName);
1403 }
1404 }
1405
1406 return rc;
1407 }
1408
1409
ixmlNode_setNodeProperties(IXML_Node * destNode,IXML_Node * src)1410 int ixmlNode_setNodeProperties(
1411 IXML_Node *destNode,
1412 IXML_Node *src)
1413 {
1414 int rc;
1415
1416 assert(destNode != NULL && src != NULL);
1417 if(destNode == NULL || src == NULL) {
1418 return IXML_INVALID_PARAMETER;
1419 }
1420
1421 rc = ixmlNode_setNodeValue(destNode, src->nodeValue);
1422 if(rc != IXML_SUCCESS) {
1423 goto ErrorHandler;
1424 }
1425
1426 rc = ixmlNode_setLocalName(destNode, src->localName);
1427 if(rc != IXML_SUCCESS) {
1428 goto ErrorHandler;
1429 }
1430
1431 rc = ixmlNode_setPrefix(destNode, src->prefix);
1432 if(rc != IXML_SUCCESS) {
1433 goto ErrorHandler;
1434 }
1435 /* set nodetype */
1436 destNode->nodeType = src->nodeType;
1437
1438 return IXML_SUCCESS;
1439
1440 ErrorHandler:
1441 if(destNode->nodeName != NULL) {
1442 free(destNode->nodeName);
1443 destNode->nodeName = NULL;
1444 }
1445 if(destNode->nodeValue != NULL) {
1446 free(destNode->nodeValue);
1447 destNode->nodeValue = NULL;
1448 }
1449 if(destNode->localName != NULL) {
1450 free(destNode->localName);
1451 destNode->localName = NULL;
1452 }
1453
1454 return IXML_INSUFFICIENT_MEMORY;
1455 }
1456
1457 #ifdef IXML_HAVE_SCRIPTSUPPORT
ixmlNode_setCTag(IXML_Node * nodeptr,void * ctag)1458 void ixmlNode_setCTag(IXML_Node *nodeptr, void *ctag)
1459 {
1460 if (nodeptr != NULL) nodeptr->ctag = ctag;
1461 }
1462
ixmlNode_getCTag(IXML_Node * nodeptr)1463 void* ixmlNode_getCTag(IXML_Node *nodeptr)
1464 {
1465 if (nodeptr != NULL)
1466 return nodeptr->ctag;
1467 else
1468 return NULL;
1469 }
1470 #endif
1471