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


rospack
Author(s): Brian Gerkey/gerkey@willowgarage.com, Morgan Quigley/mquigley@cs.stanford.edu
autogenerated on Fri Jan 3 2014 11:51:40