blob: 3bb3f8b1e50cd2e5f70e4e58c91284917dee0597 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2000-2003 Intel Corporation
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
13// and/or other materials provided with the distribution.
14// * Neither name of Intel Corporation nor the names of its contributors
15// may be used to endorse or promote products derived from this software
16// without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
22// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30///////////////////////////////////////////////////////////////////////////
31
32#include "xmlparser.h"
33
34/*================================================================
35* XmlNodeInit
36* Intializes a node.
37* External function.
38*
39*=================================================================*/
40void
41XmlNodeInit( XmlNode * nodeptr )
42{
43 assert( nodeptr != NULL );
44 memset( nodeptr, 0, sizeof( XmlNode ) );
45
46}
47
48/*================================================================
49* XmlCDATASectionInit
50* Initializes a CDATASection node.
51* External function.
52*
53*=================================================================*/
54void
55XmlCDATASectionInit( XmlCDATASection * nodeptr )
56{
57 memset( nodeptr, 0, sizeof( XmlCDATASection ) );
58}
59
60/*================================================================
61* XmlCDATASectionFree
62* XFREEs a CDATASection node.
63* External function.
64*
65*=================================================================*/
66void
67XmlCDATASectionFree(
68 Pool * pool,
69 XmlCDATASection * nodeptr )
70{
71 if ( nodeptr != NULL )
72 {
73 XmlNodeFree(
74#ifdef USE_CWMP_MEMORY_POOL
75 pool ,
76#endif
77 ( XmlNode * ) nodeptr );
78 }
79}
80
81/*================================================================
82* XmlNodeFreeSingleNode
83* XFREEs a node content.
84* Internal to parser only.
85*
86*=================================================================*/
87void
88XmlNodeFreeSingleNode(
89 Pool * pool,
90 XmlNode * nodeptr )
91{
92 XmlElement *element = NULL;
93
94 if ( nodeptr != NULL )
95 {
96
97 if ( nodeptr->nodeName != NULL )
98 {
99 PFREE( nodeptr->nodeName );
100 }
101
102 if ( nodeptr->nodeValue != NULL )
103 {
104 PFREE( nodeptr->nodeValue );
105 }
106
107 if ( nodeptr->namespaceURI != NULL )
108 {
109 PFREE( nodeptr->namespaceURI );
110 }
111
112 if ( nodeptr->prefix != NULL )
113 {
114 PFREE( nodeptr->prefix );
115 }
116
117 if ( nodeptr->localName != NULL )
118 {
119 PFREE( nodeptr->localName );
120 }
121
122 if ( nodeptr->nodeType == XML_ELEMENT_NODE )
123 {
124 element = ( XmlElement * ) nodeptr;
125 PFREE( element->tagName );
126 }
127
128 PFREE( nodeptr );
129
130 }
131}
132
133/*================================================================
134* XmlNodeFree
135* Frees all nodes under nodeptr subtree.
136* External function.
137*
138*=================================================================*/
139void
140XmlNodeFree(
141
142
143 Pool * pool,
144 XmlNode * nodeptr )
145{
146 if ( nodeptr != NULL )
147 {
148 XmlNodeFree(
149#ifdef USE_CWMP_MEMORY_POOL
150 pool ,
151#endif
152 nodeptr->firstChild );
153 XmlNodeFree(
154#ifdef USE_CWMP_MEMORY_POOL
155 pool ,
156#endif
157 nodeptr->nextSibling );
158 XmlNodeFree(
159#ifdef USE_CWMP_MEMORY_POOL
160 pool ,
161#endif
162 nodeptr->firstAttr );
163
164 XmlNodeFreeSingleNode(
165#ifdef USE_CWMP_MEMORY_POOL
166 pool ,
167#endif
168 nodeptr );
169 }
170}
171
172/*================================================================
173* XmlNodeGetNodeName
174* Returns the nodename(the qualified name)
175* External function.
176*
177*=================================================================*/
178const char *
179XmlNodeGetNodeName( XmlNode * nodeptr )
180{
181
182 if ( nodeptr != NULL )
183 {
184 return ( nodeptr->nodeName );
185 }
186
187 return NULL;
188}
189
190/*================================================================
191* XmlNodeGetLocalName
192* Returns the node local name
193* External function.
194*
195*=================================================================*/
196const char *
197XmlNodeGetLocalName( XmlNode * nodeptr )
198{
199
200 if ( nodeptr != NULL )
201 {
202 return ( nodeptr->localName );
203 }
204
205 return NULL;
206}
207
208/*================================================================
209* XmlNodeSetNamespaceURI
210* sets the namespace URI of the node.
211* Internal function.
212* Return:
213* XML_OK or failure
214*
215*=================================================================*/
216int
217XmlNodeSetNamespaceURI(
218 Pool * pool,
219 XmlNode * nodeptr,
220 IN char *namespaceURI )
221{
222
223 if ( nodeptr == NULL )
224 {
225 return XML_INVALID_PARAMETER;
226 }
227
228 if ( nodeptr->namespaceURI != NULL )
229 {
230 PFREE( nodeptr->namespaceURI );
231 nodeptr->namespaceURI = NULL;
232 }
233
234 if ( namespaceURI != NULL )
235 {
236 nodeptr->namespaceURI = PSTRDUP( namespaceURI );
237 if ( nodeptr->namespaceURI == NULL )
238 {
239 return XML_INSUFFICIENT_MEMORY;
240 }
241 }
242
243 return XML_OK;
244}
245
246/*================================================================
247* XmlNodeSetPrefix
248* set the prefix of the node.
249* Internal to parser only.
250* Returns:
251* XML_OK or failure.
252*
253*=================================================================*/
254int
255XmlNodeSetPrefix(
256 Pool * pool,
257 XmlNode * nodeptr,
258 IN char *prefix )
259{
260
261 if ( nodeptr == NULL )
262 {
263 return XML_INVALID_PARAMETER;
264 }
265
266 if ( nodeptr->prefix != NULL )
267 {
268 PFREE( nodeptr->prefix );
269 nodeptr->prefix = NULL;
270 }
271
272 if ( prefix != NULL )
273 {
274 nodeptr->prefix = PSTRDUP( prefix );
275 if ( nodeptr->prefix == NULL )
276 {
277 return XML_INSUFFICIENT_MEMORY;
278 }
279 }
280
281 return XML_OK;
282
283}
284
285/*================================================================
286* XmlNodeSetLocalName
287* set the localName of the node.
288* Internal to parser only.
289* Returns:
290* XML_OK or failure.
291*
292*=================================================================*/
293int
294XmlNodeSetLocalName(
295 Pool * pool,
296 XmlNode * nodeptr,
297 IN char *localName )
298{
299
300 assert( nodeptr != NULL );
301
302 if ( nodeptr->localName != NULL )
303 {
304 PFREE( nodeptr->localName );
305 nodeptr->localName = NULL;
306 }
307
308 if ( localName != NULL )
309 {
310 nodeptr->localName = PSTRDUP( localName );
311 if ( nodeptr->localName == NULL )
312 {
313 return XML_INSUFFICIENT_MEMORY;
314 }
315 }
316
317 return XML_OK;
318}
319
320/*================================================================
321* XmlNodeGetNodeNamespaceURI
322* Returns the node namespaceURI
323* External function.
324* Returns:
325* the namespaceURI of the node
326*
327*=================================================================*/
328const char *
329XmlNodeGetNamespaceURI( XmlNode * nodeptr )
330{
331 char * retNamespaceURI = NULL;
332
333 if ( nodeptr != NULL )
334 {
335 retNamespaceURI = nodeptr->namespaceURI;
336 }
337
338 return retNamespaceURI;
339}
340
341/*================================================================
342* XmlNodeGetPrefix
343* Returns the node prefix
344* External function.
345* Returns:
346* the prefix of the node.
347*
348*=================================================================*/
349char *
350XmlNodeGetPrefix( XmlNode * nodeptr )
351{
352 char * prefix = NULL;
353
354 if ( nodeptr != NULL )
355 {
356 prefix = nodeptr->prefix;
357 }
358
359 return prefix;
360
361}
362
363/*================================================================
364* XmlNodeGetNodeValue
365* Returns the nodeValue of this node
366* External function.
367* Return:
368* the nodeValue of the node.
369*
370*=================================================================*/
371char *
372XmlNodeGetNodeValue( XmlNode * nodeptr )
373{
374
375 if ( nodeptr != NULL )
376 {
377 return ( nodeptr->nodeValue );
378 }
379
380 return NULL;
381}
382
383/*================================================================
384* XmlNodeSetNodeValue
385* Sets the nodeValue
386* Internal function.
387* Returns:
388* XML_OK or failure
389*
390*=================================================================*/
391int
392XmlNodeSetNodeValue(
393 Pool * pool,
394 XmlNode * nodeptr,
395 const char *newNodeValue )
396{
397 int rc = XML_OK;
398
399 if ( nodeptr == NULL )
400 {
401 return XML_INVALID_PARAMETER;
402 }
403
404 if ( nodeptr->nodeValue != NULL )
405 {
406 PFREE( nodeptr->nodeValue );
407 nodeptr->nodeValue = NULL;
408 }
409
410 if ( newNodeValue != NULL )
411 {
412 nodeptr->nodeValue = XmlStrduptrim(
413#ifdef USE_CWMP_MEMORY_POOL
414 pool ,
415#endif
416 newNodeValue );
417 if ( nodeptr->nodeValue == NULL )
418 {
419 return XML_INSUFFICIENT_MEMORY;
420 }
421 }
422
423 return rc;
424}
425
426/*================================================================
427* XmlNodeGetNodeType
428* Gets the NodeType of this node
429* External function.
430*
431*=================================================================*/
432int
433XmlNodeGetNodeType( XmlNode * nodeptr )
434{
435 if ( nodeptr != NULL )
436 {
437 return ( nodeptr->nodeType );
438 }
439 else
440 {
441 return ( XML_INVALID_NODE );
442 }
443}
444
445/*================================================================
446* XmlNodeGetParentNode
447* Get the parent node
448* External function.
449* Return:
450*
451*=================================================================*/
452XmlNode *
453XmlNodeGetParentNode( XmlNode * nodeptr )
454{
455
456 if ( nodeptr != NULL )
457 {
458 return nodeptr->parentNode;
459 }
460 else
461 {
462 return NULL;
463 }
464}
465
466/*================================================================
467* XmlNodeGetFirstChild
468* Returns the first child of nodeptr.
469* External function.
470*
471*=================================================================*/
472XmlNode *
473XmlNodeGetFirstChild( XmlNode * nodeptr )
474{
475 if ( nodeptr != NULL )
476 {
477 return nodeptr->firstChild;
478 }
479 else
480 {
481 return NULL;
482 }
483}
484
485/*================================================================
486* XmlNodeGetLastChild
487* Returns the last child of nodeptr.
488* External function.
489*
490*=================================================================*/
491XmlNode *
492XmlNodeGetLastChild( XmlNode * nodeptr )
493{
494 XmlNode * prev;
495 XmlNode * next;
496
497 if ( nodeptr != NULL )
498 {
499 prev = nodeptr;
500 next = nodeptr->firstChild;
501
502 while ( next != NULL )
503 {
504 prev = next;
505 next = next->nextSibling;
506 }
507 return prev;
508 }
509 else
510 {
511 return NULL;
512 }
513
514}
515
516/*================================================================
517* XmlNodeGetPreviousSibling
518* returns the previous sibling node of nodeptr.
519* External function.
520*
521*=================================================================*/
522XmlNode *
523XmlNodeGetPreviousSibling( XmlNode * nodeptr )
524{
525 if ( nodeptr != NULL )
526 {
527 return nodeptr->prevSibling;
528 }
529 else
530 {
531 return NULL;
532 }
533}
534
535/*================================================================
536* XmlNodeGetNextSibling
537* Returns the next sibling node.
538* External function.
539*
540*=================================================================*/
541XmlNode *
542XmlNodeGetNextSibling( XmlNode * nodeptr )
543{
544
545 if ( nodeptr != NULL )
546 {
547 return nodeptr->nextSibling;
548 }
549 else
550 {
551 return NULL;
552 }
553
554}
555
556/*================================================================
557* XmlNodeGetOwnerDocument
558* Returns the owner document node.
559* External function.
560*
561*=================================================================*/
562XmlDocument *
563XmlNodeGetOwnerDocument( XmlNode * nodeptr )
564{
565 if ( nodeptr != NULL )
566 {
567 return ( XmlDocument * ) nodeptr->ownerDocument;
568 }
569 else
570 {
571 return NULL;
572 }
573}
574
575/*================================================================
576* XmlNodeIsAncestor
577* check if ancestorNode is ancestor of toFind
578* Internal to parser only.
579* Returns:
580* TRUE or FALSE
581*
582*=================================================================*/
583BOOL
584XmlNodeIsAncestor( XmlNode * ancestorNode,
585 XmlNode * toFind )
586{
587
588 BOOL found = FALSE;
589
590 if ( ( ancestorNode != NULL ) && ( toFind != NULL ) )
591 {
592 if ( toFind->parentNode == ancestorNode )
593 {
594 return TRUE;
595 }
596 else
597 {
598 found =
599 XmlNodeIsAncestor( ancestorNode->firstChild, toFind );
600 if ( found == FALSE )
601 {
602 found =
603 XmlNodeIsAncestor( ancestorNode->nextSibling,
604 toFind );
605 }
606 }
607 }
608
609 return found;
610}
611
612/*================================================================
613* XmlNodeIsParent
614* Check whether toFind is a children of nodeptr.
615* Internal to parser only.
616* Return:
617* TRUE or FALSE
618*
619*=================================================================*/
620BOOL
621XmlNodeIsParent( XmlNode * nodeptr,
622 XmlNode * toFind )
623{
624 BOOL found = FALSE;
625
626 assert( nodeptr != NULL && toFind != NULL );
627 if ( toFind->parentNode == nodeptr )
628 {
629 found = TRUE;
630 }
631
632 return found;
633}
634
635/*================================================================
636* XmlNodeAllowChildren
637* Check to see whether nodeptr allows children of type newChild.
638* Internal to parser only.
639* Returns:
640* TRUE, if nodeptr can have newChild as children
641* FALSE,if nodeptr cannot have newChild as children
642*
643*=================================================================*/
644BOOL
645XmlNodeAllowChildren( XmlNode * nodeptr,
646 XmlNode * newChild )
647{
648
649 assert( nodeptr != NULL && newChild != NULL );
650 switch ( nodeptr->nodeType )
651 {
652 case XML_ATTRIBUTE_NODE:
653 case XML_TEXT_NODE:
654 case XML_CDATA_SECTION_NODE:
655 return FALSE;
656 break;
657
658 case XML_ELEMENT_NODE:
659 if ( ( newChild->nodeType == XML_ATTRIBUTE_NODE ) ||
660 ( newChild->nodeType == XML_DOCUMENT_NODE ) )
661 {
662 return FALSE;
663 }
664 break;
665
666 case XML_DOCUMENT_NODE:
667 if ( newChild->nodeType != XML_ELEMENT_NODE )
668 {
669 return FALSE;
670 }
671
672 default:
673 break;
674 }
675
676 return TRUE;
677}
678
679/*================================================================
680* XmlNodeCompare
681* Compare two nodes to see whether they are the same node.
682* Parent, sibling and children node are ignored.
683* Internal to parser only.
684* Returns:
685* TRUE, the two nodes are the same.
686* FALSE, the two nodes are not the same.
687*
688*=================================================================*/
689BOOL
690XmlNodeCompare( XmlNode * srcNode,
691 XmlNode * destNode )
692{
693 assert( srcNode != NULL && destNode != NULL );
694 if ( ( srcNode == destNode ) ||
695 ( strcmp( srcNode->nodeName, destNode->nodeName ) == 0 &&
696 strcmp( srcNode->nodeValue, destNode->nodeValue ) == 0 &&
697 ( srcNode->nodeType == destNode->nodeType ) &&
698 strcmp( srcNode->namespaceURI, destNode->namespaceURI ) == 0 &&
699 strcmp( srcNode->prefix, destNode->prefix ) == 0 &&
700 strcmp( srcNode->localName, destNode->localName ) == 0 ) )
701 {
702 return TRUE;
703 }
704 else
705 {
706 return FALSE;
707 }
708}
709
710/*================================================================
711* XmlNodeInsertBefore
712* Inserts the node newChild before the existing child node refChild.
713* If refChild is null, insert newChild at the end of the list of
714* children. If the newChild is already in the tree, it is first
715* removed.
716* External function.
717* Parameters:
718* newChild: the node to insert.
719* Returns:
720*
721*=================================================================*/
722int
723XmlNodeInsertBefore( XmlNode * nodeptr,
724 XmlNode * newChild,
725 XmlNode * refChild )
726{
727
728 int ret = XML_OK;
729
730 if ( ( nodeptr == NULL ) || ( newChild == NULL ) )
731 {
732 return XML_INVALID_PARAMETER;
733 }
734 // whether nodeptr allow children of the type of newChild
735 if ( XmlNodeAllowChildren( nodeptr, newChild ) == FALSE )
736 {
737 return XML_HIERARCHY_REQUEST_ERR;
738 }
739 // or if newChild is one of nodeptr's ancestors
740 if ( XmlNodeIsAncestor( newChild, nodeptr ) == TRUE )
741 {
742 return XML_HIERARCHY_REQUEST_ERR;
743 }
744 // if newChild was created from a different document
745 if ( nodeptr->ownerDocument != newChild->ownerDocument )
746 {
747 return XML_WRONG_DOCUMENT_ERR;
748 }
749 // if refChild is not a child of nodeptr
750 if ( XmlNodeIsParent( nodeptr, refChild ) == FALSE )
751 {
752 return XML_NOT_FOUND_ERR;
753 }
754
755 if ( refChild != NULL )
756 {
757 if ( XmlNodeIsParent( nodeptr, newChild ) == TRUE )
758 {
759 XmlNodeRemoveChild( nodeptr, newChild, NULL );
760 newChild->nextSibling = NULL;
761 newChild->prevSibling = NULL;
762 }
763
764 newChild->nextSibling = refChild;
765 if ( refChild->prevSibling != NULL )
766 {
767 ( refChild->prevSibling )->nextSibling = newChild;
768 newChild->prevSibling = refChild->prevSibling;
769 }
770
771 refChild->prevSibling = newChild;
772
773 if ( newChild->prevSibling == NULL )
774 {
775 nodeptr->firstChild = newChild;
776 }
777
778 newChild->parentNode = nodeptr;
779
780 }
781 else
782 {
783 ret = XmlNodeAppendChild( nodeptr, newChild );
784 }
785
786 return ret;
787}
788
789/*================================================================
790* XmlNodeReplaceChild
791* Replaces the child node oldChild with newChild in the list of children,
792* and returns the oldChild node.
793* External function.
794* Parameters:
795* newChild: the new node to put in the child list.
796* oldChild: the node being replaced in the list.
797* returnNode: the node replaced.
798* Return Value:
799* XML_OK
800* XML_INVALID_PARAMETER: if anyone of nodeptr, newChild or oldChild is NULL.
801* XML_HIERARCHY_REQUEST_ERR: if the newChild is ancestor of nodeptr or nodeptr
802* is of a type that does not allow children of the
803* type of the newChild node.
804* XML_WRONG_DOCUMENT_ERR: if newChild was created from a different document than
805* the one that created this node.
806* XML_NOT_FOUND_ERR: if oldChild is not a child of nodeptr.
807*
808*=================================================================*/
809int
810XmlNodeReplaceChild( XmlNode * nodeptr,
811 XmlNode * newChild,
812 XmlNode * oldChild,
813 OUT XmlNode ** returnNode )
814{
815 int ret = XML_OK;
816
817 if ( ( nodeptr == NULL ) || ( newChild == NULL )
818 || ( oldChild == NULL ) )
819 {
820 return XML_INVALID_PARAMETER;
821 }
822 // if nodetype of nodeptr does not allow children of the type of newChild
823 // needs to add later
824
825 // or if newChild is one of nodeptr's ancestors
826 if ( XmlNodeIsAncestor( newChild, nodeptr ) == TRUE )
827 {
828 return XML_HIERARCHY_REQUEST_ERR;
829 }
830
831 if ( XmlNodeAllowChildren( nodeptr, newChild ) == FALSE )
832 {
833 return XML_HIERARCHY_REQUEST_ERR;
834 }
835 // if newChild was created from a different document
836 if ( nodeptr->ownerDocument != newChild->ownerDocument )
837 {
838 return XML_WRONG_DOCUMENT_ERR;
839 }
840 // if refChild is not a child of nodeptr
841 if ( XmlNodeIsParent( nodeptr, oldChild ) != TRUE )
842 {
843 return XML_NOT_FOUND_ERR;
844 }
845
846 ret = XmlNodeInsertBefore( nodeptr, newChild, oldChild );
847 if ( ret != XML_OK )
848 {
849 return ret;
850 }
851
852 ret = XmlNodeRemoveChild( nodeptr, oldChild, returnNode );
853 return ret;
854}
855
856/*================================================================
857* XmlNodeRemoveChild
858* Removes the child node indicated by oldChild from the list of
859* children, and returns it.
860* External function.
861* Parameters:
862* oldChild: the node being removed.
863* returnNode: the node removed.
864* Return Value:
865* XML_OK
866* XML_NOT_FOUND_ERR: if oldChild is not a child of this node.
867* XML_INVALID_PARAMETER: if either oldChild or nodeptr is NULL
868*
869*=================================================================*/
870int
871XmlNodeRemoveChild( XmlNode * nodeptr,
872 XmlNode * oldChild,
873 OUT XmlNode ** returnNode )
874{
875
876 if ( ( nodeptr == NULL ) || ( oldChild == NULL ) )
877 {
878 return XML_INVALID_PARAMETER;
879 }
880
881 if ( XmlNodeIsParent( nodeptr, oldChild ) == FALSE )
882 {
883 return XML_NOT_FOUND_ERR;
884 }
885
886 if ( oldChild->prevSibling != NULL )
887 {
888 ( oldChild->prevSibling )->nextSibling = oldChild->nextSibling;
889 }
890
891 if ( nodeptr->firstChild == oldChild )
892 {
893 nodeptr->firstChild = oldChild->nextSibling;
894 }
895
896 if ( oldChild->nextSibling != NULL )
897 {
898 ( oldChild->nextSibling )->prevSibling = oldChild->prevSibling;
899 }
900
901 oldChild->nextSibling = NULL;
902 oldChild->prevSibling = NULL;
903 oldChild->parentNode = NULL;
904
905 if ( returnNode != NULL )
906 {
907 *returnNode = oldChild;
908 }
909 return XML_OK;
910}
911
912/*========================================================================================
913* XmlNodeAppendChild
914* Adds the node newChild to the end of the list of children of this node.
915* If the newChild is already in the tree, it is first removed.
916* External function.
917* Parameter:
918* newChild: the node to add.
919* Return Value:
920* XML_OK
921* XML_INVALID_PARAMETER: if either nodeptr or newChild is NULL
922* XML_WRONG_DOCUMENT_ERR: if newChild was created from a different document than
923* the one that created nodeptr.
924* XML_HIERARCHY_REQUEST_ERR: if newChild is ancestor of nodeptr or if nodeptr is of
925* a type that does not allow children of the type of the
926* newChild node.
927*
928*========================================================================================*/
929int
930XmlNodeAppendChild( XmlNode * nodeptr,
931 XmlNode * newChild )
932{
933
934 XmlNode * prev = NULL;
935 XmlNode * next = NULL;
936
937
938 if ( ( nodeptr == NULL ) || ( newChild == NULL ) )
939 {
940 return XML_INVALID_PARAMETER;
941 }
942 // if newChild was created from a different document
943 if ( ( newChild->ownerDocument != NULL ) &&
944 ( nodeptr->ownerDocument != newChild->ownerDocument ) )
945 {
946 return XML_WRONG_DOCUMENT_ERR;
947 }
948 // if newChild is an ancestor of nodeptr
949 if ( XmlNodeIsAncestor( newChild, nodeptr ) == TRUE )
950 {
951 return XML_HIERARCHY_REQUEST_ERR;
952 }
953 // if nodeptr does not allow to have newChild as children
954 if ( XmlNodeAllowChildren( nodeptr, newChild ) == FALSE )
955 {
956 return XML_HIERARCHY_REQUEST_ERR;
957 }
958
959 if ( XmlNodeIsParent( nodeptr, newChild ) == TRUE )
960 {
961 XmlNodeRemoveChild( nodeptr, newChild, NULL );
962 }
963 // set the parent node pointer
964 newChild->parentNode = nodeptr;
965 newChild->ownerDocument = nodeptr->ownerDocument;
966
967 //if the first child
968 if ( nodeptr->firstChild == NULL )
969 {
970 nodeptr->firstChild = newChild;
971 }
972 else
973 {
974 prev = nodeptr->firstChild;
975 next = prev->nextSibling;
976 while ( next != NULL )
977 {
978 prev = next;
979 next = prev->nextSibling;
980 }
981 prev->nextSibling = newChild;
982 newChild->prevSibling = prev;
983 }
984
985
986 return XML_OK;
987}
988
989/*================================================================
990* XmlNodeCloneTextNode
991* Returns a clone of nodeptr
992* Internal to parser only.
993*
994*=================================================================*/
995XmlNode *
996#ifdef USE_CWMP_MEMORY_POOL
997XmlNodeCloneTextNode(Pool * pool, XmlNode * nodeptr )
998#else
999XmlNodeCloneTextNode( XmlNode * nodeptr )
1000#endif
1001
1002{
1003 XmlNode * newNode = NULL;
1004
1005 assert( nodeptr != NULL );
1006
1007 newNode = ( XmlNode * ) PMALLOC( sizeof( XmlNode ) );
1008 if ( newNode == NULL )
1009 {
1010 return NULL;
1011 }
1012 else
1013 {
1014 XmlNodeInit( newNode );
1015
1016 XmlNodeSetNodeName(
1017#ifdef USE_CWMP_MEMORY_POOL
1018 pool ,
1019#endif
1020
1021 newNode, nodeptr->nodeName );
1022 XmlNodeSetNodeValue(
1023#ifdef USE_CWMP_MEMORY_POOL
1024 pool ,
1025#endif
1026 newNode, nodeptr->nodeValue );
1027 newNode->nodeType = XML_TEXT_NODE;
1028 }
1029
1030 return newNode;
1031}
1032
1033/*================================================================
1034* XmlNodeCloneCDATASect
1035* Return a clone of CDATASection node.
1036* Internal to parser only.
1037*
1038*=================================================================*/
1039XmlCDATASection *
1040#ifdef USE_CWMP_MEMORY_POOL
1041XmlNodeCloneCDATASect(Pool * pool, XmlCDATASection * nodeptr )
1042#else
1043XmlNodeCloneCDATASect( XmlCDATASection * nodeptr )
1044#endif
1045
1046{
1047 XmlCDATASection *newCDATA = NULL;
1048 XmlNode * newNode;
1049 XmlNode * srcNode;
1050
1051 assert( nodeptr != NULL );
1052 newCDATA =
1053 ( XmlCDATASection * ) PMALLOC( sizeof( XmlCDATASection ) );
1054 if ( newCDATA != NULL )
1055 {
1056 newNode = ( XmlNode * ) newCDATA;
1057 XmlNodeInit( newNode );
1058
1059 srcNode = ( XmlNode * ) nodeptr;
1060 XmlNodeSetNodeName(
1061#ifdef USE_CWMP_MEMORY_POOL
1062 pool ,
1063#endif
1064 newNode, srcNode->nodeName );
1065 XmlNodeSetNodeValue(
1066#ifdef USE_CWMP_MEMORY_POOL
1067 pool ,
1068#endif
1069 newNode, srcNode->nodeValue );
1070 newNode->nodeType = XML_CDATA_SECTION_NODE;
1071 }
1072
1073 return newCDATA;
1074}
1075
1076/*================================================================
1077* XmlNodeCloneElement
1078* returns a clone of element node
1079* Internal to parser only.
1080*
1081*=================================================================*/
1082XmlElement *
1083#ifdef USE_CWMP_MEMORY_POOL
1084XmlNodeCloneElement(Pool * pool, XmlElement * nodeptr )
1085#else
1086XmlNodeCloneElement( XmlElement * nodeptr )
1087#endif
1088
1089{
1090 XmlElement *newElement;
1091 XmlNode * elementNode;
1092 XmlNode * srcNode;
1093 int rc;
1094
1095 assert( nodeptr != NULL );
1096
1097 newElement = ( XmlElement * ) PMALLOC( sizeof( XmlElement ) );
1098 if ( newElement == NULL )
1099 {
1100 return NULL;
1101 }
1102
1103 XmlElementInit( newElement );
1104 rc = XmlElementSetTagName(
1105#ifdef USE_CWMP_MEMORY_POOL
1106 pool ,
1107#endif
1108 newElement, nodeptr->tagName );
1109 if ( rc != XML_OK )
1110 {
1111 goto ErrorHandle;
1112 }
1113
1114 elementNode = ( XmlNode * ) newElement;
1115 srcNode = ( XmlNode * ) nodeptr;
1116 rc = XmlNodeSetNodeName(
1117#ifdef USE_CWMP_MEMORY_POOL
1118 pool ,
1119#endif
1120 elementNode, srcNode->nodeName );
1121 if ( rc != XML_OK )
1122 {
1123 goto ErrorHandle;
1124 }
1125
1126 rc = XmlNodeSetNodeValue(
1127#ifdef USE_CWMP_MEMORY_POOL
1128 pool ,
1129#endif
1130 elementNode, srcNode->nodeValue );
1131 if ( rc != XML_OK )
1132 {
1133 goto ErrorHandle;
1134 }
1135
1136 rc = XmlNodeSetNamespaceURI(
1137#ifdef USE_CWMP_MEMORY_POOL
1138 pool ,
1139#endif
1140 elementNode, srcNode->namespaceURI );
1141 if ( rc != XML_OK )
1142 {
1143 goto ErrorHandle;
1144 }
1145
1146 rc = XmlNodeSetPrefix(
1147#ifdef USE_CWMP_MEMORY_POOL
1148 pool ,
1149#endif
1150 elementNode, srcNode->prefix );
1151 if ( rc != XML_OK )
1152 {
1153 goto ErrorHandle;
1154 }
1155
1156 rc = XmlNodeSetLocalName(
1157#ifdef USE_CWMP_MEMORY_POOL
1158 pool ,
1159#endif
1160 elementNode, srcNode->localName );
1161 if ( rc != XML_OK )
1162 {
1163 goto ErrorHandle;
1164 }
1165
1166 elementNode->nodeType = XML_ELEMENT_NODE;
1167
1168 return newElement;
1169
1170ErrorHandle:
1171 XmlElementFree(
1172#ifdef USE_CWMP_MEMORY_POOL
1173 pool ,
1174#endif
1175 newElement );
1176
1177 return NULL;
1178
1179}
1180
1181/*================================================================
1182* XmlNodeCloneDoc
1183* Returns a clone of document node
1184* Internal to parser only.
1185*
1186*=================================================================*/
1187XmlDocument *
1188#ifdef USE_CWMP_MEMORY_POOL
1189XmlNodeCloneDoc(Pool * pool, XmlDocument * nodeptr)
1190#else
1191XmlNodeCloneDoc(XmlDocument * nodeptr)
1192#endif
1193{
1194 XmlDocument *newDoc;
1195 XmlNode * docNode;
1196 int rc;
1197
1198 assert( nodeptr != NULL );
1199 newDoc = ( XmlDocument * ) PMALLOC( sizeof( XmlDocument ) );
1200 if ( newDoc == NULL )
1201 {
1202 return NULL;
1203 }
1204
1205 XmlDocumentInit( newDoc );
1206 docNode = ( XmlNode * ) newDoc;
1207
1208 rc = XmlNodeSetNodeName(
1209#ifdef USE_CWMP_MEMORY_POOL
1210 pool ,
1211#endif
1212
1213 docNode, DOCUMENTNODENAME );
1214 if ( rc != XML_OK )
1215 {
1216 XmlDocumentFree(
1217#ifdef USE_CWMP_MEMORY_POOL
1218 pool ,
1219#endif
1220 newDoc );
1221 return NULL;
1222 }
1223
1224 newDoc->node.nodeType = XML_DOCUMENT_NODE;
1225
1226 return newDoc;
1227
1228}
1229
1230/*================================================================
1231* XmlNodeCloneAttr
1232* Returns a clone of attribute node
1233* Internal to parser only
1234*
1235*=================================================================*/
1236XmlAttribute *
1237#ifdef USE_CWMP_MEMORY_POOL
1238XmlNodeCloneAttr(Pool * pool, XmlAttribute * nodeptr )
1239#else
1240XmlNodeCloneAttr( XmlAttribute * nodeptr )
1241#endif
1242{
1243 XmlAttribute *newAttr;
1244 XmlNode * attrNode;
1245 XmlNode * srcNode;
1246 int rc;
1247
1248 assert( nodeptr != NULL );
1249 newAttr = ( XmlAttribute * ) PMALLOC( sizeof( XmlAttribute ) );
1250 if ( newAttr == NULL )
1251 {
1252 return NULL;
1253 }
1254
1255 XmlAttrInit( newAttr );
1256 attrNode = ( XmlNode * ) newAttr;
1257 srcNode = ( XmlNode * ) nodeptr;
1258
1259 rc = XmlNodeSetNodeName(
1260#ifdef USE_CWMP_MEMORY_POOL
1261 pool ,
1262#endif
1263 attrNode, srcNode->nodeName );
1264 if ( rc != XML_OK )
1265 {
1266 XmlAttrFree(
1267#ifdef USE_CWMP_MEMORY_POOL
1268 pool ,
1269#endif
1270
1271 newAttr );
1272 return NULL;
1273 }
1274
1275 rc = XmlNodeSetNodeValue(
1276#ifdef USE_CWMP_MEMORY_POOL
1277 pool ,
1278#endif
1279 attrNode, srcNode->nodeValue );
1280 if ( rc != XML_OK )
1281 {
1282 XmlAttrFree(
1283#ifdef USE_CWMP_MEMORY_POOL
1284 pool ,
1285#endif
1286 newAttr );
1287 return NULL;
1288 }
1289 //check to see whether we need to split prefix and localname for attribute
1290 rc = XmlNodeSetNamespaceURI(
1291#ifdef USE_CWMP_MEMORY_POOL
1292 pool ,
1293#endif
1294 attrNode, srcNode->namespaceURI );
1295 if ( rc != XML_OK )
1296 {
1297 XmlAttrFree(
1298#ifdef USE_CWMP_MEMORY_POOL
1299 pool ,
1300#endif
1301 newAttr );
1302 return NULL;
1303 }
1304
1305 rc = XmlNodeSetPrefix(
1306#ifdef USE_CWMP_MEMORY_POOL
1307 pool ,
1308#endif
1309 attrNode, srcNode->prefix );
1310 if ( rc != XML_OK )
1311 {
1312 XmlAttrFree(
1313#ifdef USE_CWMP_MEMORY_POOL
1314 pool ,
1315#endif
1316 newAttr );
1317 return NULL;
1318 }
1319
1320 rc = XmlNodeSetLocalName(
1321#ifdef USE_CWMP_MEMORY_POOL
1322 pool ,
1323#endif
1324 attrNode, srcNode->localName );
1325 if ( rc != XML_OK )
1326 {
1327 XmlAttrFree(
1328#ifdef USE_CWMP_MEMORY_POOL
1329 pool ,
1330#endif
1331 newAttr );
1332 return NULL;
1333 }
1334
1335 attrNode->nodeType = XML_ATTRIBUTE_NODE;
1336
1337 return newAttr;
1338}
1339
1340/*================================================================
1341* XmlNodeCloneAttrDirect
1342* Return a clone of attribute node, with specified field set
1343* to TRUE.
1344*
1345*=================================================================*/
1346XmlAttribute *
1347XmlNodeCloneAttrDirect(
1348 Pool * pool,
1349
1350 XmlAttribute * nodeptr )
1351{
1352
1353 XmlAttribute *newAttr;
1354
1355 assert( nodeptr != NULL );
1356
1357 newAttr = XmlNodeCloneAttr(
1358#ifdef USE_CWMP_MEMORY_POOL
1359 pool ,
1360#endif
1361
1362 nodeptr );
1363 if ( newAttr != NULL )
1364 {
1365 newAttr->specified = TRUE;
1366 }
1367
1368 return newAttr;
1369}
1370
1371void
1372XmlNodeSetSiblingNodesParent( XmlNode * nodeptr )
1373{
1374 XmlNode * parentNode = nodeptr->parentNode;
1375 XmlNode * nextptr = nodeptr->nextSibling;
1376
1377 while ( nextptr != NULL )
1378 {
1379 nextptr->parentNode = parentNode;
1380 nextptr = nextptr->nextSibling;
1381 }
1382}
1383
1384/*================================================================
1385* XmlNodeCloneNodeTreeRecursive
1386* recursive functions that clones node tree of nodeptr.
1387* Internal to parser only.
1388*
1389*=================================================================*/
1390XmlNode *
1391XmlNodeCloneNodeTreeRecursive(
1392 Pool * pool,
1393
1394 XmlNode * nodeptr,
1395 IN BOOL deep )
1396{
1397 XmlNode * newNode = NULL;
1398 XmlElement *newElement;
1399 XmlAttribute *newAttr = NULL;
1400 XmlCDATASection *newCDATA = NULL;
1401 XmlDocument *newDoc;
1402 XmlNode * nextSib;
1403
1404 if ( nodeptr != NULL )
1405 {
1406 switch ( nodeptr->nodeType )
1407 {
1408 case XML_ELEMENT_NODE:
1409 newElement =
1410 XmlNodeCloneElement(
1411#ifdef USE_CWMP_MEMORY_POOL
1412 pool ,
1413#endif
1414 ( XmlElement * ) nodeptr );
1415 if(NULL == newElement)
1416 {
1417 return NULL;
1418 }
1419
1420 newElement->node.firstAttr =
1421 XmlNodeCloneNodeTreeRecursive(
1422#ifdef USE_CWMP_MEMORY_POOL
1423 pool ,
1424#endif
1425 nodeptr->firstAttr,
1426 deep );
1427 if ( deep )
1428 {
1429 newElement->node.firstChild =
1430 XmlNodeCloneNodeTreeRecursive(
1431#ifdef USE_CWMP_MEMORY_POOL
1432 pool ,
1433#endif
1434 nodeptr->
1435 firstChild,
1436 deep );
1437 if ( newElement->node.firstChild != NULL )
1438 {
1439 ( newElement->node.firstChild )->parentNode =
1440 ( XmlNode * ) newElement;
1441 XmlNodeSetSiblingNodesParent( newElement->node.
1442 firstChild );
1443 }
1444 nextSib =
1445 XmlNodeCloneNodeTreeRecursive(
1446#ifdef USE_CWMP_MEMORY_POOL
1447 pool ,
1448#endif
1449
1450 nodeptr->
1451 nextSibling,
1452 deep );
1453 newElement->node.nextSibling = nextSib;
1454 if ( nextSib != NULL )
1455 {
1456 nextSib->prevSibling = ( XmlNode * ) newElement;
1457 }
1458 }
1459
1460 newNode = ( XmlNode * ) newElement;
1461 break;
1462
1463 case XML_ATTRIBUTE_NODE:
1464 newAttr = XmlNodeCloneAttr(
1465#ifdef USE_CWMP_MEMORY_POOL
1466 pool ,
1467#endif
1468
1469 ( XmlAttribute * ) nodeptr );
1470 if(NULL == newAttr)
1471 {
1472 return NULL;
1473 }
1474
1475
1476 nextSib =
1477 XmlNodeCloneNodeTreeRecursive(
1478#ifdef USE_CWMP_MEMORY_POOL
1479 pool ,
1480#endif
1481 nodeptr->nextSibling,
1482 deep );
1483 newAttr->node.nextSibling = nextSib;
1484
1485 if ( nextSib != NULL )
1486 {
1487 nextSib->prevSibling = ( XmlNode * ) newAttr;
1488 }
1489 newNode = ( XmlNode * ) newAttr;
1490 break;
1491
1492 case XML_TEXT_NODE:
1493 newNode = XmlNodeCloneTextNode(
1494#ifdef USE_CWMP_MEMORY_POOL
1495 pool ,
1496#endif
1497
1498 nodeptr );
1499 break;
1500
1501 case XML_CDATA_SECTION_NODE:
1502 newCDATA =
1503 XmlNodeCloneCDATASect(
1504#ifdef USE_CWMP_MEMORY_POOL
1505 pool ,
1506#endif
1507
1508 ( XmlCDATASection * )
1509 nodeptr );
1510 newNode = ( XmlNode * ) newCDATA;
1511 break;
1512
1513 case XML_DOCUMENT_NODE:
1514 newDoc = XmlNodeCloneDoc(
1515#ifdef USE_CWMP_MEMORY_POOL
1516 pool ,
1517#endif
1518
1519 ( XmlDocument * ) nodeptr );
1520
1521 if(NULL == newDoc)
1522 {
1523 return NULL;
1524 }
1525
1526 newNode = ( XmlNode * ) newDoc;
1527 if ( deep )
1528 {
1529 newNode->firstChild =
1530 XmlNodeCloneNodeTreeRecursive(
1531#ifdef USE_CWMP_MEMORY_POOL
1532 pool ,
1533#endif
1534
1535 nodeptr->
1536 firstChild,
1537 deep );
1538 if ( newNode->firstChild != NULL )
1539 {
1540 newNode->firstChild->parentNode = newNode;
1541 }
1542 }
1543
1544 break;
1545
1546 case XML_INVALID_NODE:
1547 case XML_ENTITY_REFERENCE_NODE:
1548 case XML_ENTITY_NODE:
1549 case XML_PROCESSING_INSTRUCTION_NODE:
1550 case XML_COMMENT_NODE:
1551 case XML_DOCUMENT_TYPE_NODE:
1552 case XML_DOCUMENT_FRAGMENT_NODE:
1553 case XML_NOTATION_NODE:
1554 break;
1555 }
1556 }
1557
1558 return newNode;
1559}
1560
1561/*================================================================
1562* XmlNodeCloneNodeTree
1563* clones a node tree.
1564* Internal to parser only.
1565*
1566*=================================================================*/
1567XmlNode *
1568XmlNodeCloneNodeTree(
1569 Pool * pool,
1570 XmlNode * nodeptr,
1571 IN BOOL deep )
1572{
1573 XmlNode * newNode = NULL;
1574 XmlElement *newElement;
1575 XmlNode * childNode;
1576
1577 assert( nodeptr != NULL );
1578
1579 switch ( nodeptr->nodeType )
1580 {
1581 case XML_ELEMENT_NODE:
1582 newElement =
1583 XmlNodeCloneElement(
1584#ifdef USE_CWMP_MEMORY_POOL
1585 pool ,
1586#endif
1587
1588 ( XmlElement * ) nodeptr );
1589
1590 if(NULL == newElement)
1591 {
1592 return NULL;
1593 }
1594
1595 newElement->node.firstAttr =
1596 XmlNodeCloneNodeTreeRecursive(
1597#ifdef USE_CWMP_MEMORY_POOL
1598 pool ,
1599#endif
1600
1601 nodeptr->firstAttr,
1602 deep );
1603 if ( deep )
1604 {
1605 newElement->node.firstChild =
1606 XmlNodeCloneNodeTreeRecursive(
1607#ifdef USE_CWMP_MEMORY_POOL
1608 pool ,
1609#endif
1610
1611 nodeptr->firstChild,
1612 deep );
1613 childNode = newElement->node.firstChild;
1614 while ( childNode != NULL )
1615 {
1616 childNode->parentNode = ( XmlNode * ) newElement;
1617 childNode = childNode->nextSibling;
1618 }
1619 newElement->node.nextSibling = NULL;
1620 }
1621
1622 newNode = ( XmlNode * ) newElement;
1623 break;
1624
1625 case XML_ATTRIBUTE_NODE:
1626 case XML_TEXT_NODE:
1627 case XML_CDATA_SECTION_NODE:
1628 case XML_DOCUMENT_NODE:
1629 newNode = XmlNodeCloneNodeTreeRecursive(
1630#ifdef USE_CWMP_MEMORY_POOL
1631 pool ,
1632#endif
1633
1634 nodeptr, deep );
1635 break;
1636
1637 case XML_INVALID_NODE:
1638 case XML_ENTITY_REFERENCE_NODE:
1639 case XML_ENTITY_NODE:
1640 case XML_PROCESSING_INSTRUCTION_NODE:
1641 case XML_COMMENT_NODE:
1642 case XML_DOCUMENT_TYPE_NODE:
1643 case XML_DOCUMENT_FRAGMENT_NODE:
1644 case XML_NOTATION_NODE:
1645 break;
1646 }
1647
1648 if(NULL != newNode)
1649 {
1650 // by spec, the duplicate node has no parent
1651 newNode->parentNode = NULL;
1652 }
1653
1654 return newNode;
1655}
1656
1657/*================================================================
1658* XmlNodeCloneNode
1659* Clones a node, if deep==TRUE, clones subtree under nodeptr.
1660* External function.
1661* Returns:
1662* the cloned node or NULL if error occurs.
1663*
1664*=================================================================*/
1665XmlNode *
1666XmlNodeCloneNode(
1667 Pool * pool,
1668
1669 XmlNode * nodeptr,
1670 IN BOOL deep )
1671{
1672
1673 XmlNode * newNode;
1674 XmlAttribute *newAttrNode;
1675
1676 if ( nodeptr == NULL )
1677 {
1678 return NULL;
1679 }
1680
1681 switch ( nodeptr->nodeType )
1682 {
1683 case XML_ATTRIBUTE_NODE:
1684 newAttrNode =
1685 XmlNodeCloneAttrDirect(
1686#ifdef USE_CWMP_MEMORY_POOL
1687 pool ,
1688#endif
1689
1690 ( XmlAttribute * ) nodeptr );
1691 return ( XmlNode * ) newAttrNode;
1692 break;
1693
1694 default:
1695 newNode = XmlNodeCloneNodeTree(
1696#ifdef USE_CWMP_MEMORY_POOL
1697 pool ,
1698#endif
1699
1700 nodeptr, deep );
1701 return newNode;
1702 break;
1703 }
1704
1705}
1706
1707/*================================================================
1708* XmlNodeGetChildNodes
1709* Returns a XmlNodeList of all the child nodes of nodeptr.
1710* External function.
1711*
1712*=================================================================*/
1713XmlNodeList *
1714#ifdef USE_CWMP_MEMORY_POOL
1715XmlNodeGetChildNodes(Pool * pool, XmlNode * nodeptr )
1716#else
1717XmlNodeGetChildNodes( XmlNode * nodeptr )
1718#endif
1719{
1720 XmlNode * tempNode;
1721 XmlNodeList *newNodeList;
1722 int rc;
1723
1724 if ( nodeptr == NULL )
1725 {
1726 return NULL;
1727 }
1728
1729 newNodeList = ( XmlNodeList * ) PMALLOC( sizeof( XmlNodeList ) );
1730 if ( newNodeList == NULL )
1731 {
1732 return NULL;
1733 }
1734
1735 XmlNodeListInit( newNodeList );
1736
1737 tempNode = nodeptr->firstChild;
1738 while ( tempNode != NULL )
1739 {
1740 rc = XmlNodeListAddToNodeList(
1741#ifdef USE_CWMP_MEMORY_POOL
1742 pool ,
1743#endif
1744
1745 &newNodeList, tempNode );
1746 if ( rc != XML_OK )
1747 {
1748 XmlNodeListFree(
1749#ifdef USE_CWMP_MEMORY_POOL
1750 pool ,
1751#endif
1752 newNodeList );
1753 return NULL;
1754 }
1755
1756 tempNode = tempNode->nextSibling;
1757 }
1758 return newNodeList;
1759}
1760
1761/*================================================================
1762* XmlNodeGetAttributes
1763* returns a namedNodeMap of attributes of nodeptr
1764* External function.
1765* Returns:
1766*
1767*=================================================================*/
1768XmlNamedNodeMap *
1769#ifdef USE_CWMP_MEMORY_POOL
1770XmlNodeGetAttributes(Pool * pool, XmlNode * nodeptr )
1771#else
1772XmlNodeGetAttributes( XmlNode * nodeptr )
1773#endif
1774{
1775 XmlNamedNodeMap *returnNamedNodeMap = NULL;
1776 XmlNode * tempNode;
1777 int rc;
1778
1779 if ( nodeptr == NULL )
1780 {
1781 return NULL;
1782 }
1783
1784 if ( nodeptr->nodeType == XML_ELEMENT_NODE )
1785 {
1786 returnNamedNodeMap =
1787 ( XmlNamedNodeMap * ) PMALLOC( sizeof( XmlNamedNodeMap ) );
1788 if ( returnNamedNodeMap == NULL )
1789 {
1790 return NULL;
1791 }
1792
1793 XmlNamedNodeMapInit( returnNamedNodeMap );
1794
1795 tempNode = nodeptr->firstAttr;
1796 while ( tempNode != NULL )
1797 {
1798 rc = XmlNamedNodeMapAddToNamedNodeMap(
1799#ifdef USE_CWMP_MEMORY_POOL
1800 pool ,
1801#endif
1802 &returnNamedNodeMap,
1803 tempNode );
1804 if ( rc != XML_OK )
1805 {
1806 XmlNamedNodeMapFree(
1807#ifdef USE_CWMP_MEMORY_POOL
1808 pool ,
1809#endif
1810 returnNamedNodeMap );
1811 return NULL;
1812 }
1813
1814 tempNode = tempNode->nextSibling;
1815 }
1816 return returnNamedNodeMap;
1817 }
1818 else // if not an ELEMENT_NODE
1819 {
1820 return NULL;
1821 }
1822}
1823
1824/*================================================================
1825* XmlNodeHasChildNodes
1826* External function.
1827*
1828*=================================================================*/
1829BOOL
1830XmlNodeHasChildNodes( XmlNode * nodeptr )
1831{
1832 if ( nodeptr == NULL )
1833 {
1834 return FALSE;
1835 }
1836
1837 return ( nodeptr->firstChild != NULL );
1838
1839}
1840
1841/*================================================================
1842* XmlNodeHasAttributes
1843* External function.
1844*
1845*=================================================================*/
1846BOOL
1847XmlNodeHasAttributes( XmlNode * nodeptr )
1848{
1849 if ( nodeptr != NULL )
1850 {
1851 if ( ( nodeptr->nodeType == XML_ELEMENT_NODE )
1852 && ( nodeptr->firstAttr != NULL ) )
1853 {
1854 return TRUE;
1855 }
1856 }
1857 return FALSE;
1858
1859}
1860
1861/*================================================================
1862* XmlNodeGetElementsByTagNameRecursive
1863* Recursively traverse the whole tree, search for element
1864* with the given tagname.
1865* Internal to parser.
1866*
1867*=================================================================*/
1868void
1869XmlNodeGetElementsByTagNameRecursive(
1870 Pool * pool,
1871 XmlNode * n,
1872 IN char *tagname,
1873 OUT XmlNodeList ** list )
1874{
1875 const char *name;
1876
1877 if ( n != NULL )
1878 {
1879 if ( XmlNodeGetNodeType( n ) == XML_ELEMENT_NODE )
1880 {
1881 name = XmlNodeGetNodeName( n )? XmlNodeGetNodeName( n ):"";
1882 if ( strcmp( tagname, name ) == 0
1883 || strcmp( tagname, "*" ) == 0 )
1884 {
1885 XmlNodeListAddToNodeList(
1886#ifdef USE_CWMP_MEMORY_POOL
1887 pool ,
1888#endif
1889
1890 list, n );
1891 }
1892 }
1893
1894 XmlNodeGetElementsByTagNameRecursive(
1895#ifdef USE_CWMP_MEMORY_POOL
1896 pool ,
1897#endif
1898 XmlNodeGetFirstChild
1899 ( n ), tagname, list );
1900 XmlNodeGetElementsByTagNameRecursive(
1901#ifdef USE_CWMP_MEMORY_POOL
1902 pool ,
1903#endif
1904
1905 XmlNodeGetNextSibling
1906 ( n ), tagname, list );
1907 }
1908
1909}
1910
1911/*================================================================
1912* XmlNodeGetElementsByTagName
1913* Returns a nodeList of all descendant Elements with a given
1914* tagName, in the order in which they are encountered in a
1915* traversal of this element tree.
1916* External function.
1917*
1918*=================================================================*/
1919void
1920XmlNodeGetElementsByTagName(
1921 Pool * pool,
1922 XmlNode * n,
1923 IN char *tagname,
1924 OUT XmlNodeList ** list )
1925{
1926 const char *name;
1927
1928 assert( n != NULL && tagname != NULL );
1929
1930 if ( XmlNodeGetNodeType( n ) == XML_ELEMENT_NODE )
1931 {
1932 name = XmlNodeGetNodeName( n )?XmlNodeGetNodeName( n ):"";
1933 if ( strcmp( tagname, name ) == 0 || strcmp( tagname, "*" ) == 0 )
1934 {
1935 XmlNodeListAddToNodeList(
1936#ifdef USE_CWMP_MEMORY_POOL
1937 pool ,
1938#endif
1939 list, n );
1940 }
1941 }
1942
1943 XmlNodeGetElementsByTagNameRecursive(
1944#ifdef USE_CWMP_MEMORY_POOL
1945 pool ,
1946#endif
1947 XmlNodeGetFirstChild( n ),
1948 tagname, list );
1949
1950}
1951
1952/*================================================================
1953* XmlNodeGetElementsByTagNameNSRecursive
1954* Internal function to parser.
1955*
1956*
1957*=================================================================*/
1958void
1959XmlNodeGetElementsByTagNameNSRecursive(
1960 Pool * pool,
1961 XmlNode * n,
1962 const char *namespaceURI,
1963 const char *localName,
1964 OUT XmlNodeList ** list )
1965{
1966 const char * nsURI;
1967 const char * name;
1968
1969 if ( n != NULL )
1970 {
1971 if ( XmlNodeGetNodeType( n ) == XML_ELEMENT_NODE )
1972 {
1973 name = XmlNodeGetLocalName( n );
1974 nsURI = XmlNodeGetNamespaceURI( n );
1975
1976 if ( ( name != NULL ) && ( nsURI != NULL ) &&
1977 ( strcmp( namespaceURI, nsURI ) == 0
1978 || strcmp( namespaceURI, "*" ) == 0 )
1979 && ( strcmp( name, localName ) == 0
1980 || strcmp( localName, "*" ) == 0 ) )
1981 {
1982 XmlNodeListAddToNodeList(
1983#ifdef USE_CWMP_MEMORY_POOL
1984 pool ,
1985#endif
1986 list, n );
1987 }
1988 }
1989
1990 XmlNodeGetElementsByTagNameNSRecursive(
1991#ifdef USE_CWMP_MEMORY_POOL
1992 pool ,
1993#endif
1994
1995 XmlNodeGetFirstChild
1996 ( n ), namespaceURI,
1997 localName, list );
1998 XmlNodeGetElementsByTagNameNSRecursive(
1999#ifdef USE_CWMP_MEMORY_POOL
2000 pool ,
2001#endif
2002 XmlNodeGetNextSibling
2003 ( n ), namespaceURI,
2004 localName, list );
2005 }
2006
2007}
2008
2009/*================================================================
2010* XmlNodeGetElementsByTagNameNS
2011* Returns a nodeList of all the descendant Elements with a given
2012* local name and namespace URI in the order in which they are
2013* encountered in a preorder traversal of this Elememt tree.
2014* External function.
2015*
2016*=================================================================*/
2017void
2018XmlNodeGetElementsByTagNameNS(
2019 Pool * pool,
2020 XmlNode * n,
2021 const char *namespaceURI,
2022 const char *localName,
2023 OUT XmlNodeList ** list )
2024{
2025 const char * nsURI;
2026 const char * name;
2027
2028 assert( n != NULL && namespaceURI != NULL && localName != NULL );
2029
2030 if ( XmlNodeGetNodeType( n ) == XML_ELEMENT_NODE )
2031 {
2032 name = XmlNodeGetLocalName( n );
2033 nsURI = XmlNodeGetNamespaceURI( n );
2034
2035 if ( ( name != NULL ) && ( nsURI != NULL ) &&
2036 ( strcmp( namespaceURI, nsURI ) == 0
2037 || strcmp( namespaceURI, "*" ) == 0 )
2038 && ( strcmp( name, localName ) == 0
2039 || strcmp( localName, "*" ) == 0 ) )
2040 {
2041 XmlNodeListAddToNodeList(
2042#ifdef USE_CWMP_MEMORY_POOL
2043 pool ,
2044#endif
2045 list, n );
2046 }
2047 }
2048
2049 XmlNodeGetElementsByTagNameNSRecursive(
2050#ifdef USE_CWMP_MEMORY_POOL
2051 pool ,
2052#endif
2053 XmlNodeGetFirstChild( n ),
2054 namespaceURI, localName,
2055 list );
2056
2057}
2058
2059/*================================================================
2060* XmlNodeSetNodeName
2061* Internal to parser only.
2062*
2063*=================================================================*/
2064int
2065XmlNodeSetNodeName(
2066 Pool * pool,
2067
2068 XmlNode * node,
2069 const char * qualifiedName )
2070{
2071 int rc = XML_OK;
2072
2073 assert( node != NULL );
2074
2075 if ( node->nodeName != NULL )
2076 {
2077 PFREE( node->nodeName );
2078 node->nodeName = NULL;
2079 }
2080
2081 if ( qualifiedName != NULL )
2082 {
2083 // set the name part
2084 node->nodeName = PSTRDUP( qualifiedName );
2085 if ( node->nodeName == NULL )
2086 {
2087 return XML_INSUFFICIENT_MEMORY;
2088 }
2089
2090 rc = XmlParserSetNodePrefixAndLocalName(
2091#ifdef USE_CWMP_MEMORY_POOL
2092 pool ,
2093#endif
2094 node );
2095 if ( rc != XML_OK )
2096 {
2097 PFREE( node->nodeName );
2098 }
2099 }
2100
2101 return rc;
2102}
2103
2104/*================================================================
2105* XmlNodeSetNodeProperties
2106* Internal to parser only.
2107*
2108*=================================================================*/
2109int
2110XmlNodeSetNodeProperties(
2111 Pool * pool,
2112 XmlNode * destNode,
2113 XmlNode * src )
2114{
2115
2116 int rc;
2117
2118 assert( destNode != NULL || src != NULL );
2119
2120 rc = XmlNodeSetNodeValue(
2121#ifdef USE_CWMP_MEMORY_POOL
2122 pool ,
2123#endif
2124 destNode, src->nodeValue );
2125 if ( rc != XML_OK )
2126 {
2127 goto ErrorHandler;
2128 }
2129
2130 rc = XmlNodeSetLocalName(
2131#ifdef USE_CWMP_MEMORY_POOL
2132 pool ,
2133#endif
2134 destNode, src->localName );
2135 if ( rc != XML_OK )
2136 {
2137 goto ErrorHandler;
2138 }
2139
2140 rc = XmlNodeSetPrefix(
2141#ifdef USE_CWMP_MEMORY_POOL
2142 pool ,
2143#endif
2144 destNode, src->prefix );
2145 if ( rc != XML_OK )
2146 {
2147 goto ErrorHandler;
2148 }
2149 // set nodetype
2150 destNode->nodeType = src->nodeType;
2151
2152 return XML_OK;
2153
2154ErrorHandler:
2155#ifndef USE_CWMP_MEMORY_POOL
2156 if ( destNode->nodeName != NULL )
2157 {
2158 PFREE( destNode->nodeName );
2159 destNode->nodeName = NULL;
2160 }
2161 if ( destNode->nodeValue != NULL )
2162 {
2163 PFREE( destNode->nodeValue );
2164 destNode->nodeValue = NULL;
2165 }
2166 if ( destNode->localName != NULL )
2167 {
2168 PFREE( destNode->localName );
2169 destNode->localName = NULL;
2170 }
2171#endif
2172 return XML_INSUFFICIENT_MEMORY;
2173}