CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/Utilities/src/tinyxml.cc

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