00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <ctype.h>
00026
00027 #ifdef TIXML_USE_STL
00028 #include <sstream>
00029 #include <iostream>
00030 #endif
00031
00032 #include "tinyxml.h"
00033
00034 FILE* TiXmlFOpen( const char* filename, const char* mode );
00035
00036 bool TiXmlBase::condenseWhiteSpace = true;
00037
00038
00039 FILE* TiXmlFOpen( const char* filename, const char* mode )
00040 {
00041 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00042 FILE* fp = 0;
00043 errno_t err = fopen_s( &fp, filename, mode );
00044 if ( !err && fp )
00045 return fp;
00046 return 0;
00047 #else
00048 return fopen( filename, mode );
00049 #endif
00050 }
00051
00052 void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
00053 {
00054 int i=0;
00055
00056 while( i<(int)str.length() )
00057 {
00058 unsigned char c = (unsigned char) str[i];
00059
00060 if ( c == '&'
00061 && i < ( (int)str.length() - 2 )
00062 && str[i+1] == '#'
00063 && str[i+2] == 'x' )
00064 {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 while ( i<(int)str.length()-1 )
00076 {
00077 outString->append( str.c_str() + i, 1 );
00078 ++i;
00079 if ( str[i] == ';' )
00080 break;
00081 }
00082 }
00083 else if ( c == '&' )
00084 {
00085 outString->append( entity[0].str, entity[0].strLength );
00086 ++i;
00087 }
00088 else if ( c == '<' )
00089 {
00090 outString->append( entity[1].str, entity[1].strLength );
00091 ++i;
00092 }
00093 else if ( c == '>' )
00094 {
00095 outString->append( entity[2].str, entity[2].strLength );
00096 ++i;
00097 }
00098 else if ( c == '\"' )
00099 {
00100 outString->append( entity[3].str, entity[3].strLength );
00101 ++i;
00102 }
00103 else if ( c == '\'' )
00104 {
00105 outString->append( entity[4].str, entity[4].strLength );
00106 ++i;
00107 }
00108 else if ( c < 32 )
00109 {
00110
00111
00112 char buf[ 32 ];
00113
00114 #if defined(TIXML_SNPRINTF)
00115 TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
00116 #else
00117 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
00118 #endif
00119
00120
00121
00122 outString->append( buf, (int)strlen( buf ) );
00123 ++i;
00124 }
00125 else
00126 {
00127
00128
00129 *outString += (char) c;
00130 ++i;
00131 }
00132 }
00133 }
00134
00135
00136 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
00137 {
00138 parent = 0;
00139 type = _type;
00140 firstChild = 0;
00141 lastChild = 0;
00142 prev = 0;
00143 next = 0;
00144 }
00145
00146
00147 TiXmlNode::~TiXmlNode()
00148 {
00149 TiXmlNode* node = firstChild;
00150 TiXmlNode* temp = 0;
00151
00152 while ( node )
00153 {
00154 temp = node;
00155 node = node->next;
00156 delete temp;
00157 }
00158 }
00159
00160
00161 void TiXmlNode::CopyTo( TiXmlNode* target ) const
00162 {
00163 target->SetValue (value.c_str() );
00164 target->userData = userData;
00165 target->location = location;
00166 }
00167
00168
00169 void TiXmlNode::Clear()
00170 {
00171 TiXmlNode* node = firstChild;
00172 TiXmlNode* temp = 0;
00173
00174 while ( node )
00175 {
00176 temp = node;
00177 node = node->next;
00178 delete temp;
00179 }
00180
00181 firstChild = 0;
00182 lastChild = 0;
00183 }
00184
00185
00186 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
00187 {
00188 assert( node->parent == 0 || node->parent == this );
00189 assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
00190
00191 if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
00192 {
00193 delete node;
00194 TiXmlDocument *document = GetDocument();
00195 if ( document ) document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
00196 return 0;
00197 }
00198
00199 node->parent = this;
00200
00201 node->prev = lastChild;
00202 node->next = 0;
00203
00204 if ( lastChild )
00205 lastChild->next = node;
00206 else
00207 firstChild = node;
00208
00209 lastChild = node;
00210 return node;
00211 }
00212
00213
00214 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
00215 {
00216 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
00217 {
00218 TiXmlDocument *document = GetDocument();
00219 if ( document ) document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
00220 return 0;
00221 }
00222 TiXmlNode* node = addThis.Clone();
00223 if ( !node )
00224 return 0;
00225
00226 return LinkEndChild( node );
00227 }
00228
00229
00230 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
00231 {
00232 if ( !beforeThis || beforeThis->parent != this ) {
00233 return 0;
00234 }
00235 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
00236 {
00237 TiXmlDocument *document = GetDocument();
00238 if ( document ) document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
00239 return 0;
00240 }
00241
00242 TiXmlNode* node = addThis.Clone();
00243 if ( !node )
00244 return 0;
00245 node->parent = this;
00246
00247 node->next = beforeThis;
00248 node->prev = beforeThis->prev;
00249 if ( beforeThis->prev )
00250 {
00251 beforeThis->prev->next = node;
00252 }
00253 else
00254 {
00255 assert( firstChild == beforeThis );
00256 firstChild = node;
00257 }
00258 beforeThis->prev = node;
00259 return node;
00260 }
00261
00262
00263 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
00264 {
00265 if ( !afterThis || afterThis->parent != this ) {
00266 return 0;
00267 }
00268 if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
00269 {
00270 TiXmlDocument *document = GetDocument();
00271 if ( document ) document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
00272 return 0;
00273 }
00274
00275 TiXmlNode* node = addThis.Clone();
00276 if ( !node )
00277 return 0;
00278 node->parent = this;
00279
00280 node->prev = afterThis;
00281 node->next = afterThis->next;
00282 if ( afterThis->next )
00283 {
00284 afterThis->next->prev = node;
00285 }
00286 else
00287 {
00288 assert( lastChild == afterThis );
00289 lastChild = node;
00290 }
00291 afterThis->next = node;
00292 return node;
00293 }
00294
00295
00296 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
00297 {
00298 if ( !replaceThis )
00299 return 0;
00300
00301 if ( replaceThis->parent != this )
00302 return 0;
00303
00304 if ( withThis.ToDocument() ) {
00305
00306 TiXmlDocument* document = GetDocument();
00307 if ( document )
00308 document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
00309 return 0;
00310 }
00311
00312 TiXmlNode* node = withThis.Clone();
00313 if ( !node )
00314 return 0;
00315
00316 node->next = replaceThis->next;
00317 node->prev = replaceThis->prev;
00318
00319 if ( replaceThis->next )
00320 replaceThis->next->prev = node;
00321 else
00322 lastChild = node;
00323
00324 if ( replaceThis->prev )
00325 replaceThis->prev->next = node;
00326 else
00327 firstChild = node;
00328
00329 delete replaceThis;
00330 node->parent = this;
00331 return node;
00332 }
00333
00334
00335 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
00336 {
00337 if ( !removeThis ) {
00338 return false;
00339 }
00340
00341 if ( removeThis->parent != this )
00342 {
00343 assert( 0 );
00344 return false;
00345 }
00346
00347 if ( removeThis->next )
00348 removeThis->next->prev = removeThis->prev;
00349 else
00350 lastChild = removeThis->prev;
00351
00352 if ( removeThis->prev )
00353 removeThis->prev->next = removeThis->next;
00354 else
00355 firstChild = removeThis->next;
00356
00357 delete removeThis;
00358 return true;
00359 }
00360
00361 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
00362 {
00363 const TiXmlNode* node;
00364 for ( node = firstChild; node; node = node->next )
00365 {
00366 if ( strcmp( node->Value(), _value ) == 0 )
00367 return node;
00368 }
00369 return 0;
00370 }
00371
00372
00373 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
00374 {
00375 const TiXmlNode* node;
00376 for ( node = lastChild; node; node = node->prev )
00377 {
00378 if ( strcmp( node->Value(), _value ) == 0 )
00379 return node;
00380 }
00381 return 0;
00382 }
00383
00384
00385 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
00386 {
00387 if ( !previous )
00388 {
00389 return FirstChild();
00390 }
00391 else
00392 {
00393 assert( previous->parent == this );
00394 return previous->NextSibling();
00395 }
00396 }
00397
00398
00399 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
00400 {
00401 if ( !previous )
00402 {
00403 return FirstChild( val );
00404 }
00405 else
00406 {
00407 assert( previous->parent == this );
00408 return previous->NextSibling( val );
00409 }
00410 }
00411
00412
00413 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
00414 {
00415 const TiXmlNode* node;
00416 for ( node = next; node; node = node->next )
00417 {
00418 if ( strcmp( node->Value(), _value ) == 0 )
00419 return node;
00420 }
00421 return 0;
00422 }
00423
00424
00425 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
00426 {
00427 const TiXmlNode* node;
00428 for ( node = prev; node; node = node->prev )
00429 {
00430 if ( strcmp( node->Value(), _value ) == 0 )
00431 return node;
00432 }
00433 return 0;
00434 }
00435
00436
00437 void TiXmlElement::RemoveAttribute( const char * name )
00438 {
00439 #ifdef TIXML_USE_STL
00440 TIXML_STRING str( name );
00441 TiXmlAttribute* node = attributeSet.Find( str );
00442 #else
00443 TiXmlAttribute* node = attributeSet.Find( name );
00444 #endif
00445 if ( node )
00446 {
00447 attributeSet.Remove( node );
00448 delete node;
00449 }
00450 }
00451
00452 const TiXmlElement* TiXmlNode::FirstChildElement() const
00453 {
00454 const TiXmlNode* node;
00455
00456 for ( node = FirstChild();
00457 node;
00458 node = node->NextSibling() )
00459 {
00460 if ( node->ToElement() )
00461 return node->ToElement();
00462 }
00463 return 0;
00464 }
00465
00466
00467 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
00468 {
00469 const TiXmlNode* node;
00470
00471 for ( node = FirstChild( _value );
00472 node;
00473 node = node->NextSibling( _value ) )
00474 {
00475 if ( node->ToElement() )
00476 return node->ToElement();
00477 }
00478 return 0;
00479 }
00480
00481
00482 const TiXmlElement* TiXmlNode::NextSiblingElement() const
00483 {
00484 const TiXmlNode* node;
00485
00486 for ( node = NextSibling();
00487 node;
00488 node = node->NextSibling() )
00489 {
00490 if ( node->ToElement() )
00491 return node->ToElement();
00492 }
00493 return 0;
00494 }
00495
00496
00497 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
00498 {
00499 const TiXmlNode* node;
00500
00501 for ( node = NextSibling( _value );
00502 node;
00503 node = node->NextSibling( _value ) )
00504 {
00505 if ( node->ToElement() )
00506 return node->ToElement();
00507 }
00508 return 0;
00509 }
00510
00511
00512 const TiXmlDocument* TiXmlNode::GetDocument() const
00513 {
00514 const TiXmlNode* node;
00515
00516 for( node = this; node; node = node->parent )
00517 {
00518 if ( node->ToDocument() )
00519 return node->ToDocument();
00520 }
00521 return 0;
00522 }
00523
00524
00525 TiXmlElement::TiXmlElement (const char * _value)
00526 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
00527 {
00528 firstChild = lastChild = 0;
00529 value = _value;
00530 }
00531
00532
00533 #ifdef TIXML_USE_STL
00534 TiXmlElement::TiXmlElement( const std::string& _value )
00535 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
00536 {
00537 firstChild = lastChild = 0;
00538 value = _value;
00539 }
00540 #endif
00541
00542
00543 TiXmlElement::TiXmlElement( const TiXmlElement& copy)
00544 : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
00545 {
00546 firstChild = lastChild = 0;
00547 copy.CopyTo( this );
00548 }
00549
00550
00551 TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
00552 {
00553 ClearThis();
00554 base.CopyTo( this );
00555 return *this;
00556 }
00557
00558
00559 TiXmlElement::~TiXmlElement()
00560 {
00561 ClearThis();
00562 }
00563
00564
00565 void TiXmlElement::ClearThis()
00566 {
00567 Clear();
00568 while( attributeSet.First() )
00569 {
00570 TiXmlAttribute* node = attributeSet.First();
00571 attributeSet.Remove( node );
00572 delete node;
00573 }
00574 }
00575
00576
00577 const char* TiXmlElement::Attribute( const char* name ) const
00578 {
00579 const TiXmlAttribute* node = attributeSet.Find( name );
00580 if ( node )
00581 return node->Value();
00582 return 0;
00583 }
00584
00585
00586 #ifdef TIXML_USE_STL
00587 const std::string* TiXmlElement::Attribute( const std::string& name ) const
00588 {
00589 const TiXmlAttribute* attrib = attributeSet.Find( name );
00590 if ( attrib )
00591 return &attrib->ValueStr();
00592 return 0;
00593 }
00594 #endif
00595
00596
00597 const char* TiXmlElement::Attribute( const char* name, int* i ) const
00598 {
00599 const TiXmlAttribute* attrib = attributeSet.Find( name );
00600 const char* result = 0;
00601
00602 if ( attrib ) {
00603 result = attrib->Value();
00604 if ( i ) {
00605 attrib->QueryIntValue( i );
00606 }
00607 }
00608 return result;
00609 }
00610
00611
00612 #ifdef TIXML_USE_STL
00613 const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
00614 {
00615 const TiXmlAttribute* attrib = attributeSet.Find( name );
00616 const std::string* result = 0;
00617
00618 if ( attrib ) {
00619 result = &attrib->ValueStr();
00620 if ( i ) {
00621 attrib->QueryIntValue( i );
00622 }
00623 }
00624 return result;
00625 }
00626 #endif
00627
00628
00629 const char* TiXmlElement::Attribute( const char* name, double* d ) const
00630 {
00631 const TiXmlAttribute* attrib = attributeSet.Find( name );
00632 const char* result = 0;
00633
00634 if ( attrib ) {
00635 result = attrib->Value();
00636 if ( d ) {
00637 attrib->QueryDoubleValue( d );
00638 }
00639 }
00640 return result;
00641 }
00642
00643
00644 #ifdef TIXML_USE_STL
00645 const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
00646 {
00647 const TiXmlAttribute* attrib = attributeSet.Find( name );
00648 const std::string* result = 0;
00649
00650 if ( attrib ) {
00651 result = &attrib->ValueStr();
00652 if ( d ) {
00653 attrib->QueryDoubleValue( d );
00654 }
00655 }
00656 return result;
00657 }
00658 #endif
00659
00660
00661 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
00662 {
00663 const TiXmlAttribute* attrib = attributeSet.Find( name );
00664 if ( !attrib )
00665 return TIXML_NO_ATTRIBUTE;
00666 return attrib->QueryIntValue( ival );
00667 }
00668
00669
00670 #ifdef TIXML_USE_STL
00671 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
00672 {
00673 const TiXmlAttribute* attrib = attributeSet.Find( name );
00674 if ( !attrib )
00675 return TIXML_NO_ATTRIBUTE;
00676 return attrib->QueryIntValue( ival );
00677 }
00678 #endif
00679
00680
00681 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
00682 {
00683 const TiXmlAttribute* attrib = attributeSet.Find( name );
00684 if ( !attrib )
00685 return TIXML_NO_ATTRIBUTE;
00686 return attrib->QueryDoubleValue( dval );
00687 }
00688
00689
00690 #ifdef TIXML_USE_STL
00691 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
00692 {
00693 const TiXmlAttribute* attrib = attributeSet.Find( name );
00694 if ( !attrib )
00695 return TIXML_NO_ATTRIBUTE;
00696 return attrib->QueryDoubleValue( dval );
00697 }
00698 #endif
00699
00700
00701 void TiXmlElement::SetAttribute( const char * name, int val )
00702 {
00703 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00704 if ( attrib ) {
00705 attrib->SetIntValue( val );
00706 }
00707 }
00708
00709
00710 #ifdef TIXML_USE_STL
00711 void TiXmlElement::SetAttribute( const std::string& name, int val )
00712 {
00713 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00714 if ( attrib ) {
00715 attrib->SetIntValue( val );
00716 }
00717 }
00718 #endif
00719
00720
00721 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
00722 {
00723 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00724 if ( attrib ) {
00725 attrib->SetDoubleValue( val );
00726 }
00727 }
00728
00729
00730 #ifdef TIXML_USE_STL
00731 void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
00732 {
00733 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00734 if ( attrib ) {
00735 attrib->SetDoubleValue( val );
00736 }
00737 }
00738 #endif
00739
00740
00741 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
00742 {
00743 TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
00744 if ( attrib ) {
00745 attrib->SetValue( cvalue );
00746 }
00747 }
00748
00749
00750 #ifdef TIXML_USE_STL
00751 void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
00752 {
00753 TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
00754 if ( attrib ) {
00755 attrib->SetValue( _value );
00756 }
00757 }
00758 #endif
00759
00760
00761 void TiXmlElement::Print( FILE* cfile, int depth ) const
00762 {
00763 int i;
00764 assert( cfile );
00765 for ( i=0; i<depth; i++ ) {
00766 fprintf( cfile, " " );
00767 }
00768
00769 fprintf( cfile, "<%s", (const char*)value.c_str() );
00770
00771 const TiXmlAttribute* attrib;
00772 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
00773 {
00774 fprintf( cfile, " " );
00775 attrib->Print( cfile, depth );
00776 }
00777
00778
00779
00780
00781
00782 TiXmlNode* node;
00783 if ( !firstChild )
00784 {
00785 fprintf( cfile, " />" );
00786 }
00787 else if ( firstChild == lastChild && firstChild->ToText() )
00788 {
00789 fprintf( cfile, ">" );
00790 firstChild->Print( cfile, depth + 1 );
00791 fprintf( cfile, "</%s>", (const char*)value.c_str() );
00792 }
00793 else
00794 {
00795 fprintf( cfile, ">" );
00796
00797 for ( node = firstChild; node; node=node->NextSibling() )
00798 {
00799 if ( !node->ToText() )
00800 {
00801 fprintf( cfile, "\n" );
00802 }
00803 node->Print( cfile, depth+1 );
00804 }
00805 fprintf( cfile, "\n" );
00806 for( i=0; i<depth; ++i ) {
00807 fprintf( cfile, " " );
00808 }
00809 fprintf( cfile, "</%s>", (const char*)value.c_str() );
00810 }
00811 }
00812
00813
00814 void TiXmlElement::CopyTo( TiXmlElement* target ) const
00815 {
00816
00817 TiXmlNode::CopyTo( target );
00818
00819
00820
00821 const TiXmlAttribute* attribute = 0;
00822 for( attribute = attributeSet.First();
00823 attribute;
00824 attribute = attribute->Next() )
00825 {
00826 target->SetAttribute( attribute->Name(), attribute->Value() );
00827 }
00828
00829 TiXmlNode* node = 0;
00830 for ( node = firstChild; node; node = node->NextSibling() )
00831 {
00832 target->LinkEndChild( node->Clone() );
00833 }
00834 }
00835
00836 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
00837 {
00838 if ( visitor->VisitEnter( *this, attributeSet.First() ) )
00839 {
00840 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
00841 {
00842 if ( !node->Accept( visitor ) )
00843 break;
00844 }
00845 }
00846 return visitor->VisitExit( *this );
00847 }
00848
00849
00850 TiXmlNode* TiXmlElement::Clone() const
00851 {
00852 TiXmlElement* clone = new TiXmlElement( Value() );
00853 if ( !clone )
00854 return 0;
00855
00856 CopyTo( clone );
00857 return clone;
00858 }
00859
00860
00861 const char* TiXmlElement::GetText() const
00862 {
00863 const TiXmlNode* child = this->FirstChild();
00864 if ( child ) {
00865 const TiXmlText* childText = child->ToText();
00866 if ( childText ) {
00867 return childText->Value();
00868 }
00869 }
00870 return 0;
00871 }
00872
00873
00874 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00875 {
00876 tabsize = 4;
00877 useMicrosoftBOM = false;
00878 ClearError();
00879 }
00880
00881 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00882 {
00883 tabsize = 4;
00884 useMicrosoftBOM = false;
00885 value = documentName;
00886 ClearError();
00887 }
00888
00889
00890 #ifdef TIXML_USE_STL
00891 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00892 {
00893 tabsize = 4;
00894 useMicrosoftBOM = false;
00895 value = documentName;
00896 ClearError();
00897 }
00898 #endif
00899
00900
00901 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00902 {
00903 copy.CopyTo( this );
00904 }
00905
00906
00907 TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
00908 {
00909 Clear();
00910 copy.CopyTo( this );
00911 return *this;
00912 }
00913
00914
00915 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
00916 {
00917 return LoadFile( Value(), encoding );
00918 }
00919
00920
00921 bool TiXmlDocument::SaveFile() const
00922 {
00923 return SaveFile( Value() );
00924 }
00925
00926 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
00927 {
00928 TIXML_STRING filename( _filename );
00929 value = filename;
00930
00931
00932 FILE* file = TiXmlFOpen( value.c_str (), "rb" );
00933
00934 if ( file )
00935 {
00936 bool result = LoadFile( file, encoding );
00937 fclose( file );
00938 return result;
00939 }
00940 else
00941 {
00942 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
00943 return false;
00944 }
00945 }
00946
00947 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
00948 {
00949 if ( !file )
00950 {
00951 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
00952 return false;
00953 }
00954
00955
00956 Clear();
00957 location.Clear();
00958
00959
00960 long length = 0;
00961 fseek( file, 0, SEEK_END );
00962 length = ftell( file );
00963 fseek( file, 0, SEEK_SET );
00964
00965
00966 if ( length <= 0 )
00967 {
00968 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
00969 return false;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 char* buf = new char[ length+1 ];
00994 buf[0] = 0;
00995
00996 if ( fread( buf, length, 1, file ) != 1 ) {
00997 delete [] buf;
00998 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
00999 return false;
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 const char* p = buf;
01014 char* q = buf;
01015 const char CR = 0x0d;
01016 const char LF = 0x0a;
01017
01018 buf[length] = 0;
01019 while( *p ) {
01020 assert( p < (buf+length) );
01021 assert( q <= (buf+length) );
01022 assert( q <= p );
01023
01024 if ( *p == CR ) {
01025 *q++ = LF;
01026 p++;
01027 if ( *p == LF ) {
01028 p++;
01029 }
01030 }
01031 else {
01032 *q++ = *p++;
01033 }
01034 }
01035 assert( q <= (buf+length) );
01036 *q = 0;
01037
01038 Parse( buf, 0, encoding );
01039
01040 delete [] buf;
01041 return !Error();
01042 }
01043
01044
01045 bool TiXmlDocument::SaveFile( const char * filename ) const
01046 {
01047
01048 FILE* fp = TiXmlFOpen( filename, "w" );
01049 if ( fp )
01050 {
01051 bool result = SaveFile( fp );
01052 fclose( fp );
01053 return result;
01054 }
01055 return false;
01056 }
01057
01058
01059 bool TiXmlDocument::SaveFile( FILE* fp ) const
01060 {
01061 if ( useMicrosoftBOM )
01062 {
01063 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
01064 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
01065 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
01066
01067 fputc( TIXML_UTF_LEAD_0, fp );
01068 fputc( TIXML_UTF_LEAD_1, fp );
01069 fputc( TIXML_UTF_LEAD_2, fp );
01070 }
01071 Print( fp, 0 );
01072 return (ferror(fp) == 0);
01073 }
01074
01075
01076 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
01077 {
01078 TiXmlNode::CopyTo( target );
01079
01080 target->error = error;
01081 target->errorId = errorId;
01082 target->errorDesc = errorDesc;
01083 target->tabsize = tabsize;
01084 target->errorLocation = errorLocation;
01085 target->useMicrosoftBOM = useMicrosoftBOM;
01086
01087 TiXmlNode* node = 0;
01088 for ( node = firstChild; node; node = node->NextSibling() )
01089 {
01090 target->LinkEndChild( node->Clone() );
01091 }
01092 }
01093
01094
01095 TiXmlNode* TiXmlDocument::Clone() const
01096 {
01097 TiXmlDocument* clone = new TiXmlDocument();
01098 if ( !clone )
01099 return 0;
01100
01101 CopyTo( clone );
01102 return clone;
01103 }
01104
01105
01106 void TiXmlDocument::Print( FILE* cfile, int depth ) const
01107 {
01108 assert( cfile );
01109 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
01110 {
01111 node->Print( cfile, depth );
01112 fprintf( cfile, "\n" );
01113 }
01114 }
01115
01116
01117 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
01118 {
01119 if ( visitor->VisitEnter( *this ) )
01120 {
01121 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
01122 {
01123 if ( !node->Accept( visitor ) )
01124 break;
01125 }
01126 }
01127 return visitor->VisitExit( *this );
01128 }
01129
01130
01131 const TiXmlAttribute* TiXmlAttribute::Next() const
01132 {
01133
01134
01135 if ( next->value.empty() && next->name.empty() )
01136 return 0;
01137 return next;
01138 }
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 const TiXmlAttribute* TiXmlAttribute::Previous() const
01152 {
01153
01154
01155 if ( prev->value.empty() && prev->name.empty() )
01156 return 0;
01157 return prev;
01158 }
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171 void TiXmlAttribute::Print( FILE* cfile, int , TIXML_STRING* str ) const
01172 {
01173 TIXML_STRING n, v;
01174
01175 EncodeString( name, &n );
01176 EncodeString( value, &v );
01177
01178 if (value.find ('\"') == TIXML_STRING::npos) {
01179 if ( cfile ) {
01180 fprintf (cfile, "%s=\"%s\"", (const char*)n.c_str(), (const char*)v.c_str() );
01181 }
01182 if ( str ) {
01183 (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
01184 }
01185 }
01186 else {
01187 if ( cfile ) {
01188 fprintf (cfile, "%s='%s'", (const char*)n.c_str(), (const char*)v.c_str() );
01189 }
01190 if ( str ) {
01191 (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
01192 }
01193 }
01194 }
01195
01196
01197 int TiXmlAttribute::QueryIntValue( int* ival ) const
01198 {
01199 if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
01200 return TIXML_SUCCESS;
01201 return TIXML_WRONG_TYPE;
01202 }
01203
01204 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
01205 {
01206 if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
01207 return TIXML_SUCCESS;
01208 return TIXML_WRONG_TYPE;
01209 }
01210
01211 void TiXmlAttribute::SetIntValue( int _value )
01212 {
01213 char buf [64];
01214 #if defined(TIXML_SNPRINTF)
01215 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
01216 #else
01217 sprintf (buf, "%d", _value);
01218 #endif
01219 SetValue (buf);
01220 }
01221
01222 void TiXmlAttribute::SetDoubleValue( double _value )
01223 {
01224 char buf [256];
01225 #if defined(TIXML_SNPRINTF)
01226 TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
01227 #else
01228 sprintf (buf, "%g", _value);
01229 #endif
01230 SetValue (buf);
01231 }
01232
01233 int TiXmlAttribute::IntValue() const
01234 {
01235 return atoi (value.c_str ());
01236 }
01237
01238 double TiXmlAttribute::DoubleValue() const
01239 {
01240 return atof (value.c_str ());
01241 }
01242
01243
01244 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
01245 {
01246 copy.CopyTo( this );
01247 }
01248
01249
01250 TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
01251 {
01252 Clear();
01253 base.CopyTo( this );
01254 return *this;
01255 }
01256
01257
01258 void TiXmlComment::Print( FILE* cfile, int depth ) const
01259 {
01260 assert( cfile );
01261 for ( int i=0; i<depth; i++ )
01262 {
01263 fprintf( cfile, " " );
01264 }
01265 fprintf( cfile, "<!--%s-->", (const char*)value.c_str() );
01266 }
01267
01268
01269 void TiXmlComment::CopyTo( TiXmlComment* target ) const
01270 {
01271 TiXmlNode::CopyTo( target );
01272 }
01273
01274
01275 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
01276 {
01277 return visitor->Visit( *this );
01278 }
01279
01280
01281 TiXmlNode* TiXmlComment::Clone() const
01282 {
01283 TiXmlComment* clone = new TiXmlComment();
01284
01285 if ( !clone )
01286 return 0;
01287
01288 CopyTo( clone );
01289 return clone;
01290 }
01291
01292
01293 void TiXmlText::Print( FILE* cfile, int depth ) const
01294 {
01295 assert( cfile );
01296 if ( cdata )
01297 {
01298 int i;
01299 fprintf( cfile, "\n" );
01300 for ( i=0; i<depth; i++ ) {
01301 fprintf( cfile, " " );
01302 }
01303 fprintf( cfile, "<![CDATA[%s]]>\n", (const char*)value.c_str() );
01304 }
01305 else
01306 {
01307 TIXML_STRING buffer;
01308 EncodeString( value, &buffer );
01309 fprintf( cfile, "%s", (const char*)buffer.c_str() );
01310 }
01311 }
01312
01313
01314 void TiXmlText::CopyTo( TiXmlText* target ) const
01315 {
01316 TiXmlNode::CopyTo( target );
01317 target->cdata = cdata;
01318 }
01319
01320
01321 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
01322 {
01323 return visitor->Visit( *this );
01324 }
01325
01326
01327 TiXmlNode* TiXmlText::Clone() const
01328 {
01329 TiXmlText* clone = 0;
01330 clone = new TiXmlText( "" );
01331
01332 if ( !clone )
01333 return 0;
01334
01335 CopyTo( clone );
01336 return clone;
01337 }
01338
01339
01340 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
01341 const char * _encoding,
01342 const char * _standalone )
01343 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01344 {
01345 version = _version;
01346 encoding = _encoding;
01347 standalone = _standalone;
01348 }
01349
01350
01351 #ifdef TIXML_USE_STL
01352 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
01353 const std::string& _encoding,
01354 const std::string& _standalone )
01355 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01356 {
01357 version = _version;
01358 encoding = _encoding;
01359 standalone = _standalone;
01360 }
01361 #endif
01362
01363
01364 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
01365 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01366 {
01367 copy.CopyTo( this );
01368 }
01369
01370
01371 TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
01372 {
01373 Clear();
01374 copy.CopyTo( this );
01375 return *this;
01376 }
01377
01378
01379 void TiXmlDeclaration::Print( FILE* cfile, int , TIXML_STRING* str ) const
01380 {
01381 if ( cfile ) fprintf( cfile, "<?xml " );
01382 if ( str ) (*str) += "<?xml ";
01383
01384 if ( !version.empty() ) {
01385 if ( cfile ) fprintf (cfile, "version=\"%s\" ", (const char*)version.c_str ());
01386 if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
01387 }
01388 if ( !encoding.empty() ) {
01389 if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", (const char*)encoding.c_str ());
01390 if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
01391 }
01392 if ( !standalone.empty() ) {
01393 if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", (const char*)standalone.c_str ());
01394 if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
01395 }
01396 if ( cfile ) fprintf( cfile, "?>" );
01397 if ( str ) (*str) += "?>";
01398 }
01399
01400
01401 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
01402 {
01403 TiXmlNode::CopyTo( target );
01404
01405 target->version = version;
01406 target->encoding = encoding;
01407 target->standalone = standalone;
01408 }
01409
01410
01411 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
01412 {
01413 return visitor->Visit( *this );
01414 }
01415
01416
01417 TiXmlNode* TiXmlDeclaration::Clone() const
01418 {
01419 TiXmlDeclaration* clone = new TiXmlDeclaration();
01420
01421 if ( !clone )
01422 return 0;
01423
01424 CopyTo( clone );
01425 return clone;
01426 }
01427
01428
01429 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
01430 {
01431 for ( int i=0; i<depth; i++ )
01432 fprintf( cfile, " " );
01433 fprintf( cfile, "<%s>", (const char*)value.c_str() );
01434 }
01435
01436
01437 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
01438 {
01439 TiXmlNode::CopyTo( target );
01440 }
01441
01442
01443 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
01444 {
01445 return visitor->Visit( *this );
01446 }
01447
01448
01449 TiXmlNode* TiXmlUnknown::Clone() const
01450 {
01451 TiXmlUnknown* clone = new TiXmlUnknown();
01452
01453 if ( !clone )
01454 return 0;
01455
01456 CopyTo( clone );
01457 return clone;
01458 }
01459
01460
01461 TiXmlAttributeSet::TiXmlAttributeSet()
01462 {
01463 sentinel.next = &sentinel;
01464 sentinel.prev = &sentinel;
01465 }
01466
01467
01468 TiXmlAttributeSet::~TiXmlAttributeSet()
01469 {
01470 assert( sentinel.next == &sentinel );
01471 assert( sentinel.prev == &sentinel );
01472 }
01473
01474
01475 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
01476 {
01477 #ifdef TIXML_USE_STL
01478 assert( !Find( TIXML_STRING( addMe->Name() ) ) );
01479 #else
01480 assert( !Find( addMe->Name() ) );
01481 #endif
01482
01483 addMe->next = &sentinel;
01484 addMe->prev = sentinel.prev;
01485
01486 sentinel.prev->next = addMe;
01487 sentinel.prev = addMe;
01488 }
01489
01490 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
01491 {
01492 TiXmlAttribute* node;
01493
01494 for( node = sentinel.next; node != &sentinel; node = node->next )
01495 {
01496 if ( node == removeMe )
01497 {
01498 node->prev->next = node->next;
01499 node->next->prev = node->prev;
01500 node->next = 0;
01501 node->prev = 0;
01502 return;
01503 }
01504 }
01505 assert( 0 );
01506 }
01507
01508
01509 #ifdef TIXML_USE_STL
01510 TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
01511 {
01512 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
01513 {
01514 if ( node->name == name )
01515 return node;
01516 }
01517 return 0;
01518 }
01519
01520 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
01521 {
01522 TiXmlAttribute* attrib = Find( _name );
01523 if ( !attrib ) {
01524 attrib = new TiXmlAttribute();
01525 Add( attrib );
01526 attrib->SetName( _name );
01527 }
01528 return attrib;
01529 }
01530 #endif
01531
01532
01533 TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
01534 {
01535 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
01536 {
01537 if ( strcmp( node->name.c_str(), name ) == 0 )
01538 return node;
01539 }
01540 return 0;
01541 }
01542
01543
01544 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
01545 {
01546 TiXmlAttribute* attrib = Find( _name );
01547 if ( !attrib ) {
01548 attrib = new TiXmlAttribute();
01549 Add( attrib );
01550 attrib->SetName( _name );
01551 }
01552 return attrib;
01553 }
01554
01555
01556 #ifdef TIXML_USE_STL
01557 std::istream& operator>> (std::istream & in, TiXmlNode & base)
01558 {
01559 TIXML_STRING tag;
01560 tag.reserve( 8 * 1000 );
01561 base.StreamIn( &in, &tag );
01562
01563 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
01564 return in;
01565 }
01566 #endif
01567
01568
01569 #ifdef TIXML_USE_STL
01570 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
01571 {
01572 TiXmlPrinter printer;
01573 printer.SetStreamPrinting();
01574 base.Accept( &printer );
01575 out << printer.Str();
01576
01577 return out;
01578 }
01579
01580
01581 std::string& operator<< (std::string& out, const TiXmlNode& base )
01582 {
01583 TiXmlPrinter printer;
01584 printer.SetStreamPrinting();
01585 base.Accept( &printer );
01586 out.append( printer.Str() );
01587
01588 return out;
01589 }
01590 #endif
01591
01592
01593 TiXmlHandle TiXmlHandle::FirstChild() const
01594 {
01595 if ( node )
01596 {
01597 TiXmlNode* child = node->FirstChild();
01598 if ( child )
01599 return TiXmlHandle( child );
01600 }
01601 return TiXmlHandle( 0 );
01602 }
01603
01604
01605 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
01606 {
01607 if ( node )
01608 {
01609 TiXmlNode* child = node->FirstChild( value );
01610 if ( child )
01611 return TiXmlHandle( child );
01612 }
01613 return TiXmlHandle( 0 );
01614 }
01615
01616
01617 TiXmlHandle TiXmlHandle::FirstChildElement() const
01618 {
01619 if ( node )
01620 {
01621 TiXmlElement* child = node->FirstChildElement();
01622 if ( child )
01623 return TiXmlHandle( child );
01624 }
01625 return TiXmlHandle( 0 );
01626 }
01627
01628
01629 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
01630 {
01631 if ( node )
01632 {
01633 TiXmlElement* child = node->FirstChildElement( value );
01634 if ( child )
01635 return TiXmlHandle( child );
01636 }
01637 return TiXmlHandle( 0 );
01638 }
01639
01640
01641 TiXmlHandle TiXmlHandle::Child( int count ) const
01642 {
01643 if ( node )
01644 {
01645 int i;
01646 TiXmlNode* child = node->FirstChild();
01647 for ( i=0;
01648 child && i<count;
01649 child = child->NextSibling(), ++i )
01650 {
01651
01652 }
01653 if ( child )
01654 return TiXmlHandle( child );
01655 }
01656 return TiXmlHandle( 0 );
01657 }
01658
01659
01660 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
01661 {
01662 if ( node )
01663 {
01664 int i;
01665 TiXmlNode* child = node->FirstChild( value );
01666 for ( i=0;
01667 child && i<count;
01668 child = child->NextSibling( value ), ++i )
01669 {
01670
01671 }
01672 if ( child )
01673 return TiXmlHandle( child );
01674 }
01675 return TiXmlHandle( 0 );
01676 }
01677
01678
01679 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
01680 {
01681 if ( node )
01682 {
01683 int i;
01684 TiXmlElement* child = node->FirstChildElement();
01685 for ( i=0;
01686 child && i<count;
01687 child = child->NextSiblingElement(), ++i )
01688 {
01689
01690 }
01691 if ( child )
01692 return TiXmlHandle( child );
01693 }
01694 return TiXmlHandle( 0 );
01695 }
01696
01697
01698 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
01699 {
01700 if ( node )
01701 {
01702 int i;
01703 TiXmlElement* child = node->FirstChildElement( value );
01704 for ( i=0;
01705 child && i<count;
01706 child = child->NextSiblingElement( value ), ++i )
01707 {
01708
01709 }
01710 if ( child )
01711 return TiXmlHandle( child );
01712 }
01713 return TiXmlHandle( 0 );
01714 }
01715
01716
01717 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
01718 {
01719 return true;
01720 }
01721
01722 bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
01723 {
01724 return true;
01725 }
01726
01727 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
01728 {
01729 DoIndent();
01730 buffer += "<";
01731 buffer += element.Value();
01732
01733 for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
01734 {
01735 buffer += " ";
01736 attrib->Print( 0, 0, &buffer );
01737 }
01738
01739 if ( !element.FirstChild() )
01740 {
01741 buffer += " />";
01742 DoLineBreak();
01743 }
01744 else
01745 {
01746 buffer += ">";
01747 if ( element.FirstChild()->ToText()
01748 && element.LastChild() == element.FirstChild()
01749 && element.FirstChild()->ToText()->CDATA() == false )
01750 {
01751 simpleTextPrint = true;
01752
01753 }
01754 else
01755 {
01756 DoLineBreak();
01757 }
01758 }
01759 ++depth;
01760 return true;
01761 }
01762
01763
01764 bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
01765 {
01766 --depth;
01767 if ( !element.FirstChild() )
01768 {
01769
01770 }
01771 else
01772 {
01773 if ( simpleTextPrint )
01774 {
01775 simpleTextPrint = false;
01776 }
01777 else
01778 {
01779 DoIndent();
01780 }
01781 buffer += "</";
01782 buffer += element.Value();
01783 buffer += ">";
01784 DoLineBreak();
01785 }
01786 return true;
01787 }
01788
01789
01790 bool TiXmlPrinter::Visit( const TiXmlText& text )
01791 {
01792 if ( text.CDATA() )
01793 {
01794 DoIndent();
01795 buffer += "<![CDATA[";
01796 buffer += text.Value();
01797 buffer += "]]>";
01798 DoLineBreak();
01799 }
01800 else if ( simpleTextPrint )
01801 {
01802 TIXML_STRING str;
01803 TiXmlBase::EncodeString( text.ValueTStr(), &str );
01804 buffer += str;
01805 }
01806 else
01807 {
01808 DoIndent();
01809 TIXML_STRING str;
01810 TiXmlBase::EncodeString( text.ValueTStr(), &str );
01811 buffer += str;
01812 DoLineBreak();
01813 }
01814 return true;
01815 }
01816
01817
01818 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
01819 {
01820 DoIndent();
01821 declaration.Print( 0, 0, &buffer );
01822 DoLineBreak();
01823 return true;
01824 }
01825
01826
01827 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
01828 {
01829 DoIndent();
01830 buffer += "<!--";
01831 buffer += comment.Value();
01832 buffer += "-->";
01833 DoLineBreak();
01834 return true;
01835 }
01836
01837
01838 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
01839 {
01840 DoIndent();
01841 buffer += "<";
01842 buffer += unknown.Value();
01843 buffer += ">";
01844 DoLineBreak();
01845 return true;
01846 }
01847