Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

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), "%f", _value);
01327                 //TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
01328         #else
01329                 sprintf (buf, "%lf", _value);
01330         #endif
01331         SetValue (buf);
01332 }
01333 
01334 int TiXmlAttribute::IntValue() const
01335 {
01336         return atoi (value.c_str ());
01337 }
01338 
01339 double  TiXmlAttribute::DoubleValue() const
01340 {
01341         return atof (value.c_str ());
01342 }
01343 
01344 
01345 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
01346 {
01347         copy.CopyTo( this );
01348 }
01349 
01350 
01351 void TiXmlComment::operator=( const TiXmlComment& base )
01352 {
01353         Clear();
01354         base.CopyTo( this );
01355 }
01356 
01357 
01358 void TiXmlComment::Print( FILE* cfile, int depth ) const
01359 {
01360         for ( int i=0; i<depth; i++ )
01361         {
01362                 fputs( "    ", cfile );
01363         }
01364         fprintf( cfile, "<!--%s-->", value.c_str() );
01365 }
01366 
01367 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
01368 {
01369         (*stream) << "<!--";
01370         //PutString( value, stream );
01371         (*stream) << value;
01372         (*stream) << "-->";
01373 }
01374 
01375 
01376 void TiXmlComment::CopyTo( TiXmlComment* target ) const
01377 {
01378         TiXmlNode::CopyTo( target );
01379 }
01380 
01381 
01382 TiXmlNode* TiXmlComment::Clone() const
01383 {
01384         TiXmlComment* clone = new TiXmlComment();
01385 
01386         if ( !clone )
01387                 return 0;
01388 
01389         CopyTo( clone );
01390         return clone;
01391 }
01392 
01393 
01394 void TiXmlText::Print( FILE* cfile, int depth ) const
01395 {
01396         if ( cdata )
01397         {
01398                 int i;
01399                 fprintf( cfile, "\n" );
01400                 for ( i=0; i<depth; i++ ) {
01401                         fprintf( cfile, "    " );
01402                 }
01403                 fprintf( cfile, "<![CDATA[" );
01404                 fprintf( cfile, "%s", value.c_str() );  // unformatted output
01405                 fprintf( cfile, "]]>\n" );
01406         }
01407         else
01408         {
01409                 TIXML_STRING buffer;
01410                 PutString( value, &buffer );
01411                 fprintf( cfile, "%s", buffer.c_str() );
01412         }
01413 }
01414 
01415 
01416 void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
01417 {
01418         if ( cdata )
01419         {
01420                 (*stream) << "<![CDATA[" << value << "]]>";
01421         }
01422         else
01423         {
01424                 PutString( value, stream );
01425         }
01426 }
01427 
01428 
01429 void TiXmlText::CopyTo( TiXmlText* target ) const
01430 {
01431         TiXmlNode::CopyTo( target );
01432         target->cdata = cdata;
01433 }
01434 
01435 
01436 TiXmlNode* TiXmlText::Clone() const
01437 {       
01438         TiXmlText* clone = 0;
01439         clone = new TiXmlText( "" );
01440 
01441         if ( !clone )
01442                 return 0;
01443 
01444         CopyTo( clone );
01445         return clone;
01446 }
01447 
01448 
01449 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
01450                                                                         const char * _encoding,
01451                                                                         const char * _standalone )
01452         : TiXmlNode( TiXmlNode::DECLARATION )
01453 {
01454         version = _version;
01455         encoding = _encoding;
01456         standalone = _standalone;
01457 }
01458 
01459 
01460 #ifdef TIXML_USE_STL
01461 TiXmlDeclaration::TiXmlDeclaration(     const std::string& _version,
01462                                                                         const std::string& _encoding,
01463                                                                         const std::string& _standalone )
01464         : TiXmlNode( TiXmlNode::DECLARATION )
01465 {
01466         version = _version;
01467         encoding = _encoding;
01468         standalone = _standalone;
01469 }
01470 #endif
01471 
01472 
01473 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
01474         : TiXmlNode( TiXmlNode::DECLARATION )
01475 {
01476         copy.CopyTo( this );    
01477 }
01478 
01479 
01480 void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
01481 {
01482         Clear();
01483         copy.CopyTo( this );
01484 }
01485 
01486 
01487 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
01488 {
01489         fprintf (cfile, "<?xml ");
01490 
01491         if ( !version.empty() )
01492                 fprintf (cfile, "version=\"%s\" ", version.c_str ());
01493         if ( !encoding.empty() )
01494                 fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
01495         if ( !standalone.empty() )
01496                 fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
01497         fprintf (cfile, "?>");
01498 }
01499 
01500 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
01501 {
01502         (*stream) << "<?xml ";
01503 
01504         if ( !version.empty() )
01505         {
01506                 (*stream) << "version=\"";
01507                 PutString( version, stream );
01508                 (*stream) << "\" ";
01509         }
01510         if ( !encoding.empty() )
01511         {
01512                 (*stream) << "encoding=\"";
01513                 PutString( encoding, stream );
01514                 (*stream ) << "\" ";
01515         }
01516         if ( !standalone.empty() )
01517         {
01518                 (*stream) << "standalone=\"";
01519                 PutString( standalone, stream );
01520                 (*stream) << "\" ";
01521         }
01522         (*stream) << "?>";
01523 }
01524 
01525 
01526 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
01527 {
01528         TiXmlNode::CopyTo( target );
01529 
01530         target->version = version;
01531         target->encoding = encoding;
01532         target->standalone = standalone;
01533 }
01534 
01535 
01536 TiXmlNode* TiXmlDeclaration::Clone() const
01537 {       
01538         TiXmlDeclaration* clone = new TiXmlDeclaration();
01539 
01540         if ( !clone )
01541                 return 0;
01542 
01543         CopyTo( clone );
01544         return clone;
01545 }
01546 
01547 
01548 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
01549 {
01550         for ( int i=0; i<depth; i++ )
01551                 fprintf( cfile, "    " );
01552         fprintf( cfile, "<%s>", value.c_str() );
01553 }
01554 
01555 
01556 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
01557 {
01558         (*stream) << "<" << value << ">";               // Don't use entities here! It is unknown.
01559 }
01560 
01561 
01562 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
01563 {
01564         TiXmlNode::CopyTo( target );
01565 }
01566 
01567 
01568 TiXmlNode* TiXmlUnknown::Clone() const
01569 {
01570         TiXmlUnknown* clone = new TiXmlUnknown();
01571 
01572         if ( !clone )
01573                 return 0;
01574 
01575         CopyTo( clone );
01576         return clone;
01577 }
01578 
01579 
01580 TiXmlAttributeSet::TiXmlAttributeSet()
01581 {
01582         sentinel.next = &sentinel;
01583         sentinel.prev = &sentinel;
01584 }
01585 
01586 
01587 TiXmlAttributeSet::~TiXmlAttributeSet()
01588 {
01589         assert( sentinel.next == &sentinel );
01590         assert( sentinel.prev == &sentinel );
01591 }
01592 
01593 
01594 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
01595 {
01596         assert( !Find( TIXML_STRING( addMe->Name() ) ) );       // Shouldn't be multiply adding to the set.
01597 
01598         addMe->next = &sentinel;
01599         addMe->prev = sentinel.prev;
01600 
01601         sentinel.prev->next = addMe;
01602         sentinel.prev      = addMe;
01603 }
01604 
01605 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
01606 {
01607         TiXmlAttribute* node;
01608 
01609         for( node = sentinel.next; node != &sentinel; node = node->next )
01610         {
01611                 if ( node == removeMe )
01612                 {
01613                         node->prev->next = node->next;
01614                         node->next->prev = node->prev;
01615                         node->next = 0;
01616                         node->prev = 0;
01617                         return;
01618                 }
01619         }
01620         assert( 0 );            // we tried to remove a non-linked attribute.
01621 }
01622 
01623 const TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const
01624 {
01625         const TiXmlAttribute* node;
01626 
01627         for( node = sentinel.next; node != &sentinel; node = node->next )
01628         {
01629                 if ( node->name == name )
01630                         return node;
01631         }
01632         return 0;
01633 }
01634 
01635 TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name )
01636 {
01637         TiXmlAttribute* node;
01638 
01639         for( node = sentinel.next; node != &sentinel; node = node->next )
01640         {
01641                 if ( node->name == name )
01642                         return node;
01643         }
01644         return 0;
01645 }
01646 
01647 #ifdef TIXML_USE_STL    
01648 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
01649 {
01650         TIXML_STRING tag;
01651         tag.reserve( 8 * 1000 );
01652         base.StreamIn( &in, &tag );
01653 
01654         base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
01655         return in;
01656 }
01657 #endif
01658 
01659 
01660 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
01661 {
01662         base.StreamOut (& out);
01663         return out;
01664 }
01665 
01666 
01667 #ifdef TIXML_USE_STL    
01668 std::string & operator<< (std::string& out, const TiXmlNode& base )
01669 {
01670    std::ostringstream os_stream( std::ostringstream::out );
01671    base.StreamOut( &os_stream );
01672    
01673    out.append( os_stream.str() );
01674    return out;
01675 }
01676 #endif
01677 
01678 
01679 TiXmlHandle TiXmlHandle::FirstChild() const
01680 {
01681         if ( node )
01682         {
01683                 TiXmlNode* child = node->FirstChild();
01684                 if ( child )
01685                         return TiXmlHandle( child );
01686         }
01687         return TiXmlHandle( 0 );
01688 }
01689 
01690 
01691 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
01692 {
01693         if ( node )
01694         {
01695                 TiXmlNode* child = node->FirstChild( value );
01696                 if ( child )
01697                         return TiXmlHandle( child );
01698         }
01699         return TiXmlHandle( 0 );
01700 }
01701 
01702 
01703 TiXmlHandle TiXmlHandle::FirstChildElement() const
01704 {
01705         if ( node )
01706         {
01707                 TiXmlElement* child = node->FirstChildElement();
01708                 if ( child )
01709                         return TiXmlHandle( child );
01710         }
01711         return TiXmlHandle( 0 );
01712 }
01713 
01714 
01715 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
01716 {
01717         if ( node )
01718         {
01719                 TiXmlElement* child = node->FirstChildElement( value );
01720                 if ( child )
01721                         return TiXmlHandle( child );
01722         }
01723         return TiXmlHandle( 0 );
01724 }
01725 
01726 
01727 TiXmlHandle TiXmlHandle::Child( int count ) const
01728 {
01729         if ( node )
01730         {
01731                 int i;
01732                 TiXmlNode* child = node->FirstChild();
01733                 for (   i=0;
01734                                 child && i<count;
01735                                 child = child->NextSibling(), ++i )
01736                 {
01737                         // nothing
01738                 }
01739                 if ( child )
01740                         return TiXmlHandle( child );
01741         }
01742         return TiXmlHandle( 0 );
01743 }
01744 
01745 
01746 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
01747 {
01748         if ( node )
01749         {
01750                 int i;
01751                 TiXmlNode* child = node->FirstChild( value );
01752                 for (   i=0;
01753                                 child && i<count;
01754                                 child = child->NextSibling( value ), ++i )
01755                 {
01756                         // nothing
01757                 }
01758                 if ( child )
01759                         return TiXmlHandle( child );
01760         }
01761         return TiXmlHandle( 0 );
01762 }
01763 
01764 
01765 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
01766 {
01767         if ( node )
01768         {
01769                 int i;
01770                 TiXmlElement* child = node->FirstChildElement();
01771                 for (   i=0;
01772                                 child && i<count;
01773                                 child = child->NextSiblingElement(), ++i )
01774                 {
01775                         // nothing
01776                 }
01777                 if ( child )
01778                         return TiXmlHandle( child );
01779         }
01780         return TiXmlHandle( 0 );
01781 }
01782 
01783 
01784 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
01785 {
01786         if ( node )
01787         {
01788                 int i;
01789                 TiXmlElement* child = node->FirstChildElement( value );
01790                 for (   i=0;
01791                                 child && i<count;
01792                                 child = child->NextSiblingElement( value ), ++i )
01793                 {
01794                         // nothing
01795                 }
01796                 if ( child )
01797                         return TiXmlHandle( child );
01798         }
01799         return TiXmlHandle( 0 );
01800 }

Generated on Wed Sep 5 12:54:26 2007 for DSACSS Operational Code by  doxygen 1.3.9.1