tinyxml.h

00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning( push )
00031 #pragma warning( disable : 4530 )
00032 #pragma warning( disable : 4786 )
00033 #endif
00034 
00035 #include <ctype.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040 
00041 // Help out windows:
00042 #if defined( _DEBUG ) && !defined( DEBUG )
00043 #define DEBUG
00044 #endif
00045 
00046 #ifdef TIXML_USE_STL
00047     #include <string>
00048     #include <iostream>
00049     #include <sstream>
00050     #define TIXML_STRING        std::string
00051 #else
00052     #include "tinystr.h"
00053     #define TIXML_STRING        TiXmlString
00054 #endif
00055 
00056 // Deprecated library function hell. Compilers want to use the
00057 // new safe versions. This probably doesn't fully address the problem,
00058 // but it gets closer. There are too many compilers for me to fully
00059 // test. If you get compilation troubles, undefine TIXML_SAFE
00060 #define TIXML_SAFE
00061 
00062 #ifdef TIXML_SAFE
00063     #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00064         // Microsoft visual studio, version 2005 and higher.
00065         #define TIXML_SNPRINTF _snprintf_s
00066         #define TIXML_SNSCANF  _snscanf_s
00067     #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00068         // Microsoft visual studio, version 6 and higher.
00069         //#pragma message( "Using _sn* functions." )
00070         #define TIXML_SNPRINTF _snprintf
00071         #define TIXML_SNSCANF  _snscanf
00072     #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00073         // GCC version 3 and higher.s
00074         //#warning( "Using sn* functions." )
00075         #define TIXML_SNPRINTF snprintf
00076         #define TIXML_SNSCANF  snscanf
00077     #endif
00078 #endif  
00079 
00080 class TiXmlDocument;
00081 class TiXmlElement;
00082 class TiXmlComment;
00083 class TiXmlUnknown;
00084 class TiXmlAttribute;
00085 class TiXmlText;
00086 class TiXmlDeclaration;
00087 class TiXmlParsingData;
00088 
00089 const int TIXML_MAJOR_VERSION = 2;
00090 const int TIXML_MINOR_VERSION = 5;
00091 const int TIXML_PATCH_VERSION = 2;
00092 
00093 /*  Internal structure for tracking location of items 
00094     in the XML file.
00095 */
00096 struct TiXmlCursor
00097 {
00098     TiXmlCursor()       { Clear(); }
00099     void Clear()        { row = col = -1; }
00100 
00101     int row;    // 0 based.
00102     int col;    // 0 based.
00103 };
00104 
00105 
00124 class TiXmlVisitor
00125 {
00126 public:
00127     virtual ~TiXmlVisitor() {}
00128 
00130     virtual bool VisitEnter( const TiXmlDocument& doc ) { return true; }
00132     virtual bool VisitExit( const TiXmlDocument& doc )  { return true; }
00133 
00135     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )    { return true; }
00137     virtual bool VisitExit( const TiXmlElement& element )                                           { return true; }
00138 
00140     virtual bool Visit( const TiXmlDeclaration& declaration )       { return true; }
00142     virtual bool Visit( const TiXmlText& text )                     { return true; }
00144     virtual bool Visit( const TiXmlComment& comment )               { return true; }
00146     virtual bool Visit( const TiXmlUnknown& unknown )               { return true; }
00147 };
00148 
00149 // Only used by Attribute::Query functions
00150 enum 
00151 { 
00152     TIXML_SUCCESS,
00153     TIXML_NO_ATTRIBUTE,
00154     TIXML_WRONG_TYPE
00155 };
00156 
00157 
00158 // Used by the parsing routines.
00159 enum TiXmlEncoding
00160 {
00161     TIXML_ENCODING_UNKNOWN,
00162     TIXML_ENCODING_UTF8,
00163     TIXML_ENCODING_LEGACY
00164 };
00165 
00166 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00167 
00190 class TiXmlBase
00191 {
00192     friend class TiXmlNode;
00193     friend class TiXmlElement;
00194     friend class TiXmlDocument;
00195 
00196 public:
00197     TiXmlBase() :   userData(0)     {}
00198     virtual ~TiXmlBase()            {}
00199 
00209     virtual void Print( FILE* cfile, int depth ) const = 0;
00210 
00217     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00218 
00220     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00221 
00240     int Row() const         { return location.row + 1; }
00241     int Column() const      { return location.col + 1; }    
00242 
00243     void  SetUserData( void* user )         { userData = user; }    
00244     void* GetUserData()                     { return userData; }    
00245     const void* GetUserData() const         { return userData; }    
00246 
00247     // Table that returs, for a given lead byte, the total number of bytes
00248     // in the UTF-8 sequence.
00249     static const int utf8ByteTable[256];
00250 
00251     virtual const char* Parse(  const char* p, 
00252                                 TiXmlParsingData* data, 
00253                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00254 
00255     enum
00256     {
00257         TIXML_NO_ERROR = 0,
00258         TIXML_ERROR,
00259         TIXML_ERROR_OPENING_FILE,
00260         TIXML_ERROR_OUT_OF_MEMORY,
00261         TIXML_ERROR_PARSING_ELEMENT,
00262         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00263         TIXML_ERROR_READING_ELEMENT_VALUE,
00264         TIXML_ERROR_READING_ATTRIBUTES,
00265         TIXML_ERROR_PARSING_EMPTY,
00266         TIXML_ERROR_READING_END_TAG,
00267         TIXML_ERROR_PARSING_UNKNOWN,
00268         TIXML_ERROR_PARSING_COMMENT,
00269         TIXML_ERROR_PARSING_DECLARATION,
00270         TIXML_ERROR_DOCUMENT_EMPTY,
00271         TIXML_ERROR_EMBEDDED_NULL,
00272         TIXML_ERROR_PARSING_CDATA,
00273         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00274 
00275         TIXML_ERROR_STRING_COUNT
00276     };
00277 
00278 protected:
00279 
00280     static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00281     inline static bool IsWhiteSpace( char c )       
00282     { 
00283         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00284     }
00285     inline static bool IsWhiteSpace( int c )
00286     {
00287         if ( c < 256 )
00288             return IsWhiteSpace( (char) c );
00289         return false;   // Again, only truly correct for English/Latin...but usually works.
00290     }
00291 
00292     #ifdef TIXML_USE_STL
00293     static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00294     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00295     #endif
00296 
00297     /*  Reads an XML name into the string provided. Returns
00298         a pointer just past the last character of the name,
00299         or 0 if the function has an error.
00300     */
00301     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00302 
00303     /*  Reads text. Returns a pointer past the given end tag.
00304         Wickedly complex options, but it keeps the (sensitive) code in one place.
00305     */
00306     static const char* ReadText(    const char* in,             // where to start
00307                                     TIXML_STRING* text,         // the string read
00308                                     bool ignoreWhiteSpace,      // whether to keep the white space
00309                                     const char* endTag,         // what ends this text
00310                                     bool ignoreCase,            // whether to ignore case in the end tag
00311                                     TiXmlEncoding encoding );   // the current encoding
00312 
00313     // If an entity has been found, transform it into a character.
00314     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00315 
00316     // Get a character, while interpreting entities.
00317     // The length can be from 0 to 4 bytes.
00318     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00319     {
00320         assert( p );
00321         if ( encoding == TIXML_ENCODING_UTF8 )
00322         {
00323             *length = utf8ByteTable[ *((const unsigned char*)p) ];
00324             assert( *length >= 0 && *length < 5 );
00325         }
00326         else
00327         {
00328             *length = 1;
00329         }
00330 
00331         if ( *length == 1 )
00332         {
00333             if ( *p == '&' )
00334                 return GetEntity( p, _value, length, encoding );
00335             *_value = *p;
00336             return p+1;
00337         }
00338         else if ( *length )
00339         {
00340             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
00341                                                 // and the null terminator isn't needed
00342             for( int i=0; p[i] && i<*length; ++i ) {
00343                 _value[i] = p[i];
00344             }
00345             return p + (*length);
00346         }
00347         else
00348         {
00349             // Not valid text.
00350             return 0;
00351         }
00352     }
00353 
00354     // Puts a string to a stream, expanding entities as it goes.
00355     // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
00356     static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00357 
00358     // Return true if the next characters in the stream are any of the endTag sequences.
00359     // Ignore case only works for english, and should only be relied on when comparing
00360     // to English words: StringEqual( p, "version", true ) is fine.
00361     static bool StringEqual(    const char* p,
00362                                 const char* endTag,
00363                                 bool ignoreCase,
00364                                 TiXmlEncoding encoding );
00365 
00366     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00367 
00368     TiXmlCursor location;
00369 
00371     void*           userData;
00372     
00373     // None of these methods are reliable for any language except English.
00374     // Good for approximation, not great for accuracy.
00375     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00376     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00377     inline static int ToLower( int v, TiXmlEncoding encoding )
00378     {
00379         if ( encoding == TIXML_ENCODING_UTF8 )
00380         {
00381             if ( v < 128 ) return tolower( v );
00382             return v;
00383         }
00384         else
00385         {
00386             return tolower( v );
00387         }
00388     }
00389     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00390 
00391 private:
00392     TiXmlBase( const TiXmlBase& );              // not implemented.
00393     void operator=( const TiXmlBase& base );    // not allowed.
00394 
00395     struct Entity
00396     {
00397         const char*     str;
00398         unsigned int    strLength;
00399         char            chr;
00400     };
00401     enum
00402     {
00403         NUM_ENTITY = 5,
00404         MAX_ENTITY_LENGTH = 6
00405 
00406     };
00407     static Entity entity[ NUM_ENTITY ];
00408     static bool condenseWhiteSpace;
00409 };
00410 
00411 
00418 class TiXmlNode : public TiXmlBase
00419 {
00420     friend class TiXmlDocument;
00421     friend class TiXmlElement;
00422 
00423 public:
00424     #ifdef TIXML_USE_STL    
00425 
00429         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00430 
00447         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00448 
00450         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00451 
00452     #endif
00453 
00457     enum NodeType
00458     {
00459         DOCUMENT,
00460         ELEMENT,
00461         COMMENT,
00462         UNKNOWN,
00463         TEXT,
00464         DECLARATION,
00465         TYPECOUNT
00466     };
00467 
00468     virtual ~TiXmlNode();
00469 
00482     const char *Value() const { return value.c_str (); }
00483 
00484     #ifdef TIXML_USE_STL
00485 
00489     const std::string& ValueStr() const { return value; }
00490     #endif
00491 
00501     void SetValue(const char * _value) { value = _value;}
00502 
00503     #ifdef TIXML_USE_STL
00505     void SetValue( const std::string& _value )  { value = _value; }
00506     #endif
00507 
00509     void Clear();
00510 
00512     TiXmlNode* Parent()                         { return parent; }
00513     const TiXmlNode* Parent() const             { return parent; }
00514 
00515     const TiXmlNode* FirstChild()   const   { return firstChild; }      
00516     TiXmlNode* FirstChild()                 { return firstChild; }
00517     const TiXmlNode* FirstChild( const char * value ) const;            
00518 
00519     TiXmlNode* FirstChild( const char * _value ) {
00520         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00521         // call the method, cast the return back to non-const.
00522         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00523     }
00524     const TiXmlNode* LastChild() const  { return lastChild; }       
00525     TiXmlNode* LastChild()  { return lastChild; }
00526     
00527     const TiXmlNode* LastChild( const char * value ) const;         
00528     TiXmlNode* LastChild( const char * _value ) {
00529         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00530     }
00531 
00532     #ifdef TIXML_USE_STL
00533     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   
00534     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   
00535     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   
00536     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   
00537     #endif
00538 
00555     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00556     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00557         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00558     }
00559 
00561     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00562     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00563         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00564     }
00565 
00566     #ifdef TIXML_USE_STL
00567     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   
00568     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous); }   
00569     #endif
00570 
00574     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00575 
00576 
00586     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00587 
00591     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00592 
00596     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00597 
00601     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00602 
00604     bool RemoveChild( TiXmlNode* removeThis );
00605 
00607     const TiXmlNode* PreviousSibling() const            { return prev; }
00608     TiXmlNode* PreviousSibling()                        { return prev; }
00609 
00611     const TiXmlNode* PreviousSibling( const char * ) const;
00612     TiXmlNode* PreviousSibling( const char *_prev ) {
00613         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00614     }
00615 
00616     #ifdef TIXML_USE_STL
00617     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   
00618     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   
00619     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   
00620     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   
00621     #endif
00622 
00624     const TiXmlNode* NextSibling() const                { return next; }
00625     TiXmlNode* NextSibling()                            { return next; }
00626 
00628     const TiXmlNode* NextSibling( const char * ) const;
00629     TiXmlNode* NextSibling( const char* _next ) {
00630         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00631     }
00632 
00637     const TiXmlElement* NextSiblingElement() const;
00638     TiXmlElement* NextSiblingElement() {
00639         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00640     }
00641 
00646     const TiXmlElement* NextSiblingElement( const char * ) const;
00647     TiXmlElement* NextSiblingElement( const char *_next ) {
00648         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00649     }
00650 
00651     #ifdef TIXML_USE_STL
00652     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   
00653     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   
00654     #endif
00655 
00657     const TiXmlElement* FirstChildElement() const;
00658     TiXmlElement* FirstChildElement() {
00659         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00660     }
00661 
00663     const TiXmlElement* FirstChildElement( const char * _value ) const;
00664     TiXmlElement* FirstChildElement( const char * _value ) {
00665         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00666     }
00667 
00668     #ifdef TIXML_USE_STL
00669     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   
00670     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   
00671     #endif
00672 
00677     int Type() const    { return type; }
00678 
00682     const TiXmlDocument* GetDocument() const;
00683     TiXmlDocument* GetDocument() {
00684         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00685     }
00686 
00688     bool NoChildren() const                     { return !firstChild; }
00689 
00690     virtual const TiXmlDocument*    ToDocument()    const { return 0; } 
00691     virtual const TiXmlElement*     ToElement()     const { return 0; } 
00692     virtual const TiXmlComment*     ToComment()     const { return 0; } 
00693     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } 
00694     virtual const TiXmlText*        ToText()        const { return 0; } 
00695     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 
00696 
00697     virtual TiXmlDocument*          ToDocument()    { return 0; } 
00698     virtual TiXmlElement*           ToElement()     { return 0; } 
00699     virtual TiXmlComment*           ToComment()     { return 0; } 
00700     virtual TiXmlUnknown*           ToUnknown()     { return 0; } 
00701     virtual TiXmlText*              ToText()        { return 0; } 
00702     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } 
00703 
00707     virtual TiXmlNode* Clone() const = 0;
00708 
00731     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00732 
00733 protected:
00734     TiXmlNode( NodeType _type );
00735 
00736     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00737     // and the assignment operator.
00738     void CopyTo( TiXmlNode* target ) const;
00739 
00740     #ifdef TIXML_USE_STL
00741         // The real work of the input operator.
00742     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00743     #endif
00744 
00745     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00746     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00747 
00748     TiXmlNode*      parent;
00749     NodeType        type;
00750 
00751     TiXmlNode*      firstChild;
00752     TiXmlNode*      lastChild;
00753 
00754     TIXML_STRING    value;
00755 
00756     TiXmlNode*      prev;
00757     TiXmlNode*      next;
00758 
00759 private:
00760     TiXmlNode( const TiXmlNode& );              // not implemented.
00761     void operator=( const TiXmlNode& base );    // not allowed.
00762 };
00763 
00764 
00772 class TiXmlAttribute : public TiXmlBase
00773 {
00774     friend class TiXmlAttributeSet;
00775 
00776 public:
00778     TiXmlAttribute() : TiXmlBase()
00779     {
00780         document = 0;
00781         prev = next = 0;
00782     }
00783 
00784     #ifdef TIXML_USE_STL
00786     TiXmlAttribute( const std::string& _name, const std::string& _value )
00787     {
00788         name = _name;
00789         value = _value;
00790         document = 0;
00791         prev = next = 0;
00792     }
00793     #endif
00794 
00796     TiXmlAttribute( const char * _name, const char * _value )
00797     {
00798         name = _name;
00799         value = _value;
00800         document = 0;
00801         prev = next = 0;
00802     }
00803 
00804     const char*     Name()  const       { return name.c_str(); }        
00805     const char*     Value() const       { return value.c_str(); }       
00806     #ifdef TIXML_USE_STL
00807     const std::string& ValueStr() const { return value; }               
00808     #endif
00809     int             IntValue() const;                                   
00810     double          DoubleValue() const;                                
00811 
00812     // Get the tinyxml string representation
00813     const TIXML_STRING& NameTStr() const { return name; }
00814 
00824     int QueryIntValue( int* _value ) const;
00826     int QueryDoubleValue( double* _value ) const;
00827 
00828     void SetName( const char* _name )   { name = _name; }               
00829     void SetValue( const char* _value ) { value = _value; }             
00830 
00831     void SetIntValue( int _value );                                     
00832     void SetDoubleValue( double _value );                               
00833 
00834     #ifdef TIXML_USE_STL
00836     void SetName( const std::string& _name )    { name = _name; }   
00838     void SetValue( const std::string& _value )  { value = _value; }
00839     #endif
00840 
00842     const TiXmlAttribute* Next() const;
00843     TiXmlAttribute* Next() {
00844         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00845     }
00846 
00848     const TiXmlAttribute* Previous() const;
00849     TiXmlAttribute* Previous() {
00850         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00851     }
00852 
00853     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00854     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00855     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00856 
00857     /*  Attribute parsing starts: first letter of the name
00858                          returns: the next char after the value end quote
00859     */
00860     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00861 
00862     // Prints this Attribute to a FILE stream.
00863     virtual void Print( FILE* cfile, int depth ) const {
00864         Print( cfile, depth, 0 );
00865     }
00866     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00867 
00868     // [internal use]
00869     // Set the document pointer so the attribute can report errors.
00870     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00871 
00872 private:
00873     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00874     void operator=( const TiXmlAttribute& base );   // not allowed.
00875 
00876     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00877     TIXML_STRING name;
00878     TIXML_STRING value;
00879     TiXmlAttribute* prev;
00880     TiXmlAttribute* next;
00881 };
00882 
00883 
00884 /*  A class used to manage a group of attributes.
00885     It is only used internally, both by the ELEMENT and the DECLARATION.
00886     
00887     The set can be changed transparent to the Element and Declaration
00888     classes that use it, but NOT transparent to the Attribute
00889     which has to implement a next() and previous() method. Which makes
00890     it a bit problematic and prevents the use of STL.
00891 
00892     This version is implemented with circular lists because:
00893         - I like circular lists
00894         - it demonstrates some independence from the (typical) doubly linked list.
00895 */
00896 class TiXmlAttributeSet
00897 {
00898 public:
00899     TiXmlAttributeSet();
00900     ~TiXmlAttributeSet();
00901 
00902     void Add( TiXmlAttribute* attribute );
00903     void Remove( TiXmlAttribute* attribute );
00904 
00905     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00906     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00907     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00908     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00909 
00910     const TiXmlAttribute*   Find( const char* _name ) const;
00911     TiXmlAttribute* Find( const char* _name ) {
00912         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00913     }
00914     #ifdef TIXML_USE_STL
00915     const TiXmlAttribute*   Find( const std::string& _name ) const;
00916     TiXmlAttribute* Find( const std::string& _name ) {
00917         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
00918     }
00919 
00920     #endif
00921 
00922 private:
00923     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00924     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00925     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00926     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
00927 
00928     TiXmlAttribute sentinel;
00929 };
00930 
00931 
00936 class TiXmlElement : public TiXmlNode
00937 {
00938 public:
00940     TiXmlElement (const char * in_value);
00941 
00942     #ifdef TIXML_USE_STL
00944     TiXmlElement( const std::string& _value );
00945     #endif
00946 
00947     TiXmlElement( const TiXmlElement& );
00948 
00949     void operator=( const TiXmlElement& base );
00950 
00951     virtual ~TiXmlElement();
00952 
00956     const char* Attribute( const char* name ) const;
00957 
00964     const char* Attribute( const char* name, int* i ) const;
00965 
00972     const char* Attribute( const char* name, double* d ) const;
00973 
00981     int QueryIntAttribute( const char* name, int* _value ) const;
00983     int QueryDoubleAttribute( const char* name, double* _value ) const;
00985     int QueryFloatAttribute( const char* name, float* _value ) const {
00986         double d;
00987         int result = QueryDoubleAttribute( name, &d );
00988         if ( result == TIXML_SUCCESS ) {
00989             *_value = (float)d;
00990         }
00991         return result;
00992     }
00993     #ifdef TIXML_USE_STL
00994 
01000     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01001     {
01002         const TiXmlAttribute* node = attributeSet.Find( name );
01003         if ( !node )
01004             return TIXML_NO_ATTRIBUTE;
01005 
01006         std::stringstream sstream( node->ValueStr() );
01007         sstream >> *outValue;
01008         if ( !sstream.fail() )
01009             return TIXML_SUCCESS;
01010         return TIXML_WRONG_TYPE;
01011     }
01012     #endif
01013 
01017     void SetAttribute( const char* name, const char * _value );
01018 
01019     #ifdef TIXML_USE_STL
01020     const std::string* Attribute( const std::string& name ) const;
01021     const std::string* Attribute( const std::string& name, int* i ) const;
01022     const std::string* Attribute( const std::string& name, double* d ) const;
01023     int QueryIntAttribute( const std::string& name, int* _value ) const;
01024     int QueryDoubleAttribute( const std::string& name, double* _value ) const;
01025 
01027     void SetAttribute( const std::string& name, const std::string& _value );
01029     void SetAttribute( const std::string& name, int _value );
01030     #endif
01031 
01035     void SetAttribute( const char * name, int value );
01036 
01040     void SetDoubleAttribute( const char * name, double value );
01041 
01044     void RemoveAttribute( const char * name );
01045     #ifdef TIXML_USE_STL
01046     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
01047     #endif
01048 
01049     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        
01050     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
01051     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     
01052     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
01053 
01086     const char* GetText() const;
01087 
01089     virtual TiXmlNode* Clone() const;
01090     // Print the Element to a FILE stream.
01091     virtual void Print( FILE* cfile, int depth ) const;
01092 
01093     /*  Attribtue parsing starts: next char past '<'
01094                          returns: next char past '>'
01095     */
01096     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01097 
01098     virtual const TiXmlElement*     ToElement()     const { return this; } 
01099     virtual TiXmlElement*           ToElement()           { return this; } 
01100 
01103     virtual bool Accept( TiXmlVisitor* visitor ) const;
01104 
01105 protected:
01106 
01107     void CopyTo( TiXmlElement* target ) const;
01108     void ClearThis();   // like clear, but initializes 'this' object as well
01109 
01110     // Used to be public [internal use]
01111     #ifdef TIXML_USE_STL
01112     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01113     #endif
01114     /*  [internal use]
01115         Reads the "value" of the element -- another element, or text.
01116         This should terminate with the current end tag.
01117     */
01118     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01119 
01120 private:
01121 
01122     TiXmlAttributeSet attributeSet;
01123 };
01124 
01125 
01128 class TiXmlComment : public TiXmlNode
01129 {
01130 public:
01132     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
01134     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
01135         SetValue( _value );
01136     }
01137     TiXmlComment( const TiXmlComment& );
01138     void operator=( const TiXmlComment& base );
01139 
01140     virtual ~TiXmlComment() {}
01141 
01143     virtual TiXmlNode* Clone() const;
01144     // Write this Comment to a FILE stream.
01145     virtual void Print( FILE* cfile, int depth ) const;
01146 
01147     /*  Attribtue parsing starts: at the ! of the !--
01148                          returns: next char past '>'
01149     */
01150     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01151 
01152     virtual const TiXmlComment*  ToComment() const { return this; } 
01153     virtual TiXmlComment*  ToComment() { return this; } 
01154 
01157     virtual bool Accept( TiXmlVisitor* visitor ) const;
01158 
01159 protected:
01160     void CopyTo( TiXmlComment* target ) const;
01161 
01162     // used to be public
01163     #ifdef TIXML_USE_STL
01164     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01165     #endif
01166 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
01167 
01168 private:
01169 
01170 };
01171 
01172 
01178 class TiXmlText : public TiXmlNode
01179 {
01180     friend class TiXmlElement;
01181 public:
01186     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
01187     {
01188         SetValue( initValue );
01189         cdata = false;
01190     }
01191     virtual ~TiXmlText() {}
01192 
01193     #ifdef TIXML_USE_STL
01195     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
01196     {
01197         SetValue( initValue );
01198         cdata = false;
01199     }
01200     #endif
01201 
01202     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )   { copy.CopyTo( this ); }
01203     void operator=( const TiXmlText& base )                             { base.CopyTo( this ); }
01204 
01205     // Write this text object to a FILE stream.
01206     virtual void Print( FILE* cfile, int depth ) const;
01207 
01209     bool CDATA() const              { return cdata; }
01211     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01212 
01213     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01214 
01215     virtual const TiXmlText* ToText() const { return this; } 
01216     virtual TiXmlText*       ToText()       { return this; } 
01217 
01220     virtual bool Accept( TiXmlVisitor* content ) const;
01221 
01222 protected :
01224     virtual TiXmlNode* Clone() const;
01225     void CopyTo( TiXmlText* target ) const;
01226 
01227     bool Blank() const; // returns true if all white space and new lines
01228     // [internal use]
01229     #ifdef TIXML_USE_STL
01230     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01231     #endif
01232 
01233 private:
01234     bool cdata;         // true if this should be input and output as a CDATA style text element
01235 };
01236 
01237 
01251 class TiXmlDeclaration : public TiXmlNode
01252 {
01253 public:
01255     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
01256 
01257 #ifdef TIXML_USE_STL
01259     TiXmlDeclaration(   const std::string& _version,
01260                         const std::string& _encoding,
01261                         const std::string& _standalone );
01262 #endif
01263 
01265     TiXmlDeclaration(   const char* _version,
01266                         const char* _encoding,
01267                         const char* _standalone );
01268 
01269     TiXmlDeclaration( const TiXmlDeclaration& copy );
01270     void operator=( const TiXmlDeclaration& copy );
01271 
01272     virtual ~TiXmlDeclaration() {}
01273 
01275     const char *Version() const         { return version.c_str (); }
01277     const char *Encoding() const        { return encoding.c_str (); }
01279     const char *Standalone() const      { return standalone.c_str (); }
01280 
01282     virtual TiXmlNode* Clone() const;
01283     // Print this declaration to a FILE stream.
01284     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01285     virtual void Print( FILE* cfile, int depth ) const {
01286         Print( cfile, depth, 0 );
01287     }
01288 
01289     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01290 
01291     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 
01292     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } 
01293 
01296     virtual bool Accept( TiXmlVisitor* visitor ) const;
01297 
01298 protected:
01299     void CopyTo( TiXmlDeclaration* target ) const;
01300     // used to be public
01301     #ifdef TIXML_USE_STL
01302     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01303     #endif
01304 
01305 private:
01306 
01307     TIXML_STRING version;
01308     TIXML_STRING encoding;
01309     TIXML_STRING standalone;
01310 };
01311 
01312 
01320 class TiXmlUnknown : public TiXmlNode
01321 {
01322 public:
01323     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )    {}
01324     virtual ~TiXmlUnknown() {}
01325 
01326     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )      { copy.CopyTo( this ); }
01327     void operator=( const TiXmlUnknown& copy )                                      { copy.CopyTo( this ); }
01328 
01330     virtual TiXmlNode* Clone() const;
01331     // Print this Unknown to a FILE stream.
01332     virtual void Print( FILE* cfile, int depth ) const;
01333 
01334     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01335 
01336     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } 
01337     virtual TiXmlUnknown*           ToUnknown()     { return this; } 
01338 
01341     virtual bool Accept( TiXmlVisitor* content ) const;
01342 
01343 protected:
01344     void CopyTo( TiXmlUnknown* target ) const;
01345 
01346     #ifdef TIXML_USE_STL
01347     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01348     #endif
01349 
01350 private:
01351 
01352 };
01353 
01354 
01359 class TiXmlDocument : public TiXmlNode
01360 {
01361 public:
01363     TiXmlDocument();
01365     TiXmlDocument( const char * documentName );
01366 
01367     #ifdef TIXML_USE_STL
01369     TiXmlDocument( const std::string& documentName );
01370     #endif
01371 
01372     TiXmlDocument( const TiXmlDocument& copy );
01373     void operator=( const TiXmlDocument& copy );
01374 
01375     virtual ~TiXmlDocument() {}
01376 
01381     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01383     bool SaveFile() const;
01385     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01387     bool SaveFile( const char * filename ) const;
01393     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01395     bool SaveFile( FILE* ) const;
01396 
01397     #ifdef TIXML_USE_STL
01398     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           
01399     {
01400 //      StringToBuffer f( filename );
01401 //      return ( f.buffer && LoadFile( f.buffer, encoding ));
01402         return LoadFile( filename.c_str(), encoding );
01403     }
01404     bool SaveFile( const std::string& filename ) const      
01405     {
01406 //      StringToBuffer f( filename );
01407 //      return ( f.buffer && SaveFile( f.buffer ));
01408         return SaveFile( filename.c_str() );
01409     }
01410     #endif
01411 
01416     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01417 
01422     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
01423     TiXmlElement* RootElement()                 { return FirstChildElement(); }
01424 
01430     bool Error() const                      { return error; }
01431 
01433     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01434 
01438     int ErrorId()   const               { return errorId; }
01439 
01447     int ErrorRow() const    { return errorLocation.row+1; }
01448     int ErrorCol() const    { return errorLocation.col+1; } 
01449 
01474     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01475 
01476     int TabSize() const { return tabsize; }
01477 
01481     void ClearError()                       {   error = false; 
01482                                                 errorId = 0; 
01483                                                 errorDesc = ""; 
01484                                                 errorLocation.row = errorLocation.col = 0; 
01485                                                 //errorLocation.last = 0; 
01486                                             }
01487 
01489     void Print() const                      { Print( stdout, 0 ); }
01490 
01491     /* Write the document to a string using formatted printing ("pretty print"). This
01492         will allocate a character array (new char[]) and return it as a pointer. The
01493         calling code pust call delete[] on the return char* to avoid a memory leak.
01494     */
01495     //char* PrintToMemory() const; 
01496 
01498     virtual void Print( FILE* cfile, int depth = 0 ) const;
01499     // [internal use]
01500     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01501 
01502     virtual const TiXmlDocument*    ToDocument()    const { return this; } 
01503     virtual TiXmlDocument*          ToDocument()          { return this; } 
01504 
01507     virtual bool Accept( TiXmlVisitor* content ) const;
01508 
01509 protected :
01510     // [internal use]
01511     virtual TiXmlNode* Clone() const;
01512     #ifdef TIXML_USE_STL
01513     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01514     #endif
01515 
01516 private:
01517     void CopyTo( TiXmlDocument* target ) const;
01518 
01519     bool error;
01520     int  errorId;
01521     TIXML_STRING errorDesc;
01522     int tabsize;
01523     TiXmlCursor errorLocation;
01524     bool useMicrosoftBOM;       // the UTF-8 BOM were found when read. Note this, and try to write.
01525 };
01526 
01527 
01608 class TiXmlHandle
01609 {
01610 public:
01612     TiXmlHandle( TiXmlNode* _node )                 { this->node = _node; }
01614     TiXmlHandle( const TiXmlHandle& ref )           { this->node = ref.node; }
01615     TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
01616 
01618     TiXmlHandle FirstChild() const;
01620     TiXmlHandle FirstChild( const char * value ) const;
01622     TiXmlHandle FirstChildElement() const;
01624     TiXmlHandle FirstChildElement( const char * value ) const;
01625 
01629     TiXmlHandle Child( const char* value, int index ) const;
01633     TiXmlHandle Child( int index ) const;
01638     TiXmlHandle ChildElement( const char* value, int index ) const;
01643     TiXmlHandle ChildElement( int index ) const;
01644 
01645     #ifdef TIXML_USE_STL
01646     TiXmlHandle FirstChild( const std::string& _value ) const               { return FirstChild( _value.c_str() ); }
01647     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01648 
01649     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
01650     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01651     #endif
01652 
01655     TiXmlNode* ToNode() const           { return node; } 
01658     TiXmlElement* ToElement() const     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01661     TiXmlText* ToText() const           { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01664     TiXmlUnknown* ToUnknown() const     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01665 
01669     TiXmlNode* Node() const         { return ToNode(); } 
01673     TiXmlElement* Element() const   { return ToElement(); }
01677     TiXmlText* Text() const         { return ToText(); }
01681     TiXmlUnknown* Unknown() const   { return ToUnknown(); }
01682 
01683 private:
01684     TiXmlNode* node;
01685 };
01686 
01687 
01707 class TiXmlPrinter : public TiXmlVisitor
01708 {
01709 public:
01710     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01711                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
01712 
01713     virtual bool VisitEnter( const TiXmlDocument& doc );
01714     virtual bool VisitExit( const TiXmlDocument& doc );
01715 
01716     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01717     virtual bool VisitExit( const TiXmlElement& element );
01718 
01719     virtual bool Visit( const TiXmlDeclaration& declaration );
01720     virtual bool Visit( const TiXmlText& text );
01721     virtual bool Visit( const TiXmlComment& comment );
01722     virtual bool Visit( const TiXmlUnknown& unknown );
01723 
01727     void SetIndent( const char* _indent )           { indent = _indent ? _indent : "" ; }
01729     const char* Indent()                            { return indent.c_str(); }
01734     void SetLineBreak( const char* _lineBreak )     { lineBreak = _lineBreak ? _lineBreak : ""; }
01736     const char* LineBreak()                         { return lineBreak.c_str(); }
01737 
01741     void SetStreamPrinting()                        { indent = "";
01742                                                       lineBreak = "";
01743                                                     }   
01745     const char* CStr()                              { return buffer.c_str(); }
01747     size_t Size()                                   { return buffer.size(); }
01748 
01749     #ifdef TIXML_USE_STL
01751     const std::string& Str()                        { return buffer; }
01752     #endif
01753 
01754 private:
01755     void DoIndent() {
01756         for( int i=0; i<depth; ++i )
01757             buffer += indent;
01758     }
01759     void DoLineBreak() {
01760         buffer += lineBreak;
01761     }
01762 
01763     int depth;
01764     bool simpleTextPrint;
01765     TIXML_STRING buffer;
01766     TIXML_STRING indent;
01767     TIXML_STRING lineBreak;
01768 };
01769 
01770 
01771 #ifdef _MSC_VER
01772 #pragma warning( pop )
01773 #endif
01774 
01775 #endif
01776 

Generated on Tue Sep 19 19:04:34 2006 for TinyXml by  doxygen 1.4.7