00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning( disable : 4530 )
00031 #pragma warning( disable : 4786 )
00032 #endif
00033 
00034 #include <iostream>
00035 #include <ctype.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040 
00041 
00042 #if defined( _DEBUG ) && !defined( DEBUG )
00043 #define DEBUG
00044 #endif
00045 
00046 #if defined( DEBUG ) && defined( _MSC_VER )
00047 #include <windows.h>
00048 #define TIXML_LOG OutputDebugString
00049 #else
00050 #define TIXML_LOG printf
00051 #endif
00052 
00053 
00054 
00055 #define TIXML_USE_STL
00056 
00057 #ifdef TIXML_USE_STL
00058     #include <string>
00059     #ifdef TIXML_NEED_STREAM
00060         #include <istream>
00061         #include <ostream>
00062     #endif
00063     #define TIXML_STRING    std::string
00064     #define TIXML_ISTREAM   std::istream
00065     #define TIXML_OSTREAM   std::ostream
00066 #else
00067     #include "tinystr.h"
00068     #define TIXML_STRING    TiXmlString
00069     #define TIXML_OSTREAM   TiXmlOutStream
00070 #endif
00071 
00072 class TiXmlDocument;
00073 class TiXmlElement;
00074 class TiXmlComment;
00075 class TiXmlUnknown;
00076 class TiXmlAttribute;
00077 class TiXmlText;
00078 class TiXmlDeclaration;
00079 
00080 
00103 class TiXmlBase
00104 {
00105     friend class TiXmlNode;
00106     friend class TiXmlElement;
00107     friend class TiXmlDocument;
00108 
00109 public:
00110     TiXmlBase()                             {}
00111     virtual ~TiXmlBase()                    {}
00112 
00118     virtual void Print( FILE* cfile, int depth ) const = 0;
00119 
00126     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00127 
00129     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00130 
00131 protected:
00132     
00133     
00134     class StringToBuffer
00135     {
00136       public:
00137         StringToBuffer( const TIXML_STRING& str );
00138         ~StringToBuffer();
00139         char* buffer;
00140     };
00141 
00142     static const char*  SkipWhiteSpace( const char* );
00143     inline static bool  IsWhiteSpace( int c )       { return ( isspace( c ) || c == '\n' || c == '\r' ); }
00144 
00145     virtual void StreamOut (TIXML_OSTREAM *) const = 0;
00146 
00147     #ifdef TIXML_USE_STL
00148         static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
00149         static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
00150     #endif
00151 
00152     
00153 
00154 
00155 
00156     static const char* ReadName( const char* p, TIXML_STRING* name );
00157 
00158     
00159 
00160 
00161     static const char* ReadText(    const char* in,             
00162                                     TIXML_STRING* text,         
00163                                     bool ignoreWhiteSpace,      
00164                                     const char* endTag,         
00165                                     bool ignoreCase );          
00166     virtual const char* Parse( const char* p ) = 0;
00167 
00168     
00169     static const char* GetEntity( const char* in, char* value );
00170 
00171     
00172     inline static const char* GetChar( const char* p, char* value )
00173     {
00174         assert( p );
00175         if ( *p == '&' )
00176         {
00177             return GetEntity( p, value );
00178         }
00179         else
00180         {
00181             *value = *p;
00182             return p+1;
00183         }
00184     }
00185 
00186     
00187     
00188     static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
00189 
00190     static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00191 
00192     
00193     bool static StringEqual(    const char* p,
00194                                 const char* endTag,
00195                                 bool ignoreCase );
00196 
00197 
00198     enum
00199     {
00200         TIXML_NO_ERROR = 0,
00201         TIXML_ERROR,
00202         TIXML_ERROR_OPENING_FILE,
00203         TIXML_ERROR_OUT_OF_MEMORY,
00204         TIXML_ERROR_PARSING_ELEMENT,
00205         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00206         TIXML_ERROR_READING_ELEMENT_VALUE,
00207         TIXML_ERROR_READING_ATTRIBUTES,
00208         TIXML_ERROR_PARSING_EMPTY,
00209         TIXML_ERROR_READING_END_TAG,
00210         TIXML_ERROR_PARSING_UNKNOWN,
00211         TIXML_ERROR_PARSING_COMMENT,
00212         TIXML_ERROR_PARSING_DECLARATION,
00213         TIXML_ERROR_DOCUMENT_EMPTY,
00214 
00215         TIXML_ERROR_STRING_COUNT
00216     };
00217     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00218 
00219 private:
00220     struct Entity
00221     {
00222         const char*     str;
00223         unsigned int    strLength;
00224         char            chr;
00225     };
00226     enum
00227     {
00228         NUM_ENTITY = 5,
00229         MAX_ENTITY_LENGTH = 6
00230 
00231     };
00232     static Entity entity[ NUM_ENTITY ];
00233     static bool condenseWhiteSpace;
00234 };
00235 
00236 
00243 class TiXmlNode : public TiXmlBase
00244 {
00245     friend class TiXmlDocument;
00246     friend class TiXmlElement;
00247 
00248 public:
00249     #ifdef TIXML_USE_STL    
00250 
00254         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00255 
00271         friend std::ostream & operator<< (std::ostream& out, const TiXmlNode& base);
00272 
00273     #else
00274         
00275         friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
00276     #endif
00277 
00281     enum NodeType
00282     {
00283         DOCUMENT,
00284         ELEMENT,
00285         COMMENT,
00286         UNKNOWN,
00287         TEXT,
00288         DECLARATION,
00289         TYPECOUNT
00290     };
00291 
00292     virtual ~TiXmlNode();
00293 
00306     const char * Value () const { return value.c_str (); }
00307 
00317     void SetValue (const char * _value) { value = _value;}
00318 
00319     #ifdef TIXML_USE_STL
00320 
00321     void SetValue( const std::string& value )    
00322     {     
00323         StringToBuffer buf( value );
00324         SetValue( buf.buffer ? buf.buffer : "" );       
00325     }   
00326     #endif
00327 
00329     void Clear();
00330 
00332     TiXmlNode* Parent() const                   { return parent; }
00333 
00334     TiXmlNode* FirstChild() const   { return firstChild; }      
00335     TiXmlNode* FirstChild( const char * value ) const;          
00336 
00337     TiXmlNode* LastChild() const    { return lastChild; }       
00338     TiXmlNode* LastChild( const char * value ) const;           
00339 
00340     #ifdef TIXML_USE_STL
00341     TiXmlNode* FirstChild( const std::string& value ) const {   return FirstChild (value.c_str ()); }   
00342     TiXmlNode* LastChild( const std::string& value ) const  {   return LastChild (value.c_str ());  }   
00343     #endif
00344 
00361     TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
00362 
00364     TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
00365 
00366     #ifdef TIXML_USE_STL
00367     TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const   {   return IterateChildren (value.c_str (), previous);  }   
00368     #endif
00369 
00373     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00374 
00375 
00385     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00386 
00390     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00391 
00395     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00396 
00400     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00401 
00403     bool RemoveChild( TiXmlNode* removeThis );
00404 
00406     TiXmlNode* PreviousSibling() const          { return prev; }
00407 
00409     TiXmlNode* PreviousSibling( const char * ) const;
00410 
00411     #ifdef TIXML_USE_STL
00412     TiXmlNode* PreviousSibling( const std::string& value ) const    {   return PreviousSibling (value.c_str ());    }   
00413     TiXmlNode* NextSibling( const std::string& value) const {   return NextSibling (value.c_str ());    }   
00414     #endif
00415 
00417     TiXmlNode* NextSibling() const              { return next; }
00418 
00420     TiXmlNode* NextSibling( const char * ) const;
00421 
00426     TiXmlElement* NextSiblingElement() const;
00427 
00432     TiXmlElement* NextSiblingElement( const char * ) const;
00433 
00434     #ifdef TIXML_USE_STL
00435     TiXmlElement* NextSiblingElement( const std::string& value) const   {   return NextSiblingElement (value.c_str ()); }   
00436     #endif
00437 
00439     TiXmlElement* FirstChildElement()   const;
00440 
00442     TiXmlElement* FirstChildElement( const char * value ) const;
00443 
00444     #ifdef TIXML_USE_STL
00445     TiXmlElement* FirstChildElement( const std::string& value ) const   {   return FirstChildElement (value.c_str ());  }   
00446     #endif
00447 
00449     virtual int Type() const    { return type; }
00450 
00454     TiXmlDocument* GetDocument() const;
00455 
00457     bool NoChildren() const                     { return !firstChild; }
00458 
00459     TiXmlDocument* ToDocument() const       { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } 
00460     TiXmlElement*  ToElement() const        { return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } 
00461     TiXmlComment*  ToComment() const        { return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } 
00462     TiXmlUnknown*  ToUnknown() const        { return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } 
00463     TiXmlText*     ToText()    const        { return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } 
00464     TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } 
00465 
00466     virtual TiXmlNode* Clone() const = 0;
00467 
00468     void  SetUserData( void* user )         { userData = user; }
00469     void* GetUserData()                     { return userData; }
00470 
00471 protected:
00472     TiXmlNode( NodeType type );
00473 
00474     #ifdef TIXML_USE_STL
00475         
00476         virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
00477     #endif
00478 
00479     
00480     TiXmlNode* Identify( const char* start );
00481     void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() );
00482                                                   target->userData = userData; }
00483 
00484     
00485     TIXML_STRING SValue() const { return value ; }
00486 
00487     TiXmlNode*      parent;
00488     NodeType        type;
00489 
00490     TiXmlNode*      firstChild;
00491     TiXmlNode*      lastChild;
00492 
00493     TIXML_STRING    value;
00494 
00495     TiXmlNode*      prev;
00496     TiXmlNode*      next;
00497     void*           userData;
00498 };
00499 
00500 
00510 class TiXmlAttribute : public TiXmlBase
00511 {
00512     friend class TiXmlAttributeSet;
00513 
00514 public:
00516     TiXmlAttribute() : prev( 0 ), next( 0 ) {}
00517 
00518     #ifdef TIXML_USE_STL
00519 
00520     TiXmlAttribute( const std::string& _name, const std::string& _value )
00521     {
00522         name = _name;
00523         value = _value;
00524     }
00525     #endif
00526 
00528     TiXmlAttribute( const char * _name, const char * _value ): name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
00529     const char*     Name()  const       { return name.c_str (); }       
00530     const char*     Value() const       { return value.c_str (); }      
00531     int             IntValue() const;                                   
00532     double          DoubleValue() const;                                
00533 
00534     void SetName( const char* _name )   { name = _name; }               
00535     void SetValue( const char* _value ) { value = _value; }             
00536 
00537     void SetIntValue( int value );                                      
00538     void SetDoubleValue( double value );                                
00539 
00540     #ifdef TIXML_USE_STL
00541 
00542     void SetName( const std::string& _name )    
00543     {   
00544         StringToBuffer buf( _name );
00545         SetName ( buf.buffer ? buf.buffer : "error" );  
00546     }
00548     void SetValue( const std::string& _value )  
00549     {   
00550         StringToBuffer buf( _value );
00551         SetValue( buf.buffer ? buf.buffer : "error" );  
00552     }
00553     #endif
00554 
00556     TiXmlAttribute* Next() const;
00558     TiXmlAttribute* Previous() const;
00559 
00560     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00561     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00562     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00563 
00564     
00565 
00566 
00567 
00568     virtual const char* Parse( const char* p );
00569 
00570     
00571     virtual void Print( FILE* cfile, int depth ) const;
00572 
00573     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00574     
00575     
00576     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00577 
00578 private:
00579     TiXmlDocument*  document;   
00580     TIXML_STRING name;
00581     TIXML_STRING value;
00582     TiXmlAttribute* prev;
00583     TiXmlAttribute* next;
00584 };
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 class TiXmlAttributeSet
00600 {
00601 public:
00602     TiXmlAttributeSet();
00603     ~TiXmlAttributeSet();
00604 
00605     void Add( TiXmlAttribute* attribute );
00606     void Remove( TiXmlAttribute* attribute );
00607 
00608     TiXmlAttribute* First() const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00609     TiXmlAttribute* Last()  const   { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00610     TiXmlAttribute* Find( const char * name ) const;
00611 
00612 private:
00613     TiXmlAttribute sentinel;
00614 };
00615 
00616 
00621 class TiXmlElement : public TiXmlNode
00622 {
00623 public:
00625     TiXmlElement (const char * in_value);
00626 
00627     #ifdef TIXML_USE_STL
00628 
00629     TiXmlElement( const std::string& _value ) :     TiXmlNode( TiXmlNode::ELEMENT )
00630     {
00631         firstChild = lastChild = 0;
00632         value = _value;
00633     }
00634     #endif
00635 
00636     virtual ~TiXmlElement();
00637 
00641     const char* Attribute( const char* name ) const;
00642 
00649     const char* Attribute( const char* name, int* i ) const;
00650 
00654     void SetAttribute( const char* name, const char * value );
00655 
00656     #ifdef TIXML_USE_STL
00657     const char* Attribute( const std::string& name ) const              { return Attribute( name.c_str() ); }
00658     const char* Attribute( const std::string& name, int* i ) const      { return Attribute( name.c_str(), i ); }
00659 
00661     void SetAttribute( const std::string& name, const std::string& value )  
00662     {   
00663         StringToBuffer n( name );
00664         StringToBuffer v( value );
00665         if ( n.buffer && v.buffer )
00666             SetAttribute (n.buffer, v.buffer ); 
00667     }   
00669     void SetAttribute( const std::string& name, int value ) 
00670     {   
00671         StringToBuffer n( name );
00672         if ( n.buffer )
00673             SetAttribute (n.buffer, value); 
00674     }   
00675     #endif
00676 
00680     void SetAttribute( const char * name, int value );
00681 
00684     void RemoveAttribute( const char * name );
00685     #ifdef TIXML_USE_STL
00686     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
00687     #endif
00688 
00689     TiXmlAttribute* FirstAttribute() const  { return attributeSet.First(); }        
00690     TiXmlAttribute* LastAttribute() const   { return attributeSet.Last(); }     
00691 
00692     
00693     virtual TiXmlNode* Clone() const;
00694     
00695 
00696     virtual void Print( FILE* cfile, int depth ) const;
00697 
00698 protected:
00699 
00700     
00701     #ifdef TIXML_USE_STL
00702         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00703     #endif
00704     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00705 
00706     
00707 
00708 
00709 
00710     virtual const char* Parse( const char* p );
00711 
00712     
00713 
00714 
00715 
00716     const char* ReadValue( const char* in );
00717 
00718 private:
00719     TiXmlAttributeSet attributeSet;
00720 };
00721 
00722 
00725 class TiXmlComment : public TiXmlNode
00726 {
00727 public:
00729     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
00730     virtual ~TiXmlComment() {}
00731 
00732     
00733     virtual TiXmlNode* Clone() const;
00734     
00735     virtual void Print( FILE* cfile, int depth ) const;
00736 protected:
00737     
00738     #ifdef TIXML_USE_STL
00739         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00740     #endif
00741     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00742     
00743 
00744 
00745 
00746     virtual const char* Parse( const char* p );
00747 };
00748 
00749 
00752 class TiXmlText : public TiXmlNode
00753 {
00754     friend class TiXmlElement;
00755 public:
00757     TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
00758     {
00759         SetValue( initValue );
00760     }
00761     virtual ~TiXmlText() {}
00762 
00763     #ifdef TIXML_USE_STL
00764 
00765     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
00766     {
00767         SetValue( initValue );
00768     }
00769     #endif
00770 
00771     
00772     virtual void Print( FILE* cfile, int depth ) const;
00773 
00774 protected :
00775     
00776     virtual TiXmlNode* Clone() const;
00777     virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00778     
00779     bool Blank() const; 
00780     
00781 
00782 
00783 
00784     virtual const char* Parse( const char* p );
00785     
00786     #ifdef TIXML_USE_STL
00787         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00788     #endif
00789 };
00790 
00791 
00805 class TiXmlDeclaration : public TiXmlNode
00806 {
00807 public:
00809     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
00810 
00811 #ifdef TIXML_USE_STL
00812 
00813     TiXmlDeclaration(
00814                         const std::string& _version,
00815                         const std::string& _encoding,
00816                         const std::string& _standalone )
00817                     : TiXmlNode( TiXmlNode::DECLARATION )
00818     {
00819         version = _version;
00820         encoding = _encoding;
00821         standalone = _standalone;
00822     }
00823 #endif
00824 
00826     TiXmlDeclaration( const char * _version,
00827                                         const char * _encoding,
00828                                         const char * _standalone );
00829 
00830     virtual ~TiXmlDeclaration() {}
00831 
00833     const char * Version() const        { return version.c_str (); }
00835     const char * Encoding() const       { return encoding.c_str (); }
00837     const char * Standalone() const     { return standalone.c_str (); }
00838 
00839     
00840     virtual TiXmlNode* Clone() const;
00841     
00842     virtual void Print( FILE* cfile, int depth ) const;
00843 
00844 protected:
00845     
00846     #ifdef TIXML_USE_STL
00847         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00848     #endif
00849     virtual void StreamOut ( TIXML_OSTREAM * out) const;
00850     
00851     
00852     
00853 
00854     virtual const char* Parse( const char* p );
00855 
00856 private:
00857     TIXML_STRING version;
00858     TIXML_STRING encoding;
00859     TIXML_STRING standalone;
00860 };
00861 
00862 
00868 class TiXmlUnknown : public TiXmlNode
00869 {
00870 public:
00871     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
00872     virtual ~TiXmlUnknown() {}
00873 
00874     
00875     virtual TiXmlNode* Clone() const;
00876     
00877     virtual void Print( FILE* cfile, int depth ) const;
00878 protected:
00879     
00880     #ifdef TIXML_USE_STL
00881         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00882     #endif
00883     virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00884     
00885 
00886 
00887 
00888     virtual const char* Parse( const char* p );
00889 };
00890 
00891 
00896 class TiXmlDocument : public TiXmlNode
00897 {
00898 public:
00900     TiXmlDocument();
00902     TiXmlDocument( const char * documentName );
00903 
00904     #ifdef TIXML_USE_STL
00905 
00906     TiXmlDocument( const std::string& documentName ) :
00907         TiXmlNode( TiXmlNode::DOCUMENT )
00908     {
00909         value = documentName;
00910         error = false;
00911     }
00912     #endif
00913 
00914     virtual ~TiXmlDocument() {}
00915 
00920     bool LoadFile();
00922     bool SaveFile() const;
00924     bool LoadFile( const char * filename );
00926     bool SaveFile( const char * filename ) const;
00927 
00928     #ifdef TIXML_USE_STL
00929     bool LoadFile( const std::string& filename )            
00930     {
00931         StringToBuffer f( filename );
00932         return ( f.buffer && LoadFile( f.buffer ));
00933     }
00934     bool SaveFile( const std::string& filename ) const      
00935     {
00936         StringToBuffer f( filename );
00937         return ( f.buffer && SaveFile( f.buffer ));
00938     }
00939     #endif
00940 
00942     virtual const char* Parse( const char* p );
00943 
00948     TiXmlElement* RootElement() const       { return FirstChildElement(); }
00949 
00951     bool Error() const                      { return error; }
00952 
00954     const char * ErrorDesc() const  { return errorDesc.c_str (); }
00955 
00959     int ErrorId()   const               { return errorId; }
00960 
00962     void ClearError()                       { error = false; errorId = 0; errorDesc = ""; }
00963 
00965     void Print() const                      { Print( stdout, 0 ); }
00966 
00967     
00968     virtual void Print( FILE* cfile, int depth = 0 ) const;
00969     
00970     void SetError( int err ) {      assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
00971         error   = true;
00972         errorId = err;
00973     errorDesc = errorString[ errorId ]; }
00974 
00975 protected :
00976     virtual void StreamOut ( TIXML_OSTREAM * out) const;
00977     
00978     virtual TiXmlNode* Clone() const;
00979     #ifdef TIXML_USE_STL
00980         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00981     #endif
00982 
00983 private:
00984     bool error;
00985     int  errorId;
00986     TIXML_STRING errorDesc;
00987 };
00988 
00989 #endif
00990