Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 738


Ignore:
Timestamp:
Dec 31, 2007, 12:06:33 AM (17 years ago)
Author:
landauf
Message:

updated to the newest tinyXML library and changed one line in the LevelLoader

Location:
code/branches/FICN/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • code/branches/FICN/src/loader/LevelLoader.cc

    r733 r738  
    5151
    5252    // Open xml file
    53     doc_.LoadFile(path);
     53    doc_.LoadFile(path.c_str());
    5454
    5555    // Check if file was loaded
  • code/branches/FICN/src/tinyxml/tinystr.cc

    r660 r738  
    2424
    2525/*
    26  * THIS FILE WAS ALTERED BY Tyge Lvset, 7. April 2005.
     26 * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
    2727 */
    2828
     
    3333
    3434// Error value for find primitive
    35 const TiXmlString::size_type TiXmlString::npos = static_cast< size_type >(-1);
     35const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
     36
    3637
    3738// Null rep.
    38 //FIXME: missing braces around initializer for ‘char [1]’
    39 TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' };
     39TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
    4040
    4141
  • code/branches/FICN/src/tinyxml/tinystr.h

    r471 r738  
    4343#include <string.h>
    4444
     45/*      The support for explicit isn't that universal, and it isn't really
     46        required - it is used to check that the TiXmlString class isn't incorrectly
     47        used. Be nice to old compilers and macro it here:
     48*/
     49#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
     50        // Microsoft visual studio, version 6 and higher.
     51        #define TIXML_EXPLICIT explicit
     52#elif defined(__GNUC__) && (__GNUC__ >= 3 )
     53        // GCC version 3 and higher.s
     54        #define TIXML_EXPLICIT explicit
     55#else
     56        #define TIXML_EXPLICIT
     57#endif
     58
     59
    4560/*
    4661   TiXmlString is an emulation of a subset of the std::string template.
     
    5469  public :
    5570        // The size type used
    56         typedef unsigned int size_type;
     71        typedef size_t size_type;
    5772
    5873        // Error value for find primitive
     
    6681
    6782        // TiXmlString copy constructor
    68         TiXmlString (const TiXmlString & copy)
     83        TiXmlString ( const TiXmlString & copy) : rep_(0)
    6984        {
    7085                init(copy.length());
     
    7388
    7489        // TiXmlString constructor, based on a string
    75         TiXmlString (const char * copy)
     90        TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
    7691        {
    7792                init( static_cast<size_type>( strlen(copy) ));
     
    8095
    8196        // TiXmlString constructor, based on a string
    82         TiXmlString (const char * str, size_type len)
     97        TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
    8398        {
    8499                init(len);
  • code/branches/FICN/src/tinyxml/tinyxml.cc

    r471 r738  
    11/*
    22www.sourceforge.net/projects/tinyxml
    3 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
     3Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
    44
    55This software is provided 'as-is', without any express or implied
     
    2424
    2525#include <ctype.h>
    26 #include "tinyxml.h"
    2726
    2827#ifdef TIXML_USE_STL
    2928#include <sstream>
     29#include <iostream>
    3030#endif
    3131
     32#include "tinyxml.h"
     33
    3234
    3335bool TiXmlBase::condenseWhiteSpace = true;
    3436
    35 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
    36 {
    37         TIXML_STRING buffer;
    38         PutString( str, &buffer );
    39         (*stream) << buffer;
    40 }
    41 
    42 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
     37// Microsoft compiler security
     38FILE* TiXmlFOpen( const char* filename, const char* mode )
     39{
     40        #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
     41                FILE* fp = 0;
     42                errno_t err = fopen_s( &fp, filename, mode );
     43                if ( !err && fp )
     44                        return fp;
     45                return 0;
     46        #else
     47                return fopen( filename, mode );
     48        #endif
     49}
     50
     51void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
    4352{
    4453        int i=0;
     
    4857                unsigned char c = (unsigned char) str[i];
    4958
    50                 if (    c == '&' 
     59                if (    c == '&'
    5160                     && i < ( (int)str.length() - 2 )
    5261                         && str[i+1] == '#'
     
    101110                        // Below 32 is symbolic.
    102111                        char buf[ 32 ];
    103                        
    104                         #if defined(TIXML_SNPRINTF)             
     112
     113                        #if defined(TIXML_SNPRINTF)
    105114                                TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
    106115                        #else
    107116                                sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
    108                         #endif         
     117                        #endif
    109118
    110119                        //*ME:  warning C4267: convert 'size_t' to 'int'
     
    122131        }
    123132}
    124 
    125 
    126 // <-- Strange class for a bug fix. Search for STL_STRING_BUG
    127 TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
    128 {
    129         buffer = new char[ str.length()+1 ];
    130         if ( buffer )
    131         {
    132                 strcpy( buffer, str.c_str() );
    133         }
    134 }
    135 
    136 
    137 TiXmlBase::StringToBuffer::~StringToBuffer()
    138 {
    139         delete [] buffer;
    140 }
    141 // End strange bug fix. -->
    142133
    143134
     
    163154                node = node->next;
    164155                delete temp;
    165         }       
     156        }
    166157}
    167158
     
    170161{
    171162        target->SetValue (value.c_str() );
    172         target->userData = userData; 
     163        target->userData = userData;
    173164}
    174165
     
    184175                node = node->next;
    185176                delete temp;
    186         }       
     177        }
    187178
    188179        firstChild = 0;
     
    193184TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
    194185{
     186        assert( node->parent == 0 || node->parent == this );
     187        assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
     188
     189        if ( node->Type() == TiXmlNode::DOCUMENT )
     190        {
     191                delete node;
     192                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
     193                return 0;
     194        }
     195
    195196        node->parent = this;
    196197
     
    210211TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
    211212{
     213        if ( addThis.Type() == TiXmlNode::DOCUMENT )
     214        {
     215                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
     216                return 0;
     217        }
    212218        TiXmlNode* node = addThis.Clone();
    213219        if ( !node )
     
    219225
    220226TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
    221 {       
    222         if ( !beforeThis || beforeThis->parent != this )
    223                 return 0;
     227{
     228        if ( !beforeThis || beforeThis->parent != this ) {
     229                return 0;
     230        }
     231        if ( addThis.Type() == TiXmlNode::DOCUMENT )
     232        {
     233                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
     234                return 0;
     235        }
    224236
    225237        TiXmlNode* node = addThis.Clone();
     
    246258TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
    247259{
    248         if ( !afterThis || afterThis->parent != this )
    249                 return 0;
     260        if ( !afterThis || afterThis->parent != this ) {
     261                return 0;
     262        }
     263        if ( addThis.Type() == TiXmlNode::DOCUMENT )
     264        {
     265                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
     266                return 0;
     267        }
    250268
    251269        TiXmlNode* node = addThis.Clone();
     
    301319{
    302320        if ( removeThis->parent != this )
    303         {       
     321        {
    304322                assert( 0 );
    305323                return false;
     
    332350
    333351
    334 TiXmlNode* TiXmlNode::FirstChild( const char * _value )
    335 {
    336         TiXmlNode* node;
    337         for ( node = firstChild; node; node = node->next )
     352const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
     353{
     354        const TiXmlNode* node;
     355        for ( node = lastChild; node; node = node->prev )
    338356        {
    339357                if ( strcmp( node->Value(), _value ) == 0 )
     
    344362
    345363
    346 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
     364const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
     365{
     366        if ( !previous )
     367        {
     368                return FirstChild();
     369        }
     370        else
     371        {
     372                assert( previous->parent == this );
     373                return previous->NextSibling();
     374        }
     375}
     376
     377
     378const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
     379{
     380        if ( !previous )
     381        {
     382                return FirstChild( val );
     383        }
     384        else
     385        {
     386                assert( previous->parent == this );
     387                return previous->NextSibling( val );
     388        }
     389}
     390
     391
     392const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
    347393{
    348394        const TiXmlNode* node;
    349         for ( node = lastChild; node; node = node->prev )
     395        for ( node = next; node; node = node->next )
    350396        {
    351397                if ( strcmp( node->Value(), _value ) == 0 )
     
    355401}
    356402
    357 TiXmlNode* TiXmlNode::LastChild( const char * _value )
    358 {
    359         TiXmlNode* node;
    360         for ( node = lastChild; node; node = node->prev )
     403
     404const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
     405{
     406        const TiXmlNode* node;
     407        for ( node = prev; node; node = node->prev )
    361408        {
    362409                if ( strcmp( node->Value(), _value ) == 0 )
     
    366413}
    367414
    368 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
    369 {
    370         if ( !previous )
    371         {
    372                 return FirstChild();
    373         }
    374         else
    375         {
    376                 assert( previous->parent == this );
    377                 return previous->NextSibling();
    378         }
    379 }
    380 
    381 TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
    382 {
    383         if ( !previous )
    384         {
    385                 return FirstChild();
    386         }
    387         else
    388         {
    389                 assert( previous->parent == this );
    390                 return previous->NextSibling();
    391         }
    392 }
    393 
    394 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
    395 {
    396         if ( !previous )
    397         {
    398                 return FirstChild( val );
    399         }
    400         else
    401         {
    402                 assert( previous->parent == this );
    403                 return previous->NextSibling( val );
    404         }
    405 }
    406 
    407 TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )
    408 {
    409         if ( !previous )
    410         {
    411                 return FirstChild( val );
    412         }
    413         else
    414         {
    415                 assert( previous->parent == this );
    416                 return previous->NextSibling( val );
    417         }
    418 }
    419 
    420 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
    421 {
    422         const TiXmlNode* node;
    423         for ( node = next; node; node = node->next )
    424         {
    425                 if ( strcmp( node->Value(), _value ) == 0 )
    426                         return node;
    427         }
    428         return 0;
    429 }
    430 
    431 TiXmlNode* TiXmlNode::NextSibling( const char * _value )
    432 {
    433         TiXmlNode* node;
    434         for ( node = next; node; node = node->next )
    435         {
    436                 if ( strcmp( node->Value(), _value ) == 0 )
    437                         return node;
    438         }
    439         return 0;
    440 }
    441 
    442 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
    443 {
    444         const TiXmlNode* node;
    445         for ( node = prev; node; node = node->prev )
    446         {
    447                 if ( strcmp( node->Value(), _value ) == 0 )
    448                         return node;
    449         }
    450         return 0;
    451 }
    452 
    453 TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )
    454 {
    455         TiXmlNode* node;
    456         for ( node = prev; node; node = node->prev )
    457         {
    458                 if ( strcmp( node->Value(), _value ) == 0 )
    459                         return node;
    460         }
    461         return 0;
    462 }
    463415
    464416void TiXmlElement::RemoveAttribute( const char * name )
    465417{
     418    #ifdef TIXML_USE_STL
     419        TIXML_STRING str( name );
     420        TiXmlAttribute* node = attributeSet.Find( str );
     421        #else
    466422        TiXmlAttribute* node = attributeSet.Find( name );
     423        #endif
    467424        if ( node )
    468425        {
     
    486443}
    487444
    488 TiXmlElement* TiXmlNode::FirstChildElement()
    489 {
    490         TiXmlNode* node;
    491 
    492         for (   node = FirstChild();
    493                         node;
    494                         node = node->NextSibling() )
    495         {
    496                 if ( node->ToElement() )
    497                         return node->ToElement();
    498         }
    499         return 0;
    500 }
    501445
    502446const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
     
    514458}
    515459
    516 TiXmlElement* TiXmlNode::FirstChildElement( const char * _value )
    517 {
    518         TiXmlNode* node;
    519 
    520         for (   node = FirstChild( _value );
     460
     461const TiXmlElement* TiXmlNode::NextSiblingElement() const
     462{
     463        const TiXmlNode* node;
     464
     465        for (   node = NextSibling();
     466                        node;
     467                        node = node->NextSibling() )
     468        {
     469                if ( node->ToElement() )
     470                        return node->ToElement();
     471        }
     472        return 0;
     473}
     474
     475
     476const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
     477{
     478        const TiXmlNode* node;
     479
     480        for (   node = NextSibling( _value );
    521481                        node;
    522482                        node = node->NextSibling( _value ) )
     
    528488}
    529489
    530 const TiXmlElement* TiXmlNode::NextSiblingElement() const
    531 {
    532         const TiXmlNode* node;
    533 
    534         for (   node = NextSibling();
    535         node;
    536         node = node->NextSibling() )
    537         {
    538                 if ( node->ToElement() )
    539                         return node->ToElement();
    540         }
    541         return 0;
    542 }
    543 
    544 TiXmlElement* TiXmlNode::NextSiblingElement()
    545 {
    546         TiXmlNode* node;
    547 
    548         for (   node = NextSibling();
    549         node;
    550         node = node->NextSibling() )
    551         {
    552                 if ( node->ToElement() )
    553                         return node->ToElement();
    554         }
    555         return 0;
    556 }
    557 
    558 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
    559 {
    560         const TiXmlNode* node;
    561 
    562         for (   node = NextSibling( _value );
    563         node;
    564         node = node->NextSibling( _value ) )
    565         {
    566                 if ( node->ToElement() )
    567                         return node->ToElement();
    568         }
    569         return 0;
    570 }
    571 
    572 TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )
    573 {
    574         TiXmlNode* node;
    575 
    576         for (   node = NextSibling( _value );
    577         node;
    578         node = node->NextSibling( _value ) )
    579         {
    580                 if ( node->ToElement() )
    581                         return node->ToElement();
    582         }
    583         return 0;
    584 }
    585 
    586490
    587491const TiXmlDocument* TiXmlNode::GetDocument() const
     
    597501}
    598502
    599 TiXmlDocument* TiXmlNode::GetDocument()
    600 {
    601         TiXmlNode* node;
    602 
    603         for( node = this; node; node = node->parent )
    604         {
    605                 if ( node->ToDocument() )
    606                         return node->ToDocument();
    607         }
    608         return 0;
    609 }
    610503
    611504TiXmlElement::TiXmlElement (const char * _value)
     
    618511
    619512#ifdef TIXML_USE_STL
    620 TiXmlElement::TiXmlElement( const std::string& _value ) 
     513TiXmlElement::TiXmlElement( const std::string& _value )
    621514        : TiXmlNode( TiXmlNode::ELEMENT )
    622515{
     
    631524{
    632525        firstChild = lastChild = 0;
    633         copy.CopyTo( this );   
     526        copy.CopyTo( this );
    634527}
    635528
     
    660553
    661554
    662 const char * TiXmlElement::Attribute( const char * name ) const
     555const char* TiXmlElement::Attribute( const char* name ) const
    663556{
    664557        const TiXmlAttribute* node = attributeSet.Find( name );
    665 
    666558        if ( node )
    667559                return node->Value();
    668 
    669560        return 0;
    670561}
    671562
    672563
    673 const char * TiXmlElement::Attribute( const char * name, int* i ) const
    674 {
    675         const char * s = Attribute( name );
     564#ifdef TIXML_USE_STL
     565const std::string* TiXmlElement::Attribute( const std::string& name ) const
     566{
     567        const TiXmlAttribute* node = attributeSet.Find( name );
     568        if ( node )
     569                return &node->ValueStr();
     570        return 0;
     571}
     572#endif
     573
     574
     575const char* TiXmlElement::Attribute( const char* name, int* i ) const
     576{
     577        const char* s = Attribute( name );
    676578        if ( i )
    677579        {
    678                 if ( s )
     580                if ( s ) {
    679581                        *i = atoi( s );
    680                 else
     582                }
     583                else {
    681584                        *i = 0;
     585                }
    682586        }
    683587        return s;
     
    685589
    686590
    687 const char * TiXmlElement::Attribute( const char * name, double* d ) const
    688 {
    689         const char * s = Attribute( name );
     591#ifdef TIXML_USE_STL
     592const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
     593{
     594        const std::string* s = Attribute( name );
     595        if ( i )
     596        {
     597                if ( s ) {
     598                        *i = atoi( s->c_str() );
     599                }
     600                else {
     601                        *i = 0;
     602                }
     603        }
     604        return s;
     605}
     606#endif
     607
     608
     609const char* TiXmlElement::Attribute( const char* name, double* d ) const
     610{
     611        const char* s = Attribute( name );
    690612        if ( d )
    691613        {
    692                 if ( s )
     614                if ( s ) {
    693615                        *d = atof( s );
    694                 else
     616                }
     617                else {
    695618                        *d = 0;
     619                }
    696620        }
    697621        return s;
    698622}
     623
     624
     625#ifdef TIXML_USE_STL
     626const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
     627{
     628        const std::string* s = Attribute( name );
     629        if ( d )
     630        {
     631                if ( s ) {
     632                        *d = atof( s->c_str() );
     633                }
     634                else {
     635                        *d = 0;
     636                }
     637        }
     638        return s;
     639}
     640#endif
    699641
    700642
     
    704646        if ( !node )
    705647                return TIXML_NO_ATTRIBUTE;
    706 
    707648        return node->QueryIntValue( ival );
    708649}
    709650
    710651
    711 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
     652#ifdef TIXML_USE_STL
     653int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
    712654{
    713655        const TiXmlAttribute* node = attributeSet.Find( name );
    714656        if ( !node )
    715657                return TIXML_NO_ATTRIBUTE;
    716 
     658        return node->QueryIntValue( ival );
     659}
     660#endif
     661
     662
     663int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
     664{
     665        const TiXmlAttribute* node = attributeSet.Find( name );
     666        if ( !node )
     667                return TIXML_NO_ATTRIBUTE;
    717668        return node->QueryDoubleValue( dval );
    718669}
    719670
    720671
     672#ifdef TIXML_USE_STL
     673int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
     674{
     675        const TiXmlAttribute* node = attributeSet.Find( name );
     676        if ( !node )
     677                return TIXML_NO_ATTRIBUTE;
     678        return node->QueryDoubleValue( dval );
     679}
     680#endif
     681
     682
    721683void TiXmlElement::SetAttribute( const char * name, int val )
    722 {       
     684{
    723685        char buf[64];
    724         #if defined(TIXML_SNPRINTF)             
     686        #if defined(TIXML_SNPRINTF)
    725687                TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
    726688        #else
     
    731693
    732694
     695#ifdef TIXML_USE_STL
     696void TiXmlElement::SetAttribute( const std::string& name, int val )
     697{
     698   std::ostringstream oss;
     699   oss << val;
     700   SetAttribute( name, oss.str() );
     701}
     702#endif
     703
     704
    733705void TiXmlElement::SetDoubleAttribute( const char * name, double val )
    734 {       
     706{
    735707        char buf[256];
    736         #if defined(TIXML_SNPRINTF)             
     708        #if defined(TIXML_SNPRINTF)
    737709                TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
    738710        #else
     
    743715
    744716
    745 void TiXmlElement::SetAttribute( const char * name, const char * _value )
     717void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
     718{
     719    #ifdef TIXML_USE_STL
     720        TIXML_STRING _name( cname );
     721        TIXML_STRING _value( cvalue );
     722        #else
     723        const char* _name = cname;
     724        const char* _value = cvalue;
     725        #endif
     726
     727        TiXmlAttribute* node = attributeSet.Find( _name );
     728        if ( node )
     729        {
     730                node->SetValue( _value );
     731                return;
     732        }
     733
     734        TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
     735        if ( attrib )
     736        {
     737                attributeSet.Add( attrib );
     738        }
     739        else
     740        {
     741                TiXmlDocument* document = GetDocument();
     742                if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
     743        }
     744}
     745
     746
     747#ifdef TIXML_USE_STL
     748void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
    746749{
    747750        TiXmlAttribute* node = attributeSet.Find( name );
     
    763766        }
    764767}
     768#endif
     769
    765770
    766771void TiXmlElement::Print( FILE* cfile, int depth ) const
    767772{
    768773        int i;
    769         for ( i=0; i<depth; i++ )
    770         {
     774        assert( cfile );
     775        for ( i=0; i<depth; i++ ) {
    771776                fprintf( cfile, "    " );
    772777        }
     
    809814                }
    810815                fprintf( cfile, "\n" );
    811                 for( i=0; i<depth; ++i )
    812                 fprintf( cfile, "    " );
     816                for( i=0; i<depth; ++i ) {
     817                        fprintf( cfile, "    " );
     818                }
    813819                fprintf( cfile, "</%s>", value.c_str() );
    814         }
    815 }
    816 
    817 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
    818 {
    819         (*stream) << "<" << value;
    820 
    821         const TiXmlAttribute* attrib;
    822         for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
    823         {       
    824                 (*stream) << " ";
    825                 attrib->StreamOut( stream );
    826         }
    827 
    828         // If this node has children, give it a closing tag. Else
    829         // make it an empty tag.
    830         TiXmlNode* node;
    831         if ( firstChild )
    832         {               
    833                 (*stream) << ">";
    834 
    835                 for ( node = firstChild; node; node=node->NextSibling() )
    836                 {
    837                         node->StreamOut( stream );
    838                 }
    839                 (*stream) << "</" << value << ">";
    840         }
    841         else
    842         {
    843                 (*stream) << " />";
    844820        }
    845821}
     
    851827        TiXmlNode::CopyTo( target );
    852828
    853         // Element class: 
     829        // Element class:
    854830        // Clone the attributes, then clone the children.
    855831        const TiXmlAttribute* attribute = 0;
     
    868844}
    869845
     846bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
     847{
     848        if ( visitor->VisitEnter( *this, attributeSet.First() ) )
     849        {
     850                for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
     851                {
     852                        if ( !node->Accept( visitor ) )
     853                                break;
     854                }
     855        }
     856        return visitor->VisitExit( *this );
     857}
     858
    870859
    871860TiXmlNode* TiXmlElement::Clone() const
     
    936925{
    937926        // See STL_STRING_BUG below.
    938         StringToBuffer buf( value );
    939 
    940         if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
    941                 return true;
    942 
    943         return false;
     927        //StringToBuffer buf( value );
     928
     929        return LoadFile( Value(), encoding );
    944930}
    945931
     
    948934{
    949935        // See STL_STRING_BUG below.
    950         StringToBuffer buf( value );
    951 
    952         if ( buf.buffer && SaveFile( buf.buffer ) )
    953                 return true;
    954 
    955         return false;
    956 }
    957 
    958 bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
    959 {
    960         // Delete the existing data:
    961         Clear();
    962         location.Clear();
    963 
     936//      StringToBuffer buf( value );
     937//
     938//      if ( buf.buffer && SaveFile( buf.buffer ) )
     939//              return true;
     940//
     941//      return false;
     942        return SaveFile( Value() );
     943}
     944
     945bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
     946{
    964947        // There was a really terrifying little bug here. The code:
    965948        //              value = filename
     
    968951        // address as it's c_str() method, and so bad things happen. Looks
    969952        // like a bug in the Microsoft STL implementation.
    970         // See STL_STRING_BUG above.
    971         // Fixed with the StringToBuffer class.
     953        // Add an extra string to avoid the crash.
     954        TIXML_STRING filename( _filename );
    972955        value = filename;
    973956
    974957        // reading in binary mode so that tinyxml can normalize the EOL
    975         FILE* file = fopen( value.c_str (), "rb" );     
     958        FILE* file = TiXmlFOpen( value.c_str (), "rb" );
    976959
    977960        if ( file )
    978961        {
    979                 // Get the file size, so we can pre-allocate the string. HUGE speed impact.
    980                 long length = 0;
    981                 fseek( file, 0, SEEK_END );
    982                 length = ftell( file );
    983                 fseek( file, 0, SEEK_SET );
    984 
    985                 // Strange case, but good to handle up front.
    986                 if ( length == 0 )
    987                 {
    988                         fclose( file );
    989                         return false;
    990                 }
    991 
    992                 // If we have a file, assume it is all one big XML file, and read it in.
    993                 // The document parser may decide the document ends sooner than the entire file, however.
    994                 TIXML_STRING data;
    995                 data.reserve( length );
    996 
    997                 // Subtle bug here. TinyXml did use fgets. But from the XML spec:
    998                 // 2.11 End-of-Line Handling
    999                 // <snip>
    1000                 // <quote>
    1001                 // ...the XML processor MUST behave as if it normalized all line breaks in external
    1002                 // parsed entities (including the document entity) on input, before parsing, by translating
    1003                 // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
    1004                 // a single #xA character.
    1005                 // </quote>
    1006                 //
    1007                 // It is not clear fgets does that, and certainly isn't clear it works cross platform.
    1008                 // Generally, you expect fgets to translate from the convention of the OS to the c/unix
    1009                 // convention, and not work generally.
    1010 
    1011                 /*
    1012                 while( fgets( buf, sizeof(buf), file ) )
    1013                 {
    1014                         data += buf;
    1015                 }
    1016                 */
    1017 
    1018                 char* buf = new char[ length+1 ];
    1019                 buf[0] = 0;
    1020 
    1021                 if ( fread( buf, length, 1, file ) != 1 ) {
    1022                 //if ( fread( buf, 1, length, file ) != (size_t)length ) {
    1023                         SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
    1024                         fclose( file );
    1025                         return false;
    1026                 }
     962                bool result = LoadFile( file, encoding );
    1027963                fclose( file );
    1028 
    1029                 const char* lastPos = buf;
    1030                 const char* p = buf;
    1031 
    1032                 buf[length] = 0;
    1033                 while( *p ) {
    1034                         assert( p < (buf+length) );
    1035                         if ( *p == 0xa ) {
    1036                                 // Newline character. No special rules for this. Append all the characters
    1037                                 // since the last string, and include the newline.
    1038                                 data.append( lastPos, p-lastPos+1 );    // append, include the newline
    1039                                 ++p;                                                                    // move past the newline
    1040                                 lastPos = p;                                                    // and point to the new buffer (may be 0)
     964                return result;
     965        }
     966        else
     967        {
     968                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
     969                return false;
     970        }
     971}
     972
     973bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
     974{
     975        if ( !file )
     976        {
     977                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
     978                return false;
     979        }
     980
     981        // Delete the existing data:
     982        Clear();
     983        location.Clear();
     984
     985        // Get the file size, so we can pre-allocate the string. HUGE speed impact.
     986        long length = 0;
     987        fseek( file, 0, SEEK_END );
     988        length = ftell( file );
     989        fseek( file, 0, SEEK_SET );
     990
     991        // Strange case, but good to handle up front.
     992        if ( length <= 0 )
     993        {
     994                SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
     995                return false;
     996        }
     997
     998        // If we have a file, assume it is all one big XML file, and read it in.
     999        // The document parser may decide the document ends sooner than the entire file, however.
     1000        TIXML_STRING data;
     1001        data.reserve( length );
     1002
     1003        // Subtle bug here. TinyXml did use fgets. But from the XML spec:
     1004        // 2.11 End-of-Line Handling
     1005        // <snip>
     1006        // <quote>
     1007        // ...the XML processor MUST behave as if it normalized all line breaks in external
     1008        // parsed entities (including the document entity) on input, before parsing, by translating
     1009        // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
     1010        // a single #xA character.
     1011        // </quote>
     1012        //
     1013        // It is not clear fgets does that, and certainly isn't clear it works cross platform.
     1014        // Generally, you expect fgets to translate from the convention of the OS to the c/unix
     1015        // convention, and not work generally.
     1016
     1017        /*
     1018        while( fgets( buf, sizeof(buf), file ) )
     1019        {
     1020                data += buf;
     1021        }
     1022        */
     1023
     1024        char* buf = new char[ length+1 ];
     1025        buf[0] = 0;
     1026
     1027        if ( fread( buf, length, 1, file ) != 1 ) {
     1028                delete [] buf;
     1029                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
     1030                return false;
     1031        }
     1032
     1033        const char* lastPos = buf;
     1034        const char* p = buf;
     1035
     1036        buf[length] = 0;
     1037        while( *p ) {
     1038                assert( p < (buf+length) );
     1039                if ( *p == 0xa ) {
     1040                        // Newline character. No special rules for this. Append all the characters
     1041                        // since the last string, and include the newline.
     1042                        data.append( lastPos, (p-lastPos+1) );  // append, include the newline
     1043                        ++p;                                                                    // move past the newline
     1044                        lastPos = p;                                                    // and point to the new buffer (may be 0)
     1045                        assert( p <= (buf+length) );
     1046                }
     1047                else if ( *p == 0xd ) {
     1048                        // Carriage return. Append what we have so far, then
     1049                        // handle moving forward in the buffer.
     1050                        if ( (p-lastPos) > 0 ) {
     1051                                data.append( lastPos, p-lastPos );      // do not add the CR
     1052                        }
     1053                        data += (char)0xa;                                              // a proper newline
     1054
     1055                        if ( *(p+1) == 0xa ) {
     1056                                // Carriage return - new line sequence
     1057                                p += 2;
     1058                                lastPos = p;
    10411059                                assert( p <= (buf+length) );
    10421060                        }
    1043                         else if ( *p == 0xd ) {
    1044                                 // Carriage return. Append what we have so far, then
    1045                                 // handle moving forward in the buffer.
    1046                                 if ( (p-lastPos) > 0 ) {
    1047                                         data.append( lastPos, p-lastPos );      // do not add the CR
    1048                                 }
    1049                                 data += (char)0xa;                                              // a proper newline
    1050 
    1051                                 if ( *(p+1) == 0xa ) {
    1052                                         // Carriage return - new line sequence
    1053                                         p += 2;
    1054                                         lastPos = p;
    1055                                         assert( p <= (buf+length) );
    1056                                 }
    1057                                 else {
    1058                                         // it was followed by something else...that is presumably characters again.
    1059                                         ++p;
    1060                                         lastPos = p;
    1061                                         assert( p <= (buf+length) );
    1062                                 }
     1061                        else {
     1062                                // it was followed by something else...that is presumably characters again.
     1063                                ++p;
     1064                                lastPos = p;
     1065                                assert( p <= (buf+length) );
    10631066                        }
    1064                         else {
    1065                                 ++p;
    1066                         }
    1067                 }
    1068                 // Handle any left over characters.
    1069                 if ( p-lastPos ) {
    1070                         data.append( lastPos, p-lastPos );
    1071                 }               
    1072                 delete [] buf;
    1073                 buf = 0;
    1074 
    1075                 Parse( data.c_str(), 0, encoding );
    1076 
    1077                 if (  Error() )
    1078             return false;
    1079         else
    1080                         return true;
    1081         }
    1082         SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
     1067                }
     1068                else {
     1069                        ++p;
     1070                }
     1071        }
     1072        // Handle any left over characters.
     1073        if ( p-lastPos ) {
     1074                data.append( lastPos, p-lastPos );
     1075        }
     1076        delete [] buf;
     1077        buf = 0;
     1078
     1079        Parse( data.c_str(), 0, encoding );
     1080
     1081        if (  Error() )
     1082        return false;
     1083    else
     1084                return true;
     1085}
     1086
     1087
     1088bool TiXmlDocument::SaveFile( const char * filename ) const
     1089{
     1090        // The old c stuff lives on...
     1091        FILE* fp = TiXmlFOpen( filename, "w" );
     1092        if ( fp )
     1093        {
     1094                bool result = SaveFile( fp );
     1095                fclose( fp );
     1096                return result;
     1097        }
    10831098        return false;
    10841099}
    10851100
    1086 bool TiXmlDocument::SaveFile( const char * filename ) const
    1087 {
    1088         // The old c stuff lives on...
    1089         FILE* fp = fopen( filename, "w" );
    1090         if ( fp )
    1091         {
    1092                 if ( useMicrosoftBOM )
    1093                 {
    1094                         const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
    1095                         const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
    1096                         const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
    1097 
    1098                         fputc( TIXML_UTF_LEAD_0, fp );
    1099                         fputc( TIXML_UTF_LEAD_1, fp );
    1100                         fputc( TIXML_UTF_LEAD_2, fp );
    1101                 }
    1102                 Print( fp, 0 );
    1103                 fclose( fp );
    1104                 return true;
    1105         }
    1106         return false;
     1101
     1102bool TiXmlDocument::SaveFile( FILE* fp ) const
     1103{
     1104        if ( useMicrosoftBOM )
     1105        {
     1106                const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
     1107                const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
     1108                const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
     1109
     1110                fputc( TIXML_UTF_LEAD_0, fp );
     1111                fputc( TIXML_UTF_LEAD_1, fp );
     1112                fputc( TIXML_UTF_LEAD_2, fp );
     1113        }
     1114        Print( fp, 0 );
     1115        return (ferror(fp) == 0);
    11071116}
    11081117
     
    11131122
    11141123        target->error = error;
    1115         target->errorDesc = errorDesc.c_str ();
     1124        target->errorId = errorId;
     1125        target->errorDesc = errorDesc;
     1126        target->tabsize = tabsize;
     1127        target->errorLocation = errorLocation;
     1128        target->useMicrosoftBOM = useMicrosoftBOM;
    11161129
    11171130        TiXmlNode* node = 0;
     
    11191132        {
    11201133                target->LinkEndChild( node->Clone() );
    1121         }       
     1134        }
    11221135}
    11231136
     
    11361149void TiXmlDocument::Print( FILE* cfile, int depth ) const
    11371150{
    1138         const TiXmlNode* node;
    1139         for ( node=FirstChild(); node; node=node->NextSibling() )
     1151        assert( cfile );
     1152        for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
    11401153        {
    11411154                node->Print( cfile, depth );
     
    11441157}
    11451158
    1146 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
    1147 {
    1148         const TiXmlNode* node;
    1149         for ( node=FirstChild(); node; node=node->NextSibling() )
    1150         {
    1151                 node->StreamOut( out );
    1152 
    1153                 // Special rule for streams: stop after the root element.
    1154                 // The stream in code will only read one element, so don't
    1155                 // write more than one.
    1156                 if ( node->ToElement() )
    1157                         break;
    1158         }
     1159
     1160bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
     1161{
     1162        if ( visitor->VisitEnter( *this ) )
     1163        {
     1164                for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
     1165                {
     1166                        if ( !node->Accept( visitor ) )
     1167                                break;
     1168                }
     1169        }
     1170        return visitor->VisitExit( *this );
    11591171}
    11601172
     
    11691181}
    11701182
     1183/*
    11711184TiXmlAttribute* TiXmlAttribute::Next()
    11721185{
     
    11771190        return next;
    11781191}
     1192*/
    11791193
    11801194const TiXmlAttribute* TiXmlAttribute::Previous() const
     
    11871201}
    11881202
     1203/*
    11891204TiXmlAttribute* TiXmlAttribute::Previous()
    11901205{
     
    11951210        return prev;
    11961211}
    1197 
    1198 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
     1212*/
     1213
     1214void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
    11991215{
    12001216        TIXML_STRING n, v;
    12011217
    1202         PutString( name, &n );
    1203         PutString( value, &v );
    1204 
    1205         if (value.find ('\"') == TIXML_STRING::npos)
     1218        EncodeString( name, &n );
     1219        EncodeString( value, &v );
     1220
     1221        if (value.find ('\"') == TIXML_STRING::npos) {
     1222                if ( cfile ) {
    12061223                fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
    1207         else
     1224                }
     1225                if ( str ) {
     1226                        (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
     1227                }
     1228        }
     1229        else {
     1230                if ( cfile ) {
    12081231                fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
    1209 }
    1210 
    1211 
    1212 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
    1213 {
    1214         if (value.find( '\"' ) != TIXML_STRING::npos)
    1215         {
    1216                 PutString( name, stream );
    1217                 (*stream) << "=" << "'";
    1218                 PutString( value, stream );
    1219                 (*stream) << "'";
    1220         }
    1221         else
    1222         {
    1223                 PutString( name, stream );
    1224                 (*stream) << "=" << "\"";
    1225                 PutString( value, stream );
    1226                 (*stream) << "\"";
    1227         }
    1228 }
     1232                }
     1233                if ( str ) {
     1234                        (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
     1235                }
     1236        }
     1237}
     1238
    12291239
    12301240int TiXmlAttribute::QueryIntValue( int* ival ) const
    12311241{
    1232         if ( sscanf( value.c_str(), "%d", ival ) == 1 )
     1242        if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
    12331243                return TIXML_SUCCESS;
    12341244        return TIXML_WRONG_TYPE;
     
    12371247int TiXmlAttribute::QueryDoubleValue( double* dval ) const
    12381248{
    1239         if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
     1249        if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
    12401250                return TIXML_SUCCESS;
    12411251        return TIXML_WRONG_TYPE;
     
    12451255{
    12461256        char buf [64];
    1247         #if defined(TIXML_SNPRINTF)             
     1257        #if defined(TIXML_SNPRINTF)
    12481258                TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
    12491259        #else
     
    12561266{
    12571267        char buf [256];
    1258         #if defined(TIXML_SNPRINTF)             
     1268        #if defined(TIXML_SNPRINTF)
    12591269                TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
    12601270        #else
     
    12901300void TiXmlComment::Print( FILE* cfile, int depth ) const
    12911301{
     1302        assert( cfile );
    12921303        for ( int i=0; i<depth; i++ )
    12931304        {
    1294                 fputs( "    ", cfile );
     1305                fprintf( cfile,  "    " );
    12951306        }
    12961307        fprintf( cfile, "<!--%s-->", value.c_str() );
    12971308}
    12981309
    1299 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
    1300 {
    1301         (*stream) << "<!--";
    1302         //PutString( value, stream );
    1303         (*stream) << value;
    1304         (*stream) << "-->";
    1305 }
    1306 
    13071310
    13081311void TiXmlComment::CopyTo( TiXmlComment* target ) const
    13091312{
    13101313        TiXmlNode::CopyTo( target );
     1314}
     1315
     1316
     1317bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
     1318{
     1319        return visitor->Visit( *this );
    13111320}
    13121321
     
    13261335void TiXmlText::Print( FILE* cfile, int depth ) const
    13271336{
     1337        assert( cfile );
    13281338        if ( cdata )
    13291339        {
     
    13331343                        fprintf( cfile, "    " );
    13341344                }
    1335                 fprintf( cfile, "<![CDATA[" );
    1336                 fprintf( cfile, "%s", value.c_str() );  // unformatted output
    1337                 fprintf( cfile, "]]>\n" );
     1345                fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );    // unformatted output
    13381346        }
    13391347        else
    13401348        {
    13411349                TIXML_STRING buffer;
    1342                 PutString( value, &buffer );
     1350                EncodeString( value, &buffer );
    13431351                fprintf( cfile, "%s", buffer.c_str() );
    1344         }
    1345 }
    1346 
    1347 
    1348 void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
    1349 {
    1350         if ( cdata )
    1351         {
    1352                 (*stream) << "<![CDATA[" << value << "]]>";
    1353         }
    1354         else
    1355         {
    1356                 PutString( value, stream );
    13571352        }
    13581353}
     
    13661361
    13671362
     1363bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
     1364{
     1365        return visitor->Visit( *this );
     1366}
     1367
     1368
    13681369TiXmlNode* TiXmlText::Clone() const
    1369 {       
     1370{
    13701371        TiXmlText* clone = 0;
    13711372        clone = new TiXmlText( "" );
     
    14061407        : TiXmlNode( TiXmlNode::DECLARATION )
    14071408{
    1408         copy.CopyTo( this );   
     1409        copy.CopyTo( this );
    14091410}
    14101411
     
    14171418
    14181419
    1419 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
    1420 {
    1421         fprintf (cfile, "<?xml ");
    1422 
    1423         if ( !version.empty() )
    1424                 fprintf (cfile, "version=\"%s\" ", version.c_str ());
    1425         if ( !encoding.empty() )
    1426                 fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
    1427         if ( !standalone.empty() )
    1428                 fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
    1429         fprintf (cfile, "?>");
    1430 }
    1431 
    1432 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
    1433 {
    1434         (*stream) << "<?xml ";
    1435 
    1436         if ( !version.empty() )
    1437         {
    1438                 (*stream) << "version=\"";
    1439                 PutString( version, stream );
    1440                 (*stream) << "\" ";
    1441         }
    1442         if ( !encoding.empty() )
    1443         {
    1444                 (*stream) << "encoding=\"";
    1445                 PutString( encoding, stream );
    1446                 (*stream ) << "\" ";
    1447         }
    1448         if ( !standalone.empty() )
    1449         {
    1450                 (*stream) << "standalone=\"";
    1451                 PutString( standalone, stream );
    1452                 (*stream) << "\" ";
    1453         }
    1454         (*stream) << "?>";
     1420void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
     1421{
     1422        if ( cfile ) fprintf( cfile, "<?xml " );
     1423        if ( str )       (*str) += "<?xml ";
     1424
     1425        if ( !version.empty() ) {
     1426                if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
     1427                if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
     1428        }
     1429        if ( !encoding.empty() ) {
     1430                if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
     1431                if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
     1432        }
     1433        if ( !standalone.empty() ) {
     1434                if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
     1435                if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
     1436        }
     1437        if ( cfile ) fprintf( cfile, "?>" );
     1438        if ( str )       (*str) += "?>";
    14551439}
    14561440
     
    14661450
    14671451
     1452bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
     1453{
     1454        return visitor->Visit( *this );
     1455}
     1456
     1457
    14681458TiXmlNode* TiXmlDeclaration::Clone() const
    1469 {       
     1459{
    14701460        TiXmlDeclaration* clone = new TiXmlDeclaration();
    14711461
     
    14861476
    14871477
    1488 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
    1489 {
    1490         (*stream) << "<" << value << ">";               // Don't use entities here! It is unknown.
    1491 }
    1492 
    1493 
    14941478void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
    14951479{
    14961480        TiXmlNode::CopyTo( target );
     1481}
     1482
     1483
     1484bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
     1485{
     1486        return visitor->Visit( *this );
    14971487}
    14981488
     
    15261516void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
    15271517{
     1518    #ifdef TIXML_USE_STL
     1519        assert( !Find( TIXML_STRING( addMe->Name() ) ) );       // Shouldn't be multiply adding to the set.
     1520        #else
    15281521        assert( !Find( addMe->Name() ) );       // Shouldn't be multiply adding to the set.
     1522        #endif
    15291523
    15301524        addMe->next = &sentinel;
     
    15531547}
    15541548
    1555 const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
    1556 {
    1557         const TiXmlAttribute* node;
    1558 
    1559         for( node = sentinel.next; node != &sentinel; node = node->next )
     1549
     1550#ifdef TIXML_USE_STL
     1551const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
     1552{
     1553        for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
    15601554        {
    15611555                if ( node->name == name )
     
    15651559}
    15661560
    1567 TiXmlAttribute* TiXmlAttributeSet::Find( const char * name )
    1568 {
    1569         TiXmlAttribute* node;
    1570 
    1571         for( node = sentinel.next; node != &sentinel; node = node->next )
     1561/*
     1562TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name )
     1563{
     1564        for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
    15721565        {
    15731566                if ( node->name == name )
     
    15761569        return 0;
    15771570}
    1578 
    1579 #ifdef TIXML_USE_STL   
    1580 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
     1571*/
     1572#endif
     1573
     1574
     1575const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
     1576{
     1577        for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
     1578        {
     1579                if ( strcmp( node->name.c_str(), name ) == 0 )
     1580                        return node;
     1581        }
     1582        return 0;
     1583}
     1584
     1585/*
     1586TiXmlAttribute* TiXmlAttributeSet::Find( const char* name )
     1587{
     1588        for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
     1589        {
     1590                if ( strcmp( node->name.c_str(), name ) == 0 )
     1591                        return node;
     1592        }
     1593        return 0;
     1594}
     1595*/
     1596
     1597#ifdef TIXML_USE_STL
     1598std::istream& operator>> (std::istream & in, TiXmlNode & base)
    15811599{
    15821600        TIXML_STRING tag;
     
    15901608
    15911609
    1592 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
    1593 {
    1594         base.StreamOut (& out);
     1610#ifdef TIXML_USE_STL
     1611std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
     1612{
     1613        TiXmlPrinter printer;
     1614        printer.SetStreamPrinting();
     1615        base.Accept( &printer );
     1616        out << printer.Str();
     1617
    15951618        return out;
    15961619}
    15971620
    15981621
    1599 #ifdef TIXML_USE_STL   
    1600 std::string & operator<< (std::string& out, const TiXmlNode& base )
    1601 {
    1602    std::ostringstream os_stream( std::ostringstream::out );
    1603    base.StreamOut( &os_stream );
    1604    
    1605    out.append( os_stream.str() );
    1606    return out;
     1622std::string& operator<< (std::string& out, const TiXmlNode& base )
     1623{
     1624        TiXmlPrinter printer;
     1625        printer.SetStreamPrinting();
     1626        base.Accept( &printer );
     1627        out.append( printer.Str() );
     1628
     1629        return out;
    16071630}
    16081631#endif
     
    17311754        return TiXmlHandle( 0 );
    17321755}
     1756
     1757
     1758bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
     1759{
     1760        return true;
     1761}
     1762
     1763bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
     1764{
     1765        return true;
     1766}
     1767
     1768bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
     1769{
     1770        DoIndent();
     1771        buffer += "<";
     1772        buffer += element.Value();
     1773
     1774        for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
     1775        {
     1776                buffer += " ";
     1777                attrib->Print( 0, 0, &buffer );
     1778        }
     1779
     1780        if ( !element.FirstChild() )
     1781        {
     1782                buffer += " />";
     1783                DoLineBreak();
     1784        }
     1785        else
     1786        {
     1787                buffer += ">";
     1788                if (    element.FirstChild()->ToText()
     1789                          && element.LastChild() == element.FirstChild()
     1790                          && element.FirstChild()->ToText()->CDATA() == false )
     1791                {
     1792                        simpleTextPrint = true;
     1793                        // no DoLineBreak()!
     1794                }
     1795                else
     1796                {
     1797                        DoLineBreak();
     1798                }
     1799        }
     1800        ++depth;
     1801        return true;
     1802}
     1803
     1804
     1805bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
     1806{
     1807        --depth;
     1808        if ( !element.FirstChild() )
     1809        {
     1810                // nothing.
     1811        }
     1812        else
     1813        {
     1814                if ( simpleTextPrint )
     1815                {
     1816                        simpleTextPrint = false;
     1817                }
     1818                else
     1819                {
     1820                        DoIndent();
     1821                }
     1822                buffer += "</";
     1823                buffer += element.Value();
     1824                buffer += ">";
     1825                DoLineBreak();
     1826        }
     1827        return true;
     1828}
     1829
     1830
     1831bool TiXmlPrinter::Visit( const TiXmlText& text )
     1832{
     1833        if ( text.CDATA() )
     1834        {
     1835                DoIndent();
     1836                buffer += "<![CDATA[";
     1837                buffer += text.Value();
     1838                buffer += "]]>";
     1839                DoLineBreak();
     1840        }
     1841        else if ( simpleTextPrint )
     1842        {
     1843                TIXML_STRING str;
     1844                TiXmlBase::EncodeString( text.ValueTStr(), &str );
     1845                buffer += str;
     1846        }
     1847        else
     1848        {
     1849                DoIndent();
     1850                TIXML_STRING str;
     1851                TiXmlBase::EncodeString( text.ValueTStr(), &str );
     1852                buffer += str;
     1853                DoLineBreak();
     1854        }
     1855        return true;
     1856}
     1857
     1858
     1859bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
     1860{
     1861        DoIndent();
     1862        declaration.Print( 0, 0, &buffer );
     1863        DoLineBreak();
     1864        return true;
     1865}
     1866
     1867
     1868bool TiXmlPrinter::Visit( const TiXmlComment& comment )
     1869{
     1870        DoIndent();
     1871        buffer += "<!--";
     1872        buffer += comment.Value();
     1873        buffer += "-->";
     1874        DoLineBreak();
     1875        return true;
     1876}
     1877
     1878
     1879bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
     1880{
     1881        DoIndent();
     1882        buffer += "<";
     1883        buffer += unknown.Value();
     1884        buffer += ">";
     1885        DoLineBreak();
     1886        return true;
     1887}
     1888
  • code/branches/FICN/src/tinyxml/tinyxml.h

    r471 r738  
    11/*
    22www.sourceforge.net/projects/tinyxml
    3 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
     3Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
    44
    55This software is provided 'as-is', without any express or implied
     
    2626#ifndef TINYXML_INCLUDED
    2727#define TINYXML_INCLUDED
    28 
    29 #define TIXML_USE_STL
    3028
    3129#ifdef _MSC_VER
     
    4644#endif
    4745
    48 #if defined( DEBUG ) && defined( _MSC_VER )
    49 #include <windows.h>
    50 #define TIXML_LOG OutputDebugString
    51 #else
    52 #define TIXML_LOG printf
    53 #endif
    54 
    5546#ifdef TIXML_USE_STL
    5647        #include <string>
    5748        #include <iostream>
    58         #define TIXML_STRING    std::string
    59         #define TIXML_ISTREAM   std::istream
    60         #define TIXML_OSTREAM   std::ostream
     49        #include <sstream>
     50        #define TIXML_STRING            std::string
    6151#else
    6252        #include "tinystr.h"
    63         #define TIXML_STRING    TiXmlString
    64         #define TIXML_OSTREAM   TiXmlOutStream
     53        #define TIXML_STRING            TiXmlString
    6554#endif
    6655
     
    6958// but it gets closer. There are too many compilers for me to fully
    7059// test. If you get compilation troubles, undefine TIXML_SAFE
    71 
    72 #define TIXML_SAFE              // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
     60#define TIXML_SAFE
     61
    7362#ifdef TIXML_SAFE
    74         #if defined(_MSC_VER) && (_MSC_VER >= 1200 )
     63        #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
     64                // Microsoft visual studio, version 2005 and higher.
     65                #define TIXML_SNPRINTF _snprintf_s
     66                #define TIXML_SNSCANF  _snscanf_s
     67                #define TIXML_SSCANF   sscanf_s
     68        #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
    7569                // Microsoft visual studio, version 6 and higher.
    7670                //#pragma message( "Using _sn* functions." )
    7771                #define TIXML_SNPRINTF _snprintf
    7872                #define TIXML_SNSCANF  _snscanf
     73                #define TIXML_SSCANF   sscanf
    7974        #elif defined(__GNUC__) && (__GNUC__ >= 3 )
    8075                // GCC version 3 and higher.s
     
    8277                #define TIXML_SNPRINTF snprintf
    8378                #define TIXML_SNSCANF  snscanf
    84         #endif
    85 #endif
     79                #define TIXML_SSCANF   sscanf
     80        #else
     81                #define TIXML_SSCANF   sscanf
     82        #endif
     83#endif 
    8684
    8785class TiXmlDocument;
     
    9593
    9694const int TIXML_MAJOR_VERSION = 2;
    97 const int TIXML_MINOR_VERSION = 4;
    98 const int TIXML_PATCH_VERSION = 2;
    99 
    100 /*      Internal structure for tracking location of items
     95const int TIXML_MINOR_VERSION = 5;
     96const int TIXML_PATCH_VERSION = 3;
     97
     98/*      Internal structure for tracking location of items 
    10199        in the XML file.
    102100*/
     
    111109
    112110
     111/**
     112        If you call the Accept() method, it requires being passed a TiXmlVisitor
     113        class to handle callbacks. For nodes that contain other nodes (Document, Element)
     114        you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
     115        are simple called with Visit().
     116
     117        If you return 'true' from a Visit method, recursive parsing will continue. If you return
     118        false, <b>no children of this node or its sibilings</b> will be Visited.
     119
     120        All flavors of Visit methods have a default implementation that returns 'true' (continue
     121        visiting). You need to only override methods that are interesting to you.
     122
     123        Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
     124
     125        You should never change the document from a callback.
     126
     127        @sa TiXmlNode::Accept()
     128*/
     129class TiXmlVisitor
     130{
     131public:
     132        virtual ~TiXmlVisitor() {}
     133
     134        /// Visit a document.
     135        virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )                 { return true; }
     136        /// Visit a document.
     137        virtual bool VisitExit( const TiXmlDocument& /*doc*/ )                  { return true; }
     138
     139        /// Visit an element.
     140        virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
     141        /// Visit an element.
     142        virtual bool VisitExit( const TiXmlElement& /*element*/ )               { return true; }
     143
     144        /// Visit a declaration
     145        virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
     146        /// Visit a text node
     147        virtual bool Visit( const TiXmlText& /*text*/ )                                 { return true; }
     148        /// Visit a comment node
     149        virtual bool Visit( const TiXmlComment& /*comment*/ )                   { return true; }
     150        /// Visit an unknow node
     151        virtual bool Visit( const TiXmlUnknown& /*unknown*/ )                   { return true; }
     152};
     153
    113154// Only used by Attribute::Query functions
    114 enum
    115 {
     155enum 
     156{ 
    116157        TIXML_SUCCESS,
    117158        TIXML_NO_ATTRIBUTE,
     
    159200
    160201public:
    161         TiXmlBase()     :       userData(0) {}
    162         virtual ~TiXmlBase()                                    {}
    163 
    164         /**     All TinyXml classes can print themselves to a filestream.
    165                 This is a formatted print, and will insert tabs and newlines.
    166 
     202        TiXmlBase()     :       userData(0)             {}
     203        virtual ~TiXmlBase()                    {}
     204
     205        /**     All TinyXml classes can print themselves to a filestream
     206                or the string class (TiXmlString in non-STL mode, std::string
     207                in STL mode.) Either or both cfile and str can be null.
     208               
     209                This is a formatted print, and will insert
     210                tabs and newlines.
     211               
    167212                (For an unformatted stream, use the << operator.)
    168213        */
     
    173218                are provided to set whether or not TinyXml will condense all white space
    174219                into a single space or not. The default is to condense. Note changing this
    175                 values is not thread safe.
     220                value is not thread safe.
    176221        */
    177222        static void SetCondenseWhiteSpace( bool condense )              { condenseWhiteSpace = condense; }
     
    201246        int Column() const              { return location.col + 1; }    ///< See Row()
    202247
    203         void  SetUserData( void* user )                 { userData = user; }
    204         void* GetUserData()                                             { return userData; }
     248        void  SetUserData( void* user )                 { userData = user; }    ///< Set a pointer to arbitrary user data.
     249        void* GetUserData()                                             { return userData; }    ///< Get a pointer to arbitrary user data.
     250        const void* GetUserData() const                 { return userData; }    ///< Get a pointer to arbitrary user data.
    205251
    206252        // Table that returs, for a given lead byte, the total number of bytes
     
    208254        static const int utf8ByteTable[256];
    209255
    210         virtual const char* Parse(      const char* p,
    211                                                                 TiXmlParsingData* data,
     256        virtual const char* Parse(      const char* p, 
     257                                                                TiXmlParsingData* data, 
    212258                                                                TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
     259
     260        /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
     261                or they will be transformed into entities!
     262        */
     263        static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
    213264
    214265        enum
     
    230281                TIXML_ERROR_EMBEDDED_NULL,
    231282                TIXML_ERROR_PARSING_CDATA,
     283                TIXML_ERROR_DOCUMENT_TOP_ONLY,
    232284
    233285                TIXML_ERROR_STRING_COUNT
     
    236288protected:
    237289
    238         // See STL_STRING_BUG
    239         // Utility class to overcome a bug.
    240         class StringToBuffer
    241         {
    242           public:
    243                 StringToBuffer( const TIXML_STRING& str );
    244                 ~StringToBuffer();
    245                 char* buffer;
    246         };
    247 
    248         static const char*      SkipWhiteSpace( const char*, TiXmlEncoding encoding );
    249         inline static bool      IsWhiteSpace( char c )
    250         {
    251                 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
    252         }
    253 
    254         virtual void StreamOut (TIXML_OSTREAM *) const = 0;
     290        static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
     291        inline static bool IsWhiteSpace( char c )               
     292        {
     293                return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
     294        }
     295        inline static bool IsWhiteSpace( int c )
     296        {
     297                if ( c < 256 )
     298                        return IsWhiteSpace( (char) c );
     299                return false;   // Again, only truly correct for English/Latin...but usually works.
     300        }
    255301
    256302        #ifdef TIXML_USE_STL
    257             static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
    258             static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
     303        static bool     StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
     304        static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
    259305        #endif
    260306
     
    285331                if ( encoding == TIXML_ENCODING_UTF8 )
    286332                {
    287                         *length = utf8ByteTable[ *((unsigned char*)p) ];
     333                        *length = utf8ByteTable[ *((const unsigned char*)p) ];
    288334                        assert( *length >= 0 && *length < 5 );
    289335                }
     
    316362        }
    317363
    318         // Puts a string to a stream, expanding entities as it goes.
    319         // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
    320         static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
    321 
    322         static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
    323 
    324364        // Return true if the next characters in the stream are any of the endTag sequences.
    325365        // Ignore case only works for english, and should only be relied on when comparing
     
    336376    /// Field containing a generic user pointer
    337377        void*                   userData;
    338 
     378       
    339379        // None of these methods are reliable for any language except English.
    340380        // Good for approximation, not great for accuracy.
     
    388428
    389429public:
    390         #ifdef TIXML_USE_STL
     430        #ifdef TIXML_USE_STL   
    391431
    392432            /** An input stream operator, for every class. Tolerant of newlines and
     
    402442                    a node to a stream is very well defined. You'll get a nice stream
    403443                    of output, without any extra whitespace or newlines.
    404 
     444                   
    405445                    But reading is not as well defined. (As it always is.) If you create
    406446                    a TiXmlElement (for example) and read that from an input stream,
     
    410450                    A TiXmlDocument will read nodes until it reads a root element, and
    411451                        all the children of that root element.
    412             */
     452            */ 
    413453            friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
    414454
     
    416456                friend std::string& operator<< (std::string& out, const TiXmlNode& base );
    417457
    418         #else
    419             // Used internally, not part of the public API.
    420             friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
    421458        #endif
    422459
     
    459496        #endif
    460497
     498        const TIXML_STRING& ValueTStr() const { return value; }
     499
    461500        /** Changes the value of the node. Defined as:
    462501                @verbatim
     
    472511    #ifdef TIXML_USE_STL
    473512        /// STL std::string form.
    474         void SetValue( const std::string& _value )
    475         {
    476                 StringToBuffer buf( _value );
    477                 SetValue( buf.buffer ? buf.buffer : "" );
    478         }
     513        void SetValue( const std::string& _value )      { value = _value; }
    479514        #endif
    480515
     
    486521        const TiXmlNode* Parent() const                         { return parent; }
    487522
    488         const TiXmlNode* FirstChild()   const   { return firstChild; }          ///< The first child of this node. Will be null if there are no children.
    489         TiXmlNode* FirstChild()                                 { return firstChild; }
     523        const TiXmlNode* FirstChild()   const           { return firstChild; }  ///< The first child of this node. Will be null if there are no children.
     524        TiXmlNode* FirstChild()                                         { return firstChild; }
    490525        const TiXmlNode* FirstChild( const char * value ) const;                        ///< The first child of this node with the matching 'value'. Will be null if none found.
    491         TiXmlNode* FirstChild( const char * value );                                            ///< The first child of this node with the matching 'value'. Will be null if none found.
    492 
     526        /// The first child of this node with the matching 'value'. Will be null if none found.
     527        TiXmlNode* FirstChild( const char * _value ) {
     528                // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
     529                // call the method, cast the return back to non-const.
     530                return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
     531        }
    493532        const TiXmlNode* LastChild() const      { return lastChild; }           /// The last child of this node. Will be null if there are no children.
    494533        TiXmlNode* LastChild()  { return lastChild; }
     534       
    495535        const TiXmlNode* LastChild( const char * value ) const;                 /// The last child of this node matching 'value'. Will be null if there are no children.
    496         TiXmlNode* LastChild( const char * value );
     536        TiXmlNode* LastChild( const char * _value ) {
     537                return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
     538        }
    497539
    498540    #ifdef TIXML_USE_STL
     
    520562        */
    521563        const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
    522         TiXmlNode* IterateChildren( TiXmlNode* previous );
     564        TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
     565                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
     566        }
    523567
    524568        /// This flavor of IterateChildren searches for children with a particular 'value'
    525569        const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
    526         TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
     570        TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
     571                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
     572        }
    527573
    528574    #ifdef TIXML_USE_STL
    529575        const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {       return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
    530         TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {  return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
     576        TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
    531577        #endif
    532578
     
    572618        /// Navigate to a sibling node.
    573619        const TiXmlNode* PreviousSibling( const char * ) const;
    574         TiXmlNode* PreviousSibling( const char * );
     620        TiXmlNode* PreviousSibling( const char *_prev ) {
     621                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
     622        }
    575623
    576624    #ifdef TIXML_USE_STL
     
    587635        /// Navigate to a sibling node with the given 'value'.
    588636        const TiXmlNode* NextSibling( const char * ) const;
    589         TiXmlNode* NextSibling( const char * );
     637        TiXmlNode* NextSibling( const char* _next ) {
     638                return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
     639        }
    590640
    591641        /** Convenience function to get through elements.
     
    594644        */
    595645        const TiXmlElement* NextSiblingElement() const;
    596         TiXmlElement* NextSiblingElement();
     646        TiXmlElement* NextSiblingElement() {
     647                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
     648        }
    597649
    598650        /** Convenience function to get through elements.
     
    601653        */
    602654        const TiXmlElement* NextSiblingElement( const char * ) const;
    603         TiXmlElement* NextSiblingElement( const char * );
     655        TiXmlElement* NextSiblingElement( const char *_next ) {
     656                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
     657        }
    604658
    605659    #ifdef TIXML_USE_STL
     
    610664        /// Convenience function to get through elements.
    611665        const TiXmlElement* FirstChildElement() const;
    612         TiXmlElement* FirstChildElement();
     666        TiXmlElement* FirstChildElement() {
     667                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
     668        }
    613669
    614670        /// Convenience function to get through elements.
    615         const TiXmlElement* FirstChildElement( const char * value ) const;
    616         TiXmlElement* FirstChildElement( const char * value );
     671        const TiXmlElement* FirstChildElement( const char * _value ) const;
     672        TiXmlElement* FirstChildElement( const char * _value ) {
     673                return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
     674        }
    617675
    618676    #ifdef TIXML_USE_STL
     
    631689        */
    632690        const TiXmlDocument* GetDocument() const;
    633         TiXmlDocument* GetDocument();
     691        TiXmlDocument* GetDocument() {
     692                return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
     693        }
    634694
    635695        /// Returns true if this node has no children.
    636696        bool NoChildren() const                                         { return !firstChild; }
    637697
    638         const TiXmlDocument* ToDocument()       const           { return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    639         const TiXmlElement*  ToElement() const                  { return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    640         const TiXmlComment*  ToComment() const                  { return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    641         const TiXmlUnknown*  ToUnknown() const                  { return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    642         const TiXmlText*           ToText()    const            { return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    643         const TiXmlDeclaration* ToDeclaration() const   { return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    644 
    645         TiXmlDocument* ToDocument()                     { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    646         TiXmlElement*  ToElement()                      { return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    647         TiXmlComment*  ToComment()                      { return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    648         TiXmlUnknown*  ToUnknown()                      { return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    649         TiXmlText*         ToText()                     { return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    650         TiXmlDeclaration* ToDeclaration()       { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
     698        virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     699        virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     700        virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     701        virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     702        virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     703        virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     704
     705        virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     706        virtual TiXmlElement*           ToElement()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     707        virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     708        virtual TiXmlUnknown*           ToUnknown()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     709        virtual TiXmlText*                  ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
     710        virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
    651711
    652712        /** Create an exact duplicate of this node and return it. The memory must be deleted
    653                 by the caller.
     713                by the caller. 
    654714        */
    655715        virtual TiXmlNode* Clone() const = 0;
     716
     717        /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
     718                XML tree will be conditionally visited and the host will be called back
     719                via the TiXmlVisitor interface.
     720
     721                This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
     722                the XML for the callbacks, so the performance of TinyXML is unchanged by using this
     723                interface versus any other.)
     724
     725                The interface has been based on ideas from:
     726
     727                - http://www.saxproject.org/
     728                - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
     729
     730                Which are both good references for "visiting".
     731
     732                An example of using Accept():
     733                @verbatim
     734                TiXmlPrinter printer;
     735                tinyxmlDoc.Accept( &printer );
     736                const char* xmlcstr = printer.CStr();
     737                @endverbatim
     738        */
     739        virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
    656740
    657741protected:
     
    664748        #ifdef TIXML_USE_STL
    665749            // The real work of the input operator.
    666             virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
     750        virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
    667751        #endif
    668752
     
    726810        }
    727811
    728         const char*             Name()  const           { return name.c_str (); }               ///< Return the name of this attribute.
    729         const char*             Value() const           { return value.c_str (); }              ///< Return the value of this attribute.
     812        const char*             Name()  const           { return name.c_str(); }                ///< Return the name of this attribute.
     813        const char*             Value() const           { return value.c_str(); }               ///< Return the value of this attribute.
     814        #ifdef TIXML_USE_STL
     815        const std::string& ValueStr() const     { return value; }                               ///< Return the value of this attribute.
     816        #endif
    730817        int                             IntValue() const;                                                                       ///< Return the value of this attribute, converted to an integer.
    731818        double                  DoubleValue() const;                                                            ///< Return the value of this attribute, converted to a double.
    732819
     820        // Get the tinyxml string representation
     821        const TIXML_STRING& NameTStr() const { return name; }
     822
    733823        /** QueryIntValue examines the value string. It is an alternative to the
    734824                IntValue() method with richer error checking.
    735                 If the value is an integer, it is stored in 'value' and
     825                If the value is an integer, it is stored in 'value' and 
    736826                the call returns TIXML_SUCCESS. If it is not
    737827                an integer, it returns TIXML_WRONG_TYPE.
     
    752842    #ifdef TIXML_USE_STL
    753843        /// STL std::string form.
    754         void SetName( const std::string& _name )
    755         {
    756                 StringToBuffer buf( _name );
    757                 SetName ( buf.buffer ? buf.buffer : "error" );
    758         }
    759         /// STL std::string form.
    760         void SetValue( const std::string& _value )
    761         {
    762                 StringToBuffer buf( _value );
    763                 SetValue( buf.buffer ? buf.buffer : "error" );
    764         }
     844        void SetName( const std::string& _name )        { name = _name; }       
     845        /// STL std::string form.       
     846        void SetValue( const std::string& _value )      { value = _value; }
    765847        #endif
    766848
    767849        /// Get the next sibling attribute in the DOM. Returns null at end.
    768850        const TiXmlAttribute* Next() const;
    769         TiXmlAttribute* Next();
     851        TiXmlAttribute* Next() {
     852                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
     853        }
     854
    770855        /// Get the previous sibling attribute in the DOM. Returns null at beginning.
    771856        const TiXmlAttribute* Previous() const;
    772         TiXmlAttribute* Previous();
     857        TiXmlAttribute* Previous() {
     858                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
     859        }
    773860
    774861        bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
     
    782869
    783870        // Prints this Attribute to a FILE stream.
    784         virtual void Print( FILE* cfile, int depth ) const;
    785 
    786         virtual void StreamOut( TIXML_OSTREAM * out ) const;
     871        virtual void Print( FILE* cfile, int depth ) const {
     872                Print( cfile, depth, 0 );
     873        }
     874        void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
     875
    787876        // [internal use]
    788877        // Set the document pointer so the attribute can report errors.
     
    803892/*      A class used to manage a group of attributes.
    804893        It is only used internally, both by the ELEMENT and the DECLARATION.
    805 
     894       
    806895        The set can be changed transparent to the Element and Declaration
    807896        classes that use it, but NOT transparent to the Attribute
     
    827916        TiXmlAttribute* Last()                                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    828917
    829         const TiXmlAttribute*   Find( const char * name ) const;
    830         TiXmlAttribute* Find( const char * name );
     918        const TiXmlAttribute*   Find( const char* _name ) const;
     919        TiXmlAttribute* Find( const char* _name ) {
     920                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
     921        }
     922        #ifdef TIXML_USE_STL
     923        const TiXmlAttribute*   Find( const std::string& _name ) const;
     924        TiXmlAttribute* Find( const std::string& _name ) {
     925                return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
     926        }
     927
     928        #endif
    831929
    832930private:
     
    884982        /** QueryIntAttribute examines the attribute - it is an alternative to the
    885983                Attribute() method with richer error checking.
    886                 If the attribute is an integer, it is stored in 'value' and
     984                If the attribute is an integer, it is stored in 'value' and 
    887985                the call returns TIXML_SUCCESS. If it is not
    888986                an integer, it returns TIXML_WRONG_TYPE. If the attribute
    889987                does not exist, then TIXML_NO_ATTRIBUTE is returned.
    890         */
     988        */     
    891989        int QueryIntAttribute( const char* name, int* _value ) const;
    892990        /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
     
    9021000        }
    9031001
     1002    #ifdef TIXML_USE_STL
     1003        /** Template form of the attribute query which will try to read the
     1004                attribute into the specified type. Very easy, very powerful, but
     1005                be careful to make sure to call this with the correct type.
     1006               
     1007                NOTE: This method doesn't work correctly for 'string' types.
     1008
     1009                @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
     1010        */
     1011        template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
     1012        {
     1013                const TiXmlAttribute* node = attributeSet.Find( name );
     1014                if ( !node )
     1015                        return TIXML_NO_ATTRIBUTE;
     1016
     1017                std::stringstream sstream( node->ValueStr() );
     1018                sstream >> *outValue;
     1019                if ( !sstream.fail() )
     1020                        return TIXML_SUCCESS;
     1021                return TIXML_WRONG_TYPE;
     1022        }
     1023        /*
     1024         This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
     1025         but template specialization is hard to get working cross-compiler. Leaving the bug for now.
     1026         
     1027        // The above will fail for std::string because the space character is used as a seperator.
     1028        // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
     1029        template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
     1030        {
     1031                const TiXmlAttribute* node = attributeSet.Find( name );
     1032                if ( !node )
     1033                        return TIXML_NO_ATTRIBUTE;
     1034                *outValue = node->ValueStr();
     1035                return TIXML_SUCCESS;
     1036        }
     1037        */
     1038        #endif
     1039
    9041040        /** Sets an attribute of name to a given value. The attribute
    9051041                will be created if it does not exist, or changed if it does.
     
    9081044
    9091045    #ifdef TIXML_USE_STL
    910         const char* Attribute( const std::string& name ) const                          { return Attribute( name.c_str() ); }
    911         const char* Attribute( const std::string& name, int* i ) const          { return Attribute( name.c_str(), i ); }
    912         const char* Attribute( const std::string& name, double* d ) const       { return Attribute( name.c_str(), d ); }
    913         int QueryIntAttribute( const std::string& name, int* _value ) const     { return QueryIntAttribute( name.c_str(), _value ); }
    914         int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
     1046        const std::string* Attribute( const std::string& name ) const;
     1047        const std::string* Attribute( const std::string& name, int* i ) const;
     1048        const std::string* Attribute( const std::string& name, double* d ) const;
     1049        int QueryIntAttribute( const std::string& name, int* _value ) const;
     1050        int QueryDoubleAttribute( const std::string& name, double* _value ) const;
    9151051
    9161052        /// STL std::string form.
    917         void SetAttribute( const std::string& name, const std::string& _value )
    918         {
    919                 StringToBuffer n( name );
    920                 StringToBuffer v( _value );
    921                 if ( n.buffer && v.buffer )
    922                         SetAttribute (n.buffer, v.buffer );
    923         }
     1053        void SetAttribute( const std::string& name, const std::string& _value );
    9241054        ///< STL std::string form.
    925         void SetAttribute( const std::string& name, int _value )
    926         {
    927                 StringToBuffer n( name );
    928                 if ( n.buffer )
    929                         SetAttribute (n.buffer, _value);
    930         }
     1055        void SetAttribute( const std::string& name, int _value );
    9311056        #endif
    9321057
     
    9561081                and concise, GetText() is limited compared to getting the TiXmlText child
    9571082                and accessing it directly.
    958 
     1083       
    9591084                If the first child of 'this' is a TiXmlText, the GetText()
    9601085                returns the character string of the Text node, else null is returned.
     
    9661091                @endverbatim
    9671092
    968                 'str' will be a pointer to "This is text".
    969 
     1093                'str' will be a pointer to "This is text". 
     1094               
    9701095                Note that this function can be misleading. If the element foo was created from
    9711096                this XML:
    9721097                @verbatim
    973                 <foo><b>This is text</b></foo>
     1098                <foo><b>This is text</b></foo> 
    9741099                @endverbatim
    9751100
     
    9771102                another element. From this XML:
    9781103                @verbatim
    979                 <foo>This is <b>text</b></foo>
     1104                <foo>This is <b>text</b></foo> 
    9801105                @endverbatim
    9811106                GetText() will return "This is ".
    9821107
    983                 WARNING: GetText() accesses a child node - don't become confused with the
    984                                  similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
     1108                WARNING: GetText() accesses a child node - don't become confused with the 
     1109                                 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
    9851110                                 safe type casts on the referenced node.
    9861111        */
     
    9971122        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    9981123
     1124        virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1125        virtual TiXmlElement*           ToElement()               { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1126
     1127        /** Walk the XML tree visiting this node and all of its children.
     1128        */
     1129        virtual bool Accept( TiXmlVisitor* visitor ) const;
     1130
    9991131protected:
    10001132
     
    10041136        // Used to be public [internal use]
    10051137        #ifdef TIXML_USE_STL
    1006             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
    1007         #endif
    1008         virtual void StreamOut( TIXML_OSTREAM * out ) const;
    1009 
     1138        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
     1139        #endif
    10101140        /*      [internal use]
    10111141                Reads the "value" of the element -- another element, or text.
     
    10271157        /// Constructs an empty comment.
    10281158        TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
     1159        /// Construct a comment from text.
     1160        TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
     1161                SetValue( _value );
     1162        }
    10291163        TiXmlComment( const TiXmlComment& );
    10301164        void operator=( const TiXmlComment& base );
     
    10341168        /// Returns a copy of this Comment.
    10351169        virtual TiXmlNode* Clone() const;
    1036         /// Write this Comment to a FILE stream.
     1170        // Write this Comment to a FILE stream.
    10371171        virtual void Print( FILE* cfile, int depth ) const;
    10381172
     
    10421176        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    10431177
     1178        virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1179        virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1180
     1181        /** Walk the XML tree visiting this node and all of its children.
     1182        */
     1183        virtual bool Accept( TiXmlVisitor* visitor ) const;
     1184
    10441185protected:
    10451186        void CopyTo( TiXmlComment* target ) const;
     
    10471188        // used to be public
    10481189        #ifdef TIXML_USE_STL
    1049             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
    1050         #endif
    1051         virtual void StreamOut( TIXML_OSTREAM * out ) const;
     1190        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
     1191        #endif
     1192//      virtual void StreamOut( TIXML_OSTREAM * out ) const;
    10521193
    10531194private:
     
    10561197
    10571198
    1058 /** XML text. A text node can have 2 ways to output the next. "normal" output
     1199/** XML text. A text node can have 2 ways to output the next. "normal" output 
    10591200        and CDATA. It will default to the mode it was parsed from the XML file and
    1060         you generally want to leave it alone, but you can change the output mode with
     1201        you generally want to leave it alone, but you can change the output mode with 
    10611202        SetCDATA() and query it with CDATA().
    10621203*/
     
    10651206        friend class TiXmlElement;
    10661207public:
    1067         /** Constructor for text element. By default, it is treated as
     1208        /** Constructor for text element. By default, it is treated as 
    10681209                normal, encoded text. If you want it be output as a CDATA text
    10691210                element, set the parameter _cdata to 'true'
     
    10881229        void operator=( const TiXmlText& base )                                                         { base.CopyTo( this ); }
    10891230
    1090         /// Write this text object to a FILE stream.
     1231        // Write this text object to a FILE stream.
    10911232        virtual void Print( FILE* cfile, int depth ) const;
    10921233
    10931234        /// Queries whether this represents text using a CDATA section.
    1094         bool CDATA()                                    { return cdata; }
     1235        bool CDATA() const                              { return cdata; }
    10951236        /// Turns on or off a CDATA representation of text.
    10961237        void SetCDATA( bool _cdata )    { cdata = _cdata; }
    10971238
    10981239        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
     1240
     1241        virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1242        virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1243
     1244        /** Walk the XML tree visiting this node and all of its children.
     1245        */
     1246        virtual bool Accept( TiXmlVisitor* content ) const;
    10991247
    11001248protected :
     
    11031251        void CopyTo( TiXmlText* target ) const;
    11041252
    1105         virtual void StreamOut ( TIXML_OSTREAM * out ) const;
    11061253        bool Blank() const;     // returns true if all white space and new lines
    11071254        // [internal use]
    11081255        #ifdef TIXML_USE_STL
    1109             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
     1256        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
    11101257        #endif
    11111258
     
    11601307        /// Creates a copy of this Declaration and returns it.
    11611308        virtual TiXmlNode* Clone() const;
    1162         /// Print this declaration to a FILE stream.
    1163         virtual void Print( FILE* cfile, int depth ) const;
     1309        // Print this declaration to a FILE stream.
     1310        virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
     1311        virtual void Print( FILE* cfile, int depth ) const {
     1312                Print( cfile, depth, 0 );
     1313        }
    11641314
    11651315        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
     1316
     1317        virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1318        virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1319
     1320        /** Walk the XML tree visiting this node and all of its children.
     1321        */
     1322        virtual bool Accept( TiXmlVisitor* visitor ) const;
    11661323
    11671324protected:
     
    11691326        // used to be public
    11701327        #ifdef TIXML_USE_STL
    1171             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
    1172         #endif
    1173         virtual void StreamOut ( TIXML_OSTREAM * out) const;
     1328        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
     1329        #endif
    11741330
    11751331private:
     
    11991355        /// Creates a copy of this Unknown and returns it.
    12001356        virtual TiXmlNode* Clone() const;
    1201         /// Print this Unknown to a FILE stream.
     1357        // Print this Unknown to a FILE stream.
    12021358        virtual void Print( FILE* cfile, int depth ) const;
    12031359
    12041360        virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
     1361
     1362        virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1363        virtual TiXmlUnknown*           ToUnknown()         { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1364
     1365        /** Walk the XML tree visiting this node and all of its children.
     1366        */
     1367        virtual bool Accept( TiXmlVisitor* content ) const;
    12051368
    12061369protected:
     
    12081371
    12091372        #ifdef TIXML_USE_STL
    1210             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
    1211         #endif
    1212         virtual void StreamOut ( TIXML_OSTREAM * out ) const;
     1373        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
     1374        #endif
    12131375
    12141376private:
     
    12501412        /// Save a file using the given filename. Returns true if successful.
    12511413        bool SaveFile( const char * filename ) const;
     1414        /** Load a file using the given FILE*. Returns true if successful. Note that this method
     1415                doesn't stream - the entire object pointed at by the FILE*
     1416                will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
     1417                file location. Streaming may be added in the future.
     1418        */
     1419        bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
     1420        /// Save a file using the given FILE*. Returns true if successful.
     1421        bool SaveFile( FILE* ) const;
    12521422
    12531423        #ifdef TIXML_USE_STL
    12541424        bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )                   ///< STL std::string version.
    12551425        {
    1256                 StringToBuffer f( filename );
    1257                 return ( f.buffer && LoadFile( f.buffer, encoding ));
     1426//              StringToBuffer f( filename );
     1427//              return ( f.buffer && LoadFile( f.buffer, encoding ));
     1428                return LoadFile( filename.c_str(), encoding );
    12581429        }
    12591430        bool SaveFile( const std::string& filename ) const              ///< STL std::string version.
    12601431        {
    1261                 StringToBuffer f( filename );
    1262                 return ( f.buffer && SaveFile( f.buffer ));
     1432//              StringToBuffer f( filename );
     1433//              return ( f.buffer && SaveFile( f.buffer ));
     1434                return SaveFile( filename.c_str() );
    12631435        }
    12641436        #endif
     
    12811453                - The ErrorDesc() method will return the name of the error. (very useful)
    12821454                - The ErrorRow() and ErrorCol() will return the location of the error (if known)
    1283         */
     1455        */     
    12841456        bool Error() const                                              { return error; }
    12851457
     
    12921464        int ErrorId()   const                           { return errorId; }
    12931465
    1294         /** Returns the location (if known) of the error. The first column is column 1,
     1466        /** Returns the location (if known) of the error. The first column is column 1, 
    12951467                and the first row is row 1. A value of 0 means the row and column wasn't applicable
    12961468                (memory errors, for example, have no row/column) or the parser lost the error. (An
     
    12991471                @sa SetTabSize, Row, Column
    13001472        */
    1301         int ErrorRow()  { return errorLocation.row+1; }
    1302         int ErrorCol()  { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
     1473        int ErrorRow() const    { return errorLocation.row+1; }
     1474        int ErrorCol() const    { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
    13031475
    13041476        /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
    13051477                to report the correct values for row and column. It does not change the output
    13061478                or input in any way.
    1307 
     1479               
    13081480                By calling this method, with a tab size
    13091481                greater than 0, the row and column of each node and attribute is stored
     
    13331505                state is automatically cleared if you Parse a new XML block.
    13341506        */
    1335         void ClearError()                                               {       error = false;
    1336                                                                                                 errorId = 0;
    1337                                                                                                 errorDesc = "";
    1338                                                                                                 errorLocation.row = errorLocation.col = 0;
    1339                                                                                                 //errorLocation.last = 0;
     1507        void ClearError()                                               {       error = false; 
     1508                                                                                                errorId = 0; 
     1509                                                                                                errorDesc = ""; 
     1510                                                                                                errorLocation.row = errorLocation.col = 0; 
     1511                                                                                                //errorLocation.last = 0; 
    13401512                                                                                        }
    13411513
    1342         /** Dump the document to standard out. */
     1514        /** Write the document to standard out using formatted printing ("pretty print"). */
    13431515        void Print() const                                              { Print( stdout, 0 ); }
     1516
     1517        /* Write the document to a string using formatted printing ("pretty print"). This
     1518                will allocate a character array (new char[]) and return it as a pointer. The
     1519                calling code pust call delete[] on the return char* to avoid a memory leak.
     1520        */
     1521        //char* PrintToMemory() const;
    13441522
    13451523        /// Print this Document to a FILE stream.
     
    13481526        void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
    13491527
     1528        virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1529        virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
     1530
     1531        /** Walk the XML tree visiting this node and all of its children.
     1532        */
     1533        virtual bool Accept( TiXmlVisitor* content ) const;
     1534
    13501535protected :
    1351         virtual void StreamOut ( TIXML_OSTREAM * out) const;
    13521536        // [internal use]
    13531537        virtual TiXmlNode* Clone() const;
    13541538        #ifdef TIXML_USE_STL
    1355             virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
     1539        virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
    13561540        #endif
    13571541
     
    13831567        @endverbatim
    13841568
    1385         Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
     1569        Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
    13861570        easy to write a *lot* of code that looks like:
    13871571
     
    14031587
    14041588        And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
    1405         of such code. A TiXmlHandle checks for null     pointers so it is perfectly safe
     1589        of such code. A TiXmlHandle checks for null     pointers so it is perfectly safe 
    14061590        and correct to use:
    14071591
    14081592        @verbatim
    14091593        TiXmlHandle docHandle( &document );
    1410         TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
     1594        TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
    14111595        if ( child2 )
    14121596        {
     
    14241608
    14251609        @verbatim
    1426         int i=0;
     1610        int i=0; 
    14271611        while ( true )
    14281612        {
    1429                 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
     1613                TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
    14301614                if ( !child )
    14311615                        break;
     
    14351619        @endverbatim
    14361620
    1437         It seems reasonable, but it is in fact two embedded while loops. The Child method is
    1438         a linear walk to find the element, so this code would iterate much more than it needs
     1621        It seems reasonable, but it is in fact two embedded while loops. The Child method is 
     1622        a linear walk to find the element, so this code would iterate much more than it needs 
    14391623        to. Instead, prefer:
    14401624
    14411625        @verbatim
    1442         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
     1626        TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
    14431627
    14441628        for( child; child; child=child->NextSiblingElement() )
     
    14661650        TiXmlHandle FirstChildElement( const char * value ) const;
    14671651
    1468         /** Return a handle to the "index" child with the given name.
     1652        /** Return a handle to the "index" child with the given name. 
    14691653                The first child is 0, the second 1, etc.
    14701654        */
    14711655        TiXmlHandle Child( const char* value, int index ) const;
    1472         /** Return a handle to the "index" child.
     1656        /** Return a handle to the "index" child. 
    14731657                The first child is 0, the second 1, etc.
    14741658        */
    14751659        TiXmlHandle Child( int index ) const;
    1476         /** Return a handle to the "index" child element with the given name.
     1660        /** Return a handle to the "index" child element with the given name. 
    14771661                The first child element is 0, the second 1, etc. Note that only TiXmlElements
    14781662                are indexed: other types are not counted.
    14791663        */
    14801664        TiXmlHandle ChildElement( const char* value, int index ) const;
    1481         /** Return a handle to the "index" child element.
     1665        /** Return a handle to the "index" child element. 
    14821666                The first child element is 0, the second 1, etc. Note that only TiXmlElements
    14831667                are indexed: other types are not counted.
     
    14931677        #endif
    14941678
    1495         /// Return the handle as a TiXmlNode. This may return null.
    1496         TiXmlNode* Node() const                 { return node; }
    1497         /// Return the handle as a TiXmlElement. This may return null.
    1498         TiXmlElement* Element() const   { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
    1499         /// Return the handle as a TiXmlText. This may return null.
    1500         TiXmlText* Text() const                 { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
    1501         /// Return the handle as a TiXmlUnknown. This may return null;
    1502         TiXmlUnknown* Unknown() const                   { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
     1679        /** Return the handle as a TiXmlNode. This may return null.
     1680        */
     1681        TiXmlNode* ToNode() const                       { return node; }
     1682        /** Return the handle as a TiXmlElement. This may return null.
     1683        */
     1684        TiXmlElement* ToElement() const         { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
     1685        /**     Return the handle as a TiXmlText. This may return null.
     1686        */
     1687        TiXmlText* ToText() const                       { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
     1688        /** Return the handle as a TiXmlUnknown. This may return null.
     1689        */
     1690        TiXmlUnknown* ToUnknown() const         { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
     1691
     1692        /** @deprecated use ToNode.
     1693                Return the handle as a TiXmlNode. This may return null.
     1694        */
     1695        TiXmlNode* Node() const                 { return ToNode(); }
     1696        /** @deprecated use ToElement.
     1697                Return the handle as a TiXmlElement. This may return null.
     1698        */
     1699        TiXmlElement* Element() const   { return ToElement(); }
     1700        /**     @deprecated use ToText()
     1701                Return the handle as a TiXmlText. This may return null.
     1702        */
     1703        TiXmlText* Text() const                 { return ToText(); }
     1704        /** @deprecated use ToUnknown()
     1705                Return the handle as a TiXmlUnknown. This may return null.
     1706        */
     1707        TiXmlUnknown* Unknown() const   { return ToUnknown(); }
    15031708
    15041709private:
     
    15061711};
    15071712
     1713
     1714/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
     1715
     1716        -# Print to memory (especially in non-STL mode)
     1717        -# Control formatting (line endings, etc.)
     1718
     1719        When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
     1720        Before calling Accept() you can call methods to control the printing
     1721        of the XML document. After TiXmlNode::Accept() is called, the printed document can
     1722        be accessed via the CStr(), Str(), and Size() methods.
     1723
     1724        TiXmlPrinter uses the Visitor API.
     1725        @verbatim
     1726        TiXmlPrinter printer;
     1727        printer.SetIndent( "\t" );
     1728
     1729        doc.Accept( &printer );
     1730        fprintf( stdout, "%s", printer.CStr() );
     1731        @endverbatim
     1732*/
     1733class TiXmlPrinter : public TiXmlVisitor
     1734{
     1735public:
     1736        TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
     1737                                         buffer(), indent( "    " ), lineBreak( "\n" ) {}
     1738
     1739        virtual bool VisitEnter( const TiXmlDocument& doc );
     1740        virtual bool VisitExit( const TiXmlDocument& doc );
     1741
     1742        virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
     1743        virtual bool VisitExit( const TiXmlElement& element );
     1744
     1745        virtual bool Visit( const TiXmlDeclaration& declaration );
     1746        virtual bool Visit( const TiXmlText& text );
     1747        virtual bool Visit( const TiXmlComment& comment );
     1748        virtual bool Visit( const TiXmlUnknown& unknown );
     1749
     1750        /** Set the indent characters for printing. By default 4 spaces
     1751                but tab (\t) is also useful, or null/empty string for no indentation.
     1752        */
     1753        void SetIndent( const char* _indent )                   { indent = _indent ? _indent : "" ; }
     1754        /// Query the indention string.
     1755        const char* Indent()                                                    { return indent.c_str(); }
     1756        /** Set the line breaking string. By default set to newline (\n).
     1757                Some operating systems prefer other characters, or can be
     1758                set to the null/empty string for no indenation.
     1759        */
     1760        void SetLineBreak( const char* _lineBreak )             { lineBreak = _lineBreak ? _lineBreak : ""; }
     1761        /// Query the current line breaking string.
     1762        const char* LineBreak()                                                 { return lineBreak.c_str(); }
     1763
     1764        /** Switch over to "stream printing" which is the most dense formatting without
     1765                linebreaks. Common when the XML is needed for network transmission.
     1766        */
     1767        void SetStreamPrinting()                                                { indent = "";
     1768                                                                                                          lineBreak = "";
     1769                                                                                                        }       
     1770        /// Return the result.
     1771        const char* CStr()                                                              { return buffer.c_str(); }
     1772        /// Return the length of the result string.
     1773        size_t Size()                                                                   { return buffer.size(); }
     1774
     1775        #ifdef TIXML_USE_STL
     1776        /// Return the result.
     1777        const std::string& Str()                                                { return buffer; }
     1778        #endif
     1779
     1780private:
     1781        void DoIndent() {
     1782                for( int i=0; i<depth; ++i )
     1783                        buffer += indent;
     1784        }
     1785        void DoLineBreak() {
     1786                buffer += lineBreak;
     1787        }
     1788
     1789        int depth;
     1790        bool simpleTextPrint;
     1791        TIXML_STRING buffer;
     1792        TIXML_STRING indent;
     1793        TIXML_STRING lineBreak;
     1794};
     1795
     1796
    15081797#ifdef _MSC_VER
    15091798#pragma warning( pop )
  • code/branches/FICN/src/tinyxml/tinyxmlerror.cc

    r471 r738  
    11/*
    22www.sourceforge.net/projects/tinyxml
    3 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
     3Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
    44
    5 This software is provided 'as-is', without any express or implied 
    6 warranty. In no event will the authors be held liable for any 
     5This software is provided 'as-is', without any express or implied
     6warranty. In no event will the authors be held liable for any
    77damages arising from the use of this software.
    88
    9 Permission is granted to anyone to use this software for any 
    10 purpose, including commercial applications, and to alter it and 
     9Permission is granted to anyone to use this software for any
     10purpose, including commercial applications, and to alter it and
    1111redistribute it freely, subject to the following restrictions:
    1212
     
    5050        "Error null (0) or unexpected EOF found in input stream.",
    5151        "Error parsing CDATA.",
     52        "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
    5253};
  • code/branches/FICN/src/tinyxml/tinyxmlparser.cc

    r471 r738  
    33Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
    44
    5 This software is provided 'as-is', without any express or implied 
    6 warranty. In no event will the authors be held liable for any 
     5This software is provided 'as-is', without any express or implied
     6warranty. In no event will the authors be held liable for any
    77damages arising from the use of this software.
    88
    9 Permission is granted to anyone to use this software for any 
    10 purpose, including commercial applications, and to alter it and 
     9Permission is granted to anyone to use this software for any
     10purpose, including commercial applications, and to alter it and
    1111redistribute it freely, subject to the following restrictions:
    1212
    13 1. The origin of this software must not be misrepresented; you must 
     131. The origin of this software must not be misrepresented; you must
    1414not claim that you wrote the original software. If you use this
    1515software in a product, an acknowledgment in the product documentation
    1616would be appreciated but is not required.
    1717
    18 2. Altered source versions must be plainly marked as such, and 
     182. Altered source versions must be plainly marked as such, and
    1919must not be misrepresented as being the original software.
    2020
    21 3. This notice may not be removed or altered from any source 
     213. This notice may not be removed or altered from any source
    2222distribution.
    2323*/
    2424
    25 #include "tinyxml.h"
    2625#include <ctype.h>
    2726#include <stddef.h>
    2827
     28#include "tinyxml.h"
     29
    2930//#define DEBUG_PARSER
     31#if defined( DEBUG_PARSER )
     32#       if defined( DEBUG ) && defined( _MSC_VER )
     33#               include <windows.h>
     34#               define TIXML_LOG OutputDebugString
     35#       else
     36#               define TIXML_LOG printf
     37#       endif
     38#endif
    3039
    3140// Note tha "PutString" hardcodes the same list. This
    3241// is less flexible than it appears. Changing the entries
    33 // or order will break putstring.       
    34 TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
     42// or order will break putstring.
     43TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
    3544{
    3645        { "&amp;",  5, '&' },
     
    4655// sequence from the lead byte. 1 placed for invalid sequences --
    4756// although the result will be junk, pass it through as much as possible.
    48 // Beware of the non-characters in UTF-8:       
     57// Beware of the non-characters in UTF-8:
    4958//                              ef bb bf (Microsoft "lead bytes")
    5059//                              ef bf be
    51 //                              ef bf bf 
     60//                              ef bf bf
    5261
    5362const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
     
    5564const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
    5665
    57 const int TiXmlBase::utf8ByteTable[256] = 
     66const int TiXmlBase::utf8ByteTable[256] =
    5867{
    5968        //      0       1       2       3       4       5       6       7       8       9       a       b       c       d       e       f
     
    6776                1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0x70 End of ASCII range
    6877                1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0x80 0x80 to 0xc1 invalid
    69                 1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0x90 
    70                 1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0xa0 
    71                 1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0xb0 
     78                1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0x90
     79                1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0xa0
     80                1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      1,      // 0xb0
    7281                1,      1,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      // 0xc0 0xc2 to 0xdf 2 byte
    7382                2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      2,      // 0xd0
     
    8392        const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
    8493
    85         if (input < 0x80) 
     94        if (input < 0x80)
    8695                *length = 1;
    8796        else if ( input < 0x800 )
     
    97106
    98107        // Scary scary fall throughs.
    99         switch (*length) 
     108        switch (*length)
    100109        {
    101110                case 4:
    102                         --output; 
    103                         *output = (char)((input | BYTE_MARK) & BYTE_MASK); 
     111                        --output;
     112                        *output = (char)((input | BYTE_MARK) & BYTE_MASK);
    104113                        input >>= 6;
    105114                case 3:
    106                         --output; 
    107                         *output = (char)((input | BYTE_MARK) & BYTE_MASK); 
     115                        --output;
     116                        *output = (char)((input | BYTE_MARK) & BYTE_MASK);
    108117                        input >>= 6;
    109118                case 2:
    110                         --output; 
    111                         *output = (char)((input | BYTE_MARK) & BYTE_MASK); 
     119                        --output;
     120                        *output = (char)((input | BYTE_MARK) & BYTE_MASK);
    112121                        input >>= 6;
    113122                case 1:
    114                         --output; 
     123                        --output;
    115124                        *output = (char)(input | FIRST_BYTE_MARK[*length]);
    116125        }
     
    122131        // This will only work for low-ascii, everything else is assumed to be a valid
    123132        // letter. I'm not sure this is the best approach, but it is quite tricky trying
    124         // to figure out alhabetical vs. not across encoding. So take a very 
     133        // to figure out alhabetical vs. not across encoding. So take a very
    125134        // conservative approach.
    126135
     
    143152        // This will only work for low-ascii, everything else is assumed to be a valid
    144153        // letter. I'm not sure this is the best approach, but it is quite tricky trying
    145         // to figure out alhabetical vs. not across encoding. So take a very 
     154        // to figure out alhabetical vs. not across encoding. So take a very
    146155        // conservative approach.
    147156
     
    216225                                // bump down to the next line
    217226                                ++row;
    218                                 col = 0;                               
     227                                col = 0;
    219228                                // Eat the character
    220229                                ++p;
     
    258267                                                // 0-width spaces.
    259268                                                if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
    260                                                         p += 3; 
     269                                                        p += 3;
    261270                                                else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
    262                                                         p += 3; 
     271                                                        p += 3;
    263272                                                else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
    264                                                         p += 3; 
     273                                                        p += 3;
    265274                                                else
    266275                                                        { p +=3; ++col; }       // A normal character.
     
    278287                                {
    279288                                        // Eat the 1 to 4 byte utf8 character.
    280                                         int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)];
     289                                        int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
    281290                                        if ( step == 0 )
    282291                                                step = 1;               // Error case from bad encoding, but handle gracefully.
     
    314323                {
    315324                        const unsigned char* pU = (const unsigned char*)p;
    316                        
     325
    317326                        // Skip the stupid Microsoft UTF-8 Byte order marks
    318327                        if (    *(pU+0)==TIXML_UTF_LEAD_0
    319                                  && *(pU+1)==TIXML_UTF_LEAD_1 
     328                                 && *(pU+1)==TIXML_UTF_LEAD_1
    320329                                 && *(pU+2)==TIXML_UTF_LEAD_2 )
    321330                        {
     
    354363
    355364#ifdef TIXML_USE_STL
    356 /*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag )
     365/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
    357366{
    358367        for( ;; )
     
    369378}
    370379
    371 /*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag )
     380/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
    372381{
    373382        //assert( character > 0 && character < 128 );   // else it won't work in utf-8
     
    387396#endif
    388397
     398// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
     399// "assign" optimization removes over 10% of the execution time.
     400//
    389401const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
    390402{
     403        // Oddly, not supported on some comilers,
     404        //name->clear();
     405        // So use this:
    391406        *name = "";
    392407        assert( p );
     
    399414        // hyphens, or colons. (Colons are valid ony for namespaces,
    400415        // but tinyxml can't tell namespaces from names.)
    401         if (    p && *p 
     416        if (    p && *p
    402417                 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
    403418        {
     419                const char* start = p;
    404420                while(          p && *p
    405                                 &&      (               IsAlphaNum( (unsigned char ) *p, encoding ) 
     421                                &&      (               IsAlphaNum( (unsigned char ) *p, encoding )
    406422                                                 || *p == '_'
    407423                                                 || *p == '-'
     
    409425                                                 || *p == ':' ) )
    410426                {
    411                         (*name) += *p;
     427                        //(*name) += *p; // expensive
    412428                        ++p;
     429                }
     430                if ( p-start > 0 ) {
     431                        name->assign( start, p-start );
    413432                }
    414433                return p;
     
    451470                                else if ( *q >= 'A' && *q <= 'F' )
    452471                                        ucs += mult * (*q - 'A' + 10 );
    453                                 else 
     472                                else
    454473                                        return 0;
    455474                                mult *= 16;
     
    474493                                if ( *q >= '0' && *q <= '9' )
    475494                                        ucs += mult * (*q - '0');
    476                                 else 
     495                                else
    477496                                        return 0;
    478497                                mult *= 10;
     
    507526        // So it wasn't an entity, its unrecognized, or something like that.
    508527        *value = *p;    // Don't put back the last one, since we return it!
     528        //*length = 1;  // Leave unrecognized entities - this doesn't really work.
     529                                        // Just writes strange XML.
    509530        return p+1;
    510531}
     
    551572}
    552573
    553 const char* TiXmlBase::ReadText(        const char* p, 
    554                                                                         TIXML_STRING * text, 
    555                                                                         bool trimWhiteSpace, 
    556                                                                         const char* endTag, 
     574const char* TiXmlBase::ReadText(        const char* p,
     575                                                                        TIXML_STRING * text,
     576                                                                        bool trimWhiteSpace,
     577                                                                        const char* endTag,
    557578                                                                        bool caseInsensitive,
    558579                                                                        TiXmlEncoding encoding )
     
    611632                }
    612633        }
    613         return p + strlen( endTag );
     634        if ( p )
     635                p += strlen( endTag );
     636        return p;
    614637}
    615638
    616639#ifdef TIXML_USE_STL
    617640
    618 void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
     641void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
    619642{
    620643        // The basic issue with a document is that we don't know what we're
     
    625648        // sub-tag can orient itself.
    626649
    627         if ( !StreamTo( in, '<', tag ) ) 
     650        if ( !StreamTo( in, '<', tag ) )
    628651        {
    629652                SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
     
    647670                if ( in->good() )
    648671                {
    649                         // We now have something we presume to be a node of 
     672                        // We now have something we presume to be a node of
    650673                        // some sort. Identify it, and call the node to
    651674                        // continue streaming.
     
    756779                        else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
    757780                                encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
    758                         else 
     781                        else
    759782                                encoding = TIXML_ENCODING_LEGACY;
    760783                }
     
    774797
    775798void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
    776 {       
     799{
    777800        // The first error in a chain is more accurate - don't set again!
    778801        if ( error )
     
    811834        }
    812835
    813         // What is this thing? 
     836        // What is this thing?
    814837        // - Elements start with a letter or underscore, but xml is reserved.
    815838        // - Comments: <!--
     
    884907#ifdef TIXML_USE_STL
    885908
    886 void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag)
     909void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
    887910{
    888911        // We're called with some amount of pre-parsing. That is, some of "this"
     
    899922                }
    900923                (*tag) += (char) c ;
    901                
     924
    902925                if ( c == '>' )
    903926                        break;
     
    909932        // If not, identify and stream.
    910933
    911         if (    tag->at( tag->length() - 1 ) == '>' 
     934        if (    tag->at( tag->length() - 1 ) == '>'
    912935                 && tag->at( tag->length() - 2 ) == '/' )
    913936        {
     
    919942                // There is more. Could be:
    920943                //              text
     944                //              cdata text (which looks like another node)
    921945                //              closing tag
    922946                //              another node.
     
    926950
    927951                        // Do we have text?
    928                         if ( in->good() && in->peek() != '<' ) 
     952                        if ( in->good() && in->peek() != '<' )
    929953                        {
    930954                                // Yep, text.
     
    959983                                        return;
    960984                                }
    961                                
     985
    962986                                if ( c == '>' )
    963987                                        break;
     
    965989                                *tag += (char) c;
    966990                                in->get();
     991
     992                                // Early out if we find the CDATA id.
     993                                if ( c == '[' && tag->size() >= 9 )
     994                                {
     995                                        size_t len = tag->size();
     996                                        const char* start = tag->c_str() + len - 9;
     997                                        if ( strcmp( start, "<![CDATA[" ) == 0 ) {
     998                                                assert( !closingTag );
     999                                                break;
     1000                                        }
     1001                                }
    9671002
    9681003                                if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
     
    10681103                        if ( *p  != '>' )
    10691104                        {
    1070                                 if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );             
     1105                                if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
    10711106                                return 0;
    10721107                        }
     
    10801115                        ++p;
    10811116                        p = ReadValue( p, data, encoding );             // Note this is an Element method, and will set the error if one happens.
    1082                         if ( !p || !*p )
     1117                        if ( !p || !*p ) {
     1118                                // We were looking for the end tag, but found nothing.
     1119                                // Fix for [ 1663758 ] Failure to report error on bad XML
     1120                                if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
    10831121                                return 0;
     1122                        }
    10841123
    10851124                        // We should find the end tag now
     
    11061145
    11071146                        attrib->SetDocument( document );
    1108                         const char* pErr = p;
     1147                        pErr = p;
    11091148                        p = attrib->Parse( p, data, encoding );
    11101149
     
    11171156
    11181157                        // Handle the strange case of double attributes:
     1158                        #ifdef TIXML_USE_STL
     1159                        TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
     1160                        #else
    11191161                        TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
     1162                        #endif
    11201163                        if ( node )
    11211164                        {
     
    11681211                        else
    11691212                                delete textNode;
    1170                 } 
    1171                 else 
     1213                }
     1214                else
    11721215                {
    11731216                        // We hit a '<'
     
    11851228                                        p = node->Parse( p, data, encoding );
    11861229                                        LinkEndChild( node );
    1187                                 }                               
     1230                                }
    11881231                                else
    11891232                                {
     
    11991242        {
    12001243                if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
    1201         }       
     1244        }
    12021245        return p;
    12031246}
     
    12051248
    12061249#ifdef TIXML_USE_STL
    1207 void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
     1250void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
    12081251{
    12091252        while ( in->good() )
    12101253        {
    1211                 int c = in->get();     
     1254                int c = in->get();
    12121255                if ( c <= 0 )
    12131256                {
     
    12221265                {
    12231266                        // All is well.
    1224                         return;         
     1267                        return;
    12251268                }
    12261269        }
     
    12631306
    12641307#ifdef TIXML_USE_STL
    1265 void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
     1308void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
    12661309{
    12671310        while ( in->good() )
    12681311        {
    1269                 int c = in->get();     
     1312                int c = in->get();
    12701313                if ( c <= 0 )
    12711314                {
     
    12781321                (*tag) += (char) c;
    12791322
    1280                 if ( c == '>' 
     1323                if ( c == '>'
    12811324                         && tag->at( tag->length() - 2 ) == '-'
    12821325                         && tag->at( tag->length() - 3 ) == '-' )
    12831326                {
    12841327                        // All is well.
    1285                         return;         
     1328                        return;
    12861329                }
    12871330        }
     
    13111354        }
    13121355        p += strlen( startTag );
    1313         p = ReadText( p, &value, false, endTag, false, encoding );
     1356
     1357        // [ 1475201 ] TinyXML parses entities in comments
     1358        // Oops - ReadText doesn't work, because we don't want to parse the entities.
     1359        // p = ReadText( p, &value, false, endTag, false, encoding );
     1360        //
     1361        // from the XML spec:
     1362        /*
     1363         [Definition: Comments may appear anywhere in a document outside other markup; in addition,
     1364                      they may appear within the document type declaration at places allowed by the grammar.
     1365                                  They are not part of the document's character data; an XML processor MAY, but need not,
     1366                                  make it possible for an application to retrieve the text of comments. For compatibility,
     1367                                  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity
     1368                                  references MUST NOT be recognized within comments.
     1369
     1370                                  An example of a comment:
     1371
     1372                                  <!-- declarations for <head> & <body> -->
     1373        */
     1374
     1375    value = "";
     1376        // Keep all the white space.
     1377        while ( p && *p && !StringEqual( p, endTag, false, encoding ) )
     1378        {
     1379                value.append( p, 1 );
     1380                ++p;
     1381        }
     1382        if ( p )
     1383                p += strlen( endTag );
     1384
    13141385        return p;
    13151386}
     
    13211392        if ( !p || !*p ) return 0;
    13221393
    1323         int tabsize = 4;
    1324         if ( document )
    1325                 tabsize = document->TabSize();
     1394//      int tabsize = 4;
     1395//      if ( document )
     1396//              tabsize = document->TabSize();
    13261397
    13271398        if ( data )
     
    13521423                return 0;
    13531424        }
    1354        
     1425
    13551426        const char* end;
    1356 
    1357         if ( *p == '\'' )
     1427        const char SINGLE_QUOTE = '\'';
     1428        const char DOUBLE_QUOTE = '\"';
     1429
     1430        if ( *p == SINGLE_QUOTE )
    13581431        {
    13591432                ++p;
    1360                 end = "\'";
     1433                end = "\'";             // single quote in string
    13611434                p = ReadText( p, &value, false, end, false, encoding );
    13621435        }
    1363         else if ( *p == '"' )
     1436        else if ( *p == DOUBLE_QUOTE )
    13641437        {
    13651438                ++p;
    1366                 end = "\"";
     1439                end = "\"";             // double quote in string
    13671440                p = ReadText( p, &value, false, end, false, encoding );
    13681441        }
     
    13731446                // its best, even without them.
    13741447                value = "";
    1375                 while (    p && *p                                                                              // existence
     1448                while (    p && *p                                                                                      // existence
    13761449                                && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'      // whitespace
    1377                                 && *p != '/' && *p != '>' )                                             // tag end
    1378                 {
     1450                                && *p != '/' && *p != '>' )                                                     // tag end
     1451                {
     1452                        if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
     1453                                // [ 1451649 ] Attribute values with trailing quotes not handled correctly
     1454                                // We did not have an opening quote but seem to have a
     1455                                // closing one. Give up and throw an error.
     1456                                if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
     1457                                return 0;
     1458                        }
    13791459                        value += *p;
    13801460                        ++p;
     
    13851465
    13861466#ifdef TIXML_USE_STL
    1387 void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
    1388 {
    1389         if ( cdata )
    1390         {
    1391                 int c = in->get();     
     1467void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
     1468{
     1469        while ( in->good() )
     1470        {
     1471                int c = in->peek();
     1472                if ( !cdata && (c == '<' ) )
     1473                {
     1474                        return;
     1475                }
    13921476                if ( c <= 0 )
    13931477                {
     
    13991483
    14001484                (*tag) += (char) c;
    1401 
    1402                 if ( c == '>'
    1403                          && tag->at( tag->length() - 2 ) == ']'
    1404                          && tag->at( tag->length() - 3 ) == ']' )
    1405                 {
    1406                         // All is well.
    1407                         return;         
    1408                 }
    1409         }
    1410         else
    1411         {
    1412                 while ( in->good() )
    1413                 {
    1414                         int c = in->peek();     
    1415                         if ( c == '<' )
     1485                in->get();      // "commits" the peek made above
     1486
     1487                if ( cdata && c == '>' && tag->size() >= 3 ) {
     1488                        size_t len = tag->size();
     1489                        if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
     1490                                // terminator of cdata.
    14161491                                return;
    1417                         if ( c <= 0 )
    1418                         {
    1419                                 TiXmlDocument* document = GetDocument();
    1420                                 if ( document )
    1421                                         document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
    1422                                 return;
    1423                         }
    1424 
    1425                         (*tag) += (char) c;
    1426                         in->get();
     1492                        }
    14271493                }
    14281494        }
     
    14641530                }
    14651531
    1466                 TIXML_STRING dummy; 
     1532                TIXML_STRING dummy;
    14671533                p = ReadText( p, &dummy, false, endTag, false, encoding );
    14681534                return p;
     
    14811547
    14821548#ifdef TIXML_USE_STL
    1483 void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
     1549void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
    14841550{
    14851551        while ( in->good() )
     
    15381604                {
    15391605                        TiXmlAttribute attrib;
    1540                         p = attrib.Parse( p, data, _encoding );         
     1606                        p = attrib.Parse( p, data, _encoding );
    15411607                        version = attrib.Value();
    15421608                }
     
    15441610                {
    15451611                        TiXmlAttribute attrib;
    1546                         p = attrib.Parse( p, data, _encoding );         
     1612                        p = attrib.Parse( p, data, _encoding );
    15471613                        encoding = attrib.Value();
    15481614                }
     
    15501616                {
    15511617                        TiXmlAttribute attrib;
    1552                         p = attrib.Parse( p, data, _encoding );         
     1618                        p = attrib.Parse( p, data, _encoding );
    15531619                        standalone = attrib.Value();
    15541620                }
Note: See TracChangeset for help on using the changeset viewer.