Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/modules/TinyXML/tinyxml.cpp

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

Archive Download this file

Revision: 1307