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