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_SSCANF   sscanf_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_SSCANF   sscanf
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_SSCANF   sscanf
00077     #else
00078         #define TIXML_SNPRINTF snprintf
00079         #define TIXML_SSCANF   sscanf
00080     #endif
00081 #endif  
00082 
00083 class TiXmlDocument;
00084 class TiXmlElement;
00085 class TiXmlComment;
00086 class TiXmlUnknown;
00087 class TiXmlAttribute;
00088 class TiXmlText;
00089 class TiXmlDeclaration;
00090 class TiXmlParsingData;
00091 
00092 const int TIXML_MAJOR_VERSION = 2;
00093 const int TIXML_MINOR_VERSION = 6;
00094 const int TIXML_PATCH_VERSION = 0;
00095 
00096 /*  Internal structure for tracking location of items 
00097     in the XML file.
00098 */
00099 struct TiXmlCursor
00100 {
00101     TiXmlCursor()       { Clear(); }
00102     void Clear()        { row = col = -1; }
00103 
00104     int row;    // 0 based.
00105     int col;    // 0 based.
00106 };
00107 
00108 
00128 class TiXmlVisitor
00129 {
00130 public:
00131     virtual ~TiXmlVisitor() {}
00132 
00134     virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )         { return true; }
00136     virtual bool VisitExit( const TiXmlDocument& /*doc*/ )          { return true; }
00137 
00139     virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
00141     virtual bool VisitExit( const TiXmlElement& /*element*/ )       { return true; }
00142 
00144     virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
00146     virtual bool Visit( const TiXmlText& /*text*/ )                 { return true; }
00148     virtual bool Visit( const TiXmlComment& /*comment*/ )           { return true; }
00150     virtual bool Visit( const TiXmlUnknown& /*unknown*/ )           { return true; }
00151 };
00152 
00153 // Only used by Attribute::Query functions
00154 enum 
00155 { 
00156     TIXML_SUCCESS,
00157     TIXML_NO_ATTRIBUTE,
00158     TIXML_WRONG_TYPE
00159 };
00160 
00161 
00162 // Used by the parsing routines.
00163 enum TiXmlEncoding
00164 {
00165     TIXML_ENCODING_UNKNOWN,
00166     TIXML_ENCODING_UTF8,
00167     TIXML_ENCODING_LEGACY
00168 };
00169 
00170 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00171 
00194 class TiXmlBase
00195 {
00196     friend class TiXmlNode;
00197     friend class TiXmlElement;
00198     friend class TiXmlDocument;
00199 
00200 public:
00201     TiXmlBase() :   userData(0)     {}
00202     virtual ~TiXmlBase()            {}
00203 
00213     virtual void Print( FILE* cfile, int depth ) const = 0;
00214 
00221     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00222 
00224     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00225 
00244     int Row() const         { return location.row + 1; }
00245     int Column() const      { return location.col + 1; }    
00246 
00247     void  SetUserData( void* user )         { userData = user; }    
00248     void* GetUserData()                     { return userData; }    
00249     const void* GetUserData() const         { return userData; }    
00250 
00251     // Table that returs, for a given lead byte, the total number of bytes
00252     // in the UTF-8 sequence.
00253     static const int utf8ByteTable[256];
00254 
00255     virtual const char* Parse(  const char* p, 
00256                                 TiXmlParsingData* data, 
00257                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00258 
00262     static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
00263 
00264     enum
00265     {
00266         TIXML_NO_ERROR = 0,
00267         TIXML_ERROR,
00268         TIXML_ERROR_OPENING_FILE,
00269         TIXML_ERROR_PARSING_ELEMENT,
00270         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00271         TIXML_ERROR_READING_ELEMENT_VALUE,
00272         TIXML_ERROR_READING_ATTRIBUTES,
00273         TIXML_ERROR_PARSING_EMPTY,
00274         TIXML_ERROR_READING_END_TAG,
00275         TIXML_ERROR_PARSING_UNKNOWN,
00276         TIXML_ERROR_PARSING_COMMENT,
00277         TIXML_ERROR_PARSING_DECLARATION,
00278         TIXML_ERROR_DOCUMENT_EMPTY,
00279         TIXML_ERROR_EMBEDDED_NULL,
00280         TIXML_ERROR_PARSING_CDATA,
00281         TIXML_ERROR_DOCUMENT_TOP_ONLY,
00282 
00283         TIXML_ERROR_STRING_COUNT
00284     };
00285 
00286 protected:
00287 
00288     static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00289 
00290     inline static bool IsWhiteSpace( char c )       
00291     { 
00292         return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00293     }
00294     inline static bool IsWhiteSpace( int c )
00295     {
00296         if ( c < 256 )
00297             return IsWhiteSpace( (char) c );
00298         return false;   // Again, only truly correct for English/Latin...but usually works.
00299     }
00300 
00301     #ifdef TIXML_USE_STL
00302     static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00303     static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00304     #endif
00305 
00306     /*  Reads an XML name into the string provided. Returns
00307         a pointer just past the last character of the name,
00308         or 0 if the function has an error.
00309     */
00310     static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00311 
00312     /*  Reads text. Returns a pointer past the given end tag.
00313         Wickedly complex options, but it keeps the (sensitive) code in one place.
00314     */
00315     static const char* ReadText(    const char* in,             // where to start
00316                                     TIXML_STRING* text,         // the string read
00317                                     bool ignoreWhiteSpace,      // whether to keep the white space
00318                                     const char* endTag,         // what ends this text
00319                                     bool ignoreCase,            // whether to ignore case in the end tag
00320                                     TiXmlEncoding encoding );   // the current encoding
00321 
00322     // If an entity has been found, transform it into a character.
00323     static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00324 
00325     // Get a character, while interpreting entities.
00326     // The length can be from 0 to 4 bytes.
00327     inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00328     {
00329         assert( p );
00330         if ( encoding == TIXML_ENCODING_UTF8 )
00331         {
00332             *length = utf8ByteTable[ *((const unsigned char*)p) ];
00333             assert( *length >= 0 && *length < 5 );
00334         }
00335         else
00336         {
00337             *length = 1;
00338         }
00339 
00340         if ( *length == 1 )
00341         {
00342             if ( *p == '&' )
00343                 return GetEntity( p, _value, length, encoding );
00344             *_value = *p;
00345             return p+1;
00346         }
00347         else if ( *length )
00348         {
00349             //strncpy( _value, p, *length );    // lots of compilers don't like this function (unsafe),
00350                                                 // and the null terminator isn't needed
00351             for( int i=0; p[i] && i<*length; ++i ) {
00352                 _value[i] = p[i];
00353             }
00354             return p + (*length);
00355         }
00356         else
00357         {
00358             // Not valid text.
00359             return 0;
00360         }
00361     }
00362 
00363     // Return true if the next characters in the stream are any of the endTag sequences.
00364     // Ignore case only works for english, and should only be relied on when comparing
00365     // to English words: StringEqual( p, "version", true ) is fine.
00366     static bool StringEqual(    const char* p,
00367                                 const char* endTag,
00368                                 bool ignoreCase,
00369                                 TiXmlEncoding encoding );
00370 
00371     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00372 
00373     TiXmlCursor location;
00374 
00376     void*           userData;
00377     
00378     // None of these methods are reliable for any language except English.
00379     // Good for approximation, not great for accuracy.
00380     static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00381     static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00382     inline static int ToLower( int v, TiXmlEncoding encoding )
00383     {
00384         if ( encoding == TIXML_ENCODING_UTF8 )
00385         {
00386             if ( v < 128 ) return tolower( v );
00387             return v;
00388         }
00389         else
00390         {
00391             return tolower( v );
00392         }
00393     }
00394     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00395 
00396 private:
00397     TiXmlBase( const TiXmlBase& );              // not implemented.
00398     void operator=( const TiXmlBase& base );    // not allowed.
00399 
00400     struct Entity
00401     {
00402         const char*     str;
00403         unsigned int    strLength;
00404         char            chr;
00405     };
00406     enum
00407     {
00408         NUM_ENTITY = 5,
00409         MAX_ENTITY_LENGTH = 6
00410 
00411     };
00412     static Entity entity[ NUM_ENTITY ];
00413     static bool condenseWhiteSpace;
00414 };
00415 
00416 
00423 class TiXmlNode : public TiXmlBase
00424 {
00425     friend class TiXmlDocument;
00426     friend class TiXmlElement;
00427 
00428 public:
00429     #ifdef TIXML_USE_STL    
00430 
00434         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00435 
00452         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00453 
00455         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00456 
00457     #endif
00458 
00462     enum NodeType
00463     {
00464         TINYXML_DOCUMENT,
00465         TINYXML_ELEMENT,
00466         TINYXML_COMMENT,
00467         TINYXML_UNKNOWN,
00468         TINYXML_TEXT,
00469         TINYXML_DECLARATION,
00470         TINYXML_TYPECOUNT
00471     };
00472 
00473     virtual ~TiXmlNode();
00474 
00487     const char *Value() const { return value.c_str (); }
00488 
00489     #ifdef TIXML_USE_STL
00490 
00494     const std::string& ValueStr() const { return value; }
00495     #endif
00496 
00497     const TIXML_STRING& ValueTStr() const { return value; }
00498 
00508     void SetValue(const char * _value) { value = _value;}
00509 
00510     #ifdef TIXML_USE_STL
00512     void SetValue( const std::string& _value )  { value = _value; }
00513     #endif
00514 
00516     void Clear();
00517 
00519     TiXmlNode* Parent()                         { return parent; }
00520     const TiXmlNode* Parent() const             { return parent; }
00521 
00522     const TiXmlNode* FirstChild()   const       { return firstChild; }  
00523     TiXmlNode* FirstChild()                     { return firstChild; }
00524     const TiXmlNode* FirstChild( const char * value ) const;            
00525 
00526     TiXmlNode* FirstChild( const char * _value ) {
00527         // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00528         // call the method, cast the return back to non-const.
00529         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00530     }
00531     const TiXmlNode* LastChild() const  { return lastChild; }       
00532     TiXmlNode* LastChild()  { return lastChild; }
00533     
00534     const TiXmlNode* LastChild( const char * value ) const;         
00535     TiXmlNode* LastChild( const char * _value ) {
00536         return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00537     }
00538 
00539     #ifdef TIXML_USE_STL
00540     const TiXmlNode* FirstChild( const std::string& _value ) const  {   return FirstChild (_value.c_str ());    }   
00541     TiXmlNode* FirstChild( const std::string& _value )              {   return FirstChild (_value.c_str ());    }   
00542     const TiXmlNode* LastChild( const std::string& _value ) const   {   return LastChild (_value.c_str ()); }   
00543     TiXmlNode* LastChild( const std::string& _value )               {   return LastChild (_value.c_str ()); }   
00544     #endif
00545 
00562     const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00563     TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00564         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00565     }
00566 
00568     const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00569     TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00570         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00571     }
00572 
00573     #ifdef TIXML_USE_STL
00574     const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   
00575     TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous); }   
00576     #endif
00577 
00581     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00582 
00583 
00593     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00594 
00598     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00599 
00603     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00604 
00608     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00609 
00611     bool RemoveChild( TiXmlNode* removeThis );
00612 
00614     const TiXmlNode* PreviousSibling() const            { return prev; }
00615     TiXmlNode* PreviousSibling()                        { return prev; }
00616 
00618     const TiXmlNode* PreviousSibling( const char * ) const;
00619     TiXmlNode* PreviousSibling( const char *_prev ) {
00620         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00621     }
00622 
00623     #ifdef TIXML_USE_STL
00624     const TiXmlNode* PreviousSibling( const std::string& _value ) const {   return PreviousSibling (_value.c_str ());   }   
00625     TiXmlNode* PreviousSibling( const std::string& _value )             {   return PreviousSibling (_value.c_str ());   }   
00626     const TiXmlNode* NextSibling( const std::string& _value) const      {   return NextSibling (_value.c_str ());   }   
00627     TiXmlNode* NextSibling( const std::string& _value)                  {   return NextSibling (_value.c_str ());   }   
00628     #endif
00629 
00631     const TiXmlNode* NextSibling() const                { return next; }
00632     TiXmlNode* NextSibling()                            { return next; }
00633 
00635     const TiXmlNode* NextSibling( const char * ) const;
00636     TiXmlNode* NextSibling( const char* _next ) {
00637         return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00638     }
00639 
00644     const TiXmlElement* NextSiblingElement() const;
00645     TiXmlElement* NextSiblingElement() {
00646         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00647     }
00648 
00653     const TiXmlElement* NextSiblingElement( const char * ) const;
00654     TiXmlElement* NextSiblingElement( const char *_next ) {
00655         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00656     }
00657 
00658     #ifdef TIXML_USE_STL
00659     const TiXmlElement* NextSiblingElement( const std::string& _value) const    {   return NextSiblingElement (_value.c_str ());    }   
00660     TiXmlElement* NextSiblingElement( const std::string& _value)                {   return NextSiblingElement (_value.c_str ());    }   
00661     #endif
00662 
00664     const TiXmlElement* FirstChildElement() const;
00665     TiXmlElement* FirstChildElement() {
00666         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00667     }
00668 
00670     const TiXmlElement* FirstChildElement( const char * _value ) const;
00671     TiXmlElement* FirstChildElement( const char * _value ) {
00672         return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00673     }
00674 
00675     #ifdef TIXML_USE_STL
00676     const TiXmlElement* FirstChildElement( const std::string& _value ) const    {   return FirstChildElement (_value.c_str ()); }   
00677     TiXmlElement* FirstChildElement( const std::string& _value )                {   return FirstChildElement (_value.c_str ()); }   
00678     #endif
00679 
00684     int Type() const    { return type; }
00685 
00689     const TiXmlDocument* GetDocument() const;
00690     TiXmlDocument* GetDocument() {
00691         return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00692     }
00693 
00695     bool NoChildren() const                     { return !firstChild; }
00696 
00697     virtual const TiXmlDocument*    ToDocument()    const { return 0; } 
00698     virtual const TiXmlElement*     ToElement()     const { return 0; } 
00699     virtual const TiXmlComment*     ToComment()     const { return 0; } 
00700     virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } 
00701     virtual const TiXmlText*        ToText()        const { return 0; } 
00702     virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } 
00703 
00704     virtual TiXmlDocument*          ToDocument()    { return 0; } 
00705     virtual TiXmlElement*           ToElement()     { return 0; } 
00706     virtual TiXmlComment*           ToComment()     { return 0; } 
00707     virtual TiXmlUnknown*           ToUnknown()     { return 0; } 
00708     virtual TiXmlText*              ToText()        { return 0; } 
00709     virtual TiXmlDeclaration*       ToDeclaration() { return 0; } 
00710 
00714     virtual TiXmlNode* Clone() const = 0;
00715 
00738     virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00739 
00740 protected:
00741     TiXmlNode( NodeType _type );
00742 
00743     // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00744     // and the assignment operator.
00745     void CopyTo( TiXmlNode* target ) const;
00746 
00747     #ifdef TIXML_USE_STL
00748         // The real work of the input operator.
00749     virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00750     #endif
00751 
00752     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00753     TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00754 
00755     TiXmlNode*      parent;
00756     NodeType        type;
00757 
00758     TiXmlNode*      firstChild;
00759     TiXmlNode*      lastChild;
00760 
00761     TIXML_STRING    value;
00762 
00763     TiXmlNode*      prev;
00764     TiXmlNode*      next;
00765 
00766 private:
00767     TiXmlNode( const TiXmlNode& );              // not implemented.
00768     void operator=( const TiXmlNode& base );    // not allowed.
00769 };
00770 
00771 
00779 class TiXmlAttribute : public TiXmlBase
00780 {
00781     friend class TiXmlAttributeSet;
00782 
00783 public:
00785     TiXmlAttribute() : TiXmlBase()
00786     {
00787         document = 0;
00788         prev = next = 0;
00789     }
00790 
00791     #ifdef TIXML_USE_STL
00793     TiXmlAttribute( const std::string& _name, const std::string& _value )
00794     {
00795         name = _name;
00796         value = _value;
00797         document = 0;
00798         prev = next = 0;
00799     }
00800     #endif
00801 
00803     TiXmlAttribute( const char * _name, const char * _value )
00804     {
00805         name = _name;
00806         value = _value;
00807         document = 0;
00808         prev = next = 0;
00809     }
00810 
00811     const char*     Name()  const       { return name.c_str(); }        
00812     const char*     Value() const       { return value.c_str(); }       
00813     #ifdef TIXML_USE_STL
00814     const std::string& ValueStr() const { return value; }               
00815     #endif
00816     int             IntValue() const;                                   
00817     double          DoubleValue() const;                                
00818 
00819     // Get the tinyxml string representation
00820     const TIXML_STRING& NameTStr() const { return name; }
00821 
00831     int QueryIntValue( int* _value ) const;
00833     int QueryDoubleValue( double* _value ) const;
00834 
00835     void SetName( const char* _name )   { name = _name; }               
00836     void SetValue( const char* _value ) { value = _value; }             
00837 
00838     void SetIntValue( int _value );                                     
00839     void SetDoubleValue( double _value );                               
00840 
00841     #ifdef TIXML_USE_STL
00843     void SetName( const std::string& _name )    { name = _name; }   
00845     void SetValue( const std::string& _value )  { value = _value; }
00846     #endif
00847 
00849     const TiXmlAttribute* Next() const;
00850     TiXmlAttribute* Next() {
00851         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00852     }
00853 
00855     const TiXmlAttribute* Previous() const;
00856     TiXmlAttribute* Previous() {
00857         return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00858     }
00859 
00860     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00861     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00862     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00863 
00864     /*  Attribute parsing starts: first letter of the name
00865                          returns: the next char after the value end quote
00866     */
00867     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00868 
00869     // Prints this Attribute to a FILE stream.
00870     virtual void Print( FILE* cfile, int depth ) const {
00871         Print( cfile, depth, 0 );
00872     }
00873     void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00874 
00875     // [internal use]
00876     // Set the document pointer so the attribute can report errors.
00877     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00878 
00879 private:
00880     TiXmlAttribute( const TiXmlAttribute& );                // not implemented.
00881     void operator=( const TiXmlAttribute& base );   // not allowed.
00882 
00883     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00884     TIXML_STRING name;
00885     TIXML_STRING value;
00886     TiXmlAttribute* prev;
00887     TiXmlAttribute* next;
00888 };
00889 
00890 
00891 /*  A class used to manage a group of attributes.
00892     It is only used internally, both by the ELEMENT and the DECLARATION.
00893     
00894     The set can be changed transparent to the Element and Declaration
00895     classes that use it, but NOT transparent to the Attribute
00896     which has to implement a next() and previous() method. Which makes
00897     it a bit problematic and prevents the use of STL.
00898 
00899     This version is implemented with circular lists because:
00900         - I like circular lists
00901         - it demonstrates some independence from the (typical) doubly linked list.
00902 */
00903 class TiXmlAttributeSet
00904 {
00905 public:
00906     TiXmlAttributeSet();
00907     ~TiXmlAttributeSet();
00908 
00909     void Add( TiXmlAttribute* attribute );
00910     void Remove( TiXmlAttribute* attribute );
00911 
00912     const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00913     TiXmlAttribute* First()                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00914     const TiXmlAttribute* Last() const      { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00915     TiXmlAttribute* Last()                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00916 
00917     TiXmlAttribute* Find( const char* _name ) const;
00918     TiXmlAttribute* FindOrCreate( const char* _name );
00919 
00920 #   ifdef TIXML_USE_STL
00921     TiXmlAttribute* Find( const std::string& _name ) const;
00922     TiXmlAttribute* FindOrCreate( const std::string& _name );
00923 #   endif
00924 
00925 
00926 private:
00927     //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00928     //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00929     TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00930     void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
00931 
00932     TiXmlAttribute sentinel;
00933 };
00934 
00935 
00940 class TiXmlElement : public TiXmlNode
00941 {
00942 public:
00944     TiXmlElement (const char * in_value);
00945 
00946     #ifdef TIXML_USE_STL
00948     TiXmlElement( const std::string& _value );
00949     #endif
00950 
00951     TiXmlElement( const TiXmlElement& );
00952 
00953     void operator=( const TiXmlElement& base );
00954 
00955     virtual ~TiXmlElement();
00956 
00960     const char* Attribute( const char* name ) const;
00961 
00968     const char* Attribute( const char* name, int* i ) const;
00969 
00976     const char* Attribute( const char* name, double* d ) const;
00977 
00985     int QueryIntAttribute( const char* name, int* _value ) const;
00987     int QueryDoubleAttribute( const char* name, double* _value ) const;
00989     int QueryFloatAttribute( const char* name, float* _value ) const {
00990         double d;
00991         int result = QueryDoubleAttribute( name, &d );
00992         if ( result == TIXML_SUCCESS ) {
00993             *_value = (float)d;
00994         }
00995         return result;
00996     }
00997 
00998     #ifdef TIXML_USE_STL
01000     int QueryStringAttribute( const char* name, std::string* _value ) const {
01001         const char* cstr = Attribute( name );
01002         if ( cstr ) {
01003             *_value = std::string( cstr );
01004             return TIXML_SUCCESS;
01005         }
01006         return TIXML_NO_ATTRIBUTE;
01007     }
01008 
01017     template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01018     {
01019         const TiXmlAttribute* node = attributeSet.Find( name );
01020         if ( !node )
01021             return TIXML_NO_ATTRIBUTE;
01022 
01023         std::stringstream sstream( node->ValueStr() );
01024         sstream >> *outValue;
01025         if ( !sstream.fail() )
01026             return TIXML_SUCCESS;
01027         return TIXML_WRONG_TYPE;
01028     }
01029 
01030     int QueryValueAttribute( const std::string& name, std::string* outValue ) const
01031     {
01032         const TiXmlAttribute* node = attributeSet.Find( name );
01033         if ( !node )
01034             return TIXML_NO_ATTRIBUTE;
01035         *outValue = node->ValueStr();
01036         return TIXML_SUCCESS;
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 );
01057     void SetDoubleAttribute( const std::string& name, double value );
01058     #endif
01059 
01063     void SetAttribute( const char * name, int value );
01064 
01068     void SetDoubleAttribute( const char * name, double value );
01069 
01072     void RemoveAttribute( const char * name );
01073     #ifdef TIXML_USE_STL
01074     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   
01075     #endif
01076 
01077     const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }        
01078     TiXmlAttribute* FirstAttribute()                { return attributeSet.First(); }
01079     const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }     
01080     TiXmlAttribute* LastAttribute()                 { return attributeSet.Last(); }
01081 
01114     const char* GetText() const;
01115 
01117     virtual TiXmlNode* Clone() const;
01118     // Print the Element to a FILE stream.
01119     virtual void Print( FILE* cfile, int depth ) const;
01120 
01121     /*  Attribtue parsing starts: next char past '<'
01122                          returns: next char past '>'
01123     */
01124     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01125 
01126     virtual const TiXmlElement*     ToElement()     const { return this; } 
01127     virtual TiXmlElement*           ToElement()           { return this; } 
01128 
01131     virtual bool Accept( TiXmlVisitor* visitor ) const;
01132 
01133 protected:
01134 
01135     void CopyTo( TiXmlElement* target ) const;
01136     void ClearThis();   // like clear, but initializes 'this' object as well
01137 
01138     // Used to be public [internal use]
01139     #ifdef TIXML_USE_STL
01140     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01141     #endif
01142     /*  [internal use]
01143         Reads the "value" of the element -- another element, or text.
01144         This should terminate with the current end tag.
01145     */
01146     const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01147 
01148 private:
01149     TiXmlAttributeSet attributeSet;
01150 };
01151 
01152 
01155 class TiXmlComment : public TiXmlNode
01156 {
01157 public:
01159     TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
01161     TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
01162         SetValue( _value );
01163     }
01164     TiXmlComment( const TiXmlComment& );
01165     void operator=( const TiXmlComment& base );
01166 
01167     virtual ~TiXmlComment() {}
01168 
01170     virtual TiXmlNode* Clone() const;
01171     // Write this Comment to a FILE stream.
01172     virtual void Print( FILE* cfile, int depth ) const;
01173 
01174     /*  Attribtue parsing starts: at the ! of the !--
01175                          returns: next char past '>'
01176     */
01177     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01178 
01179     virtual const TiXmlComment*  ToComment() const { return this; } 
01180     virtual TiXmlComment*  ToComment() { return this; } 
01181 
01184     virtual bool Accept( TiXmlVisitor* visitor ) const;
01185 
01186 protected:
01187     void CopyTo( TiXmlComment* target ) const;
01188 
01189     // used to be public
01190     #ifdef TIXML_USE_STL
01191     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01192     #endif
01193 //  virtual void StreamOut( TIXML_OSTREAM * out ) const;
01194 
01195 private:
01196 
01197 };
01198 
01199 
01205 class TiXmlText : public TiXmlNode
01206 {
01207     friend class TiXmlElement;
01208 public:
01213     TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01214     {
01215         SetValue( initValue );
01216         cdata = false;
01217     }
01218     virtual ~TiXmlText() {}
01219 
01220     #ifdef TIXML_USE_STL
01222     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01223     {
01224         SetValue( initValue );
01225         cdata = false;
01226     }
01227     #endif
01228 
01229     TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )   { copy.CopyTo( this ); }
01230     void operator=( const TiXmlText& base )                             { base.CopyTo( this ); }
01231 
01232     // Write this text object to a FILE stream.
01233     virtual void Print( FILE* cfile, int depth ) const;
01234 
01236     bool CDATA() const              { return cdata; }
01238     void SetCDATA( bool _cdata )    { cdata = _cdata; }
01239 
01240     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01241 
01242     virtual const TiXmlText* ToText() const { return this; } 
01243     virtual TiXmlText*       ToText()       { return this; } 
01244 
01247     virtual bool Accept( TiXmlVisitor* content ) const;
01248 
01249 protected :
01251     virtual TiXmlNode* Clone() const;
01252     void CopyTo( TiXmlText* target ) const;
01253 
01254     bool Blank() const; // returns true if all white space and new lines
01255     // [internal use]
01256     #ifdef TIXML_USE_STL
01257     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01258     #endif
01259 
01260 private:
01261     bool cdata;         // true if this should be input and output as a CDATA style text element
01262 };
01263 
01264 
01278 class TiXmlDeclaration : public TiXmlNode
01279 {
01280 public:
01282     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
01283 
01284 #ifdef TIXML_USE_STL
01286     TiXmlDeclaration(   const std::string& _version,
01287                         const std::string& _encoding,
01288                         const std::string& _standalone );
01289 #endif
01290 
01292     TiXmlDeclaration(   const char* _version,
01293                         const char* _encoding,
01294                         const char* _standalone );
01295 
01296     TiXmlDeclaration( const TiXmlDeclaration& copy );
01297     void operator=( const TiXmlDeclaration& copy );
01298 
01299     virtual ~TiXmlDeclaration() {}
01300 
01302     const char *Version() const         { return version.c_str (); }
01304     const char *Encoding() const        { return encoding.c_str (); }
01306     const char *Standalone() const      { return standalone.c_str (); }
01307 
01309     virtual TiXmlNode* Clone() const;
01310     // Print this declaration to a FILE stream.
01311     virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01312     virtual void Print( FILE* cfile, int depth ) const {
01313         Print( cfile, depth, 0 );
01314     }
01315 
01316     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01317 
01318     virtual const TiXmlDeclaration* ToDeclaration() const { return this; } 
01319     virtual TiXmlDeclaration*       ToDeclaration()       { return this; } 
01320 
01323     virtual bool Accept( TiXmlVisitor* visitor ) const;
01324 
01325 protected:
01326     void CopyTo( TiXmlDeclaration* target ) const;
01327     // used to be public
01328     #ifdef TIXML_USE_STL
01329     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01330     #endif
01331 
01332 private:
01333 
01334     TIXML_STRING version;
01335     TIXML_STRING encoding;
01336     TIXML_STRING standalone;
01337 };
01338 
01339 
01347 class TiXmlUnknown : public TiXmlNode
01348 {
01349 public:
01350     TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )    {}
01351     virtual ~TiXmlUnknown() {}
01352 
01353     TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )      { copy.CopyTo( this ); }
01354     void operator=( const TiXmlUnknown& copy )                                      { copy.CopyTo( this ); }
01355 
01357     virtual TiXmlNode* Clone() const;
01358     // Print this Unknown to a FILE stream.
01359     virtual void Print( FILE* cfile, int depth ) const;
01360 
01361     virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01362 
01363     virtual const TiXmlUnknown*     ToUnknown()     const { return this; } 
01364     virtual TiXmlUnknown*           ToUnknown()     { return this; } 
01365 
01368     virtual bool Accept( TiXmlVisitor* content ) const;
01369 
01370 protected:
01371     void CopyTo( TiXmlUnknown* target ) const;
01372 
01373     #ifdef TIXML_USE_STL
01374     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01375     #endif
01376 
01377 private:
01378 
01379 };
01380 
01381 
01386 class TiXmlDocument : public TiXmlNode
01387 {
01388 public:
01390     TiXmlDocument();
01392     TiXmlDocument( const char * documentName );
01393 
01394     #ifdef TIXML_USE_STL
01396     TiXmlDocument( const std::string& documentName );
01397     #endif
01398 
01399     TiXmlDocument( const TiXmlDocument& copy );
01400     void operator=( const TiXmlDocument& copy );
01401 
01402     virtual ~TiXmlDocument() {}
01403 
01408     bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01410     bool SaveFile() const;
01412     bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01414     bool SaveFile( const char * filename ) const;
01420     bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01422     bool SaveFile( FILE* ) const;
01423 
01424     #ifdef TIXML_USE_STL
01425     bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )           
01426     {
01427         return LoadFile( filename.c_str(), encoding );
01428     }
01429     bool SaveFile( const std::string& filename ) const      
01430     {
01431         return SaveFile( filename.c_str() );
01432     }
01433     #endif
01434 
01439     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01440 
01445     const TiXmlElement* RootElement() const     { return FirstChildElement(); }
01446     TiXmlElement* RootElement()                 { return FirstChildElement(); }
01447 
01453     bool Error() const                      { return error; }
01454 
01456     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01457 
01461     int ErrorId()   const               { return errorId; }
01462 
01470     int ErrorRow() const    { return errorLocation.row+1; }
01471     int ErrorCol() const    { return errorLocation.col+1; } 
01472 
01497     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01498 
01499     int TabSize() const { return tabsize; }
01500 
01504     void ClearError()                       {   error = false; 
01505                                                 errorId = 0; 
01506                                                 errorDesc = ""; 
01507                                                 errorLocation.row = errorLocation.col = 0; 
01508                                                 //errorLocation.last = 0; 
01509                                             }
01510 
01512     void Print() const                      { Print( stdout, 0 ); }
01513 
01514     /* Write the document to a string using formatted printing ("pretty print"). This
01515         will allocate a character array (new char[]) and return it as a pointer. The
01516         calling code pust call delete[] on the return char* to avoid a memory leak.
01517     */
01518     //char* PrintToMemory() const; 
01519 
01521     virtual void Print( FILE* cfile, int depth = 0 ) const;
01522     // [internal use]
01523     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01524 
01525     virtual const TiXmlDocument*    ToDocument()    const { return this; } 
01526     virtual TiXmlDocument*          ToDocument()          { return this; } 
01527 
01530     virtual bool Accept( TiXmlVisitor* content ) const;
01531 
01532 protected :
01533     // [internal use]
01534     virtual TiXmlNode* Clone() const;
01535     #ifdef TIXML_USE_STL
01536     virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01537     #endif
01538 
01539 private:
01540     void CopyTo( TiXmlDocument* target ) const;
01541 
01542     bool error;
01543     int  errorId;
01544     TIXML_STRING errorDesc;
01545     int tabsize;
01546     TiXmlCursor errorLocation;
01547     bool useMicrosoftBOM;       // the UTF-8 BOM were found when read. Note this, and try to write.
01548 };
01549 
01550 
01631 class TiXmlHandle
01632 {
01633 public:
01635     TiXmlHandle( TiXmlNode* _node )                 { this->node = _node; }
01637     TiXmlHandle( const TiXmlHandle& ref )           { this->node = ref.node; }
01638     TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
01639 
01641     TiXmlHandle FirstChild() const;
01643     TiXmlHandle FirstChild( const char * value ) const;
01645     TiXmlHandle FirstChildElement() const;
01647     TiXmlHandle FirstChildElement( const char * value ) const;
01648 
01652     TiXmlHandle Child( const char* value, int index ) const;
01656     TiXmlHandle Child( int index ) const;
01661     TiXmlHandle ChildElement( const char* value, int index ) const;
01666     TiXmlHandle ChildElement( int index ) const;
01667 
01668     #ifdef TIXML_USE_STL
01669     TiXmlHandle FirstChild( const std::string& _value ) const               { return FirstChild( _value.c_str() ); }
01670     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01671 
01672     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
01673     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01674     #endif
01675 
01678     TiXmlNode* ToNode() const           { return node; } 
01681     TiXmlElement* ToElement() const     { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01684     TiXmlText* ToText() const           { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01687     TiXmlUnknown* ToUnknown() const     { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01688 
01692     TiXmlNode* Node() const         { return ToNode(); } 
01696     TiXmlElement* Element() const   { return ToElement(); }
01700     TiXmlText* Text() const         { return ToText(); }
01704     TiXmlUnknown* Unknown() const   { return ToUnknown(); }
01705 
01706 private:
01707     TiXmlNode* node;
01708 };
01709 
01710 
01730 class TiXmlPrinter : public TiXmlVisitor
01731 {
01732 public:
01733     TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01734                      buffer(), indent( "    " ), lineBreak( "\n" ) {}
01735 
01736     virtual bool VisitEnter( const TiXmlDocument& doc );
01737     virtual bool VisitExit( const TiXmlDocument& doc );
01738 
01739     virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01740     virtual bool VisitExit( const TiXmlElement& element );
01741 
01742     virtual bool Visit( const TiXmlDeclaration& declaration );
01743     virtual bool Visit( const TiXmlText& text );
01744     virtual bool Visit( const TiXmlComment& comment );
01745     virtual bool Visit( const TiXmlUnknown& unknown );
01746 
01750     void SetIndent( const char* _indent )           { indent = _indent ? _indent : "" ; }
01752     const char* Indent()                            { return indent.c_str(); }
01757     void SetLineBreak( const char* _lineBreak )     { lineBreak = _lineBreak ? _lineBreak : ""; }
01759     const char* LineBreak()                         { return lineBreak.c_str(); }
01760 
01764     void SetStreamPrinting()                        { indent = "";
01765                                                       lineBreak = "";
01766                                                     }   
01768     const char* CStr()                              { return buffer.c_str(); }
01770     size_t Size()                                   { return buffer.size(); }
01771 
01772     #ifdef TIXML_USE_STL
01774     const std::string& Str()                        { return buffer; }
01775     #endif
01776 
01777 private:
01778     void DoIndent() {
01779         for( int i=0; i<depth; ++i )
01780             buffer += indent;
01781     }
01782     void DoLineBreak() {
01783         buffer += lineBreak;
01784     }
01785 
01786     int depth;
01787     bool simpleTextPrint;
01788     TIXML_STRING buffer;
01789     TIXML_STRING indent;
01790     TIXML_STRING lineBreak;
01791 };
01792 
01793 
01794 #ifdef _MSC_VER
01795 #pragma warning( pop )
01796 #endif
01797 
01798 #endif
01799 

Generated on Sat Mar 20 21:16:54 2010 for TinyXml by  doxygen 1.5.1-p1