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

Generated on Wed Oct 1 11:34:05 2008 for OBT by  doxygen 1.5.3