tinyxml.h

Go to the documentation of this file.
00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #define TIXML_USE_STL
00030 
00031 #ifdef _MSC_VER
00032 #pragma warning( push )
00033 #pragma warning( disable : 4530 )
00034 #pragma warning( disable : 4786 )
00035 #endif
00036 
00037 #include <ctype.h>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <assert.h>
00042 
00043 // Help out windows:
00044 #if defined( _DEBUG ) && !defined( DEBUG )
00045 #define DEBUG
00046 #endif
00047 
00048 #ifdef TIXML_USE_STL
00049     #include <string>
00050     #include <iostream>
00051     #include <sstream>
00052     #define TIXML_STRING        std::string
00053 #else
00054     #include "tinystr.h"
00055     #define TIXML_STRING        TiXmlString
00056 #endif
00057 
00058 // Deprecated library function hell. Compilers want to use the
00059 // new safe versions. This probably doesn't fully address the problem,
00060 // but it gets closer. There are too many compilers for me to fully
00061 // test. If you get compilation troubles, undefine TIXML_SAFE
00062 #define TIXML_SAFE
00063 
00064 #ifdef TIXML_SAFE
00065     #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00066         // Microsoft visual studio, version 2005 and higher.
00067         #define TIXML_SNPRINTF _snprintf_s
00068         #define TIXML_SNSCANF  _snscanf_s
00069         #define TIXML_SSCANF   sscanf_s
00070     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00071         // Microsoft visual studio, version 6 and higher.
00072         //#pragma message( "Using _sn* functions." )
00073         #define TIXML_SNPRINTF _snprintf
00074         #define TIXML_SNSCANF  _snscanf
00075         #define TIXML_SSCANF   sscanf
00076     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00077         // GCC version 3 and higher.s
00078         //#warning( "Using sn* functions." )
00079         #define TIXML_SNPRINTF snprintf
00080         #define TIXML_SNSCANF  snscanf
00081         #define TIXML_SSCANF   sscanf
00082     #else
00083         #define TIXML_SSCANF   sscanf
00084     #endif
00085 #endif  
00086 
00087 class TiXmlDocument;
00088 class TiXmlElement;
00089 class TiXmlComment;
00090 class TiXmlUnknown;
00091 class TiXmlAttribute;
00092 class TiXmlText;
00093 class TiXmlDeclaration;
00094 class TiXmlParsingData;
00095 
00096 const int TIXML_MAJOR_VERSION = 2;
00097 const int TIXML_MINOR_VERSION = 5;
00098 const int TIXML_PATCH_VERSION = 3;
00099 
00100 /*  Internal structure for tracking location of items 
00101     in the XML file.
00102 */
00103 struct TiXmlCursor
00104 {
00105     TiXmlCursor()       { Clear(); }
00106     void Clear()        { row = col = -1; }
00107 
00108     int row;    // 0 based.
00109     int col;    // 0 based.
00110 };
00111 
00112 
00131 class TiXmlVisitor
00132 {
00133 public:
00134     virtual ~TiXmlVisitor() {}
00135 
00137     virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )         { return true; }
00139     virtual bool VisitExit( const TiXmlDocument& /*doc*/ )          { return true; }
00140 
00142     virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
00144     virtual bool VisitExit( const TiXmlElement& /*element*/ )       { return true; }
00145 
00147     virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
00149     virtual bool Visit( const TiXmlText& /*text*/ )                 { return true; }
00151     virtual bool Visit( const TiXmlComment& /*comment*/ )           { return true; }
00153     virtual bool Visit( const TiXmlUnknown& /*unknown*/ )           { return true; }
00154 };
00155 
00156 // Only used by Attribute::Query functions
00157 enum 
00158 { 
00159     TIXML_SUCCESS,
00160     TIXML_NO_ATTRIBUTE,
00161     TIXML_WRONG_TYPE
00162 };
00163 
00164 
00165 // Used by the parsing routines.
00166 enum TiXmlEncoding
00167 {
00168     TIXML_ENCODING_UNKNOWN,
00169     TIXML_ENCODING_UTF8,
00170     TIXML_ENCODING_LEGACY
00171 };
00172 
00173 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00174 
00197 class TiXmlBase
00198 {
00199     friend class TiXmlNode;
00200     friend class TiXmlElement;
00201     friend class TiXmlDocument;
00202 
00203 public:
00204     TiXmlBase() :   userData(0)     {}
00205     virtual ~TiXmlBase()            {}
00206 
00216     virtual void Print( FILE* cfile, int depth ) const = 0;
00217 
00224     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00225 
00227     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00228 
00247     int Row() const         { return location.row + 1; }
00248     int Column() const      { return location.col + 1; }    
00249 
00250     void  SetUserData( void* user )         { userData = user; }    
00251     void* GetUserData()                     { return userData; }    
00252     const void* GetUserData() const         { return userData; }    
00253 
00254     // Table that returs, for a given lead byte, the total number of bytes
00255     // in the UTF-8 sequence.
00256     static const int utf8ByteTable[256];
00257 
00258     virtual const char* Parse(  const char* p, 
00259                                 TiXmlParsingData* data, 
00260                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00261 
00265     static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
00266 
00267     enum
00268     {
00269         TIXML_NO_ERROR = 0,
00270         TIXML_ERROR,
00271         TIXML_ERROR_OPENING_FILE,
00272         TIXML_ERROR_OUT_OF_MEMORY,
00273         TIXML_ERROR_PARSING_ELEMENT,
00274         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00275         TIXML_ERROR_READING_ELEMENT_VALUE,
00276         TIXML_ERROR_READING_ATTRIBUTES,
00277         TIXML_ERROR_PARSING_EMPTY,
00278         TIXML_ERROR_READING_END_TAG,
00279         TIXML_ERROR_PARSING_UNKNOWN,
00280         TIXML_ERROR_PARSING_COMMENT,
00281         TIXML_ERROR_PARSING_DECLARATION,
00282         TIXML_ERROR_DOCUMENT_EMPTY,
00283         TIXML_ERROR_EMBEDDED_NULL,
00284         TIXML_ERROR_PARSING_CDATA,
00285         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00286 
00287         TIXML_ERROR_STRING_COUNT
00288     };
00289 
00290 protected:
00291 
00292     static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00293     inline static bool IsWhiteSpace( char c )       
00294     { 
00295         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00296     }
00297     inline static bool IsWhiteSpace( int c )
00298     {
00299         if ( c < 256 )
00300             return IsWhiteSpace( (char) c );
00301         return false;   // Again, only truly correct for English/Latin...but usually works.
00302     }
00303 
00304     #ifdef TIXML_USE_STL
00305     static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00306     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00307     #endif
00308 
00309     /*  Reads an XML name into the string provided. Returns
00310         a pointer just past the last character of the name,
00311         or 0 if the function has an error.
00312     */
00313     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00314 
00315     /*  Reads text. Returns a pointer past the given end tag.
00316         Wickedly complex options, but it keeps the (sensitive) code in one place.
00317     */
00318     static const char* ReadText(    const char* in,             // where to start
00319                                     TIXML_STRING* text,         // the string read
00320                                     bool ignoreWhiteSpace,      // whether to keep the white space
00321                                     const char* endTag,         // what ends this text
00322                                     bool ignoreCase,            // whether to ignore case in the end tag
00323                                     TiXmlEncoding encoding );   // the current encoding
00324 
00325     // If an entity has been found, transform it into a character.
00326     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00327 
00328     // Get a character, while interpreting entities.
00329     // The length can be from 0 to 4 bytes.
00330     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00331     {
00332         assert( p );
00333         if ( encoding == TIXML_ENCODING_UTF8 )
00334         {
00335             *length = utf8ByteTable[ *((const unsigned char*)p) ];
00336             assert( *length >= 0 && *length < 5 );
00337         }
00338         else
00339         {
00340             *length = 1;
00341         }
00342 
00343         if ( *length == 1 )
00344         {
00345             if ( *p == '&' )
00346                 return GetEntity( p, _value, length, encoding );
00347             *_value = *p;
00348             return p+1;
00349         }
00350         else if ( *length )
00351         {
00352             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
00353                                                 // and the null terminator isn't needed
00354             for( int i=0; p[i] && i<*length; ++i ) {
00355                 _value[i] = p[i];
00356             }
00357             return p + (*length);
00358         }
00359         else
00360         {
00361             // Not valid text.
00362             return 0;
00363         }
00364     }
00365 
00366     // Return true if the next characters in the stream are any of the endTag sequences.
00367     // Ignore case only works for english, and should only be relied on when comparing
00368     // to English words: StringEqual( p, "version", true ) is fine.
00369     static bool StringEqual(    const char* p,
00370                                 const char* endTag,
00371                                 bool ignoreCase,
00372                                 TiXmlEncoding encoding );
00373 
00374     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00375 
00376     TiXmlCursor location;
00377 
00379     void*           userData;
00380     
00381     // None of these methods are reliable for any language except English.
00382     // Good for approximation, not great for accuracy.
00383     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00384     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00385     inline static int ToLower( int v, TiXmlEncoding encoding )
00386     {
00387         if ( encoding == TIXML_ENCODING_UTF8 )
00388         {
00389             if ( v < 128 ) return tolower( v );
00390             return v;
00391         }
00392         else
00393         {
00394             return tolower( v );
00395         }
00396     }
00397     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00398 
00399 private:
00400     TiXmlBase( const TiXmlBase& );              // not implemented.
00401     void operator=( const TiXmlBase& base );    // not allowed.
00402 
00403     struct Entity
00404     {
00405         const char*     str;
00406         unsigned int    strLength;
00407         char            chr;
00408     };
00409     enum
00410     {
00411         NUM_ENTITY = 5,
00412         MAX_ENTITY_LENGTH = 6
00413 
00414     };
00415     static Entity entity[ NUM_ENTITY ];
00416     static bool condenseWhiteSpace;
00417 };
00418 
00419 
00426 class TiXmlNode : public TiXmlBase
00427 {
00428     friend class TiXmlDocument;
00429     friend class TiXmlElement;
00430 
00431 public:
00432     #ifdef TIXML_USE_STL    
00433 
00437         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00438 
00455         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00456 
00458         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00459 
00460     #endif
00461 
00465     enum NodeType
00466     {
00467         DOCUMENT,
00468         ELEMENT,
00469         COMMENT,
00470         UNKNOWN,
00471         TEXT,
00472         DECLARATION,
00473         TYPECOUNT
00474     };
00475 
00476     virtual ~TiXmlNode();
00477 
00490     const char *Value() const { return value.c_str (); }
00491 
00492     #ifdef TIXML_USE_STL
00493 
00497     const std::string& ValueStr() const { return value; }
00498     #endif
00499 
00500     const TIXML_STRING& ValueTStr() const { return value; }
00501 
00511     void SetValue(const char * _value) { value = _value;}
00512 
00513     #ifdef TIXML_USE_STL
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 
00529     TiXmlNode* FirstChild( const char * _value ) {
00530         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00531         // call the method, cast the return back to non-const.
00532         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00533     }
00534     const TiXmlNode* LastChild() const  { return lastChild; }       
00535     TiXmlNode* LastChild()  { return lastChild; }
00536     
00537     const TiXmlNode* LastChild( const char * value ) const;         
00538     TiXmlNode* LastChild( const char * _value ) {
00539         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00540     }
00541 
00542     #ifdef TIXML_USE_STL
00543     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   
00544     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   
00545     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   
00546     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   
00547     #endif
00548 
00565     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00566     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00567         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00568     }
00569 
00571     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00572     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00573         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00574     }
00575 
00576     #ifdef TIXML_USE_STL
00577     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   
00578     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous); }   
00579     #endif
00580 
00584     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00585 
00586 
00596     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00597 
00601     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00602 
00606     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00607 
00611     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00612 
00614     bool RemoveChild( TiXmlNode* removeThis );
00615 
00617     const TiXmlNode* PreviousSibling() const            { return prev; }
00618     TiXmlNode* PreviousSibling()                        { return prev; }
00619 
00621     const TiXmlNode* PreviousSibling( const char * ) const;
00622     TiXmlNode* PreviousSibling( const char *_prev ) {
00623         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00624     }
00625 
00626     #ifdef TIXML_USE_STL
00627     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   
00628     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   
00629     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   
00630     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   
00631     #endif
00632 
00634     const TiXmlNode* NextSibling() const                { return next; }
00635     TiXmlNode* NextSibling()                            { return next; }
00636 
00638     const TiXmlNode* NextSibling( const char * ) const;
00639     TiXmlNode* NextSibling( const char* _next ) {
00640         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00641     }
00642 
00647     const TiXmlElement* NextSiblingElement() const;
00648     TiXmlElement* NextSiblingElement() {
00649         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00650     }
00651 
00656     const TiXmlElement* NextSiblingElement( const char * ) const;
00657     TiXmlElement* NextSiblingElement( const char *_next ) {
00658         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00659     }
00660 
00661     #ifdef TIXML_USE_STL
00662     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   
00663     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   
00664     #endif
00665 
00667     const TiXmlElement* FirstChildElement() const;
00668     TiXmlElement* FirstChildElement() {
00669         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00670     }
00671 
00673     const TiXmlElement* FirstChildElement( const char * _value ) const;
00674     TiXmlElement* FirstChildElement( const char * _value ) {
00675         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00676     }
00677 
00678     #ifdef TIXML_USE_STL
00679     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   
00680     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   
00681     #endif
00682 
00687     int Type() const    { return type; }
00688 
00692     const TiXmlDocument* GetDocument() const;
00693     TiXmlDocument* GetDocument() {
00694         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00695     }
00696 
00698     bool NoChildren() const                     { return !firstChild; }
00699 
00700     virtual const TiXmlDocument*    ToDocument()    const { return 0; } 
00701     virtual const TiXmlElement*     ToElement()     const { return 0; } 
00702     virtual const TiXmlComment*     ToComment()     const { return 0; } 
00703     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } 
00704     virtual const TiXmlText*        ToText()        const { return 0; } 
00705     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 
00706 
00707     virtual TiXmlDocument*          ToDocument()    { return 0; } 
00708     virtual TiXmlElement*           ToElement()     { return 0; } 
00709     virtual TiXmlComment*           ToComment()     { return 0; } 
00710     virtual TiXmlUnknown*           ToUnknown()     { return 0; } 
00711     virtual TiXmlText*              ToText()        { return 0; } 
00712     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } 
00713 
00717     virtual TiXmlNode* Clone() const = 0;
00718 
00741     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00742 
00743 protected:
00744     TiXmlNode( NodeType _type );
00745 
00746     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00747     // and the assignment operator.
00748     void CopyTo( TiXmlNode* target ) const;
00749 
00750     #ifdef TIXML_USE_STL
00751         // The real work of the input operator.
00752     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00753     #endif
00754 
00755     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00756     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00757 
00758     TiXmlNode*      parent;
00759     NodeType        type;
00760 
00761     TiXmlNode*      firstChild;
00762     TiXmlNode*      lastChild;
00763 
00764     TIXML_STRING    value;
00765 
00766     TiXmlNode*      prev;
00767     TiXmlNode*      next;
00768 
00769 private:
00770     TiXmlNode( const TiXmlNode& );              // not implemented.
00771     void operator=( const TiXmlNode& base );    // not allowed.
00772 };
00773 
00774 
00782 class TiXmlAttribute : public TiXmlBase
00783 {
00784     friend class TiXmlAttributeSet;
00785 
00786 public:
00788     TiXmlAttribute() : TiXmlBase()
00789     {
00790         document = 0;
00791         prev = next = 0;
00792     }
00793 
00794     #ifdef TIXML_USE_STL
00796     TiXmlAttribute( const std::string& _name, const std::string& _value )
00797     {
00798         name = _name;
00799         value = _value;
00800         document = 0;
00801         prev = next = 0;
00802     }
00803     #endif
00804 
00806     TiXmlAttribute( const char * _name, const char * _value )
00807     {
00808         name = _name;
00809         value = _value;
00810         document = 0;
00811         prev = next = 0;
00812     }
00813 
00814     const char*     Name()  const       { return name.c_str(); }        
00815     const char*     Value() const       { return value.c_str(); }       
00816     #ifdef TIXML_USE_STL
00817     const std::string& ValueStr() const { return value; }               
00818     #endif
00819     int             IntValue() const;                                   
00820     double          DoubleValue() const;                                
00821 
00822     // Get the tinyxml string representation
00823     const TIXML_STRING& NameTStr() const { return name; }
00824 
00834     int QueryIntValue( int* _value ) const;
00836     int QueryDoubleValue( double* _value ) const;
00837 
00838     void SetName( const char* _name )   { name = _name; }               
00839     void SetValue( const char* _value ) { value = _value; }             
00840 
00841     void SetIntValue( int _value );                                     
00842     void SetDoubleValue( double _value );                               
00843 
00844     #ifdef TIXML_USE_STL
00846     void SetName( const std::string& _name )    { name = _name; }   
00848     void SetValue( const std::string& _value )  { value = _value; }
00849     #endif
00850 
00852     const TiXmlAttribute* Next() const;
00853     TiXmlAttribute* Next() {
00854         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00855     }
00856 
00858     const TiXmlAttribute* Previous() const;
00859     TiXmlAttribute* Previous() {
00860         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00861     }
00862 
00863     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00864     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00865     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00866 
00867     /*  Attribute parsing starts: first letter of the name
00868                          returns: the next char after the value end quote
00869     */
00870     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00871 
00872     // Prints this Attribute to a FILE stream.
00873     virtual void Print( FILE* cfile, int depth ) const {
00874         Print( cfile, depth, 0 );
00875     }
00876     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00877 
00878     // [internal use]
00879     // Set the document pointer so the attribute can report errors.
00880     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00881 
00882 private:
00883     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00884     void operator=( const TiXmlAttribute& base );   // not allowed.
00885 
00886     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00887     TIXML_STRING name;
00888     TIXML_STRING value;
00889     TiXmlAttribute* prev;
00890     TiXmlAttribute* next;
00891 };
00892 
00893 
00894 /*  A class used to manage a group of attributes.
00895     It is only used internally, both by the ELEMENT and the DECLARATION.
00896     
00897     The set can be changed transparent to the Element and Declaration
00898     classes that use it, but NOT transparent to the Attribute
00899     which has to implement a next() and previous() method. Which makes
00900     it a bit problematic and prevents the use of STL.
00901 
00902     This version is implemented with circular lists because:
00903         - I like circular lists
00904         - it demonstrates some independence from the (typical) doubly linked list.
00905 */
00906 class TiXmlAttributeSet
00907 {
00908 public:
00909     TiXmlAttributeSet();
00910     ~TiXmlAttributeSet();
00911 
00912     void Add( TiXmlAttribute* attribute );
00913     void Remove( TiXmlAttribute* attribute );
00914 
00915     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00916     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00917     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00918     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00919 
00920     const TiXmlAttribute*   Find( const char* _name ) const;
00921     TiXmlAttribute* Find( const char* _name ) {
00922         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00923     }
00924     #ifdef TIXML_USE_STL
00925     const TiXmlAttribute*   Find( const std::string& _name ) const;
00926     TiXmlAttribute* Find( const std::string& _name ) {
00927         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00928     }
00929 
00930     #endif
00931 
00932 private:
00933     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00934     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00935     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00936     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
00937 
00938     TiXmlAttribute sentinel;
00939 };
00940 
00941 
00946 class TiXmlElement : public TiXmlNode
00947 {
00948 public:
00950     TiXmlElement (const char * in_value);
00951 
00952     #ifdef TIXML_USE_STL
00954     TiXmlElement( const std::string& _value );
00955     #endif
00956 
00957     TiXmlElement( const TiXmlElement& );
00958 
00959     void operator=( const TiXmlElement& base );
00960 
00961     virtual ~TiXmlElement();
00962 
00966     const char* Attribute( const char* name ) const;
00967 
00974     const char* Attribute( const char* name, int* i ) const;
00975 
00982     const char* Attribute( const char* name, double* d ) const;
00983 
00991     int QueryIntAttribute( const char* name, int* _value ) const;
00993     int QueryDoubleAttribute( const char* name, double* _value ) const;
00995     int QueryFloatAttribute( const char* name, float* _value ) const {
00996         double d;
00997         int result = QueryDoubleAttribute( name, &d );
00998         if ( result == TIXML_SUCCESS ) {
00999             *_value = (float)d;
01000         }
01001         return result;
01002     }
01003 
01004     #ifdef TIXML_USE_STL
01005 
01013     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01014     {
01015         const TiXmlAttribute* node = attributeSet.Find( name );
01016         if ( !node )
01017             return TIXML_NO_ATTRIBUTE;
01018 
01019         std::stringstream sstream( node->ValueStr() );
01020         sstream >> *outValue;
01021         if ( !sstream.fail() )
01022             return TIXML_SUCCESS;
01023         return TIXML_WRONG_TYPE;
01024     }
01025     /*
01026      This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
01027      but template specialization is hard to get working cross-compiler. Leaving the bug for now.
01028      
01029     // The above will fail for std::string because the space character is used as a seperator.
01030     // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
01031     template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
01032     {
01033         const TiXmlAttribute* node = attributeSet.Find( name );
01034         if ( !node )
01035             return TIXML_NO_ATTRIBUTE;
01036         *outValue = node->ValueStr();
01037         return TIXML_SUCCESS;
01038     }
01039     */
01040     #endif
01041 
01045     void SetAttribute( const char* name, const char * _value );
01046 
01047     #ifdef TIXML_USE_STL
01048     const std::string* Attribute( const std::string& name ) const;
01049     const std::string* Attribute( const std::string& name, int* i ) const;
01050     const std::string* Attribute( const std::string& name, double* d ) const;
01051     int QueryIntAttribute( const std::string& name, int* _value ) const;
01052     int QueryDoubleAttribute( const std::string& name, double* _value ) const;
01053 
01055     void SetAttribute( const std::string& name, const std::string& _value );
01057     void SetAttribute( const std::string& name, int _value );
01058     #endif
01059 
01063     void SetAttribute( const char * name, int value );
01064 
01068     void SetDoubleAttribute( const char * name, double value );
01069 
01072     void RemoveAttribute( const char * name );
01073     #ifdef TIXML_USE_STL
01074     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
01075     #endif
01076 
01077     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        
01078     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
01079     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     
01080     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
01081 
01114     const char* GetText() const;
01115 
01117     virtual TiXmlNode* Clone() const;
01118     // Print the Element to a FILE stream.
01119     virtual void Print( FILE* cfile, int depth ) const;
01120 
01121     /*  Attribtue parsing starts: next char past '<'
01122                          returns: next char past '>'
01123     */
01124     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01125 
01126     virtual const TiXmlElement*     ToElement()     const { return this; } 
01127     virtual TiXmlElement*           ToElement()           { return this; } 
01128 
01131     virtual bool Accept( TiXmlVisitor* visitor ) const;
01132 
01133 protected:
01134 
01135     void CopyTo( TiXmlElement* target ) const;
01136     void ClearThis();   // like clear, but initializes 'this' object as well
01137 
01138     // Used to be public [internal use]
01139     #ifdef TIXML_USE_STL
01140     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01141     #endif
01142     /*  [internal use]
01143         Reads the "value" of the element -- another element, or text.
01144         This should terminate with the current end tag.
01145     */
01146     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01147 
01148 private:
01149 
01150     TiXmlAttributeSet attributeSet;
01151 };
01152 
01153 
01156 class TiXmlComment : public TiXmlNode
01157 {
01158 public:
01160     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
01162     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
01163         SetValue( _value );
01164     }
01165     TiXmlComment( const TiXmlComment& );
01166     void operator=( const TiXmlComment& base );
01167 
01168     virtual ~TiXmlComment() {}
01169 
01171     virtual TiXmlNode* Clone() const;
01172     // Write this Comment to a FILE stream.
01173     virtual void Print( FILE* cfile, int depth ) const;
01174 
01175     /*  Attribtue parsing starts: at the ! of the !--
01176                          returns: next char past '>'
01177     */
01178     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01179 
01180     virtual const TiXmlComment*  ToComment() const { return this; } 
01181     virtual TiXmlComment*  ToComment() { return this; } 
01182 
01185     virtual bool Accept( TiXmlVisitor* visitor ) const;
01186 
01187 protected:
01188     void CopyTo( TiXmlComment* target ) const;
01189 
01190     // used to be public
01191     #ifdef TIXML_USE_STL
01192     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01193     #endif
01194 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
01195 
01196 private:
01197 
01198 };
01199 
01200 
01206 class TiXmlText : public TiXmlNode
01207 {
01208     friend class TiXmlElement;
01209 public:
01214     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
01215     {
01216         SetValue( initValue );
01217         cdata = false;
01218     }
01219     virtual ~TiXmlText() {}
01220 
01221     #ifdef TIXML_USE_STL
01223     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
01224     {
01225         SetValue( initValue );
01226         cdata = false;
01227     }
01228     #endif
01229 
01230     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )   { copy.CopyTo( this ); }
01231     void operator=( const TiXmlText& base )                             { base.CopyTo( this ); }
01232 
01233     // Write this text object to a FILE stream.
01234     virtual void Print( FILE* cfile, int depth ) const;
01235 
01237     bool CDATA() const              { return cdata; }
01239     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01240 
01241     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01242 
01243     virtual const TiXmlText* ToText() const { return this; } 
01244     virtual TiXmlText*       ToText()       { return this; } 
01245 
01248     virtual bool Accept( TiXmlVisitor* content ) const;
01249 
01250 protected :
01252     virtual TiXmlNode* Clone() const;
01253     void CopyTo( TiXmlText* target ) const;
01254 
01255     bool Blank() const; // returns true if all white space and new lines
01256     // [internal use]
01257     #ifdef TIXML_USE_STL
01258     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01259     #endif
01260 
01261 private:
01262     bool cdata;         // true if this should be input and output as a CDATA style text element
01263 };
01264 
01265 
01279 class TiXmlDeclaration : public TiXmlNode
01280 {
01281 public:
01283     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
01284 
01285 #ifdef TIXML_USE_STL
01287     TiXmlDeclaration(   const std::string& _version,
01288                         const std::string& _encoding,
01289                         const std::string& _standalone );
01290 #endif
01291 
01293     TiXmlDeclaration(   const char* _version,
01294                         const char* _encoding,
01295                         const char* _standalone );
01296 
01297     TiXmlDeclaration( const TiXmlDeclaration& copy );
01298     void operator=( const TiXmlDeclaration& copy );
01299 
01300     virtual ~TiXmlDeclaration() {}
01301 
01303     const char *Version() const         { return version.c_str (); }
01305     const char *Encoding() const        { return encoding.c_str (); }
01307     const char *Standalone() const      { return standalone.c_str (); }
01308 
01310     virtual TiXmlNode* Clone() const;
01311     // Print this declaration to a FILE stream.
01312     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01313     virtual void Print( FILE* cfile, int depth ) const {
01314         Print( cfile, depth, 0 );
01315     }
01316 
01317     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01318 
01319     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 
01320     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } 
01321 
01324     virtual bool Accept( TiXmlVisitor* visitor ) const;
01325 
01326 protected:
01327     void CopyTo( TiXmlDeclaration* target ) const;
01328     // used to be public
01329     #ifdef TIXML_USE_STL
01330     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01331     #endif
01332 
01333 private:
01334 
01335     TIXML_STRING version;
01336     TIXML_STRING encoding;
01337     TIXML_STRING standalone;
01338 };
01339 
01340 
01348 class TiXmlUnknown : public TiXmlNode
01349 {
01350 public:
01351     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )    {}
01352     virtual ~TiXmlUnknown() {}
01353 
01354     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )      { copy.CopyTo( this ); }
01355     void operator=( const TiXmlUnknown& copy )                                      { copy.CopyTo( this ); }
01356 
01358     virtual TiXmlNode* Clone() const;
01359     // Print this Unknown to a FILE stream.
01360     virtual void Print( FILE* cfile, int depth ) const;
01361 
01362     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01363 
01364     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } 
01365     virtual TiXmlUnknown*           ToUnknown()     { return this; } 
01366 
01369     virtual bool Accept( TiXmlVisitor* content ) const;
01370 
01371 protected:
01372     void CopyTo( TiXmlUnknown* target ) const;
01373 
01374     #ifdef TIXML_USE_STL
01375     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01376     #endif
01377 
01378 private:
01379 
01380 };
01381 
01382 
01387 class TiXmlDocument : public TiXmlNode
01388 {
01389 public:
01391     TiXmlDocument();
01393     TiXmlDocument( const char * documentName );
01394 
01395     #ifdef TIXML_USE_STL
01397     TiXmlDocument( const std::string& documentName );
01398     #endif
01399 
01400     TiXmlDocument( const TiXmlDocument& copy );
01401     void operator=( const TiXmlDocument& copy );
01402 
01403     virtual ~TiXmlDocument() {}
01404 
01409     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01411     bool SaveFile() const;
01413     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01415     bool SaveFile( const char * filename ) const;
01421     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01423     bool SaveFile( FILE* ) const;
01424 
01425     #ifdef TIXML_USE_STL
01426     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           
01427     {
01428 //      StringToBuffer f( filename );
01429 //      return ( f.buffer && LoadFile( f.buffer, encoding ));
01430         return LoadFile( filename.c_str(), encoding );
01431     }
01432     bool SaveFile( const std::string& filename ) const      
01433     {
01434 //      StringToBuffer f( filename );
01435 //      return ( f.buffer && SaveFile( f.buffer ));
01436         return SaveFile( filename.c_str() );
01437     }
01438     #endif
01439 
01444     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01445 
01450     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
01451     TiXmlElement* RootElement()                 { return FirstChildElement(); }
01452 
01458     bool Error() const                      { return error; }
01459 
01461     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01462 
01466     int ErrorId()   const               { return errorId; }
01467 
01475     int ErrorRow() const    { return errorLocation.row+1; }
01476     int ErrorCol() const    { return errorLocation.col+1; } 
01477 
01502     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01503 
01504     int TabSize() const { return tabsize; }
01505 
01509     void ClearError()                       {   error = false; 
01510                                                 errorId = 0; 
01511                                                 errorDesc = ""; 
01512                                                 errorLocation.row = errorLocation.col = 0; 
01513                                                 //errorLocation.last = 0; 
01514                                             }
01515 
01517     void Print() const                      { Print( stdout, 0 ); }
01518 
01519     /* Write the document to a string using formatted printing ("pretty print"). This
01520         will allocate a character array (new char[]) and return it as a pointer. The
01521         calling code pust call delete[] on the return char* to avoid a memory leak.
01522     */
01523     //char* PrintToMemory() const; 
01524 
01526     virtual void Print( FILE* cfile, int depth = 0 ) const;
01527     // [internal use]
01528     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01529 
01530     virtual const TiXmlDocument*    ToDocument()    const { return this; } 
01531     virtual TiXmlDocument*          ToDocument()          { return this; } 
01532 
01535     virtual bool Accept( TiXmlVisitor* content ) const;
01536 
01537 protected :
01538     // [internal use]
01539     virtual TiXmlNode* Clone() const;
01540     #ifdef TIXML_USE_STL
01541     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01542     #endif
01543 
01544 private:
01545     void CopyTo( TiXmlDocument* target ) const;
01546 
01547     bool error;
01548     int  errorId;
01549     TIXML_STRING errorDesc;
01550     int tabsize;
01551     TiXmlCursor errorLocation;
01552     bool useMicrosoftBOM;       // the UTF-8 BOM were found when read. Note this, and try to write.
01553 };
01554 
01555 
01636 class TiXmlHandle
01637 {
01638 public:
01640     TiXmlHandle( TiXmlNode* _node )                 { this->node = _node; }
01642     TiXmlHandle( const TiXmlHandle& ref )           { this->node = ref.node; }
01643     TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
01644 
01646     TiXmlHandle FirstChild() const;
01648     TiXmlHandle FirstChild( const char * value ) const;
01650     TiXmlHandle FirstChildElement() const;
01652     TiXmlHandle FirstChildElement( const char * value ) const;
01653 
01657     TiXmlHandle Child( const char* value, int index ) const;
01661     TiXmlHandle Child( int index ) const;
01666     TiXmlHandle ChildElement( const char* value, int index ) const;
01671     TiXmlHandle ChildElement( int index ) const;
01672 
01673     #ifdef TIXML_USE_STL
01674     TiXmlHandle FirstChild( const std::string& _value ) const               { return FirstChild( _value.c_str() ); }
01675     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01676 
01677     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
01678     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01679     #endif
01680 
01683     TiXmlNode* ToNode() const           { return node; } 
01686     TiXmlElement* ToElement() const     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01689     TiXmlText* ToText() const           { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01692     TiXmlUnknown* ToUnknown() const     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01693 
01697     TiXmlNode* Node() const         { return ToNode(); } 
01701     TiXmlElement* Element() const   { return ToElement(); }
01705     TiXmlText* Text() const         { return ToText(); }
01709     TiXmlUnknown* Unknown() const   { return ToUnknown(); }
01710 
01711 private:
01712     TiXmlNode* node;
01713 };
01714 
01715 
01735 class TiXmlPrinter : public TiXmlVisitor
01736 {
01737 public:
01738     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01739                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
01740 
01741     virtual bool VisitEnter( const TiXmlDocument& doc );
01742     virtual bool VisitExit( const TiXmlDocument& doc );
01743 
01744     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01745     virtual bool VisitExit( const TiXmlElement& element );
01746 
01747     virtual bool Visit( const TiXmlDeclaration& declaration );
01748     virtual bool Visit( const TiXmlText& text );
01749     virtual bool Visit( const TiXmlComment& comment );
01750     virtual bool Visit( const TiXmlUnknown& unknown );
01751 
01755     void SetIndent( const char* _indent )           { indent = _indent ? _indent : "" ; }
01757     const char* Indent()                            { return indent.c_str(); }
01762     void SetLineBreak( const char* _lineBreak )     { lineBreak = _lineBreak ? _lineBreak : ""; }
01764     const char* LineBreak()                         { return lineBreak.c_str(); }
01765 
01769     void SetStreamPrinting()                        { indent = "";
01770                                                       lineBreak = "";
01771                                                     }   
01773     const char* CStr()                              { return buffer.c_str(); }
01775     size_t Size()                                   { return buffer.size(); }
01776 
01777     #ifdef TIXML_USE_STL
01779     const std::string& Str()                        { return buffer; }
01780     #endif
01781 
01782 private:
01783     void DoIndent() {
01784         for( int i=0; i<depth; ++i )
01785             buffer += indent;
01786     }
01787     void DoLineBreak() {
01788         buffer += lineBreak;
01789     }
01790 
01791     int depth;
01792     bool simpleTextPrint;
01793     TIXML_STRING buffer;
01794     TIXML_STRING indent;
01795     TIXML_STRING lineBreak;
01796 };
01797 
01798 
01799 #ifdef _MSC_VER
01800 #pragma warning( pop )
01801 #endif
01802 
01803 #endif
01804