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