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


rtt
Author(s): RTT Developers
autogenerated on Thu Jan 2 2014 11:35:40