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         #define TIXML_SSCANF   sscanf_s
00068     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00069         // Microsoft visual studio, version 6 and higher.
00070         //#pragma message( "Using _sn* functions." )
00071         #define TIXML_SNPRINTF _snprintf
00072         #define TIXML_SNSCANF  _snscanf
00073         #define TIXML_SSCANF   sscanf
00074     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00075         // GCC version 3 and higher.s
00076         //#warning( "Using sn* functions." )
00077         #define TIXML_SNPRINTF snprintf
00078         #define TIXML_SNSCANF  snscanf
00079         #define TIXML_SSCANF   sscanf
00080     #else
00081         #define TIXML_SSCANF   sscanf
00082     #endif
00083 #endif  
00084 
00085 class TiXmlDocument;
00086 class TiXmlElement;
00087 class TiXmlComment;
00088 class TiXmlUnknown;
00089 class TiXmlAttribute;
00090 class TiXmlText;
00091 class TiXmlDeclaration;
00092 class TiXmlParsingData;
00093 
00094 const int TIXML_MAJOR_VERSION = 2;
00095 const int TIXML_MINOR_VERSION = 5;
00096 const int TIXML_PATCH_VERSION = 3;
00097 
00098 /*  Internal structure for tracking location of items 
00099     in the XML file.
00100 */
00101 struct TiXmlCursor
00102 {
00103     TiXmlCursor()       { Clear(); }
00104     void Clear()        { row = col = -1; }
00105 
00106     int row;    // 0 based.
00107     int col;    // 0 based.
00108 };
00109 
00110 
00129 class TiXmlVisitor
00130 {
00131 public:
00132     virtual ~TiXmlVisitor() {}
00133 
00135     virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )         { return true; }
00137     virtual bool VisitExit( const TiXmlDocument& /*doc*/ )          { return true; }
00138 
00140     virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
00142     virtual bool VisitExit( const TiXmlElement& /*element*/ )       { return true; }
00143 
00145     virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
00147     virtual bool Visit( const TiXmlText& /*text*/ )                 { return true; }
00149     virtual bool Visit( const TiXmlComment& /*comment*/ )           { return true; }
00151     virtual bool Visit( const TiXmlUnknown& /*unknown*/ )           { return true; }
00152 };
00153 
00154 // Only used by Attribute::Query functions
00155 enum 
00156 { 
00157     TIXML_SUCCESS,
00158     TIXML_NO_ATTRIBUTE,
00159     TIXML_WRONG_TYPE
00160 };
00161 
00162 
00163 // Used by the parsing routines.
00164 enum TiXmlEncoding
00165 {
00166     TIXML_ENCODING_UNKNOWN,
00167     TIXML_ENCODING_UTF8,
00168     TIXML_ENCODING_LEGACY
00169 };
00170 
00171 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00172 
00195 class TiXmlBase
00196 {
00197     friend class TiXmlNode;
00198     friend class TiXmlElement;
00199     friend class TiXmlDocument;
00200 
00201 public:
00202     TiXmlBase() :   userData(0)     {}
00203     virtual ~TiXmlBase()            {}
00204 
00214     virtual void Print( FILE* cfile, int depth ) const = 0;
00215 
00222     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00223 
00225     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00226 
00245     int Row() const         { return location.row + 1; }
00246     int Column() const      { return location.col + 1; }    
00247 
00248     void  SetUserData( void* user )         { userData = user; }    
00249     void* GetUserData()                     { return userData; }    
00250     const void* GetUserData() const         { return userData; }    
00251 
00252     // Table that returs, for a given lead byte, the total number of bytes
00253     // in the UTF-8 sequence.
00254     static const int utf8ByteTable[256];
00255 
00256     virtual const char* Parse(  const char* p, 
00257                                 TiXmlParsingData* data, 
00258                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00259 
00263     static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
00264 
00265     enum
00266     {
00267         TIXML_NO_ERROR = 0,
00268         TIXML_ERROR,
00269         TIXML_ERROR_OPENING_FILE,
00270         TIXML_ERROR_OUT_OF_MEMORY,
00271         TIXML_ERROR_PARSING_ELEMENT,
00272         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00273         TIXML_ERROR_READING_ELEMENT_VALUE,
00274         TIXML_ERROR_READING_ATTRIBUTES,
00275         TIXML_ERROR_PARSING_EMPTY,
00276         TIXML_ERROR_READING_END_TAG,
00277         TIXML_ERROR_PARSING_UNKNOWN,
00278         TIXML_ERROR_PARSING_COMMENT,
00279         TIXML_ERROR_PARSING_DECLARATION,
00280         TIXML_ERROR_DOCUMENT_EMPTY,
00281         TIXML_ERROR_EMBEDDED_NULL,
00282         TIXML_ERROR_PARSING_CDATA,
00283         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00284 
00285         TIXML_ERROR_STRING_COUNT
00286     };
00287 
00288 protected:
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     // Return true if the next characters in the stream are any of the endTag sequences.
00365     // Ignore case only works for english, and should only be relied on when comparing
00366     // to English words: StringEqual( p, "version", true ) is fine.
00367     static bool StringEqual(    const char* p,
00368                                 const char* endTag,
00369                                 bool ignoreCase,
00370                                 TiXmlEncoding encoding );
00371 
00372     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00373 
00374     TiXmlCursor location;
00375 
00377     void*           userData;
00378     
00379     // None of these methods are reliable for any language except English.
00380     // Good for approximation, not great for accuracy.
00381     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00382     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00383     inline static int ToLower( int v, TiXmlEncoding encoding )
00384     {
00385         if ( encoding == TIXML_ENCODING_UTF8 )
00386         {
00387             if ( v < 128 ) return tolower( v );
00388             return v;
00389         }
00390         else
00391         {
00392             return tolower( v );
00393         }
00394     }
00395     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00396 
00397 private:
00398     TiXmlBase( const TiXmlBase& );              // not implemented.
00399     void operator=( const TiXmlBase& base );    // not allowed.
00400 
00401     struct Entity
00402     {
00403         const char*     str;
00404         unsigned int    strLength;
00405         char            chr;
00406     };
00407     enum
00408     {
00409         NUM_ENTITY = 5,
00410         MAX_ENTITY_LENGTH = 6
00411 
00412     };
00413     static Entity entity[ NUM_ENTITY ];
00414     static bool condenseWhiteSpace;
00415 };
00416 
00417 
00424 class TiXmlNode : public TiXmlBase
00425 {
00426     friend class TiXmlDocument;
00427     friend class TiXmlElement;
00428 
00429 public:
00430     #ifdef TIXML_USE_STL    
00431 
00435         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00436 
00453         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00454 
00456         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00457 
00458     #endif
00459 
00463     enum NodeType
00464     {
00465         DOCUMENT,
00466         ELEMENT,
00467         COMMENT,
00468         UNKNOWN,
00469         TEXT,
00470         DECLARATION,
00471         TYPECOUNT
00472     };
00473 
00474     virtual ~TiXmlNode();
00475 
00488     const char *Value() const { return value.c_str (); }
00489 
00490     #ifdef TIXML_USE_STL
00491 
00495     const std::string& ValueStr() const { return value; }
00496     #endif
00497 
00498     const TIXML_STRING& ValueTStr() const { return value; }
00499 
00509     void SetValue(const char * _value) { value = _value;}
00510 
00511     #ifdef TIXML_USE_STL
00513     void SetValue( const std::string& _value )  { value = _value; }
00514     #endif
00515 
00517     void Clear();
00518 
00520     TiXmlNode* Parent()                         { return parent; }
00521     const TiXmlNode* Parent() const             { return parent; }
00522 
00523     const TiXmlNode* FirstChild()   const       { return firstChild; }  
00524     TiXmlNode* FirstChild()                     { return firstChild; }
00525     const TiXmlNode* FirstChild( const char * value ) const;            
00526 
00527     TiXmlNode* FirstChild( const char * _value ) {
00528         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00529         // call the method, cast the return back to non-const.
00530         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00531     }
00532     const TiXmlNode* LastChild() const  { return lastChild; }       
00533     TiXmlNode* LastChild()  { return lastChild; }
00534     
00535     const TiXmlNode* LastChild( const char * value ) const;         
00536     TiXmlNode* LastChild( const char * _value ) {
00537         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00538     }
00539 
00540     #ifdef TIXML_USE_STL
00541     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   
00542     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   
00543     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   
00544     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   
00545     #endif
00546 
00563     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00564     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00565         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00566     }
00567 
00569     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00570     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00571         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00572     }
00573 
00574     #ifdef TIXML_USE_STL
00575     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   
00576     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous); }   
00577     #endif
00578 
00582     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00583 
00584 
00594     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00595 
00599     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00600 
00604     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00605 
00609     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00610 
00612     bool RemoveChild( TiXmlNode* removeThis );
00613 
00615     const TiXmlNode* PreviousSibling() const            { return prev; }
00616     TiXmlNode* PreviousSibling()                        { return prev; }
00617 
00619     const TiXmlNode* PreviousSibling( const char * ) const;
00620     TiXmlNode* PreviousSibling( const char *_prev ) {
00621         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00622     }
00623 
00624     #ifdef TIXML_USE_STL
00625     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   
00626     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   
00627     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   
00628     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   
00629     #endif
00630 
00632     const TiXmlNode* NextSibling() const                { return next; }
00633     TiXmlNode* NextSibling()                            { return next; }
00634 
00636     const TiXmlNode* NextSibling( const char * ) const;
00637     TiXmlNode* NextSibling( const char* _next ) {
00638         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00639     }
00640 
00645     const TiXmlElement* NextSiblingElement() const;
00646     TiXmlElement* NextSiblingElement() {
00647         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00648     }
00649 
00654     const TiXmlElement* NextSiblingElement( const char * ) const;
00655     TiXmlElement* NextSiblingElement( const char *_next ) {
00656         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00657     }
00658 
00659     #ifdef TIXML_USE_STL
00660     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   
00661     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   
00662     #endif
00663 
00665     const TiXmlElement* FirstChildElement() const;
00666     TiXmlElement* FirstChildElement() {
00667         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00668     }
00669 
00671     const TiXmlElement* FirstChildElement( const char * _value ) const;
00672     TiXmlElement* FirstChildElement( const char * _value ) {
00673         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00674     }
00675 
00676     #ifdef TIXML_USE_STL
00677     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   
00678     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   
00679     #endif
00680 
00685     int Type() const    { return type; }
00686 
00690     const TiXmlDocument* GetDocument() const;
00691     TiXmlDocument* GetDocument() {
00692         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00693     }
00694 
00696     bool NoChildren() const                     { return !firstChild; }
00697 
00698     virtual const TiXmlDocument*    ToDocument()    const { return 0; } 
00699     virtual const TiXmlElement*     ToElement()     const { return 0; } 
00700     virtual const TiXmlComment*     ToComment()     const { return 0; } 
00701     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } 
00702     virtual const TiXmlText*        ToText()        const { return 0; } 
00703     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 
00704 
00705     virtual TiXmlDocument*          ToDocument()    { return 0; } 
00706     virtual TiXmlElement*           ToElement()     { return 0; } 
00707     virtual TiXmlComment*           ToComment()     { return 0; } 
00708     virtual TiXmlUnknown*           ToUnknown()     { return 0; } 
00709     virtual TiXmlText*              ToText()        { return 0; } 
00710     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } 
00711 
00715     virtual TiXmlNode* Clone() const = 0;
00716 
00739     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00740 
00741 protected:
00742     TiXmlNode( NodeType _type );
00743 
00744     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00745     // and the assignment operator.
00746     void CopyTo( TiXmlNode* target ) const;
00747 
00748     #ifdef TIXML_USE_STL
00749         // The real work of the input operator.
00750     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00751     #endif
00752 
00753     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00754     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00755 
00756     TiXmlNode*      parent;
00757     NodeType        type;
00758 
00759     TiXmlNode*      firstChild;
00760     TiXmlNode*      lastChild;
00761 
00762     TIXML_STRING    value;
00763 
00764     TiXmlNode*      prev;
00765     TiXmlNode*      next;
00766 
00767 private:
00768     TiXmlNode( const TiXmlNode& );              // not implemented.
00769     void operator=( const TiXmlNode& base );    // not allowed.
00770 };
00771 
00772 
00780 class TiXmlAttribute : public TiXmlBase
00781 {
00782     friend class TiXmlAttributeSet;
00783 
00784 public:
00786     TiXmlAttribute() : TiXmlBase()
00787     {
00788         document = 0;
00789         prev = next = 0;
00790     }
00791 
00792     #ifdef TIXML_USE_STL
00794     TiXmlAttribute( const std::string& _name, const std::string& _value )
00795     {
00796         name = _name;
00797         value = _value;
00798         document = 0;
00799         prev = next = 0;
00800     }
00801     #endif
00802 
00804     TiXmlAttribute( const char * _name, const char * _value )
00805     {
00806         name = _name;
00807         value = _value;
00808         document = 0;
00809         prev = next = 0;
00810     }
00811 
00812     const char*     Name()  const       { return name.c_str(); }        
00813     const char*     Value() const       { return value.c_str(); }       
00814     #ifdef TIXML_USE_STL
00815     const std::string& ValueStr() const { return value; }               
00816     #endif
00817     int             IntValue() const;                                   
00818     double          DoubleValue() const;                                
00819 
00820     // Get the tinyxml string representation
00821     const TIXML_STRING& NameTStr() const { return name; }
00822 
00832     int QueryIntValue( int* _value ) const;
00834     int QueryDoubleValue( double* _value ) const;
00835 
00836     void SetName( const char* _name )   { name = _name; }               
00837     void SetValue( const char* _value ) { value = _value; }             
00838 
00839     void SetIntValue( int _value );                                     
00840     void SetDoubleValue( double _value );                               
00841 
00842     #ifdef TIXML_USE_STL
00844     void SetName( const std::string& _name )    { name = _name; }   
00846     void SetValue( const std::string& _value )  { value = _value; }
00847     #endif
00848 
00850     const TiXmlAttribute* Next() const;
00851     TiXmlAttribute* Next() {
00852         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00853     }
00854 
00856     const TiXmlAttribute* Previous() const;
00857     TiXmlAttribute* Previous() {
00858         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00859     }
00860 
00861     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00862     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00863     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00864 
00865     /*  Attribute parsing starts: first letter of the name
00866                          returns: the next char after the value end quote
00867     */
00868     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00869 
00870     // Prints this Attribute to a FILE stream.
00871     virtual void Print( FILE* cfile, int depth ) const {
00872         Print( cfile, depth, 0 );
00873     }
00874     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00875 
00876     // [internal use]
00877     // Set the document pointer so the attribute can report errors.
00878     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00879 
00880 private:
00881     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00882     void operator=( const TiXmlAttribute& base );   // not allowed.
00883 
00884     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00885     TIXML_STRING name;
00886     TIXML_STRING value;
00887     TiXmlAttribute* prev;
00888     TiXmlAttribute* next;
00889 };
00890 
00891 
00892 /*  A class used to manage a group of attributes.
00893     It is only used internally, both by the ELEMENT and the DECLARATION.
00894     
00895     The set can be changed transparent to the Element and Declaration
00896     classes that use it, but NOT transparent to the Attribute
00897     which has to implement a next() and previous() method. Which makes
00898     it a bit problematic and prevents the use of STL.
00899 
00900     This version is implemented with circular lists because:
00901         - I like circular lists
00902         - it demonstrates some independence from the (typical) doubly linked list.
00903 */
00904 class TiXmlAttributeSet
00905 {
00906 public:
00907     TiXmlAttributeSet();
00908     ~TiXmlAttributeSet();
00909 
00910     void Add( TiXmlAttribute* attribute );
00911     void Remove( TiXmlAttribute* attribute );
00912 
00913     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00914     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00915     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00916     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00917 
00918     const TiXmlAttribute*   Find( const char* _name ) const;
00919     TiXmlAttribute* Find( const char* _name ) {
00920         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00921     }
00922     #ifdef TIXML_USE_STL
00923     const TiXmlAttribute*   Find( const std::string& _name ) const;
00924     TiXmlAttribute* Find( const std::string& _name ) {
00925         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00926     }
00927 
00928     #endif
00929 
00930 private:
00931     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00932     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00933     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00934     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
00935 
00936     TiXmlAttribute sentinel;
00937 };
00938 
00939 
00944 class TiXmlElement : public TiXmlNode
00945 {
00946 public:
00948     TiXmlElement (const char * in_value);
00949 
00950     #ifdef TIXML_USE_STL
00952     TiXmlElement( const std::string& _value );
00953     #endif
00954 
00955     TiXmlElement( const TiXmlElement& );
00956 
00957     void operator=( const TiXmlElement& base );
00958 
00959     virtual ~TiXmlElement();
00960 
00964     const char* Attribute( const char* name ) const;
00965 
00972     const char* Attribute( const char* name, int* i ) const;
00973 
00980     const char* Attribute( const char* name, double* d ) const;
00981 
00989     int QueryIntAttribute( const char* name, int* _value ) const;
00991     int QueryDoubleAttribute( const char* name, double* _value ) const;
00993     int QueryFloatAttribute( const char* name, float* _value ) const {
00994         double d;
00995         int result = QueryDoubleAttribute( name, &d );
00996         if ( result == TIXML_SUCCESS ) {
00997             *_value = (float)d;
00998         }
00999         return result;
01000     }
01001 
01002     #ifdef TIXML_USE_STL
01003 
01011     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01012     {
01013         const TiXmlAttribute* node = attributeSet.Find( name );
01014         if ( !node )
01015             return TIXML_NO_ATTRIBUTE;
01016 
01017         std::stringstream sstream( node->ValueStr() );
01018         sstream >> *outValue;
01019         if ( !sstream.fail() )
01020             return TIXML_SUCCESS;
01021         return TIXML_WRONG_TYPE;
01022     }
01023     /*
01024      This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
01025      but template specialization is hard to get working cross-compiler. Leaving the bug for now.
01026      
01027     // The above will fail for std::string because the space character is used as a seperator.
01028     // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
01029     template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
01030     {
01031         const TiXmlAttribute* node = attributeSet.Find( name );
01032         if ( !node )
01033             return TIXML_NO_ATTRIBUTE;
01034         *outValue = node->ValueStr();
01035         return TIXML_SUCCESS;
01036     }
01037     */
01038     #endif
01039 
01043     void SetAttribute( const char* name, const char * _value );
01044 
01045     #ifdef TIXML_USE_STL
01046     const std::string* Attribute( const std::string& name ) const;
01047     const std::string* Attribute( const std::string& name, int* i ) const;
01048     const std::string* Attribute( const std::string& name, double* d ) const;
01049     int QueryIntAttribute( const std::string& name, int* _value ) const;
01050     int QueryDoubleAttribute( const std::string& name, double* _value ) const;
01051 
01053     void SetAttribute( const std::string& name, const std::string& _value );
01055     void SetAttribute( const std::string& name, int _value );
01056     #endif
01057 
01061     void SetAttribute( const char * name, int value );
01062 
01066     void SetDoubleAttribute( const char * name, double value );
01067 
01070     void RemoveAttribute( const char * name );
01071     #ifdef TIXML_USE_STL
01072     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
01073     #endif
01074 
01075     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        
01076     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
01077     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     
01078     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
01079 
01112     const char* GetText() const;
01113 
01115     virtual TiXmlNode* Clone() const;
01116     // Print the Element to a FILE stream.
01117     virtual void Print( FILE* cfile, int depth ) const;
01118 
01119     /*  Attribtue parsing starts: next char past '<'
01120                          returns: next char past '>'
01121     */
01122     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01123 
01124     virtual const TiXmlElement*     ToElement()     const { return this; } 
01125     virtual TiXmlElement*           ToElement()           { return this; } 
01126 
01129     virtual bool Accept( TiXmlVisitor* visitor ) const;
01130 
01131 protected:
01132 
01133     void CopyTo( TiXmlElement* target ) const;
01134     void ClearThis();   // like clear, but initializes 'this' object as well
01135 
01136     // Used to be public [internal use]
01137     #ifdef TIXML_USE_STL
01138     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01139     #endif
01140     /*  [internal use]
01141         Reads the "value" of the element -- another element, or text.
01142         This should terminate with the current end tag.
01143     */
01144     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01145 
01146 private:
01147 
01148     TiXmlAttributeSet attributeSet;
01149 };
01150 
01151 
01154 class TiXmlComment : public TiXmlNode
01155 {
01156 public:
01158     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
01160     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
01161         SetValue( _value );
01162     }
01163     TiXmlComment( const TiXmlComment& );
01164     void operator=( const TiXmlComment& base );
01165 
01166     virtual ~TiXmlComment() {}
01167 
01169     virtual TiXmlNode* Clone() const;
01170     // Write this Comment to a FILE stream.
01171     virtual void Print( FILE* cfile, int depth ) const;
01172 
01173     /*  Attribtue parsing starts: at the ! of the !--
01174                          returns: next char past '>'
01175     */
01176     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01177 
01178     virtual const TiXmlComment*  ToComment() const { return this; } 
01179     virtual TiXmlComment*  ToComment() { return this; } 
01180 
01183     virtual bool Accept( TiXmlVisitor* visitor ) const;
01184 
01185 protected:
01186     void CopyTo( TiXmlComment* target ) const;
01187 
01188     // used to be public
01189     #ifdef TIXML_USE_STL
01190     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01191     #endif
01192 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
01193 
01194 private:
01195 
01196 };
01197 
01198 
01204 class TiXmlText : public TiXmlNode
01205 {
01206     friend class TiXmlElement;
01207 public:
01212     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
01213     {
01214         SetValue( initValue );
01215         cdata = false;
01216     }
01217     virtual ~TiXmlText() {}
01218 
01219     #ifdef TIXML_USE_STL
01221     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
01222     {
01223         SetValue( initValue );
01224         cdata = false;
01225     }
01226     #endif
01227 
01228     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )   { copy.CopyTo( this ); }
01229     void operator=( const TiXmlText& base )                             { base.CopyTo( this ); }
01230 
01231     // Write this text object to a FILE stream.
01232     virtual void Print( FILE* cfile, int depth ) const;
01233 
01235     bool CDATA() const              { return cdata; }
01237     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01238 
01239     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01240 
01241     virtual const TiXmlText* ToText() const { return this; } 
01242     virtual TiXmlText*       ToText()       { return this; } 
01243 
01246     virtual bool Accept( TiXmlVisitor* content ) const;
01247 
01248 protected :
01250     virtual TiXmlNode* Clone() const;
01251     void CopyTo( TiXmlText* target ) const;
01252 
01253     bool Blank() const; // returns true if all white space and new lines
01254     // [internal use]
01255     #ifdef TIXML_USE_STL
01256     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01257     #endif
01258 
01259 private:
01260     bool cdata;         // true if this should be input and output as a CDATA style text element
01261 };
01262 
01263 
01277 class TiXmlDeclaration : public TiXmlNode
01278 {
01279 public:
01281     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
01282 
01283 #ifdef TIXML_USE_STL
01285     TiXmlDeclaration(   const std::string& _version,
01286                         const std::string& _encoding,
01287                         const std::string& _standalone );
01288 #endif
01289 
01291     TiXmlDeclaration(   const char* _version,
01292                         const char* _encoding,
01293                         const char* _standalone );
01294 
01295     TiXmlDeclaration( const TiXmlDeclaration& copy );
01296     void operator=( const TiXmlDeclaration& copy );
01297 
01298     virtual ~TiXmlDeclaration() {}
01299 
01301     const char *Version() const         { return version.c_str (); }
01303     const char *Encoding() const        { return encoding.c_str (); }
01305     const char *Standalone() const      { return standalone.c_str (); }
01306 
01308     virtual TiXmlNode* Clone() const;
01309     // Print this declaration to a FILE stream.
01310     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01311     virtual void Print( FILE* cfile, int depth ) const {
01312         Print( cfile, depth, 0 );
01313     }
01314 
01315     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01316 
01317     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 
01318     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } 
01319 
01322     virtual bool Accept( TiXmlVisitor* visitor ) const;
01323 
01324 protected:
01325     void CopyTo( TiXmlDeclaration* target ) const;
01326     // used to be public
01327     #ifdef TIXML_USE_STL
01328     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01329     #endif
01330 
01331 private:
01332 
01333     TIXML_STRING version;
01334     TIXML_STRING encoding;
01335     TIXML_STRING standalone;
01336 };
01337 
01338 
01346 class TiXmlUnknown : public TiXmlNode
01347 {
01348 public:
01349     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )    {}
01350     virtual ~TiXmlUnknown() {}
01351 
01352     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )      { copy.CopyTo( this ); }
01353     void operator=( const TiXmlUnknown& copy )                                      { copy.CopyTo( this ); }
01354 
01356     virtual TiXmlNode* Clone() const;
01357     // Print this Unknown to a FILE stream.
01358     virtual void Print( FILE* cfile, int depth ) const;
01359 
01360     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01361 
01362     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } 
01363     virtual TiXmlUnknown*           ToUnknown()     { return this; } 
01364 
01367     virtual bool Accept( TiXmlVisitor* content ) const;
01368 
01369 protected:
01370     void CopyTo( TiXmlUnknown* target ) const;
01371 
01372     #ifdef TIXML_USE_STL
01373     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01374     #endif
01375 
01376 private:
01377 
01378 };
01379 
01380 
01385 class TiXmlDocument : public TiXmlNode
01386 {
01387 public:
01389     TiXmlDocument();
01391     TiXmlDocument( const char * documentName );
01392 
01393     #ifdef TIXML_USE_STL
01395     TiXmlDocument( const std::string& documentName );
01396     #endif
01397 
01398     TiXmlDocument( const TiXmlDocument& copy );
01399     void operator=( const TiXmlDocument& copy );
01400 
01401     virtual ~TiXmlDocument() {}
01402 
01407     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01409     bool SaveFile() const;
01411     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01413     bool SaveFile( const char * filename ) const;
01419     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01421     bool SaveFile( FILE* ) const;
01422 
01423     #ifdef TIXML_USE_STL
01424     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           
01425     {
01426 //      StringToBuffer f( filename );
01427 //      return ( f.buffer && LoadFile( f.buffer, encoding ));
01428         return LoadFile( filename.c_str(), encoding );
01429     }
01430     bool SaveFile( const std::string& filename ) const      
01431     {
01432 //      StringToBuffer f( filename );
01433 //      return ( f.buffer && SaveFile( f.buffer ));
01434         return SaveFile( filename.c_str() );
01435     }
01436     #endif
01437 
01442     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01443 
01448     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
01449     TiXmlElement* RootElement()                 { return FirstChildElement(); }
01450 
01456     bool Error() const                      { return error; }
01457 
01459     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01460 
01464     int ErrorId()   const               { return errorId; }
01465 
01473     int ErrorRow() const    { return errorLocation.row+1; }
01474     int ErrorCol() const    { return errorLocation.col+1; } 
01475 
01500     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01501 
01502     int TabSize() const { return tabsize; }
01503 
01507     void ClearError()                       {   error = false; 
01508                                                 errorId = 0; 
01509                                                 errorDesc = ""; 
01510                                                 errorLocation.row = errorLocation.col = 0; 
01511                                                 //errorLocation.last = 0; 
01512                                             }
01513 
01515     void Print() const                      { Print( stdout, 0 ); }
01516 
01517     /* Write the document to a string using formatted printing ("pretty print"). This
01518         will allocate a character array (new char[]) and return it as a pointer. The
01519         calling code pust call delete[] on the return char* to avoid a memory leak.
01520     */
01521     //char* PrintToMemory() const; 
01522 
01524     virtual void Print( FILE* cfile, int depth = 0 ) const;
01525     // [internal use]
01526     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01527 
01528     virtual const TiXmlDocument*    ToDocument()    const { return this; } 
01529     virtual TiXmlDocument*          ToDocument()          { return this; } 
01530 
01533     virtual bool Accept( TiXmlVisitor* content ) const;
01534 
01535 protected :
01536     // [internal use]
01537     virtual TiXmlNode* Clone() const;
01538     #ifdef TIXML_USE_STL
01539     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01540     #endif
01541 
01542 private:
01543     void CopyTo( TiXmlDocument* target ) const;
01544 
01545     bool error;
01546     int  errorId;
01547     TIXML_STRING errorDesc;
01548     int tabsize;
01549     TiXmlCursor errorLocation;
01550     bool useMicrosoftBOM;       // the UTF-8 BOM were found when read. Note this, and try to write.
01551 };
01552 
01553 
01634 class TiXmlHandle
01635 {
01636 public:
01638     TiXmlHandle( TiXmlNode* _node )                 { this->node = _node; }
01640     TiXmlHandle( const TiXmlHandle& ref )           { this->node = ref.node; }
01641     TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
01642 
01644     TiXmlHandle FirstChild() const;
01646     TiXmlHandle FirstChild( const char * value ) const;
01648     TiXmlHandle FirstChildElement() const;
01650     TiXmlHandle FirstChildElement( const char * value ) const;
01651 
01655     TiXmlHandle Child( const char* value, int index ) const;
01659     TiXmlHandle Child( int index ) const;
01664     TiXmlHandle ChildElement( const char* value, int index ) const;
01669     TiXmlHandle ChildElement( int index ) const;
01670 
01671     #ifdef TIXML_USE_STL
01672     TiXmlHandle FirstChild( const std::string& _value ) const               { return FirstChild( _value.c_str() ); }
01673     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01674 
01675     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
01676     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01677     #endif
01678 
01681     TiXmlNode* ToNode() const           { return node; } 
01684     TiXmlElement* ToElement() const     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01687     TiXmlText* ToText() const           { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01690     TiXmlUnknown* ToUnknown() const     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01691 
01695     TiXmlNode* Node() const         { return ToNode(); } 
01699     TiXmlElement* Element() const   { return ToElement(); }
01703     TiXmlText* Text() const         { return ToText(); }
01707     TiXmlUnknown* Unknown() const   { return ToUnknown(); }
01708 
01709 private:
01710     TiXmlNode* node;
01711 };
01712 
01713 
01733 class TiXmlPrinter : public TiXmlVisitor
01734 {
01735 public:
01736     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01737                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
01738 
01739     virtual bool VisitEnter( const TiXmlDocument& doc );
01740     virtual bool VisitExit( const TiXmlDocument& doc );
01741 
01742     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01743     virtual bool VisitExit( const TiXmlElement& element );
01744 
01745     virtual bool Visit( const TiXmlDeclaration& declaration );
01746     virtual bool Visit( const TiXmlText& text );
01747     virtual bool Visit( const TiXmlComment& comment );
01748     virtual bool Visit( const TiXmlUnknown& unknown );
01749 
01753     void SetIndent( const char* _indent )           { indent = _indent ? _indent : "" ; }
01755     const char* Indent()                            { return indent.c_str(); }
01760     void SetLineBreak( const char* _lineBreak )     { lineBreak = _lineBreak ? _lineBreak : ""; }
01762     const char* LineBreak()                         { return lineBreak.c_str(); }
01763 
01767     void SetStreamPrinting()                        { indent = "";
01768                                                       lineBreak = "";
01769                                                     }   
01771     const char* CStr()                              { return buffer.c_str(); }
01773     size_t Size()                                   { return buffer.size(); }
01774 
01775     #ifdef TIXML_USE_STL
01777     const std::string& Str()                        { return buffer; }
01778     #endif
01779 
01780 private:
01781     void DoIndent() {
01782         for( int i=0; i<depth; ++i )
01783             buffer += indent;
01784     }
01785     void DoLineBreak() {
01786         buffer += lineBreak;
01787     }
01788 
01789     int depth;
01790     bool simpleTextPrint;
01791     TIXML_STRING buffer;
01792     TIXML_STRING indent;
01793     TIXML_STRING lineBreak;
01794 };
01795 
01796 
01797 #ifdef _MSC_VER
01798 #pragma warning( pop )
01799 #endif
01800 
01801 #endif
01802 

Generated on Sun May 6 15:41:23 2007 for TinyXml by  doxygen 1.4.7