tinyxml.cpp

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

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6