Panda3D
Loading...
Searching...
No Matches
tinyxml.cpp
1/*
2www.sourceforge.net/projects/tinyxml
3Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
4
5This software is provided 'as-is', without any express or implied
6warranty. In no event will the authors be held liable for any
7damages arising from the use of this software.
8
9Permission is granted to anyone to use this software for any
10purpose, including commercial applications, and to alter it and
11redistribute it freely, subject to the following restrictions:
12
131. The origin of this software must not be misrepresented; you must
14not claim that you wrote the original software. If you use this
15software in a product, an acknowledgment in the product documentation
16would be appreciated but is not required.
17
182. Altered source versions must be plainly marked as such, and
19must not be misrepresented as being the original software.
20
213. This notice may not be removed or altered from any source
22distribution.
23*/
24
25#include <ctype.h>
26
27#ifdef TIXML_USE_STL
28#include <sstream>
29#include <iostream>
30#endif
31#ifdef _WIN32
32#include <windows.h>
33#endif // _WIN32
34
35#include "tinyxml.h"
36
37FILE* TiXmlFOpen( const char* filename, const char* mode );
38
39bool TiXmlBase::condenseWhiteSpace = true;
40
41// Microsoft compiler security
42FILE* TiXmlFOpen( const char* filename, const char* mode )
43{
44 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
45 FILE* fp = nullptr;
46
47 /* Addition by drwr for Windows wide-character support */
48 //errno_t err = fopen_s( &fp, filename, mode );
49 errno_t err = 1;
50 {
51 int size = MultiByteToWideChar(CP_UTF8, 0, filename, -1,
52 NULL, 0);
53 if (size > 0) {
54 wchar_t *buffer = new wchar_t[size];
55 int rc = MultiByteToWideChar(CP_UTF8, 0, filename, -1,
56 buffer, size);
57 if (rc != 0) {
58 buffer[size - 1] = 0;
59 err = _wfopen_s( &fp, buffer, mode[0] == 'w' ? L"w" : L"rb" );
60 }
61 delete[] buffer;
62 }
63 }
64 /* End wide-character addition */
65
66 if ( !err && fp )
67 return fp;
68 return nullptr;
69 #else
70 return fopen( filename, mode );
71 #endif
72}
73
74void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
75{
76 int i=0;
77
78 while( i<(int)str.length() )
79 {
80 unsigned char c = (unsigned char) str[i];
81
82 if ( c == '&'
83 && i < ( (int)str.length() - 2 )
84 && str[i+1] == '#'
85 && str[i+2] == 'x' )
86 {
87 // Hexadecimal character reference.
88 // Pass through unchanged.
89 // &#xA9; -- copyright symbol, for example.
90 //
91 // The -1 is a bug fix from Rob Laveaux. It keeps
92 // an overflow from happening if there is no ';'.
93 // There are actually 2 ways to exit this loop -
94 // while fails (error case) and break (semicolon found).
95 // However, there is no mechanism (currently) for
96 // this function to return an error.
97 while ( i<(int)str.length()-1 )
98 {
99 outString->append( str.c_str() + i, 1 );
100 ++i;
101 if ( str[i] == ';' )
102 break;
103 }
104 }
105 else if ( c == '&' )
106 {
107 outString->append( entity[0].str, entity[0].strLength );
108 ++i;
109 }
110 else if ( c == '<' )
111 {
112 outString->append( entity[1].str, entity[1].strLength );
113 ++i;
114 }
115 else if ( c == '>' )
116 {
117 outString->append( entity[2].str, entity[2].strLength );
118 ++i;
119 }
120 else if ( c == '\"' )
121 {
122 outString->append( entity[3].str, entity[3].strLength );
123 ++i;
124 }
125 else if ( c == '\'' )
126 {
127 outString->append( entity[4].str, entity[4].strLength );
128 ++i;
129 }
130 else if ( c < 32 )
131 {
132 // Easy pass at non-alpha/numeric/symbol
133 // Below 32 is symbolic.
134 char buf[ 32 ];
135
136 #if defined(TIXML_SNPRINTF)
137 TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
138 #else
139 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
140 #endif
141
142 //*ME: warning C4267: convert 'size_t' to 'int'
143 //*ME: Int-Cast to make compiler happy ...
144 outString->append( buf, (int)strlen( buf ) );
145 ++i;
146 }
147 else
148 {
149 //char realc = (char) c;
150 //outString->append( &realc, 1 );
151 *outString += (char) c; // somewhat more efficient function call.
152 ++i;
153 }
154 }
155}
156
157
158TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
159{
160 parent = nullptr;
161 type = _type;
162 firstChild = nullptr;
163 lastChild = nullptr;
164 prev = nullptr;
165 next = nullptr;
166}
167
168
169TiXmlNode::~TiXmlNode()
170{
171 TiXmlNode* node = firstChild;
172 TiXmlNode* temp = nullptr;
173
174 while ( node )
175 {
176 temp = node;
177 node = node->next;
178 delete temp;
179 }
180}
181
182
183void TiXmlNode::CopyTo( TiXmlNode* target ) const
184{
185 target->SetValue (value.c_str() );
186 target->userData = userData;
187 target->location = location;
188}
189
190
192{
193 TiXmlNode* node = firstChild;
194 TiXmlNode* temp = nullptr;
195
196 while ( node )
197 {
198 temp = node;
199 node = node->next;
200 delete temp;
201 }
202
203 firstChild = nullptr;
204 lastChild = nullptr;
205}
206
207
209{
210 assert( node->parent == nullptr || node->parent == this );
211 assert( node->GetDocument() == nullptr || node->GetDocument() == this->GetDocument() );
212
213 if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
214 {
215 delete node;
216 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
217 return nullptr;
218 }
219
220 node->parent = this;
221
222 node->prev = lastChild;
223 node->next = nullptr;
224
225 if ( lastChild )
226 lastChild->next = node;
227 else
228 firstChild = node; // it was an empty list.
229
230 lastChild = node;
231 return node;
232}
233
234
236{
237 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
238 {
239 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
240 return nullptr;
241 }
242 TiXmlNode* node = addThis.Clone();
243 if ( !node )
244 return nullptr;
245
246 return LinkEndChild( node );
247}
248
249
251{
252 if ( !beforeThis || beforeThis->parent != this ) {
253 return nullptr;
254 }
255 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
256 {
257 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
258 return nullptr;
259 }
260
261 TiXmlNode* node = addThis.Clone();
262 if ( !node )
263 return nullptr;
264 node->parent = this;
265
266 node->next = beforeThis;
267 node->prev = beforeThis->prev;
268 if ( beforeThis->prev )
269 {
270 beforeThis->prev->next = node;
271 }
272 else
273 {
274 assert( firstChild == beforeThis );
275 firstChild = node;
276 }
277 beforeThis->prev = node;
278 return node;
279}
280
281
283{
284 if ( !afterThis || afterThis->parent != this ) {
285 return nullptr;
286 }
287 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
288 {
289 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
290 return nullptr;
291 }
292
293 TiXmlNode* node = addThis.Clone();
294 if ( !node )
295 return nullptr;
296 node->parent = this;
297
298 node->prev = afterThis;
299 node->next = afterThis->next;
300 if ( afterThis->next )
301 {
302 afterThis->next->prev = node;
303 }
304 else
305 {
306 assert( lastChild == afterThis );
307 lastChild = node;
308 }
309 afterThis->next = node;
310 return node;
311}
312
313
314TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
315{
316 if ( !replaceThis )
317 return nullptr;
318
319 if ( replaceThis->parent != this )
320 return nullptr;
321
322 if ( withThis.ToDocument() ) {
323 // A document can never be a child. Thanks to Noam.
324 TiXmlDocument* document = GetDocument();
325 if ( document )
326 document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
327 return nullptr;
328 }
329
330 TiXmlNode* node = withThis.Clone();
331 if ( !node )
332 return nullptr;
333
334 node->next = replaceThis->next;
335 node->prev = replaceThis->prev;
336
337 if ( replaceThis->next )
338 replaceThis->next->prev = node;
339 else
340 lastChild = node;
341
342 if ( replaceThis->prev )
343 replaceThis->prev->next = node;
344 else
345 firstChild = node;
346
347 delete replaceThis;
348 node->parent = this;
349 return node;
350}
351
352
354{
355 if ( !removeThis ) {
356 return false;
357 }
358
359 if ( removeThis->parent != this )
360 {
361 assert( 0 );
362 return false;
363 }
364
365 if ( removeThis->next )
366 removeThis->next->prev = removeThis->prev;
367 else
368 lastChild = removeThis->prev;
369
370 if ( removeThis->prev )
371 removeThis->prev->next = removeThis->next;
372 else
373 firstChild = removeThis->next;
374
375 delete removeThis;
376 return true;
377}
378
379const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
380{
381 const TiXmlNode* node;
382 for ( node = firstChild; node; node = node->next )
383 {
384 if ( strcmp( node->Value(), _value ) == 0 )
385 return node;
386 }
387 return nullptr;
388}
389
390
391const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
392{
393 const TiXmlNode* node;
394 for ( node = lastChild; node; node = node->prev )
395 {
396 if ( strcmp( node->Value(), _value ) == 0 )
397 return node;
398 }
399 return nullptr;
400}
401
402
403const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
404{
405 if ( !previous )
406 {
407 return FirstChild();
408 }
409 else
410 {
411 assert( previous->parent == this );
412 return previous->NextSibling();
413 }
414}
415
416
417const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
418{
419 if ( !previous )
420 {
421 return FirstChild( val );
422 }
423 else
424 {
425 assert( previous->parent == this );
426 return previous->NextSibling( val );
427 }
428}
429
430
431const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
432{
433 const TiXmlNode* node;
434 for ( node = next; node; node = node->next )
435 {
436 if ( strcmp( node->Value(), _value ) == 0 )
437 return node;
438 }
439 return nullptr;
440}
441
442
443const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
444{
445 const TiXmlNode* node;
446 for ( node = prev; node; node = node->prev )
447 {
448 if ( strcmp( node->Value(), _value ) == 0 )
449 return node;
450 }
451 return nullptr;
452}
453
454
455void TiXmlElement::RemoveAttribute( const char * name )
456{
457 #ifdef TIXML_USE_STL
458 TIXML_STRING str( name );
459 TiXmlAttribute* node = attributeSet.Find( str );
460 #else
461 TiXmlAttribute* node = attributeSet.Find( name );
462 #endif
463 if ( node )
464 {
465 attributeSet.Remove( node );
466 delete node;
467 }
468}
469
471{
472 const TiXmlNode* node;
473
474 for ( node = FirstChild();
475 node;
476 node = node->NextSibling() )
477 {
478 if ( node->ToElement() )
479 return node->ToElement();
480 }
481 return nullptr;
482}
483
484
485const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
486{
487 const TiXmlNode* node;
488
489 for ( node = FirstChild( _value );
490 node;
491 node = node->NextSibling( _value ) )
492 {
493 if ( node->ToElement() )
494 return node->ToElement();
495 }
496 return nullptr;
497}
498
499
501{
502 const TiXmlNode* node;
503
504 for ( node = NextSibling();
505 node;
506 node = node->NextSibling() )
507 {
508 if ( node->ToElement() )
509 return node->ToElement();
510 }
511 return nullptr;
512}
513
514
515const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
516{
517 const TiXmlNode* node;
518
519 for ( node = NextSibling( _value );
520 node;
521 node = node->NextSibling( _value ) )
522 {
523 if ( node->ToElement() )
524 return node->ToElement();
525 }
526 return nullptr;
527}
528
529
531{
532 const TiXmlNode* node;
533
534 for( node = this; node; node = node->parent )
535 {
536 if ( node->ToDocument() )
537 return node->ToDocument();
538 }
539 return nullptr;
540}
541
542
543TiXmlElement::TiXmlElement (const char * _value)
544 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
545{
546 firstChild = lastChild = nullptr;
547 value = _value;
548}
549
550
551#ifdef TIXML_USE_STL
552TiXmlElement::TiXmlElement( const std::string& _value )
553 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
554{
555 firstChild = lastChild = nullptr;
556 value = _value;
557}
558#endif
559
560
562 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
563{
564 firstChild = lastChild = nullptr;
565 copy.CopyTo( this );
566}
567
568
569void TiXmlElement::operator=( const TiXmlElement& base )
570{
571 ClearThis();
572 base.CopyTo( this );
573}
574
575
576TiXmlElement::~TiXmlElement()
577{
578 ClearThis();
579}
580
581
582void TiXmlElement::ClearThis()
583{
584 Clear();
585 while( attributeSet.First() )
586 {
587 TiXmlAttribute* node = attributeSet.First();
588 attributeSet.Remove( node );
589 delete node;
590 }
591}
592
593
594const char* TiXmlElement::Attribute( const char* name ) const
595{
596 const TiXmlAttribute* node = attributeSet.Find( name );
597 if ( node )
598 return node->Value();
599 return nullptr;
600}
601
602
603#ifdef TIXML_USE_STL
604const std::string* TiXmlElement::Attribute( const std::string& name ) const
605{
606 const TiXmlAttribute* attrib = attributeSet.Find( name );
607 if ( attrib )
608 return &attrib->ValueStr();
609 return nullptr;
610}
611#endif
612
613
614const char* TiXmlElement::Attribute( const char* name, int* i ) const
615{
616 const TiXmlAttribute* attrib = attributeSet.Find( name );
617 const char* result = nullptr;
618
619 if ( attrib ) {
620 result = attrib->Value();
621 if ( i ) {
622 attrib->QueryIntValue( i );
623 }
624 }
625 return result;
626}
627
628
629#ifdef TIXML_USE_STL
630const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
631{
632 const TiXmlAttribute* attrib = attributeSet.Find( name );
633 const std::string* result = nullptr;
634
635 if ( attrib ) {
636 result = &attrib->ValueStr();
637 if ( i ) {
638 attrib->QueryIntValue( i );
639 }
640 }
641 return result;
642}
643#endif
644
645
646const char* TiXmlElement::Attribute( const char* name, double* d ) const
647{
648 const TiXmlAttribute* attrib = attributeSet.Find( name );
649 const char* result = nullptr;
650
651 if ( attrib ) {
652 result = attrib->Value();
653 if ( d ) {
654 attrib->QueryDoubleValue( d );
655 }
656 }
657 return result;
658}
659
660
661#ifdef TIXML_USE_STL
662const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
663{
664 const TiXmlAttribute* attrib = attributeSet.Find( name );
665 const std::string* result = nullptr;
666
667 if ( attrib ) {
668 result = &attrib->ValueStr();
669 if ( d ) {
670 attrib->QueryDoubleValue( d );
671 }
672 }
673 return result;
674}
675#endif
676
677
678int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
679{
680 const TiXmlAttribute* attrib = attributeSet.Find( name );
681 if ( !attrib )
682 return TIXML_NO_ATTRIBUTE;
683 return attrib->QueryIntValue( ival );
684}
685
686
687#ifdef TIXML_USE_STL
688int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
689{
690 const TiXmlAttribute* attrib = attributeSet.Find( name );
691 if ( !attrib )
692 return TIXML_NO_ATTRIBUTE;
693 return attrib->QueryIntValue( ival );
694}
695#endif
696
697
698int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
699{
700 const TiXmlAttribute* attrib = attributeSet.Find( name );
701 if ( !attrib )
702 return TIXML_NO_ATTRIBUTE;
703 return attrib->QueryDoubleValue( dval );
704}
705
706
707#ifdef TIXML_USE_STL
708int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
709{
710 const TiXmlAttribute* attrib = attributeSet.Find( name );
711 if ( !attrib )
712 return TIXML_NO_ATTRIBUTE;
713 return attrib->QueryDoubleValue( dval );
714}
715#endif
716
717
718void TiXmlElement::SetAttribute( const char * name, int val )
719{
720 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
721 if ( attrib ) {
722 attrib->SetIntValue( val );
723 }
724}
725
726
727#ifdef TIXML_USE_STL
728void TiXmlElement::SetAttribute( const std::string& name, int val )
729{
730 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
731 if ( attrib ) {
732 attrib->SetIntValue( val );
733 }
734}
735#endif
736
737
738void TiXmlElement::SetDoubleAttribute( const char * name, double val )
739{
740 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
741 if ( attrib ) {
742 attrib->SetDoubleValue( val );
743 }
744}
745
746
747#ifdef TIXML_USE_STL
748void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
749{
750 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
751 if ( attrib ) {
752 attrib->SetDoubleValue( val );
753 }
754}
755#endif
756
757
758void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
759{
760 TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
761 if ( attrib ) {
762 attrib->SetValue( cvalue );
763 }
764}
765
766
767#ifdef TIXML_USE_STL
768void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
769{
770 TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
771 if ( attrib ) {
772 attrib->SetValue( _value );
773 }
774}
775#endif
776
777
778void TiXmlElement::Print( FILE* cfile, int depth ) const
779{
780 int i;
781 assert( cfile );
782 for ( i=0; i<depth; i++ ) {
783 fprintf( cfile, " " );
784 }
785
786 fprintf( cfile, "<%s", value.c_str() );
787
788 const TiXmlAttribute* attrib;
789 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
790 {
791 fprintf( cfile, " " );
792 attrib->Print( cfile, depth );
793 }
794
795 // There are 3 different formatting approaches:
796 // 1) An element without children is printed as a <foo /> node
797 // 2) An element with only a text child is printed as <foo> text </foo>
798 // 3) An element with children is printed on multiple lines.
799 TiXmlNode* node;
800 if ( !firstChild )
801 {
802 fprintf( cfile, " />" );
803 }
804 else if ( firstChild == lastChild && firstChild->ToText() )
805 {
806 fprintf( cfile, ">" );
807 firstChild->Print( cfile, depth + 1 );
808 fprintf( cfile, "</%s>", value.c_str() );
809 }
810 else
811 {
812 fprintf( cfile, ">" );
813
814 for ( node = firstChild; node; node=node->NextSibling() )
815 {
816 if ( !node->ToText() )
817 {
818 fprintf( cfile, "\n" );
819 }
820 node->Print( cfile, depth+1 );
821 }
822 fprintf( cfile, "\n" );
823 for( i=0; i<depth; ++i ) {
824 fprintf( cfile, " " );
825 }
826 fprintf( cfile, "</%s>", value.c_str() );
827 }
828}
829
830
831void TiXmlElement::CopyTo( TiXmlElement* target ) const
832{
833 // superclass:
834 TiXmlNode::CopyTo( target );
835
836 // Element class:
837 // Clone the attributes, then clone the children.
838 const TiXmlAttribute* attribute = nullptr;
839 for( attribute = attributeSet.First();
840 attribute;
841 attribute = attribute->Next() )
842 {
843 target->SetAttribute( attribute->Name(), attribute->Value() );
844 }
845
846 TiXmlNode* node = nullptr;
847 for ( node = firstChild; node; node = node->NextSibling() )
848 {
849 target->LinkEndChild( node->Clone() );
850 }
851}
852
853bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
854{
855 if ( visitor->VisitEnter( *this, attributeSet.First() ) )
856 {
857 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
858 {
859 if ( !node->Accept( visitor ) )
860 break;
861 }
862 }
863 return visitor->VisitExit( *this );
864}
865
866
868{
869 TiXmlElement* clone = new TiXmlElement( Value() );
870 if ( !clone )
871 return nullptr;
872
873 CopyTo( clone );
874 return clone;
875}
876
877
878const char* TiXmlElement::GetText() const
879{
880 const TiXmlNode* child = this->FirstChild();
881 if ( child ) {
882 const TiXmlText* childText = child->ToText();
883 if ( childText ) {
884 return childText->Value();
885 }
886 }
887 return nullptr;
888}
889
890
892{
893 tabsize = 4;
894 useMicrosoftBOM = false;
895 ClearError();
896}
897
898TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
899{
900 tabsize = 4;
901 useMicrosoftBOM = false;
902 value = documentName;
903 ClearError();
904}
905
906
907#ifdef TIXML_USE_STL
908TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
909{
910 tabsize = 4;
911 useMicrosoftBOM = false;
912 value = documentName;
913 ClearError();
914}
915#endif
916
917
918TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
919{
920 copy.CopyTo( this );
921}
922
923
924void TiXmlDocument::operator=( const TiXmlDocument& copy )
925{
926 Clear();
927 copy.CopyTo( this );
928}
929
930
931bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
932{
933 return LoadFile( Value(), encoding );
934}
935
936
938{
939 return SaveFile( Value() );
940}
941
942bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
943{
944 TIXML_STRING filename( _filename );
945 value = filename;
946
947 // reading in binary mode so that tinyxml can normalize the EOL
948 FILE* file = TiXmlFOpen( value.c_str (), "rb" );
949
950 if ( file )
951 {
952 bool result = LoadFile( file, encoding );
953 fclose( file );
954 return result;
955 }
956 else
957 {
958 SetError( TIXML_ERROR_OPENING_FILE, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
959 return false;
960 }
961}
962
963bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
964{
965 if ( !file )
966 {
967 SetError( TIXML_ERROR_OPENING_FILE, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
968 return false;
969 }
970
971 // Delete the existing data:
972 Clear();
973 location.Clear();
974
975 // Get the file size, so we can pre-allocate the string. HUGE speed impact.
976 long length = 0;
977 fseek( file, 0, SEEK_END );
978 length = ftell( file );
979 fseek( file, 0, SEEK_SET );
980
981 // Strange case, but good to handle up front.
982 if ( length <= 0 )
983 {
984 SetError( TIXML_ERROR_DOCUMENT_EMPTY, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
985 return false;
986 }
987
988 // Subtle bug here. TinyXml did use fgets. But from the XML spec:
989 // 2.11 End-of-Line Handling
990 // <snip>
991 // <quote>
992 // ...the XML processor MUST behave as if it normalized all line breaks in external
993 // parsed entities (including the document entity) on input, before parsing, by translating
994 // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
995 // a single #xA character.
996 // </quote>
997 //
998 // It is not clear fgets does that, and certainly isn't clear it works cross platform.
999 // Generally, you expect fgets to translate from the convention of the OS to the c/unix
1000 // convention, and not work generally.
1001
1002 /*
1003 while( fgets( buf, sizeof(buf), file ) )
1004 {
1005 data += buf;
1006 }
1007 */
1008
1009 char* buf = new char[ length+1 ];
1010 buf[0] = 0;
1011
1012 if ( fread( buf, length, 1, file ) != 1 ) {
1013 delete [] buf;
1014 SetError( TIXML_ERROR_OPENING_FILE, nullptr, nullptr, TIXML_ENCODING_UNKNOWN );
1015 return false;
1016 }
1017
1018 // Process the buffer in place to normalize new lines. (See comment above.)
1019 // Copies from the 'p' to 'q' pointer, where p can advance faster if
1020 // a newline-carriage return is hit.
1021 //
1022 // Wikipedia:
1023 // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
1024 // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
1025 // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
1026 // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
1027 // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
1028
1029 const char* p = buf; // the read head
1030 char* q = buf; // the write head
1031 const char CR = 0x0d;
1032 const char LF = 0x0a;
1033
1034 buf[length] = 0;
1035 while( *p ) {
1036 assert( p < (buf+length) );
1037 assert( q <= (buf+length) );
1038 assert( q <= p );
1039
1040 if ( *p == CR ) {
1041 *q++ = LF;
1042 p++;
1043 if ( *p == LF ) { // check for CR+LF (and skip LF)
1044 p++;
1045 }
1046 }
1047 else {
1048 *q++ = *p++;
1049 }
1050 }
1051 assert( q <= (buf+length) );
1052 *q = 0;
1053
1054 Parse( buf, nullptr, encoding );
1055
1056 delete [] buf;
1057 return !Error();
1058}
1059
1060
1061bool TiXmlDocument::SaveFile( const char * filename ) const
1062{
1063 // The old c stuff lives on...
1064 FILE* fp = TiXmlFOpen( filename, "w" );
1065 if ( fp )
1066 {
1067 bool result = SaveFile( fp );
1068 fclose( fp );
1069 return result;
1070 }
1071 return false;
1072}
1073
1074
1075bool TiXmlDocument::SaveFile( FILE* fp ) const
1076{
1077 if ( useMicrosoftBOM )
1078 {
1079 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
1080 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
1081 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
1082
1083 fputc( TIXML_UTF_LEAD_0, fp );
1084 fputc( TIXML_UTF_LEAD_1, fp );
1085 fputc( TIXML_UTF_LEAD_2, fp );
1086 }
1087 Print( fp, 0 );
1088 return (ferror(fp) == 0);
1089}
1090
1091
1092void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
1093{
1094 TiXmlNode::CopyTo( target );
1095
1096 target->error = error;
1097 target->errorId = errorId;
1098 target->errorDesc = errorDesc;
1099 target->tabsize = tabsize;
1100 target->errorLocation = errorLocation;
1101 target->useMicrosoftBOM = useMicrosoftBOM;
1102
1103 TiXmlNode* node = nullptr;
1104 for ( node = firstChild; node; node = node->NextSibling() )
1105 {
1106 target->LinkEndChild( node->Clone() );
1107 }
1108}
1109
1110
1111TiXmlNode* TiXmlDocument::Clone() const
1112{
1113 TiXmlDocument* clone = new TiXmlDocument();
1114 if ( !clone )
1115 return nullptr;
1116
1117 CopyTo( clone );
1118 return clone;
1119}
1120
1121
1122void TiXmlDocument::Print( FILE* cfile, int depth ) const
1123{
1124 assert( cfile );
1125 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1126 {
1127 node->Print( cfile, depth );
1128 fprintf( cfile, "\n" );
1129 }
1130}
1131
1132
1134{
1135 if ( visitor->VisitEnter( *this ) )
1136 {
1137 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1138 {
1139 if ( !node->Accept( visitor ) )
1140 break;
1141 }
1142 }
1143 return visitor->VisitExit( *this );
1144}
1145
1146
1148{
1149 // We are using knowledge of the sentinel. The sentinel
1150 // have a value or name.
1151 if ( next->value.empty() && next->name.empty() )
1152 return nullptr;
1153 return next;
1154}
1155
1156/*
1157TiXmlAttribute* TiXmlAttribute::Next()
1158{
1159 // We are using knowledge of the sentinel. The sentinel
1160 // have a value or name.
1161 if ( next->value.empty() && next->name.empty() )
1162 return 0;
1163 return next;
1164}
1165*/
1166
1168{
1169 // We are using knowledge of the sentinel. The sentinel
1170 // have a value or name.
1171 if ( prev->value.empty() && prev->name.empty() )
1172 return nullptr;
1173 return prev;
1174}
1175
1176/*
1177TiXmlAttribute* TiXmlAttribute::Previous()
1178{
1179 // We are using knowledge of the sentinel. The sentinel
1180 // have a value or name.
1181 if ( prev->value.empty() && prev->name.empty() )
1182 return 0;
1183 return prev;
1184}
1185*/
1186
1187void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1188{
1189 TIXML_STRING n, v;
1190
1191 EncodeString( name, &n );
1192 EncodeString( value, &v );
1193
1194 if (value.find ('\"') == TIXML_STRING::npos) {
1195 if ( cfile ) {
1196 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
1197 }
1198 if ( str ) {
1199 (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
1200 }
1201 }
1202 else {
1203 if ( cfile ) {
1204 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
1205 }
1206 if ( str ) {
1207 (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
1208 }
1209 }
1210}
1211
1212
1213int TiXmlAttribute::QueryIntValue( int* ival ) const
1214{
1215 if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
1216 return TIXML_SUCCESS;
1217 return TIXML_WRONG_TYPE;
1218}
1219
1220int TiXmlAttribute::QueryDoubleValue( double* dval ) const
1221{
1222 if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
1223 return TIXML_SUCCESS;
1224 return TIXML_WRONG_TYPE;
1225}
1226
1228{
1229 char buf [64];
1230 #if defined(TIXML_SNPRINTF)
1231 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
1232 #else
1233 sprintf (buf, "%d", _value);
1234 #endif
1235 SetValue (buf);
1236}
1237
1239{
1240 char buf [256];
1241 #if defined(TIXML_SNPRINTF)
1242 TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
1243 #else
1244 sprintf (buf, "%g", _value);
1245 #endif
1246 SetValue (buf);
1247}
1248
1250{
1251 return atoi (value.c_str ());
1252}
1253
1255{
1256 return atof (value.c_str ());
1257}
1258
1259
1260TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
1261{
1262 copy.CopyTo( this );
1263}
1264
1265
1266void TiXmlComment::operator=( const TiXmlComment& base )
1267{
1268 Clear();
1269 base.CopyTo( this );
1270}
1271
1272
1273void TiXmlComment::Print( FILE* cfile, int depth ) const
1274{
1275 assert( cfile );
1276 for ( int i=0; i<depth; i++ )
1277 {
1278 fprintf( cfile, " " );
1279 }
1280 fprintf( cfile, "<!--%s-->", value.c_str() );
1281}
1282
1283
1284void TiXmlComment::CopyTo( TiXmlComment* target ) const
1285{
1286 TiXmlNode::CopyTo( target );
1287}
1288
1289
1291{
1292 return visitor->Visit( *this );
1293}
1294
1295
1297{
1298 TiXmlComment* clone = new TiXmlComment();
1299
1300 if ( !clone )
1301 return nullptr;
1302
1303 CopyTo( clone );
1304 return clone;
1305}
1306
1307
1308void TiXmlText::Print( FILE* cfile, int depth ) const
1309{
1310 assert( cfile );
1311 if ( cdata )
1312 {
1313 int i;
1314 fprintf( cfile, "\n" );
1315 for ( i=0; i<depth; i++ ) {
1316 fprintf( cfile, " " );
1317 }
1318 fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output
1319 }
1320 else
1321 {
1322 TIXML_STRING buffer;
1323 EncodeString( value, &buffer );
1324 fprintf( cfile, "%s", buffer.c_str() );
1325 }
1326}
1327
1328
1329void TiXmlText::CopyTo( TiXmlText* target ) const
1330{
1331 TiXmlNode::CopyTo( target );
1332 target->cdata = cdata;
1333}
1334
1335
1336bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
1337{
1338 return visitor->Visit( *this );
1339}
1340
1341
1342TiXmlNode* TiXmlText::Clone() const
1343{
1344 TiXmlText* clone = nullptr;
1345 clone = new TiXmlText( "" );
1346
1347 if ( !clone )
1348 return nullptr;
1349
1350 CopyTo( clone );
1351 return clone;
1352}
1353
1354
1356 const char * _encoding,
1357 const char * _standalone )
1358 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1359{
1360 version = _version;
1361 encoding = _encoding;
1362 standalone = _standalone;
1363}
1364
1365
1366#ifdef TIXML_USE_STL
1367TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
1368 const std::string& _encoding,
1369 const std::string& _standalone )
1370 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1371{
1372 version = _version;
1373 encoding = _encoding;
1374 standalone = _standalone;
1375}
1376#endif
1377
1378
1380 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1381{
1382 copy.CopyTo( this );
1383}
1384
1385
1386void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
1387{
1388 Clear();
1389 copy.CopyTo( this );
1390}
1391
1392
1393void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1394{
1395 if ( cfile ) fprintf( cfile, "<?xml " );
1396 if ( str ) (*str) += "<?xml ";
1397
1398 if ( !version.empty() ) {
1399 if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
1400 if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
1401 }
1402 if ( !encoding.empty() ) {
1403 if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
1404 if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
1405 }
1406 if ( !standalone.empty() ) {
1407 if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
1408 if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
1409 }
1410 if ( cfile ) fprintf( cfile, "?>" );
1411 if ( str ) (*str) += "?>";
1412}
1413
1414
1415void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
1416{
1417 TiXmlNode::CopyTo( target );
1418
1419 target->version = version;
1420 target->encoding = encoding;
1421 target->standalone = standalone;
1422}
1423
1424
1426{
1427 return visitor->Visit( *this );
1428}
1429
1430
1432{
1433 TiXmlDeclaration* clone = new TiXmlDeclaration();
1434
1435 if ( !clone )
1436 return nullptr;
1437
1438 CopyTo( clone );
1439 return clone;
1440}
1441
1442
1443void TiXmlUnknown::Print( FILE* cfile, int depth ) const
1444{
1445 for ( int i=0; i<depth; i++ )
1446 fprintf( cfile, " " );
1447 fprintf( cfile, "<%s>", value.c_str() );
1448}
1449
1450
1451void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
1452{
1453 TiXmlNode::CopyTo( target );
1454}
1455
1456
1458{
1459 return visitor->Visit( *this );
1460}
1461
1462
1464{
1465 TiXmlUnknown* clone = new TiXmlUnknown();
1466
1467 if ( !clone )
1468 return nullptr;
1469
1470 CopyTo( clone );
1471 return clone;
1472}
1473
1474
1475TiXmlAttributeSet::TiXmlAttributeSet()
1476{
1477 sentinel.next = &sentinel;
1478 sentinel.prev = &sentinel;
1479}
1480
1481
1482TiXmlAttributeSet::~TiXmlAttributeSet()
1483{
1484 assert( sentinel.next == &sentinel );
1485 assert( sentinel.prev == &sentinel );
1486}
1487
1488
1489void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
1490{
1491 #ifdef TIXML_USE_STL
1492 assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set.
1493 #else
1494 assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
1495 #endif
1496
1497 addMe->next = &sentinel;
1498 addMe->prev = sentinel.prev;
1499
1500 sentinel.prev->next = addMe;
1501 sentinel.prev = addMe;
1502}
1503
1504void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
1505{
1506 TiXmlAttribute* node;
1507
1508 for( node = sentinel.next; node != &sentinel; node = node->next )
1509 {
1510 if ( node == removeMe )
1511 {
1512 node->prev->next = node->next;
1513 node->next->prev = node->prev;
1514 node->next = nullptr;
1515 node->prev = nullptr;
1516 return;
1517 }
1518 }
1519 assert( 0 ); // we tried to remove a non-linked attribute.
1520}
1521
1522
1523#ifdef TIXML_USE_STL
1524TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
1525{
1526 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1527 {
1528 if ( node->name == name )
1529 return node;
1530 }
1531 return nullptr;
1532}
1533
1534TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
1535{
1536 TiXmlAttribute* attrib = Find( _name );
1537 if ( !attrib ) {
1538 attrib = new TiXmlAttribute();
1539 Add( attrib );
1540 attrib->SetName( _name );
1541 }
1542 return attrib;
1543}
1544#endif
1545
1546
1547TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
1548{
1549 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1550 {
1551 if ( strcmp( node->name.c_str(), name ) == 0 )
1552 return node;
1553 }
1554 return nullptr;
1555}
1556
1557
1558TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
1559{
1560 TiXmlAttribute* attrib = Find( _name );
1561 if ( !attrib ) {
1562 attrib = new TiXmlAttribute();
1563 Add( attrib );
1564 attrib->SetName( _name );
1565 }
1566 return attrib;
1567}
1568
1569
1570#ifdef TIXML_USE_STL
1571std::istream& operator>> (std::istream & in, TiXmlNode & base)
1572{
1573 TIXML_STRING tag;
1574 tag.reserve( 8 * 1000 );
1575 base.StreamIn( &in, &tag );
1576
1577 base.Parse( tag.c_str(), nullptr, TIXML_DEFAULT_ENCODING );
1578 return in;
1579}
1580#endif
1581
1582
1583#ifdef TIXML_USE_STL
1584std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
1585{
1586 TiXmlPrinter printer;
1587 printer.SetStreamPrinting();
1588 base.Accept( &printer );
1589 out << printer.Str();
1590
1591 return out;
1592}
1593
1594
1595std::string& operator<< (std::string& out, const TiXmlNode& base )
1596{
1597 TiXmlPrinter printer;
1598 printer.SetStreamPrinting();
1599 base.Accept( &printer );
1600 out.append( printer.Str() );
1601
1602 return out;
1603}
1604#endif
1605
1606
1608{
1609 if ( node )
1610 {
1611 TiXmlNode* child = node->FirstChild();
1612 if ( child )
1613 return TiXmlHandle( child );
1614 }
1615 return TiXmlHandle( nullptr );
1616}
1617
1618
1619TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
1620{
1621 if ( node )
1622 {
1623 TiXmlNode* child = node->FirstChild( value );
1624 if ( child )
1625 return TiXmlHandle( child );
1626 }
1627 return TiXmlHandle( nullptr );
1628}
1629
1630
1632{
1633 if ( node )
1634 {
1635 TiXmlElement* child = node->FirstChildElement();
1636 if ( child )
1637 return TiXmlHandle( child );
1638 }
1639 return TiXmlHandle( nullptr );
1640}
1641
1642
1644{
1645 if ( node )
1646 {
1647 TiXmlElement* child = node->FirstChildElement( value );
1648 if ( child )
1649 return TiXmlHandle( child );
1650 }
1651 return TiXmlHandle( nullptr );
1652}
1653
1654
1656{
1657 if ( node )
1658 {
1659 int i;
1660 TiXmlNode* child = node->FirstChild();
1661 for ( i=0;
1662 child && i<count;
1663 child = child->NextSibling(), ++i )
1664 {
1665 // nothing
1666 }
1667 if ( child )
1668 return TiXmlHandle( child );
1669 }
1670 return TiXmlHandle( nullptr );
1671}
1672
1673
1674TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
1675{
1676 if ( node )
1677 {
1678 int i;
1679 TiXmlNode* child = node->FirstChild( value );
1680 for ( i=0;
1681 child && i<count;
1682 child = child->NextSibling( value ), ++i )
1683 {
1684 // nothing
1685 }
1686 if ( child )
1687 return TiXmlHandle( child );
1688 }
1689 return TiXmlHandle( nullptr );
1690}
1691
1692
1694{
1695 if ( node )
1696 {
1697 int i;
1698 TiXmlElement* child = node->FirstChildElement();
1699 for ( i=0;
1700 child && i<count;
1701 child = child->NextSiblingElement(), ++i )
1702 {
1703 // nothing
1704 }
1705 if ( child )
1706 return TiXmlHandle( child );
1707 }
1708 return TiXmlHandle( nullptr );
1709}
1710
1711
1712TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
1713{
1714 if ( node )
1715 {
1716 int i;
1717 TiXmlElement* child = node->FirstChildElement( value );
1718 for ( i=0;
1719 child && i<count;
1720 child = child->NextSiblingElement( value ), ++i )
1721 {
1722 // nothing
1723 }
1724 if ( child )
1725 return TiXmlHandle( child );
1726 }
1727 return TiXmlHandle( nullptr );
1728}
1729
1730
1732{
1733 return true;
1734}
1735
1737{
1738 return true;
1739}
1740
1741bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
1742{
1743 DoIndent();
1744 buffer += "<";
1745 buffer += element.Value();
1746
1747 for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
1748 {
1749 buffer += " ";
1750 attrib->Print( nullptr, 0, &buffer );
1751 }
1752
1753 if ( !element.FirstChild() )
1754 {
1755 buffer += " />";
1756 DoLineBreak();
1757 }
1758 else
1759 {
1760 buffer += ">";
1761 if ( element.FirstChild()->ToText()
1762 && element.LastChild() == element.FirstChild()
1763 && element.FirstChild()->ToText()->CDATA() == false )
1764 {
1765 simpleTextPrint = true;
1766 // no DoLineBreak()!
1767 }
1768 else
1769 {
1770 DoLineBreak();
1771 }
1772 }
1773 ++depth;
1774 return true;
1775}
1776
1777
1779{
1780 --depth;
1781 if ( !element.FirstChild() )
1782 {
1783 // nothing.
1784 }
1785 else
1786 {
1787 if ( simpleTextPrint )
1788 {
1789 simpleTextPrint = false;
1790 }
1791 else
1792 {
1793 DoIndent();
1794 }
1795 buffer += "</";
1796 buffer += element.Value();
1797 buffer += ">";
1798 DoLineBreak();
1799 }
1800 return true;
1801}
1802
1803
1805{
1806 if ( text.CDATA() )
1807 {
1808 DoIndent();
1809 buffer += "<![CDATA[";
1810 buffer += text.Value();
1811 buffer += "]]>";
1812 DoLineBreak();
1813 }
1814 else if ( simpleTextPrint )
1815 {
1816 TIXML_STRING str;
1817 TiXmlBase::EncodeString( text.ValueTStr(), &str );
1818 buffer += str;
1819 }
1820 else
1821 {
1822 DoIndent();
1823 TIXML_STRING str;
1824 TiXmlBase::EncodeString( text.ValueTStr(), &str );
1825 buffer += str;
1826 DoLineBreak();
1827 }
1828 return true;
1829}
1830
1831
1832bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
1833{
1834 DoIndent();
1835 declaration.Print( nullptr, 0, &buffer );
1836 DoLineBreak();
1837 return true;
1838}
1839
1840
1841bool TiXmlPrinter::Visit( const TiXmlComment& comment )
1842{
1843 DoIndent();
1844 buffer += "<!--";
1845 buffer += comment.Value();
1846 buffer += "-->";
1847 DoLineBreak();
1848 return true;
1849}
1850
1851
1852bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
1853{
1854 DoIndent();
1855 buffer += "<";
1856 buffer += unknown.Value();
1857 buffer += ">";
1858 DoLineBreak();
1859 return true;
1860}
1861
An attribute is a name-value pair.
Definition tinyxml.h:780
void SetDoubleValue(double _value)
Set the value from a double.
Definition tinyxml.cpp:1238
const char * Value() const
Return the value of this attribute.
Definition tinyxml.h:812
void SetValue(const char *_value)
Set the value.
Definition tinyxml.h:836
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition tinyxml.h:870
int QueryIntValue(int *_value) const
QueryIntValue examines the value string.
Definition tinyxml.cpp:1213
int QueryDoubleValue(double *_value) const
QueryDoubleValue examines the value string. See QueryIntValue().
Definition tinyxml.cpp:1220
void SetIntValue(int _value)
Set the value from an integer.
Definition tinyxml.cpp:1227
const char * Name() const
Return the name of this attribute.
Definition tinyxml.h:811
double DoubleValue() const
Return the value of this attribute, converted to a double.
Definition tinyxml.cpp:1254
void SetName(const char *_name)
Set the name of this attribute.
Definition tinyxml.h:835
int IntValue() const
Return the value of this attribute, converted to an integer.
Definition tinyxml.cpp:1249
const TiXmlAttribute * Next() const
Get the next sibling attribute in the DOM. Returns null at end.
Definition tinyxml.cpp:1147
const TiXmlAttribute * Previous() const
Get the previous sibling attribute in the DOM. Returns null at beginning.
Definition tinyxml.cpp:1167
TiXmlBase is a base class for every class in TinyXml.
Definition tinyxml.h:195
virtual void Print(FILE *cfile, int depth) const =0
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
static void EncodeString(const TiXmlString &str, TiXmlString *out)
Expands entities in a string.
Definition tinyxml.cpp:74
An XML comment.
Definition tinyxml.h:1156
virtual TiXmlNode * Clone() const
Returns a copy of this Comment.
Definition tinyxml.cpp:1296
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition tinyxml.cpp:1273
TiXmlComment()
Constructs an empty comment.
Definition tinyxml.h:1159
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:1290
In correct XML the declaration is the first entry in the file.
Definition tinyxml.h:1279
virtual TiXmlNode * Clone() const
Creates a copy of this Declaration and returns it.
Definition tinyxml.cpp:1431
TiXmlDeclaration()
Construct an empty declaration.
Definition tinyxml.h:1282
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:1425
Always the top level node.
Definition tinyxml.h:1387
bool Error() const
If an error occurs, Error will be set to true.
Definition tinyxml.h:1453
bool LoadFile(TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Load a file using the current document value.
Definition tinyxml.cpp:931
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Parse the given null terminated block of xml data.
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:1133
TiXmlDocument()
Create an empty document, that has no name.
Definition tinyxml.cpp:891
void Print() const
Write the document to standard out using formatted printing ("pretty print").
Definition tinyxml.h:1512
bool SaveFile() const
Save a file using the current document value. Returns true if successful.
Definition tinyxml.cpp:937
void ClearError()
If you have handled the error, it can be reset with this call.
Definition tinyxml.h:1504
The element is a container class.
Definition tinyxml.h:941
TiXmlElement(const char *in_value)
Construct an element.
Definition tinyxml.cpp:543
virtual bool Accept(TiXmlVisitor *visitor) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:853
void SetDoubleAttribute(const char *name, double value)
Sets an attribute of name to a given value.
Definition tinyxml.cpp:738
void RemoveAttribute(const char *name)
Deletes an attribute with the given name.
Definition tinyxml.cpp:455
int QueryIntAttribute(const char *name, int *_value) const
QueryIntAttribute examines the attribute - it is an alternative to the Attribute() method with richer...
Definition tinyxml.cpp:678
const char * Attribute(const char *name) const
Given an attribute name, Attribute() returns the value for the attribute of that name,...
Definition tinyxml.cpp:594
virtual TiXmlNode * Clone() const
Creates a new Element and returns it - the returned element is a copy.
Definition tinyxml.cpp:867
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition tinyxml.cpp:778
void SetAttribute(const char *name, const char *_value)
Sets an attribute of name to a given value.
Definition tinyxml.cpp:758
int QueryDoubleAttribute(const char *name, double *_value) const
QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
Definition tinyxml.cpp:698
const char * GetText() const
Convenience function for easy access to the text inside an element.
Definition tinyxml.cpp:878
A TiXmlHandle is a class that wraps a node pointer with null checks; this is an incredibly useful thi...
Definition tinyxml.h:1632
TiXmlHandle Child(const char *value, int index) const
Return a handle to the "index" child with the given name.
Definition tinyxml.cpp:1674
TiXmlHandle(TiXmlNode *_node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition tinyxml.h:1635
TiXmlHandle FirstChildElement() const
Return a handle to the first child element.
Definition tinyxml.cpp:1631
TiXmlHandle FirstChild() const
Return a handle to the first child node.
Definition tinyxml.cpp:1607
TiXmlHandle ChildElement(const char *value, int index) const
Return a handle to the "index" child element with the given name.
Definition tinyxml.cpp:1712
The parent class for everything in the Document Object Model.
Definition tinyxml.h:424
int Type() const
Query the type (as an enumerated value, above) of this node.
Definition tinyxml.h:684
const TiXmlElement * FirstChildElement() const
Convenience function to get through elements.
Definition tinyxml.cpp:470
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
Definition tinyxml.cpp:208
virtual const TiXmlText * ToText() const
Cast to a more defined type. Will return null if not of the requested type.
Definition tinyxml.h:701
TiXmlNode * InsertAfterChild(TiXmlNode *afterThis, const TiXmlNode &addThis)
Add a new node related to this.
Definition tinyxml.cpp:282
void SetValue(const char *_value)
Changes the value of the node.
Definition tinyxml.h:508
const TiXmlNode * PreviousSibling() const
Navigate to a sibling node.
Definition tinyxml.h:614
const char * Value() const
The meaning of 'value' changes for the specific type of TiXmlNode.
Definition tinyxml.h:487
const TiXmlNode * NextSibling() const
Navigate to a sibling node.
Definition tinyxml.h:631
TiXmlNode * ReplaceChild(TiXmlNode *replaceThis, const TiXmlNode &withThis)
Replace a child of this node.
Definition tinyxml.cpp:314
const TiXmlNode * IterateChildren(const TiXmlNode *previous) const
An alternate way to walk the children of a node.
Definition tinyxml.cpp:403
void Clear()
Delete all the children of this node. Does not affect 'this'.
Definition tinyxml.cpp:191
TiXmlNode * InsertBeforeChild(TiXmlNode *beforeThis, const TiXmlNode &addThis)
Add a new node related to this.
Definition tinyxml.cpp:250
virtual const TiXmlDocument * ToDocument() const
Cast to a more defined type. Will return null if not of the requested type.
Definition tinyxml.h:697
virtual TiXmlNode * Clone() const =0
Create an exact duplicate of this node and return it.
const TiXmlElement * NextSiblingElement() const
Convenience function to get through elements.
Definition tinyxml.cpp:500
virtual bool Accept(TiXmlVisitor *visitor) const =0
Accept a hierchical visit the nodes in the TinyXML DOM.
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
Definition tinyxml.h:698
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
Definition tinyxml.cpp:530
bool RemoveChild(TiXmlNode *removeThis)
Delete a child of this node.
Definition tinyxml.cpp:353
const TiXmlNode * FirstChild() const
The first child of this node. Will be null if there are no children.
Definition tinyxml.h:522
TiXmlNode * InsertEndChild(const TiXmlNode &addThis)
Add a new node related to this.
Definition tinyxml.cpp:235
Print to memory functionality.
Definition tinyxml.h:1731
virtual bool VisitExit(const TiXmlDocument &doc)
Visit a document.
Definition tinyxml.cpp:1736
virtual bool VisitEnter(const TiXmlDocument &doc)
Visit a document.
Definition tinyxml.cpp:1731
void SetStreamPrinting()
Switch over to "stream printing" which is the most dense formatting without linebreaks.
Definition tinyxml.h:1764
virtual bool Visit(const TiXmlDeclaration &declaration)
Visit a declaration.
Definition tinyxml.cpp:1832
XML text.
Definition tinyxml.h:1206
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition tinyxml.cpp:1308
bool CDATA() const
Queries whether this represents text using a CDATA section.
Definition tinyxml.h:1236
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:1336
TiXmlText(const char *initValue)
Constructor for text element.
Definition tinyxml.h:1213
Any tag that tinyXml doesn't recognize is saved as an unknown.
Definition tinyxml.h:1348
virtual TiXmlNode * Clone() const
Creates a copy of this Unknown and returns it.
Definition tinyxml.cpp:1463
virtual void Print(FILE *cfile, int depth) const
All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL ...
Definition tinyxml.cpp:1443
virtual bool Accept(TiXmlVisitor *content) const
Walk the XML tree visiting this node and all of its children.
Definition tinyxml.cpp:1457
Implements the interface to the "Visitor pattern" (see the Accept() method.) If you call the Accept()...
Definition tinyxml.h:129
virtual bool VisitEnter(const TiXmlDocument &)
Visit a document.
Definition tinyxml.h:134
virtual bool VisitExit(const TiXmlDocument &)
Visit a document.
Definition tinyxml.h:136
virtual bool Visit(const TiXmlDeclaration &)
Visit a declaration.
Definition tinyxml.h:144