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