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

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

Generated on Wed Sep 7 09:56:35 2005 for Crazy Eddies GUI System by  doxygen 1.4.3