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 if ( GetDocument() )
00195 GetDocument()->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 if ( GetDocument() )
00219 GetDocument()->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 if ( GetDocument() )
00238 GetDocument()->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 if ( GetDocument() )
00271 GetDocument()->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 int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
00671 {
00672 const TiXmlAttribute* node = attributeSet.Find( name );
00673 if ( !node )
00674 return TIXML_NO_ATTRIBUTE;
00675
00676 int ival = 0;
00677 int result = node->QueryIntValue( &ival );
00678 *value = (unsigned)ival;
00679 return result;
00680 }
00681
00682
00683 int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
00684 {
00685 const TiXmlAttribute* node = attributeSet.Find( name );
00686 if ( !node )
00687 return TIXML_NO_ATTRIBUTE;
00688
00689 int result = TIXML_WRONG_TYPE;
00690 if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
00691 || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
00692 || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
00693 {
00694 *bval = true;
00695 result = TIXML_SUCCESS;
00696 }
00697 else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
00698 || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
00699 || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
00700 {
00701 *bval = false;
00702 result = TIXML_SUCCESS;
00703 }
00704 return result;
00705 }
00706
00707
00708
00709 #ifdef TIXML_USE_STL
00710 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
00711 {
00712 const TiXmlAttribute* attrib = attributeSet.Find( name );
00713 if ( !attrib )
00714 return TIXML_NO_ATTRIBUTE;
00715 return attrib->QueryIntValue( ival );
00716 }
00717 #endif
00718
00719
00720 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
00721 {
00722 const TiXmlAttribute* attrib = attributeSet.Find( name );
00723 if ( !attrib )
00724 return TIXML_NO_ATTRIBUTE;
00725 return attrib->QueryDoubleValue( dval );
00726 }
00727
00728
00729 #ifdef TIXML_USE_STL
00730 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
00731 {
00732 const TiXmlAttribute* attrib = attributeSet.Find( name );
00733 if ( !attrib )
00734 return TIXML_NO_ATTRIBUTE;
00735 return attrib->QueryDoubleValue( dval );
00736 }
00737 #endif
00738
00739
00740 void TiXmlElement::SetAttribute( const char * name, int val )
00741 {
00742 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00743 if ( attrib ) {
00744 attrib->SetIntValue( val );
00745 }
00746 }
00747
00748
00749 #ifdef TIXML_USE_STL
00750 void TiXmlElement::SetAttribute( const std::string& name, int val )
00751 {
00752 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00753 if ( attrib ) {
00754 attrib->SetIntValue( val );
00755 }
00756 }
00757 #endif
00758
00759
00760 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
00761 {
00762 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00763 if ( attrib ) {
00764 attrib->SetDoubleValue( val );
00765 }
00766 }
00767
00768
00769 #ifdef TIXML_USE_STL
00770 void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
00771 {
00772 TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
00773 if ( attrib ) {
00774 attrib->SetDoubleValue( val );
00775 }
00776 }
00777 #endif
00778
00779
00780 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
00781 {
00782 TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
00783 if ( attrib ) {
00784 attrib->SetValue( cvalue );
00785 }
00786 }
00787
00788
00789 #ifdef TIXML_USE_STL
00790 void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
00791 {
00792 TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
00793 if ( attrib ) {
00794 attrib->SetValue( _value );
00795 }
00796 }
00797 #endif
00798
00799
00800 void TiXmlElement::Print( FILE* cfile, int depth ) const
00801 {
00802 int i;
00803 assert( cfile );
00804 for ( i=0; i<depth; i++ ) {
00805 fprintf( cfile, " " );
00806 }
00807
00808 fprintf( cfile, "<%s", value.c_str() );
00809
00810 const TiXmlAttribute* attrib;
00811 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
00812 {
00813 fprintf( cfile, " " );
00814 attrib->Print( cfile, depth );
00815 }
00816
00817
00818
00819
00820
00821 TiXmlNode* node;
00822 if ( !firstChild )
00823 {
00824 fprintf( cfile, " />" );
00825 }
00826 else if ( firstChild == lastChild && firstChild->ToText() )
00827 {
00828 fprintf( cfile, ">" );
00829 firstChild->Print( cfile, depth + 1 );
00830 fprintf( cfile, "</%s>", value.c_str() );
00831 }
00832 else
00833 {
00834 fprintf( cfile, ">" );
00835
00836 for ( node = firstChild; node; node=node->NextSibling() )
00837 {
00838 if ( !node->ToText() )
00839 {
00840 fprintf( cfile, "\n" );
00841 }
00842 node->Print( cfile, depth+1 );
00843 }
00844 fprintf( cfile, "\n" );
00845 for( i=0; i<depth; ++i ) {
00846 fprintf( cfile, " " );
00847 }
00848 fprintf( cfile, "</%s>", value.c_str() );
00849 }
00850 }
00851
00852
00853 void TiXmlElement::CopyTo( TiXmlElement* target ) const
00854 {
00855
00856 TiXmlNode::CopyTo( target );
00857
00858
00859
00860 const TiXmlAttribute* attribute = 0;
00861 for( attribute = attributeSet.First();
00862 attribute;
00863 attribute = attribute->Next() )
00864 {
00865 target->SetAttribute( attribute->Name(), attribute->Value() );
00866 }
00867
00868 TiXmlNode* node = 0;
00869 for ( node = firstChild; node; node = node->NextSibling() )
00870 {
00871 target->LinkEndChild( node->Clone() );
00872 }
00873 }
00874
00875 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
00876 {
00877 if ( visitor->VisitEnter( *this, attributeSet.First() ) )
00878 {
00879 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
00880 {
00881 if ( !node->Accept( visitor ) )
00882 break;
00883 }
00884 }
00885 return visitor->VisitExit( *this );
00886 }
00887
00888
00889 TiXmlNode* TiXmlElement::Clone() const
00890 {
00891 TiXmlElement* clone = new TiXmlElement( Value() );
00892 if ( !clone )
00893 return 0;
00894
00895 CopyTo( clone );
00896 return clone;
00897 }
00898
00899
00900 const char* TiXmlElement::GetText() const
00901 {
00902 const TiXmlNode* child = this->FirstChild();
00903 if ( child ) {
00904 const TiXmlText* childText = child->ToText();
00905 if ( childText ) {
00906 return childText->Value();
00907 }
00908 }
00909 return 0;
00910 }
00911
00912
00913 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00914 {
00915 tabsize = 4;
00916 useMicrosoftBOM = false;
00917 ClearError();
00918 }
00919
00920 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00921 {
00922 tabsize = 4;
00923 useMicrosoftBOM = false;
00924 value = documentName;
00925 ClearError();
00926 }
00927
00928
00929 #ifdef TIXML_USE_STL
00930 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00931 {
00932 tabsize = 4;
00933 useMicrosoftBOM = false;
00934 value = documentName;
00935 ClearError();
00936 }
00937 #endif
00938
00939
00940 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
00941 {
00942 copy.CopyTo( this );
00943 }
00944
00945
00946 TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
00947 {
00948 Clear();
00949 copy.CopyTo( this );
00950 return *this;
00951 }
00952
00953
00954 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
00955 {
00956 return LoadFile( Value(), encoding );
00957 }
00958
00959
00960 bool TiXmlDocument::SaveFile() const
00961 {
00962 return SaveFile( Value() );
00963 }
00964
00965 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
00966 {
00967 TIXML_STRING filename( _filename );
00968 value = filename;
00969
00970
00971 FILE* file = TiXmlFOpen( value.c_str (), "rb" );
00972
00973 if ( file )
00974 {
00975 bool result = LoadFile( file, encoding );
00976 fclose( file );
00977 return result;
00978 }
00979 else
00980 {
00981 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
00982 return false;
00983 }
00984 }
00985
00986 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
00987 {
00988 if ( !file )
00989 {
00990 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
00991 return false;
00992 }
00993
00994
00995 Clear();
00996 location.Clear();
00997
00998
00999 long length = 0;
01000 fseek( file, 0, SEEK_END );
01001 length = ftell( file );
01002 fseek( file, 0, SEEK_SET );
01003
01004
01005 if ( length <= 0 )
01006 {
01007 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
01008 return false;
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 char* buf = new char[ length+1 ];
01033 buf[0] = 0;
01034
01035 if ( fread( buf, length, 1, file ) != 1 ) {
01036 delete [] buf;
01037 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
01038 return false;
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 const char* p = buf;
01053 char* q = buf;
01054 const char CR = 0x0d;
01055 const char LF = 0x0a;
01056
01057 buf[length] = 0;
01058 while( *p ) {
01059 assert( p < (buf+length) );
01060 assert( q <= (buf+length) );
01061 assert( q <= p );
01062
01063 if ( *p == CR ) {
01064 *q++ = LF;
01065 p++;
01066 if ( *p == LF ) {
01067 p++;
01068 }
01069 }
01070 else {
01071 *q++ = *p++;
01072 }
01073 }
01074 assert( q <= (buf+length) );
01075 *q = 0;
01076
01077 Parse( buf, 0, encoding );
01078
01079 delete [] buf;
01080 return !Error();
01081 }
01082
01083
01084 bool TiXmlDocument::SaveFile( const char * filename ) const
01085 {
01086
01087 FILE* fp = TiXmlFOpen( filename, "w" );
01088 if ( fp )
01089 {
01090 bool result = SaveFile( fp );
01091 fclose( fp );
01092 return result;
01093 }
01094 return false;
01095 }
01096
01097
01098 bool TiXmlDocument::SaveFile( FILE* fp ) const
01099 {
01100 if ( useMicrosoftBOM )
01101 {
01102 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
01103 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
01104 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
01105
01106 fputc( TIXML_UTF_LEAD_0, fp );
01107 fputc( TIXML_UTF_LEAD_1, fp );
01108 fputc( TIXML_UTF_LEAD_2, fp );
01109 }
01110 Print( fp, 0 );
01111 return (ferror(fp) == 0);
01112 }
01113
01114
01115 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
01116 {
01117 TiXmlNode::CopyTo( target );
01118
01119 target->error = error;
01120 target->errorId = errorId;
01121 target->errorDesc = errorDesc;
01122 target->tabsize = tabsize;
01123 target->errorLocation = errorLocation;
01124 target->useMicrosoftBOM = useMicrosoftBOM;
01125
01126 TiXmlNode* node = 0;
01127 for ( node = firstChild; node; node = node->NextSibling() )
01128 {
01129 target->LinkEndChild( node->Clone() );
01130 }
01131 }
01132
01133
01134 TiXmlNode* TiXmlDocument::Clone() const
01135 {
01136 TiXmlDocument* clone = new TiXmlDocument();
01137 if ( !clone )
01138 return 0;
01139
01140 CopyTo( clone );
01141 return clone;
01142 }
01143
01144
01145 void TiXmlDocument::Print( FILE* cfile, int depth ) const
01146 {
01147 assert( cfile );
01148 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
01149 {
01150 node->Print( cfile, depth );
01151 fprintf( cfile, "\n" );
01152 }
01153 }
01154
01155
01156 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
01157 {
01158 if ( visitor->VisitEnter( *this ) )
01159 {
01160 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
01161 {
01162 if ( !node->Accept( visitor ) )
01163 break;
01164 }
01165 }
01166 return visitor->VisitExit( *this );
01167 }
01168
01169
01170 const TiXmlAttribute* TiXmlAttribute::Next() const
01171 {
01172
01173
01174 if ( next->value.empty() && next->name.empty() )
01175 return 0;
01176 return next;
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 const TiXmlAttribute* TiXmlAttribute::Previous() const
01191 {
01192
01193
01194 if ( prev->value.empty() && prev->name.empty() )
01195 return 0;
01196 return prev;
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210 void TiXmlAttribute::Print( FILE* cfile, int , TIXML_STRING* str ) const
01211 {
01212 TIXML_STRING n, v;
01213
01214 EncodeString( name, &n );
01215 EncodeString( value, &v );
01216
01217 if (value.find ('\"') == TIXML_STRING::npos) {
01218 if ( cfile ) {
01219 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
01220 }
01221 if ( str ) {
01222 (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
01223 }
01224 }
01225 else {
01226 if ( cfile ) {
01227 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
01228 }
01229 if ( str ) {
01230 (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
01231 }
01232 }
01233 }
01234
01235
01236 int TiXmlAttribute::QueryIntValue( int* ival ) const
01237 {
01238 if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
01239 return TIXML_SUCCESS;
01240 return TIXML_WRONG_TYPE;
01241 }
01242
01243 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
01244 {
01245 if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
01246 return TIXML_SUCCESS;
01247 return TIXML_WRONG_TYPE;
01248 }
01249
01250 void TiXmlAttribute::SetIntValue( int _value )
01251 {
01252 char buf [64];
01253 #if defined(TIXML_SNPRINTF)
01254 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
01255 #else
01256 sprintf (buf, "%d", _value);
01257 #endif
01258 SetValue (buf);
01259 }
01260
01261 void TiXmlAttribute::SetDoubleValue( double _value )
01262 {
01263 char buf [256];
01264 #if defined(TIXML_SNPRINTF)
01265 TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
01266 #else
01267 sprintf (buf, "%g", _value);
01268 #endif
01269 SetValue (buf);
01270 }
01271
01272 int TiXmlAttribute::IntValue() const
01273 {
01274 return atoi (value.c_str ());
01275 }
01276
01277 double TiXmlAttribute::DoubleValue() const
01278 {
01279 return atof (value.c_str ());
01280 }
01281
01282
01283 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
01284 {
01285 copy.CopyTo( this );
01286 }
01287
01288
01289 TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
01290 {
01291 Clear();
01292 base.CopyTo( this );
01293 return *this;
01294 }
01295
01296
01297 void TiXmlComment::Print( FILE* cfile, int depth ) const
01298 {
01299 assert( cfile );
01300 for ( int i=0; i<depth; i++ )
01301 {
01302 fprintf( cfile, " " );
01303 }
01304 fprintf( cfile, "<!--%s-->", value.c_str() );
01305 }
01306
01307
01308 void TiXmlComment::CopyTo( TiXmlComment* target ) const
01309 {
01310 TiXmlNode::CopyTo( target );
01311 }
01312
01313
01314 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
01315 {
01316 return visitor->Visit( *this );
01317 }
01318
01319
01320 TiXmlNode* TiXmlComment::Clone() const
01321 {
01322 TiXmlComment* clone = new TiXmlComment();
01323
01324 if ( !clone )
01325 return 0;
01326
01327 CopyTo( clone );
01328 return clone;
01329 }
01330
01331
01332 void TiXmlText::Print( FILE* cfile, int depth ) const
01333 {
01334 assert( cfile );
01335 if ( cdata )
01336 {
01337 int i;
01338 fprintf( cfile, "\n" );
01339 for ( i=0; i<depth; i++ ) {
01340 fprintf( cfile, " " );
01341 }
01342 fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );
01343 }
01344 else
01345 {
01346 TIXML_STRING buffer;
01347 EncodeString( value, &buffer );
01348 fprintf( cfile, "%s", buffer.c_str() );
01349 }
01350 }
01351
01352
01353 void TiXmlText::CopyTo( TiXmlText* target ) const
01354 {
01355 TiXmlNode::CopyTo( target );
01356 target->cdata = cdata;
01357 }
01358
01359
01360 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
01361 {
01362 return visitor->Visit( *this );
01363 }
01364
01365
01366 TiXmlNode* TiXmlText::Clone() const
01367 {
01368 TiXmlText* clone = 0;
01369 clone = new TiXmlText( "" );
01370
01371 if ( !clone )
01372 return 0;
01373
01374 CopyTo( clone );
01375 return clone;
01376 }
01377
01378
01379 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
01380 const char * _encoding,
01381 const char * _standalone )
01382 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01383 {
01384 version = _version;
01385 encoding = _encoding;
01386 standalone = _standalone;
01387 }
01388
01389
01390 #ifdef TIXML_USE_STL
01391 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
01392 const std::string& _encoding,
01393 const std::string& _standalone )
01394 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01395 {
01396 version = _version;
01397 encoding = _encoding;
01398 standalone = _standalone;
01399 }
01400 #endif
01401
01402
01403 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
01404 : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
01405 {
01406 copy.CopyTo( this );
01407 }
01408
01409
01410 TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
01411 {
01412 Clear();
01413 copy.CopyTo( this );
01414 return *this;
01415 }
01416
01417
01418 void TiXmlDeclaration::Print( FILE* cfile, int , TIXML_STRING* str ) const
01419 {
01420 if ( cfile ) fprintf( cfile, "<?xml " );
01421 if ( str ) (*str) += "<?xml ";
01422
01423 if ( !version.empty() ) {
01424 if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
01425 if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
01426 }
01427 if ( !encoding.empty() ) {
01428 if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
01429 if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
01430 }
01431 if ( !standalone.empty() ) {
01432 if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
01433 if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
01434 }
01435 if ( cfile ) fprintf( cfile, "?>" );
01436 if ( str ) (*str) += "?>";
01437 }
01438
01439
01440 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
01441 {
01442 TiXmlNode::CopyTo( target );
01443
01444 target->version = version;
01445 target->encoding = encoding;
01446 target->standalone = standalone;
01447 }
01448
01449
01450 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
01451 {
01452 return visitor->Visit( *this );
01453 }
01454
01455
01456 TiXmlNode* TiXmlDeclaration::Clone() const
01457 {
01458 TiXmlDeclaration* clone = new TiXmlDeclaration();
01459
01460 if ( !clone )
01461 return 0;
01462
01463 CopyTo( clone );
01464 return clone;
01465 }
01466
01467
01468 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
01469 {
01470 for ( int i=0; i<depth; i++ )
01471 fprintf( cfile, " " );
01472 fprintf( cfile, "<%s>", value.c_str() );
01473 }
01474
01475
01476 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
01477 {
01478 TiXmlNode::CopyTo( target );
01479 }
01480
01481
01482 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
01483 {
01484 return visitor->Visit( *this );
01485 }
01486
01487
01488 TiXmlNode* TiXmlUnknown::Clone() const
01489 {
01490 TiXmlUnknown* clone = new TiXmlUnknown();
01491
01492 if ( !clone )
01493 return 0;
01494
01495 CopyTo( clone );
01496 return clone;
01497 }
01498
01499
01500 TiXmlAttributeSet::TiXmlAttributeSet()
01501 {
01502 sentinel.next = &sentinel;
01503 sentinel.prev = &sentinel;
01504 }
01505
01506
01507 TiXmlAttributeSet::~TiXmlAttributeSet()
01508 {
01509 assert( sentinel.next == &sentinel );
01510 assert( sentinel.prev == &sentinel );
01511 }
01512
01513
01514 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
01515 {
01516 #ifdef TIXML_USE_STL
01517 assert( !Find( TIXML_STRING( addMe->Name() ) ) );
01518 #else
01519 assert( !Find( addMe->Name() ) );
01520 #endif
01521
01522 addMe->next = &sentinel;
01523 addMe->prev = sentinel.prev;
01524
01525 sentinel.prev->next = addMe;
01526 sentinel.prev = addMe;
01527 }
01528
01529 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
01530 {
01531 TiXmlAttribute* node;
01532
01533 for( node = sentinel.next; node != &sentinel; node = node->next )
01534 {
01535 if ( node == removeMe )
01536 {
01537 node->prev->next = node->next;
01538 node->next->prev = node->prev;
01539 node->next = 0;
01540 node->prev = 0;
01541 return;
01542 }
01543 }
01544 assert( 0 );
01545 }
01546
01547
01548 #ifdef TIXML_USE_STL
01549 TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
01550 {
01551 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
01552 {
01553 if ( node->name == name )
01554 return node;
01555 }
01556 return 0;
01557 }
01558
01559 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
01560 {
01561 TiXmlAttribute* attrib = Find( _name );
01562 if ( !attrib ) {
01563 attrib = new TiXmlAttribute();
01564 Add( attrib );
01565 attrib->SetName( _name );
01566 }
01567 return attrib;
01568 }
01569 #endif
01570
01571
01572 TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
01573 {
01574 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
01575 {
01576 if ( strcmp( node->name.c_str(), name ) == 0 )
01577 return node;
01578 }
01579 return 0;
01580 }
01581
01582
01583 TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
01584 {
01585 TiXmlAttribute* attrib = Find( _name );
01586 if ( !attrib ) {
01587 attrib = new TiXmlAttribute();
01588 Add( attrib );
01589 attrib->SetName( _name );
01590 }
01591 return attrib;
01592 }
01593
01594
01595 #ifdef TIXML_USE_STL
01596 std::istream& operator>> (std::istream & in, TiXmlNode & base)
01597 {
01598 TIXML_STRING tag;
01599 tag.reserve( 8 * 1000 );
01600 base.StreamIn( &in, &tag );
01601
01602 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
01603 return in;
01604 }
01605 #endif
01606
01607
01608 #ifdef TIXML_USE_STL
01609 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
01610 {
01611 TiXmlPrinter printer;
01612 printer.SetStreamPrinting();
01613 base.Accept( &printer );
01614 out << printer.Str();
01615
01616 return out;
01617 }
01618
01619
01620 std::string& operator<< (std::string& out, const TiXmlNode& base )
01621 {
01622 TiXmlPrinter printer;
01623 printer.SetStreamPrinting();
01624 base.Accept( &printer );
01625 out.append( printer.Str() );
01626
01627 return out;
01628 }
01629 #endif
01630
01631
01632 TiXmlHandle TiXmlHandle::FirstChild() const
01633 {
01634 if ( node )
01635 {
01636 TiXmlNode* child = node->FirstChild();
01637 if ( child )
01638 return TiXmlHandle( child );
01639 }
01640 return TiXmlHandle( 0 );
01641 }
01642
01643
01644 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
01645 {
01646 if ( node )
01647 {
01648 TiXmlNode* child = node->FirstChild( value );
01649 if ( child )
01650 return TiXmlHandle( child );
01651 }
01652 return TiXmlHandle( 0 );
01653 }
01654
01655
01656 TiXmlHandle TiXmlHandle::FirstChildElement() const
01657 {
01658 if ( node )
01659 {
01660 TiXmlElement* child = node->FirstChildElement();
01661 if ( child )
01662 return TiXmlHandle( child );
01663 }
01664 return TiXmlHandle( 0 );
01665 }
01666
01667
01668 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
01669 {
01670 if ( node )
01671 {
01672 TiXmlElement* child = node->FirstChildElement( value );
01673 if ( child )
01674 return TiXmlHandle( child );
01675 }
01676 return TiXmlHandle( 0 );
01677 }
01678
01679
01680 TiXmlHandle TiXmlHandle::Child( int count ) const
01681 {
01682 if ( node )
01683 {
01684 int i;
01685 TiXmlNode* child = node->FirstChild();
01686 for ( i=0;
01687 child && i<count;
01688 child = child->NextSibling(), ++i )
01689 {
01690
01691 }
01692 if ( child )
01693 return TiXmlHandle( child );
01694 }
01695 return TiXmlHandle( 0 );
01696 }
01697
01698
01699 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
01700 {
01701 if ( node )
01702 {
01703 int i;
01704 TiXmlNode* child = node->FirstChild( value );
01705 for ( i=0;
01706 child && i<count;
01707 child = child->NextSibling( value ), ++i )
01708 {
01709
01710 }
01711 if ( child )
01712 return TiXmlHandle( child );
01713 }
01714 return TiXmlHandle( 0 );
01715 }
01716
01717
01718 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
01719 {
01720 if ( node )
01721 {
01722 int i;
01723 TiXmlElement* child = node->FirstChildElement();
01724 for ( i=0;
01725 child && i<count;
01726 child = child->NextSiblingElement(), ++i )
01727 {
01728
01729 }
01730 if ( child )
01731 return TiXmlHandle( child );
01732 }
01733 return TiXmlHandle( 0 );
01734 }
01735
01736
01737 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
01738 {
01739 if ( node )
01740 {
01741 int i;
01742 TiXmlElement* child = node->FirstChildElement( value );
01743 for ( i=0;
01744 child && i<count;
01745 child = child->NextSiblingElement( value ), ++i )
01746 {
01747
01748 }
01749 if ( child )
01750 return TiXmlHandle( child );
01751 }
01752 return TiXmlHandle( 0 );
01753 }
01754
01755
01756 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
01757 {
01758 return true;
01759 }
01760
01761 bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
01762 {
01763 return true;
01764 }
01765
01766 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
01767 {
01768 DoIndent();
01769 buffer += "<";
01770 buffer += element.Value();
01771
01772 for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
01773 {
01774 buffer += " ";
01775 attrib->Print( 0, 0, &buffer );
01776 }
01777
01778 if ( !element.FirstChild() )
01779 {
01780 buffer += " />";
01781 DoLineBreak();
01782 }
01783 else
01784 {
01785 buffer += ">";
01786 if ( element.FirstChild()->ToText()
01787 && element.LastChild() == element.FirstChild()
01788 && element.FirstChild()->ToText()->CDATA() == false )
01789 {
01790 simpleTextPrint = true;
01791
01792 }
01793 else
01794 {
01795 DoLineBreak();
01796 }
01797 }
01798 ++depth;
01799 return true;
01800 }
01801
01802
01803 bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
01804 {
01805 --depth;
01806 if ( !element.FirstChild() )
01807 {
01808
01809 }
01810 else
01811 {
01812 if ( simpleTextPrint )
01813 {
01814 simpleTextPrint = false;
01815 }
01816 else
01817 {
01818 DoIndent();
01819 }
01820 buffer += "</";
01821 buffer += element.Value();
01822 buffer += ">";
01823 DoLineBreak();
01824 }
01825 return true;
01826 }
01827
01828
01829 bool TiXmlPrinter::Visit( const TiXmlText& text )
01830 {
01831 if ( text.CDATA() )
01832 {
01833 DoIndent();
01834 buffer += "<![CDATA[";
01835 buffer += text.Value();
01836 buffer += "]]>";
01837 DoLineBreak();
01838 }
01839 else if ( simpleTextPrint )
01840 {
01841 TIXML_STRING str;
01842 TiXmlBase::EncodeString( text.ValueTStr(), &str );
01843 buffer += str;
01844 }
01845 else
01846 {
01847 DoIndent();
01848 TIXML_STRING str;
01849 TiXmlBase::EncodeString( text.ValueTStr(), &str );
01850 buffer += str;
01851 DoLineBreak();
01852 }
01853 return true;
01854 }
01855
01856
01857 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
01858 {
01859 DoIndent();
01860 declaration.Print( 0, 0, &buffer );
01861 DoLineBreak();
01862 return true;
01863 }
01864
01865
01866 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
01867 {
01868 DoIndent();
01869 buffer += "<!--";
01870 buffer += comment.Value();
01871 buffer += "-->";
01872 DoLineBreak();
01873 return true;
01874 }
01875
01876
01877 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
01878 {
01879 DoIndent();
01880 buffer += "<";
01881 buffer += unknown.Value();
01882 buffer += ">";
01883 DoLineBreak();
01884 return true;
01885 }
01886