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


robbie_architecture
Author(s): Viktor Seib
autogenerated on Mon Oct 6 2014 02:53:09