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


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Fri Aug 28 2015 12:59:19