Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

tinyxml.h

00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning( push )
00031 #pragma warning( disable : 4530 )
00032 #pragma warning( disable : 4786 )
00033 #endif
00034 
00035 #include <ctype.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040 
00041 // Help out windows:
00042 #if defined( _DEBUG ) && !defined( DEBUG )
00043 #define DEBUG
00044 #endif
00045 
00046 #ifdef TIXML_USE_STL
00047     #include <string>
00048     #include <iostream>
00049     #include <sstream>
00050     #define TIXML_STRING    std::string
00051 #else
00052     #include "tinystr.h"
00053     #define TIXML_STRING    TiXmlString
00054 #endif
00055 
00056 // Deprecated library function hell. Compilers want to use the
00057 // new safe versions. This probably doesn't fully address the problem,
00058 // but it gets closer. There are too many compilers for me to fully
00059 // test. If you get compilation troubles, undefine TIXML_SAFE
00060 #define TIXML_SAFE
00061 
00062 #ifdef TIXML_SAFE
00063     #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00064         // Microsoft visual studio, version 2005 and higher.
00065         #define TIXML_SNPRINTF _snprintf_s
00066         #define TIXML_SNSCANF  _snscanf_s
00067     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00068         // Microsoft visual studio, version 6 and higher.
00069         //#pragma message( "Using _sn* functions." )
00070         #define TIXML_SNPRINTF _snprintf
00071         #define TIXML_SNSCANF  _snscanf
00072     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00073         // GCC version 3 and higher.s
00074         //#warning( "Using sn* functions." )
00075         #define TIXML_SNPRINTF snprintf
00076         #define TIXML_SNSCANF  snscanf
00077     #endif
00078 #endif  
00079 
00080 class TiXmlDocument;
00081 class TiXmlElement;
00082 class TiXmlComment;
00083 class TiXmlUnknown;
00084 class TiXmlAttribute;
00085 class TiXmlText;
00086 class TiXmlDeclaration;
00087 class TiXmlParsingData;
00088 
00089 const int TIXML_MAJOR_VERSION = 2;
00090 const int TIXML_MINOR_VERSION = 5;
00091 const int TIXML_PATCH_VERSION = 1;
00092 
00093 /*  Internal structure for tracking location of items 
00094     in the XML file.
00095 */
00096 struct TiXmlCursor
00097 {
00098     TiXmlCursor()       { Clear(); }
00099     void Clear()        { row = col = -1; }
00100 
00101     int row;    // 0 based.
00102     int col;    // 0 based.
00103 };
00104 
00105 
00124 class TiXmlVisitor
00125 {
00126 public:
00127     virtual ~TiXmlVisitor() {}
00128 
00130     virtual bool VisitEnter( const TiXmlDocument& doc ) { return true; }
00132     virtual bool VisitExit( const TiXmlDocument& doc )  { return true; }
00133 
00135     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )    { return true; }
00137     virtual bool VisitExit( const TiXmlElement& element )                                           { return true; }
00138 
00140     virtual bool Visit( const TiXmlDeclaration& declaration )       { return true; }
00142     virtual bool Visit( const TiXmlText& text )                     { return true; }
00144     virtual bool Visit( const TiXmlComment& comment )               { return true; }
00146     virtual bool Visit( const TiXmlUnknown& unknown )               { return true; }
00147 };
00148 
00149 // Only used by Attribute::Query functions
00150 enum 
00151 { 
00152     TIXML_SUCCESS,
00153     TIXML_NO_ATTRIBUTE,
00154     TIXML_WRONG_TYPE
00155 };
00156 
00157 
00158 // Used by the parsing routines.
00159 enum TiXmlEncoding
00160 {
00161     TIXML_ENCODING_UNKNOWN,
00162     TIXML_ENCODING_UTF8,
00163     TIXML_ENCODING_LEGACY
00164 };
00165 
00166 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00167 
00190 class TiXmlBase
00191 {
00192     friend class TiXmlNode;
00193     friend class TiXmlElement;
00194     friend class TiXmlDocument;
00195 
00196 public:
00197     TiXmlBase() :   userData(0)     {}
00198     virtual ~TiXmlBase()            {}
00199 
00209     virtual void Print( FILE* cfile, int depth ) const = 0;
00210 
00217     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00218 
00220     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00221 
00240     int Row() const         { return location.row + 1; }
00241     int Column() const      { return location.col + 1; }    
00242 
00243     void  SetUserData( void* user )         { userData = user; }    
00244     void* GetUserData()                     { return userData; }    
00245     const void* GetUserData() const         { return userData; }    
00246 
00247     // Table that returs, for a given lead byte, the total number of bytes
00248     // in the UTF-8 sequence.
00249     static const int utf8ByteTable[256];
00250 
00251     virtual const char* Parse(  const char* p, 
00252                                 TiXmlParsingData* data, 
00253                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00254 
00255     enum
00256     {
00257         TIXML_NO_ERROR = 0,
00258         TIXML_ERROR,
00259         TIXML_ERROR_OPENING_FILE,
00260         TIXML_ERROR_OUT_OF_MEMORY,
00261         TIXML_ERROR_PARSING_ELEMENT,
00262         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00263         TIXML_ERROR_READING_ELEMENT_VALUE,
00264         TIXML_ERROR_READING_ATTRIBUTES,
00265         TIXML_ERROR_PARSING_EMPTY,
00266         TIXML_ERROR_READING_END_TAG,
00267         TIXML_ERROR_PARSING_UNKNOWN,
00268         TIXML_ERROR_PARSING_COMMENT,
00269         TIXML_ERROR_PARSING_DECLARATION,
00270         TIXML_ERROR_DOCUMENT_EMPTY,
00271         TIXML_ERROR_EMBEDDED_NULL,
00272         TIXML_ERROR_PARSING_CDATA,
00273         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00274 
00275         TIXML_ERROR_STRING_COUNT
00276     };
00277 
00278 protected:
00279 
00280     // See STL_STRING_BUG
00281     // Utility class to overcome a bug.
00282     class StringToBuffer
00283     {
00284       public:
00285         StringToBuffer( const TIXML_STRING& str );
00286         ~StringToBuffer();
00287         char* buffer;
00288     };
00289 
00290     static const char*  SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00291     inline static bool  IsWhiteSpace( char c )      
00292     { 
00293         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00294     }
00295     inline static bool  IsWhiteSpace( int c )
00296     {
00297         if ( c < 256 )
00298             return IsWhiteSpace( (char) c );
00299         return false;   // Again, only truly correct for English/Latin...but usually works.
00300     }
00301 
00302     #ifdef TIXML_USE_STL
00303     static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00304     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00305     #endif
00306 
00307     /*  Reads an XML name into the string provided. Returns
00308         a pointer just past the last character of the name,
00309         or 0 if the function has an error.
00310     */
00311     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00312 
00313     /*  Reads text. Returns a pointer past the given end tag.
00314         Wickedly complex options, but it keeps the (sensitive) code in one place.
00315     */
00316     static const char* ReadText(    const char* in,             // where to start
00317                                     TIXML_STRING* text,         // the string read
00318                                     bool ignoreWhiteSpace,      // whether to keep the white space
00319                                     const char* endTag,         // what ends this text
00320                                     bool ignoreCase,            // whether to ignore case in the end tag
00321                                     TiXmlEncoding encoding );   // the current encoding
00322 
00323     // If an entity has been found, transform it into a character.
00324     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00325 
00326     // Get a character, while interpreting entities.
00327     // The length can be from 0 to 4 bytes.
00328     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00329     {
00330         assert( p );
00331         if ( encoding == TIXML_ENCODING_UTF8 )
00332         {
00333             *length = utf8ByteTable[ *((const unsigned char*)p) ];
00334             assert( *length >= 0 && *length < 5 );
00335         }
00336         else
00337         {
00338             *length = 1;
00339         }
00340 
00341         if ( *length == 1 )
00342         {
00343             if ( *p == '&' )
00344                 return GetEntity( p, _value, length, encoding );
00345             *_value = *p;
00346             return p+1;
00347         }
00348         else if ( *length )
00349         {
00350             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
00351                                                 // and the null terminator isn't needed
00352             for( int i=0; p[i] && i<*length; ++i ) {
00353                 _value[i] = p[i];
00354             }
00355             return p + (*length);
00356         }
00357         else
00358         {
00359             // Not valid text.
00360             return 0;
00361         }
00362     }
00363 
00364     // Puts a string to a stream, expanding entities as it goes.
00365     // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
00366     static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00367 
00368     // Return true if the next characters in the stream are any of the endTag sequences.
00369     // Ignore case only works for english, and should only be relied on when comparing
00370     // to English words: StringEqual( p, "version", true ) is fine.
00371     static bool StringEqual(    const char* p,
00372                                 const char* endTag,
00373                                 bool ignoreCase,
00374                                 TiXmlEncoding encoding );
00375 
00376     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00377 
00378     TiXmlCursor location;
00379 
00381     void*           userData;
00382     
00383     // None of these methods are reliable for any language except English.
00384     // Good for approximation, not great for accuracy.
00385     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00386     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00387     inline static int ToLower( int v, TiXmlEncoding encoding )
00388     {
00389         if ( encoding == TIXML_ENCODING_UTF8 )
00390         {
00391             if ( v < 128 ) return tolower( v );
00392             return v;
00393         }
00394         else
00395         {
00396             return tolower( v );
00397         }
00398     }
00399     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00400 
00401 private:
00402     TiXmlBase( const TiXmlBase& );              // not implemented.
00403     void operator=( const TiXmlBase& base );    // not allowed.
00404 
00405     struct Entity
00406     {
00407         const char*     str;
00408         unsigned int    strLength;
00409         char            chr;
00410     };
00411     enum
00412     {
00413         NUM_ENTITY = 5,
00414         MAX_ENTITY_LENGTH = 6
00415 
00416     };
00417     static Entity entity[ NUM_ENTITY ];
00418     static bool condenseWhiteSpace;
00419 };
00420 
00421 
00428 class TiXmlNode : public TiXmlBase
00429 {
00430     friend class TiXmlDocument;
00431     friend class TiXmlElement;
00432 
00433 public:
00434     #ifdef TIXML_USE_STL    
00435 
00439         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00440 
00457         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00458 
00460         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00461 
00462     #endif
00463 
00467     enum NodeType
00468     {
00469         DOCUMENT,
00470         ELEMENT,
00471         COMMENT,
00472         UNKNOWN,
00473         TEXT,
00474         DECLARATION,
00475         TYPECOUNT
00476     };
00477 
00478     virtual ~TiXmlNode();
00479 
00492     const char *Value() const { return value.c_str (); }
00493 
00494     #ifdef TIXML_USE_STL
00495 
00499     const std::string& ValueStr() const { return value; }
00500     #endif
00501 
00511     void SetValue(const char * _value) { value = _value;}
00512 
00513     #ifdef TIXML_USE_STL
00514 
00515     void SetValue( const std::string& _value )  { value = _value; }
00516     #endif
00517 
00519     void Clear();
00520 
00522     TiXmlNode* Parent()                         { return parent; }
00523     const TiXmlNode* Parent() const             { return parent; }
00524 
00525     const TiXmlNode* FirstChild()   const   { return firstChild; }      
00526     TiXmlNode* FirstChild()                 { return firstChild; }
00527     const TiXmlNode* FirstChild( const char * value ) const;            
00528     TiXmlNode* FirstChild( const char * value );                        
00529 
00530     const TiXmlNode* LastChild() const  { return lastChild; }       
00531     TiXmlNode* LastChild()  { return lastChild; }
00532     const TiXmlNode* LastChild( const char * value ) const;         
00533     TiXmlNode* LastChild( const char * value ); 
00534 
00535     #ifdef TIXML_USE_STL
00536     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   
00537     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   
00538     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   
00539     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   
00540     #endif
00541 
00558     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00559     TiXmlNode* IterateChildren( TiXmlNode* previous );
00560 
00562     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00563     TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
00564 
00565     #ifdef TIXML_USE_STL
00566     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   
00567     TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {  return IterateChildren (_value.c_str (), previous); }   
00568     #endif
00569 
00573     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00574 
00575 
00585     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00586 
00590     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00591 
00595     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00596 
00600     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00601 
00603     bool RemoveChild( TiXmlNode* removeThis );
00604 
00606     const TiXmlNode* PreviousSibling() const            { return prev; }
00607     TiXmlNode* PreviousSibling()                        { return prev; }
00608 
00610     const TiXmlNode* PreviousSibling( const char * ) const;
00611     TiXmlNode* PreviousSibling( const char * );
00612 
00613     #ifdef TIXML_USE_STL
00614     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   
00615     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   
00616     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   
00617     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   
00618     #endif
00619 
00621     const TiXmlNode* NextSibling() const                { return next; }
00622     TiXmlNode* NextSibling()                            { return next; }
00623 
00625     const TiXmlNode* NextSibling( const char * ) const;
00626     TiXmlNode* NextSibling( const char * );
00627 
00632     const TiXmlElement* NextSiblingElement() const;
00633     TiXmlElement* NextSiblingElement();
00634 
00639     const TiXmlElement* NextSiblingElement( const char * ) const;
00640     TiXmlElement* NextSiblingElement( const char * );
00641 
00642     #ifdef TIXML_USE_STL
00643     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   
00644     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   
00645     #endif
00646 
00648     const TiXmlElement* FirstChildElement() const;
00649     TiXmlElement* FirstChildElement();
00650 
00652     const TiXmlElement* FirstChildElement( const char * value ) const;
00653     TiXmlElement* FirstChildElement( const char * value );
00654 
00655     #ifdef TIXML_USE_STL
00656     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   
00657     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   
00658     #endif
00659 
00664     int Type() const    { return type; }
00665 
00669     const TiXmlDocument* GetDocument() const;
00670     TiXmlDocument* GetDocument();
00671 
00673     bool NoChildren() const                     { return !firstChild; }
00674 
00675     virtual const TiXmlDocument*    ToDocument()    const { return 0; } 
00676     virtual const TiXmlElement*     ToElement()     const { return 0; } 
00677     virtual const TiXmlComment*     ToComment()     const { return 0; } 
00678     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } 
00679     virtual const TiXmlText*        ToText()        const { return 0; } 
00680     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 
00681 
00682     virtual TiXmlDocument*          ToDocument()    { return 0; } 
00683     virtual TiXmlElement*           ToElement()     { return 0; } 
00684     virtual TiXmlComment*           ToComment()     { return 0; } 
00685     virtual TiXmlUnknown*           ToUnknown()     { return 0; } 
00686     virtual TiXmlText*              ToText()        { return 0; } 
00687     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } 
00688 
00692     virtual TiXmlNode* Clone() const = 0;
00693 
00716     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00717 
00718 protected:
00719     TiXmlNode( NodeType _type );
00720 
00721     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00722     // and the assignment operator.
00723     void CopyTo( TiXmlNode* target ) const;
00724 
00725     #ifdef TIXML_USE_STL
00726         // The real work of the input operator.
00727     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00728     #endif
00729 
00730     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00731     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00732 
00733     TiXmlNode*      parent;
00734     NodeType        type;
00735 
00736     TiXmlNode*      firstChild;
00737     TiXmlNode*      lastChild;
00738 
00739     TIXML_STRING    value;
00740 
00741     TiXmlNode*      prev;
00742     TiXmlNode*      next;
00743 
00744 private:
00745     TiXmlNode( const TiXmlNode& );              // not implemented.
00746     void operator=( const TiXmlNode& base );    // not allowed.
00747 };
00748 
00749 
00757 class TiXmlAttribute : public TiXmlBase
00758 {
00759     friend class TiXmlAttributeSet;
00760 
00761 public:
00763     TiXmlAttribute() : TiXmlBase()
00764     {
00765         document = 0;
00766         prev = next = 0;
00767     }
00768 
00769     #ifdef TIXML_USE_STL
00770 
00771     TiXmlAttribute( const std::string& _name, const std::string& _value )
00772     {
00773         name = _name;
00774         value = _value;
00775         document = 0;
00776         prev = next = 0;
00777     }
00778     #endif
00779 
00781     TiXmlAttribute( const char * _name, const char * _value )
00782     {
00783         name = _name;
00784         value = _value;
00785         document = 0;
00786         prev = next = 0;
00787     }
00788 
00789     const char*     Name()  const       { return name.c_str(); }        
00790     const char*     Value() const       { return value.c_str(); }       
00791     #ifdef TIXML_USE_STL
00792     const std::string& ValueStr() const { return value; }               
00793     #endif
00794     int             IntValue() const;                                   
00795     double          DoubleValue() const;                                
00796 
00797     // Get the tinyxml string representation
00798     const TIXML_STRING& NameTStr() const { return name; }
00799 
00809     int QueryIntValue( int* _value ) const;
00811     int QueryDoubleValue( double* _value ) const;
00812 
00813     void SetName( const char* _name )   { name = _name; }               
00814     void SetValue( const char* _value ) { value = _value; }             
00815 
00816     void SetIntValue( int _value );                                     
00817     void SetDoubleValue( double _value );                               
00818 
00819     #ifdef TIXML_USE_STL
00820 
00821     void SetName( const std::string& _name )    { name = _name; }   
00823     void SetValue( const std::string& _value )  { value = _value; }
00824     #endif
00825 
00827     const TiXmlAttribute* Next() const;
00828     TiXmlAttribute* Next();
00830     const TiXmlAttribute* Previous() const;
00831     TiXmlAttribute* Previous();
00832 
00833     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00834     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00835     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00836 
00837     /*  Attribute parsing starts: first letter of the name
00838                          returns: the next char after the value end quote
00839     */
00840     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00841 
00842     // Prints this Attribute to a FILE stream.
00843     virtual void Print( FILE* cfile, int depth ) const {
00844         Print( cfile, depth, 0 );
00845     }
00846     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00847 
00848     // [internal use]
00849     // Set the document pointer so the attribute can report errors.
00850     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00851 
00852 private:
00853     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00854     void operator=( const TiXmlAttribute& base );   // not allowed.
00855 
00856     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00857     TIXML_STRING name;
00858     TIXML_STRING value;
00859     TiXmlAttribute* prev;
00860     TiXmlAttribute* next;
00861 };
00862 
00863 
00864 /*  A class used to manage a group of attributes.
00865     It is only used internally, both by the ELEMENT and the DECLARATION.
00866     
00867     The set can be changed transparent to the Element and Declaration
00868     classes that use it, but NOT transparent to the Attribute
00869     which has to implement a next() and previous() method. Which makes
00870     it a bit problematic and prevents the use of STL.
00871 
00872     This version is implemented with circular lists because:
00873         - I like circular lists
00874         - it demonstrates some independence from the (typical) doubly linked list.
00875 */
00876 class TiXmlAttributeSet
00877 {
00878 public:
00879     TiXmlAttributeSet();
00880     ~TiXmlAttributeSet();
00881 
00882     void Add( TiXmlAttribute* attribute );
00883     void Remove( TiXmlAttribute* attribute );
00884 
00885     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00886     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00887     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00888     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00889 
00890     const TiXmlAttribute*   Find( const TIXML_STRING& name ) const;
00891     TiXmlAttribute* Find( const TIXML_STRING& name );
00892 
00893 private:
00894     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00895     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00896     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00897     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
00898 
00899     TiXmlAttribute sentinel;
00900 };
00901 
00902 
00907 class TiXmlElement : public TiXmlNode
00908 {
00909 public:
00911     TiXmlElement (const char * in_value);
00912 
00913     #ifdef TIXML_USE_STL
00914 
00915     TiXmlElement( const std::string& _value );
00916     #endif
00917 
00918     TiXmlElement( const TiXmlElement& );
00919 
00920     void operator=( const TiXmlElement& base );
00921 
00922     virtual ~TiXmlElement();
00923 
00927     const char* Attribute( const char* name ) const;
00928 
00935     const char* Attribute( const char* name, int* i ) const;
00936 
00943     const char* Attribute( const char* name, double* d ) const;
00944 
00952     int QueryIntAttribute( const char* name, int* _value ) const;
00954     int QueryDoubleAttribute( const char* name, double* _value ) const;
00956     int QueryFloatAttribute( const char* name, float* _value ) const {
00957         double d;
00958         int result = QueryDoubleAttribute( name, &d );
00959         if ( result == TIXML_SUCCESS ) {
00960             *_value = (float)d;
00961         }
00962         return result;
00963     }
00964     #ifdef TIXML_USE_STL
00965 
00971     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
00972     {
00973         const TiXmlAttribute* node = attributeSet.Find( name );
00974         if ( !node )
00975             return TIXML_NO_ATTRIBUTE;
00976 
00977         std::stringstream sstream( node->ValueStr() );
00978         sstream >> *outValue;
00979         if ( !sstream.fail() )
00980             return TIXML_SUCCESS;
00981         return TIXML_WRONG_TYPE;
00982     }
00983     #endif
00984 
00988     void SetAttribute( const char* name, const char * _value );
00989 
00990     #ifdef TIXML_USE_STL
00991     const char* Attribute( const std::string& name ) const              { return Attribute( name.c_str() ); }
00992     const char* Attribute( const std::string& name, int* i ) const      { return Attribute( name.c_str(), i ); }
00993     const char* Attribute( const std::string& name, double* d ) const   { return Attribute( name.c_str(), d ); }
00994     int QueryIntAttribute( const std::string& name, int* _value ) const { return QueryIntAttribute( name.c_str(), _value ); }
00995     int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
00996 
00998     void SetAttribute( const std::string& name, const std::string& _value );
01000     void SetAttribute( const std::string& name, int _value );
01001     #endif
01002 
01006     void SetAttribute( const char * name, int value );
01007 
01011     void SetDoubleAttribute( const char * name, double value );
01012 
01015     void RemoveAttribute( const char * name );
01016     #ifdef TIXML_USE_STL
01017     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
01018     #endif
01019 
01020     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        
01021     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
01022     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     
01023     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
01024 
01057     const char* GetText() const;
01058 
01060     virtual TiXmlNode* Clone() const;
01061     // Print the Element to a FILE stream.
01062     virtual void Print( FILE* cfile, int depth ) const;
01063 
01064     /*  Attribtue parsing starts: next char past '<'
01065                          returns: next char past '>'
01066     */
01067     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01068 
01069     virtual const TiXmlElement*     ToElement()     const { return this; } 
01070     virtual TiXmlElement*           ToElement()           { return this; } 
01071 
01074     virtual bool Accept( TiXmlVisitor* visitor ) const;
01075 
01076 protected:
01077 
01078     void CopyTo( TiXmlElement* target ) const;
01079     void ClearThis();   // like clear, but initializes 'this' object as well
01080 
01081     // Used to be public [internal use]
01082     #ifdef TIXML_USE_STL
01083     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01084     #endif
01085     /*  [internal use]
01086         Reads the "value" of the element -- another element, or text.
01087         This should terminate with the current end tag.
01088     */
01089     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01090 
01091 private:
01092 
01093     TiXmlAttributeSet attributeSet;
01094 };
01095 
01096 
01099 class TiXmlComment : public TiXmlNode
01100 {
01101 public:
01103     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
01104     TiXmlComment( const TiXmlComment& );
01105     void operator=( const TiXmlComment& base );
01106 
01107     virtual ~TiXmlComment() {}
01108 
01110     virtual TiXmlNode* Clone() const;
01111     // Write this Comment to a FILE stream.
01112     virtual void Print( FILE* cfile, int depth ) const;
01113 
01114     /*  Attribtue parsing starts: at the ! of the !--
01115                          returns: next char past '>'
01116     */
01117     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01118 
01119     virtual const TiXmlComment*  ToComment() const { return this; } 
01120     virtual TiXmlComment*  ToComment() { return this; } 
01121 
01124     virtual bool Accept( TiXmlVisitor* visitor ) const;
01125 
01126 protected:
01127     void CopyTo( TiXmlComment* target ) const;
01128 
01129     // used to be public
01130     #ifdef TIXML_USE_STL
01131     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01132     #endif
01133 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
01134 
01135 private:
01136 
01137 };
01138 
01139 
01145 class TiXmlText : public TiXmlNode
01146 {
01147     friend class TiXmlElement;
01148 public:
01153     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
01154     {
01155         SetValue( initValue );
01156         cdata = false;
01157     }
01158     virtual ~TiXmlText() {}
01159 
01160     #ifdef TIXML_USE_STL
01161 
01162     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
01163     {
01164         SetValue( initValue );
01165         cdata = false;
01166     }
01167     #endif
01168 
01169     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )   { copy.CopyTo( this ); }
01170     void operator=( const TiXmlText& base )                             { base.CopyTo( this ); }
01171 
01172     // Write this text object to a FILE stream.
01173     virtual void Print( FILE* cfile, int depth ) const;
01174 
01176     bool CDATA() const              { return cdata; }
01178     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01179 
01180     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01181 
01182     virtual const TiXmlText* ToText() const { return this; } 
01183     virtual TiXmlText*       ToText()       { return this; } 
01184 
01187     virtual bool Accept( TiXmlVisitor* content ) const;
01188 
01189 protected :
01191     virtual TiXmlNode* Clone() const;
01192     void CopyTo( TiXmlText* target ) const;
01193 
01194     bool Blank() const; // returns true if all white space and new lines
01195     // [internal use]
01196     #ifdef TIXML_USE_STL
01197     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01198     #endif
01199 
01200 private:
01201     bool cdata;         // true if this should be input and output as a CDATA style text element
01202 };
01203 
01204 
01218 class TiXmlDeclaration : public TiXmlNode
01219 {
01220 public:
01222     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
01223 
01224 #ifdef TIXML_USE_STL
01225 
01226     TiXmlDeclaration(   const std::string& _version,
01227                         const std::string& _encoding,
01228                         const std::string& _standalone );
01229 #endif
01230 
01232     TiXmlDeclaration(   const char* _version,
01233                         const char* _encoding,
01234                         const char* _standalone );
01235 
01236     TiXmlDeclaration( const TiXmlDeclaration& copy );
01237     void operator=( const TiXmlDeclaration& copy );
01238 
01239     virtual ~TiXmlDeclaration() {}
01240 
01242     const char *Version() const         { return version.c_str (); }
01244     const char *Encoding() const        { return encoding.c_str (); }
01246     const char *Standalone() const      { return standalone.c_str (); }
01247 
01249     virtual TiXmlNode* Clone() const;
01250     // Print this declaration to a FILE stream.
01251     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01252     virtual void Print( FILE* cfile, int depth ) const {
01253         Print( cfile, depth, 0 );
01254     }
01255 
01256     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01257 
01258     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 
01259     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } 
01260 
01263     virtual bool Accept( TiXmlVisitor* visitor ) const;
01264 
01265 protected:
01266     void CopyTo( TiXmlDeclaration* target ) const;
01267     // used to be public
01268     #ifdef TIXML_USE_STL
01269     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01270     #endif
01271 
01272 private:
01273 
01274     TIXML_STRING version;
01275     TIXML_STRING encoding;
01276     TIXML_STRING standalone;
01277 };
01278 
01279 
01287 class TiXmlUnknown : public TiXmlNode
01288 {
01289 public:
01290     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )    {}
01291     virtual ~TiXmlUnknown() {}
01292 
01293     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )      { copy.CopyTo( this ); }
01294     void operator=( const TiXmlUnknown& copy )                                      { copy.CopyTo( this ); }
01295 
01297     virtual TiXmlNode* Clone() const;
01298     // Print this Unknown to a FILE stream.
01299     virtual void Print( FILE* cfile, int depth ) const;
01300 
01301     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01302 
01303     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } 
01304     virtual TiXmlUnknown*           ToUnknown()     { return this; } 
01305 
01308     virtual bool Accept( TiXmlVisitor* content ) const;
01309 
01310 protected:
01311     void CopyTo( TiXmlUnknown* target ) const;
01312 
01313     #ifdef TIXML_USE_STL
01314     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01315     #endif
01316 
01317 private:
01318 
01319 };
01320 
01321 
01326 class TiXmlDocument : public TiXmlNode
01327 {
01328 public:
01330     TiXmlDocument();
01332     TiXmlDocument( const char * documentName );
01333 
01334     #ifdef TIXML_USE_STL
01335 
01336     TiXmlDocument( const std::string& documentName );
01337     #endif
01338 
01339     TiXmlDocument( const TiXmlDocument& copy );
01340     void operator=( const TiXmlDocument& copy );
01341 
01342     virtual ~TiXmlDocument() {}
01343 
01348     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01350     bool SaveFile() const;
01352     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01354     bool SaveFile( const char * filename ) const;
01360     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01362     bool SaveFile( FILE* ) const;
01363 
01364     #ifdef TIXML_USE_STL
01365     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           
01366     {
01367         StringToBuffer f( filename );
01368         return ( f.buffer && LoadFile( f.buffer, encoding ));
01369     }
01370     bool SaveFile( const std::string& filename ) const      
01371     {
01372         StringToBuffer f( filename );
01373         return ( f.buffer && SaveFile( f.buffer ));
01374     }
01375     #endif
01376 
01381     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01382 
01387     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
01388     TiXmlElement* RootElement()                 { return FirstChildElement(); }
01389 
01395     bool Error() const                      { return error; }
01396 
01398     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01399 
01403     int ErrorId()   const               { return errorId; }
01404 
01412     int ErrorRow()  { return errorLocation.row+1; }
01413     int ErrorCol()  { return errorLocation.col+1; } 
01414 
01439     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01440 
01441     int TabSize() const { return tabsize; }
01442 
01446     void ClearError()                       {   error = false; 
01447                                                 errorId = 0; 
01448                                                 errorDesc = ""; 
01449                                                 errorLocation.row = errorLocation.col = 0; 
01450                                                 //errorLocation.last = 0; 
01451                                             }
01452 
01454     void Print() const                      { Print( stdout, 0 ); }
01455 
01456     /* Write the document to a string using formatted printing ("pretty print"). This
01457         will allocate a character array (new char[]) and return it