osgEarth 2.1.1

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