Chameleon

Chameleon Svn Source Tree

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

Source at commit 1314 created 12 years 8 months ago.
By meklort, Temp hacks for xml parser
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{
1279double val = 0;
1280sscanf(value.c_str (), "%f", &val);
1281return val;
1282//return atof (value.c_str ());
1283}
1284
1285
1286TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
1287{
1288copy.CopyTo( this );
1289}
1290
1291
1292TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
1293{
1294Clear();
1295base.CopyTo( this );
1296return *this;
1297}
1298
1299
1300void TiXmlComment::Print( FILE* cfile, int depth ) const
1301{
1302assert( cfile );
1303for ( int i=0; i<depth; i++ )
1304{
1305fprintf( cfile, " " );
1306}
1307fprintf( cfile, "<!--%s-->", value.c_str() );
1308}
1309
1310
1311void TiXmlComment::CopyTo( TiXmlComment* target ) const
1312{
1313TiXmlNode::CopyTo( target );
1314}
1315
1316
1317bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
1318{
1319return visitor->Visit( *this );
1320}
1321
1322
1323TiXmlNode* TiXmlComment::Clone() const
1324{
1325TiXmlComment* clone = new TiXmlComment();
1326
1327if ( !clone )
1328return 0;
1329
1330CopyTo( clone );
1331return clone;
1332}
1333
1334
1335void TiXmlText::Print( FILE* cfile, int depth ) const
1336{
1337assert( cfile );
1338if ( cdata )
1339{
1340int i;
1341fprintf( cfile, "\n" );
1342for ( i=0; i<depth; i++ ) {
1343fprintf( cfile, " " );
1344}
1345fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );// unformatted output
1346}
1347else
1348{
1349TIXML_STRING buffer;
1350EncodeString( value, &buffer );
1351fprintf( cfile, "%s", buffer.c_str() );
1352}
1353}
1354
1355
1356void TiXmlText::CopyTo( TiXmlText* target ) const
1357{
1358TiXmlNode::CopyTo( target );
1359target->cdata = cdata;
1360}
1361
1362
1363bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
1364{
1365return visitor->Visit( *this );
1366}
1367
1368
1369TiXmlNode* TiXmlText::Clone() const
1370{
1371TiXmlText* clone = 0;
1372clone = new TiXmlText( "" );
1373
1374if ( !clone )
1375return 0;
1376
1377CopyTo( clone );
1378return clone;
1379}
1380
1381
1382TiXmlDeclaration::TiXmlDeclaration( const char * _version,
1383const char * _encoding,
1384const char * _standalone )
1385: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1386{
1387version = _version;
1388encoding = _encoding;
1389standalone = _standalone;
1390}
1391
1392
1393#ifdef TIXML_USE_STL
1394TiXmlDeclaration::TiXmlDeclaration(const std::string& _version,
1395const std::string& _encoding,
1396const std::string& _standalone )
1397: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1398{
1399version = _version;
1400encoding = _encoding;
1401standalone = _standalone;
1402}
1403#endif
1404
1405
1406TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
1407: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
1408{
1409copy.CopyTo( this );
1410}
1411
1412
1413TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
1414{
1415Clear();
1416copy.CopyTo( this );
1417return *this;
1418}
1419
1420
1421void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1422{
1423if ( cfile ) fprintf( cfile, "<?xml " );
1424if ( str ) (*str) += "<?xml ";
1425
1426if ( !version.empty() ) {
1427if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
1428if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
1429}
1430if ( !encoding.empty() ) {
1431if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
1432if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
1433}
1434if ( !standalone.empty() ) {
1435if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
1436if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
1437}
1438if ( cfile ) fprintf( cfile, "?>" );
1439if ( str ) (*str) += "?>";
1440}
1441
1442
1443void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
1444{
1445TiXmlNode::CopyTo( target );
1446
1447target->version = version;
1448target->encoding = encoding;
1449target->standalone = standalone;
1450}
1451
1452
1453bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
1454{
1455return visitor->Visit( *this );
1456}
1457
1458
1459TiXmlNode* TiXmlDeclaration::Clone() const
1460{
1461TiXmlDeclaration* clone = new TiXmlDeclaration();
1462
1463if ( !clone )
1464return 0;
1465
1466CopyTo( clone );
1467return clone;
1468}
1469
1470
1471void TiXmlUnknown::Print( FILE* cfile, int depth ) const
1472{
1473for ( int i=0; i<depth; i++ )
1474fprintf( cfile, " " );
1475fprintf( cfile, "<%s>", value.c_str() );
1476}
1477
1478
1479void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
1480{
1481TiXmlNode::CopyTo( target );
1482}
1483
1484
1485bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
1486{
1487return visitor->Visit( *this );
1488}
1489
1490
1491TiXmlNode* TiXmlUnknown::Clone() const
1492{
1493TiXmlUnknown* clone = new TiXmlUnknown();
1494
1495if ( !clone )
1496return 0;
1497
1498CopyTo( clone );
1499return clone;
1500}
1501
1502
1503TiXmlAttributeSet::TiXmlAttributeSet()
1504{
1505sentinel.next = &sentinel;
1506sentinel.prev = &sentinel;
1507}
1508
1509
1510TiXmlAttributeSet::~TiXmlAttributeSet()
1511{
1512assert( sentinel.next == &sentinel );
1513assert( sentinel.prev == &sentinel );
1514}
1515
1516
1517void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
1518{
1519 #ifdef TIXML_USE_STL
1520assert( !Find( TIXML_STRING( addMe->Name() ) ) );// Shouldn't be multiply adding to the set.
1521#else
1522assert( !Find( addMe->Name() ) );// Shouldn't be multiply adding to the set.
1523#endif
1524
1525addMe->next = &sentinel;
1526addMe->prev = sentinel.prev;
1527
1528sentinel.prev->next = addMe;
1529sentinel.prev = addMe;
1530}
1531
1532void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
1533{
1534TiXmlAttribute* node;
1535
1536for( node = sentinel.next; node != &sentinel; node = node->next )
1537{
1538if ( node == removeMe )
1539{
1540node->prev->next = node->next;
1541node->next->prev = node->prev;
1542node->next = 0;
1543node->prev = 0;
1544return;
1545}
1546}
1547assert( 0 );// we tried to remove a non-linked attribute.
1548}
1549
1550
1551#ifdef TIXML_USE_STL
1552TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
1553{
1554for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1555{
1556if ( node->name == name )
1557return node;
1558}
1559return 0;
1560}
1561
1562TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
1563{
1564TiXmlAttribute* attrib = Find( _name );
1565if ( !attrib ) {
1566attrib = new TiXmlAttribute();
1567Add( attrib );
1568attrib->SetName( _name );
1569}
1570return attrib;
1571}
1572#endif
1573
1574
1575TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
1576{
1577for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1578{
1579if ( strcmp( node->name.c_str(), name ) == 0 )
1580return node;
1581}
1582return 0;
1583}
1584
1585
1586TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
1587{
1588TiXmlAttribute* attrib = Find( _name );
1589if ( !attrib ) {
1590attrib = new TiXmlAttribute();
1591Add( attrib );
1592attrib->SetName( _name );
1593}
1594return attrib;
1595}
1596
1597
1598#ifdef TIXML_USE_STL
1599std::istream& operator>> (std::istream & in, TiXmlNode & base)
1600{
1601TIXML_STRING tag;
1602tag.reserve( 8 * 1000 );
1603base.StreamIn( &in, &tag );
1604
1605base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1606return in;
1607}
1608#endif
1609
1610
1611#ifdef TIXML_USE_STL
1612std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
1613{
1614TiXmlPrinter printer;
1615printer.SetStreamPrinting();
1616base.Accept( &printer );
1617out << printer.Str();
1618
1619return out;
1620}
1621
1622
1623std::string& operator<< (std::string& out, const TiXmlNode& base )
1624{
1625TiXmlPrinter printer;
1626printer.SetStreamPrinting();
1627base.Accept( &printer );
1628out.append( printer.Str() );
1629
1630return out;
1631}
1632#endif
1633
1634
1635TiXmlHandle TiXmlHandle::FirstChild() const
1636{
1637if ( node )
1638{
1639TiXmlNode* child = node->FirstChild();
1640if ( child )
1641return TiXmlHandle( child );
1642}
1643return TiXmlHandle( 0 );
1644}
1645
1646
1647TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
1648{
1649if ( node )
1650{
1651TiXmlNode* child = node->FirstChild( value );
1652if ( child )
1653return TiXmlHandle( child );
1654}
1655return TiXmlHandle( 0 );
1656}
1657
1658
1659TiXmlHandle TiXmlHandle::FirstChildElement() const
1660{
1661if ( node )
1662{
1663TiXmlElement* child = node->FirstChildElement();
1664if ( child )
1665return TiXmlHandle( child );
1666}
1667return TiXmlHandle( 0 );
1668}
1669
1670
1671TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
1672{
1673if ( node )
1674{
1675TiXmlElement* child = node->FirstChildElement( value );
1676if ( child )
1677return TiXmlHandle( child );
1678}
1679return TiXmlHandle( 0 );
1680}
1681
1682
1683TiXmlHandle TiXmlHandle::Child( int count ) const
1684{
1685if ( node )
1686{
1687int i;
1688TiXmlNode* child = node->FirstChild();
1689for (i=0;
1690child && i<count;
1691child = child->NextSibling(), ++i )
1692{
1693// nothing
1694}
1695if ( child )
1696return TiXmlHandle( child );
1697}
1698return TiXmlHandle( 0 );
1699}
1700
1701
1702TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
1703{
1704if ( node )
1705{
1706int i;
1707TiXmlNode* child = node->FirstChild( value );
1708for (i=0;
1709child && i<count;
1710child = child->NextSibling( value ), ++i )
1711{
1712// nothing
1713}
1714if ( child )
1715return TiXmlHandle( child );
1716}
1717return TiXmlHandle( 0 );
1718}
1719
1720
1721TiXmlHandle TiXmlHandle::ChildElement( int count ) const
1722{
1723if ( node )
1724{
1725int i;
1726TiXmlElement* child = node->FirstChildElement();
1727for (i=0;
1728child && i<count;
1729child = child->NextSiblingElement(), ++i )
1730{
1731// nothing
1732}
1733if ( child )
1734return TiXmlHandle( child );
1735}
1736return TiXmlHandle( 0 );
1737}
1738
1739
1740TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
1741{
1742if ( node )
1743{
1744int i;
1745TiXmlElement* child = node->FirstChildElement( value );
1746for (i=0;
1747child && i<count;
1748child = child->NextSiblingElement( value ), ++i )
1749{
1750// nothing
1751}
1752if ( child )
1753return TiXmlHandle( child );
1754}
1755return TiXmlHandle( 0 );
1756}
1757
1758
1759bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
1760{
1761return true;
1762}
1763
1764bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
1765{
1766return true;
1767}
1768
1769bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
1770{
1771DoIndent();
1772buffer += "<";
1773buffer += element.Value();
1774
1775for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
1776{
1777buffer += " ";
1778attrib->Print( 0, 0, &buffer );
1779}
1780
1781if ( !element.FirstChild() )
1782{
1783buffer += " />";
1784DoLineBreak();
1785}
1786else
1787{
1788buffer += ">";
1789if ( element.FirstChild()->ToText()
1790 && element.LastChild() == element.FirstChild()
1791 && element.FirstChild()->ToText()->CDATA() == false )
1792{
1793simpleTextPrint = true;
1794// no DoLineBreak()!
1795}
1796else
1797{
1798DoLineBreak();
1799}
1800}
1801++depth;
1802return true;
1803}
1804
1805
1806bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
1807{
1808--depth;
1809if ( !element.FirstChild() )
1810{
1811// nothing.
1812}
1813else
1814{
1815if ( simpleTextPrint )
1816{
1817simpleTextPrint = false;
1818}
1819else
1820{
1821DoIndent();
1822}
1823buffer += "</";
1824buffer += element.Value();
1825buffer += ">";
1826DoLineBreak();
1827}
1828return true;
1829}
1830
1831
1832bool TiXmlPrinter::Visit( const TiXmlText& text )
1833{
1834if ( text.CDATA() )
1835{
1836DoIndent();
1837buffer += "<![CDATA[";
1838buffer += text.Value();
1839buffer += "]]>";
1840DoLineBreak();
1841}
1842else if ( simpleTextPrint )
1843{
1844TIXML_STRING str;
1845TiXmlBase::EncodeString( text.ValueTStr(), &str );
1846buffer += str;
1847}
1848else
1849{
1850DoIndent();
1851TIXML_STRING str;
1852TiXmlBase::EncodeString( text.ValueTStr(), &str );
1853buffer += str;
1854DoLineBreak();
1855}
1856return true;
1857}
1858
1859
1860bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
1861{
1862DoIndent();
1863declaration.Print( 0, 0, &buffer );
1864DoLineBreak();
1865return true;
1866}
1867
1868
1869bool TiXmlPrinter::Visit( const TiXmlComment& comment )
1870{
1871DoIndent();
1872buffer += "<!--";
1873buffer += comment.Value();
1874buffer += "-->";
1875DoLineBreak();
1876return true;
1877}
1878
1879
1880bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
1881{
1882DoIndent();
1883buffer += "<";
1884buffer += unknown.Value();
1885buffer += ">";
1886DoLineBreak();
1887return true;
1888}
1889
1890

Archive Download this file

Revision: 1314