tinyxml2.h
Go to the documentation of this file.
00001 /*
00002 Original code by Lee Thomason (www.grinninglizard.com)
00003 
00004 This software is provided 'as-is', without any express or implied
00005 warranty. In no event will the authors be held liable for any
00006 damages arising from the use of this software.
00007 
00008 Permission is granted to anyone to use this software for any
00009 purpose, including commercial applications, and to alter it and
00010 redistribute it freely, subject to the following restrictions:
00011 
00012 1. The origin of this software must not be misrepresented; you must
00013 not claim that you wrote the original software. If you use this
00014 software in a product, an acknowledgment in the product documentation
00015 would be appreciated but is not required.
00016 
00017 2. Altered source versions must be plainly marked as such, and
00018 must not be misrepresented as being the original software.
00019 
00020 3. This notice may not be removed or altered from any source
00021 distribution.
00022 */
00023 
00024 #ifndef TINYXML2_INCLUDED
00025 #define TINYXML2_INCLUDED
00026 
00027 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
00028 #   include <ctype.h>
00029 #   include <limits.h>
00030 #   include <stdio.h>
00031 #   include <stdlib.h>
00032 #   include <string.h>
00033 #       if defined(__PS3__)
00034 #               include <stddef.h>
00035 #       endif
00036 #else
00037 #   include <cctype>
00038 #   include <climits>
00039 #   include <cstdio>
00040 #   include <cstdlib>
00041 #   include <cstring>
00042 #endif
00043 #include <stdint.h>
00044 
00045 /*
00046    TODO: intern strings instead of allocation.
00047 */
00048 /*
00049         gcc:
00050         g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
00051 
00052     Formatting, Artistic Style:
00053         AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
00054 */
00055 
00056 #if defined( _DEBUG ) || defined (__DEBUG__)
00057 #   ifndef TINYXML2_DEBUG
00058 #       define TINYXML2_DEBUG
00059 #   endif
00060 #endif
00061 
00062 #ifdef _MSC_VER
00063 #   pragma warning(push)
00064 #   pragma warning(disable: 4251)
00065 #endif
00066 
00067 // Do NOT export. This version is meant to be linked statically only.
00068 #ifdef _WIN32
00069 #   define TINYXML2_LIB // TODO?
00070 #else
00071 #   define TINYXML2_LIB __attribute__((visibility("hidden")))
00072 #endif
00073 
00074 #if defined(TINYXML2_DEBUG)
00075 #   if defined(_MSC_VER)
00076 #       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
00077 #       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
00078 #   elif defined (ANDROID_NDK)
00079 #       include <android/log.h>
00080 #       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00081 #   else
00082 #       include <assert.h>
00083 #       define TIXMLASSERT                assert
00084 #   endif
00085 #else
00086 #   define TIXMLASSERT( x )               {}
00087 #endif
00088 
00089 
00090 /* Versioning, past 1.0.14:
00091         http://semver.org/
00092 */
00093 static const int TIXML2_MAJOR_VERSION = 6;
00094 static const int TIXML2_MINOR_VERSION = 2;
00095 static const int TIXML2_PATCH_VERSION = 0;
00096 
00097 #define TINYXML2_MAJOR_VERSION 6
00098 #define TINYXML2_MINOR_VERSION 2
00099 #define TINYXML2_PATCH_VERSION 0
00100 
00101 // A fixed element depth limit is problematic. There needs to be a 
00102 // limit to avoid a stack overflow. However, that limit varies per 
00103 // system, and the capacity of the stack. On the other hand, it's a trivial 
00104 // attack that can result from ill, malicious, or even correctly formed XML, 
00105 // so there needs to be a limit in place.
00106 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
00107 
00108 namespace tinyxml2
00109 {
00110 class XMLDocument;
00111 class XMLElement;
00112 class XMLAttribute;
00113 class XMLComment;
00114 class XMLText;
00115 class XMLDeclaration;
00116 class XMLUnknown;
00117 class XMLPrinter;
00118 
00119 /*
00120         A class that wraps strings. Normally stores the start and end
00121         pointers into the XML file itself, and will apply normalization
00122         and entity translation if actually read. Can also store (and memory
00123         manage) a traditional char[]
00124 */
00125 class StrPair
00126 {
00127 public:
00128     enum {
00129         NEEDS_ENTITY_PROCESSING                 = 0x01,
00130         NEEDS_NEWLINE_NORMALIZATION             = 0x02,
00131         NEEDS_WHITESPACE_COLLAPSING     = 0x04,
00132 
00133         TEXT_ELEMENT                        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00134         TEXT_ELEMENT_LEAVE_ENTITIES             = NEEDS_NEWLINE_NORMALIZATION,
00135         ATTRIBUTE_NAME                      = 0,
00136         ATTRIBUTE_VALUE                     = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00137         ATTRIBUTE_VALUE_LEAVE_ENTITIES  = NEEDS_NEWLINE_NORMALIZATION,
00138         COMMENT                                                 = NEEDS_NEWLINE_NORMALIZATION
00139     };
00140 
00141     StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00142     ~StrPair();
00143 
00144     void Set( char* start, char* end, int flags ) {
00145         TIXMLASSERT( start );
00146         TIXMLASSERT( end );
00147         Reset();
00148         _start  = start;
00149         _end    = end;
00150         _flags  = flags | NEEDS_FLUSH;
00151     }
00152 
00153     const char* GetStr();
00154 
00155     bool Empty() const {
00156         return _start == _end;
00157     }
00158 
00159     void SetInternedStr( const char* str ) {
00160         Reset();
00161         _start = const_cast<char*>(str);
00162     }
00163 
00164     void SetStr( const char* str, int flags=0 );
00165 
00166     char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
00167     char* ParseName( char* in );
00168 
00169     void TransferTo( StrPair* other );
00170         void Reset();
00171 
00172 private:
00173     void CollapseWhitespace();
00174 
00175     enum {
00176         NEEDS_FLUSH = 0x100,
00177         NEEDS_DELETE = 0x200
00178     };
00179 
00180     int     _flags;
00181     char*   _start;
00182     char*   _end;
00183 
00184     StrPair( const StrPair& other );    // not supported
00185     void operator=( StrPair& other );   // not supported, use TransferTo()
00186 };
00187 
00188 
00189 /*
00190         A dynamic array of Plain Old Data. Doesn't support constructors, etc.
00191         Has a small initial memory pool, so that low or no usage will not
00192         cause a call to new/delete
00193 */
00194 template <class T, int INITIAL_SIZE>
00195 class DynArray
00196 {
00197 public:
00198     DynArray() :
00199         _mem( _pool ),
00200         _allocated( INITIAL_SIZE ),
00201         _size( 0 )
00202     {
00203     }
00204 
00205     ~DynArray() {
00206         if ( _mem != _pool ) {
00207             delete [] _mem;
00208         }
00209     }
00210 
00211     void Clear() {
00212         _size = 0;
00213     }
00214 
00215     void Push( T t ) {
00216         TIXMLASSERT( _size < INT_MAX );
00217         EnsureCapacity( _size+1 );
00218         _mem[_size] = t;
00219         ++_size;
00220     }
00221 
00222     T* PushArr( int count ) {
00223         TIXMLASSERT( count >= 0 );
00224         TIXMLASSERT( _size <= INT_MAX - count );
00225         EnsureCapacity( _size+count );
00226         T* ret = &_mem[_size];
00227         _size += count;
00228         return ret;
00229     }
00230 
00231     T Pop() {
00232         TIXMLASSERT( _size > 0 );
00233         --_size;
00234         return _mem[_size];
00235     }
00236 
00237     void PopArr( int count ) {
00238         TIXMLASSERT( _size >= count );
00239         _size -= count;
00240     }
00241 
00242     bool Empty() const                                  {
00243         return _size == 0;
00244     }
00245 
00246     T& operator[](int i)                                {
00247         TIXMLASSERT( i>= 0 && i < _size );
00248         return _mem[i];
00249     }
00250 
00251     const T& operator[](int i) const    {
00252         TIXMLASSERT( i>= 0 && i < _size );
00253         return _mem[i];
00254     }
00255 
00256     const T& PeekTop() const            {
00257         TIXMLASSERT( _size > 0 );
00258         return _mem[ _size - 1];
00259     }
00260 
00261     int Size() const                                    {
00262         TIXMLASSERT( _size >= 0 );
00263         return _size;
00264     }
00265 
00266     int Capacity() const                                {
00267         TIXMLASSERT( _allocated >= INITIAL_SIZE );
00268         return _allocated;
00269     }
00270 
00271         void SwapRemove(int i) {
00272                 TIXMLASSERT(i >= 0 && i < _size);
00273                 TIXMLASSERT(_size > 0);
00274                 _mem[i] = _mem[_size - 1];
00275                 --_size;
00276         }
00277 
00278     const T* Mem() const                                {
00279         TIXMLASSERT( _mem );
00280         return _mem;
00281     }
00282 
00283     T* Mem()                                                    {
00284         TIXMLASSERT( _mem );
00285         return _mem;
00286     }
00287 
00288 private:
00289     DynArray( const DynArray& ); // not supported
00290     void operator=( const DynArray& ); // not supported
00291 
00292     void EnsureCapacity( int cap ) {
00293         TIXMLASSERT( cap > 0 );
00294         if ( cap > _allocated ) {
00295             TIXMLASSERT( cap <= INT_MAX / 2 );
00296             int newAllocated = cap * 2;
00297             T* newMem = new T[newAllocated];
00298             TIXMLASSERT( newAllocated >= _size );
00299             memcpy( newMem, _mem, sizeof(T)*_size );    // warning: not using constructors, only works for PODs
00300             if ( _mem != _pool ) {
00301                 delete [] _mem;
00302             }
00303             _mem = newMem;
00304             _allocated = newAllocated;
00305         }
00306     }
00307 
00308     T*  _mem;
00309     T   _pool[INITIAL_SIZE];
00310     int _allocated;             // objects allocated
00311     int _size;                  // number objects in use
00312 };
00313 
00314 
00315 /*
00316         Parent virtual class of a pool for fast allocation
00317         and deallocation of objects.
00318 */
00319 class MemPool
00320 {
00321 public:
00322     MemPool() {}
00323     virtual ~MemPool() {}
00324 
00325     virtual int ItemSize() const = 0;
00326     virtual void* Alloc() = 0;
00327     virtual void Free( void* ) = 0;
00328     virtual void SetTracked() = 0;
00329     virtual void Clear() = 0;
00330 };
00331 
00332 
00333 /*
00334         Template child class to create pools of the correct type.
00335 */
00336 template< int ITEM_SIZE >
00337 class MemPoolT : public MemPool
00338 {
00339 public:
00340     MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)  {}
00341     ~MemPoolT() {
00342         Clear();
00343     }
00344     
00345     void Clear() {
00346         // Delete the blocks.
00347         while( !_blockPtrs.Empty()) {
00348             Block* lastBlock = _blockPtrs.Pop();
00349             delete lastBlock;
00350         }
00351         _root = 0;
00352         _currentAllocs = 0;
00353         _nAllocs = 0;
00354         _maxAllocs = 0;
00355         _nUntracked = 0;
00356     }
00357 
00358     virtual int ItemSize() const        {
00359         return ITEM_SIZE;
00360     }
00361     int CurrentAllocs() const           {
00362         return _currentAllocs;
00363     }
00364 
00365     virtual void* Alloc() {
00366         if ( !_root ) {
00367             // Need a new block.
00368             Block* block = new Block();
00369             _blockPtrs.Push( block );
00370 
00371             Item* blockItems = block->items;
00372             for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
00373                 blockItems[i].next = &(blockItems[i + 1]);
00374             }
00375             blockItems[ITEMS_PER_BLOCK - 1].next = 0;
00376             _root = blockItems;
00377         }
00378         Item* const result = _root;
00379         TIXMLASSERT( result != 0 );
00380         _root = _root->next;
00381 
00382         ++_currentAllocs;
00383         if ( _currentAllocs > _maxAllocs ) {
00384             _maxAllocs = _currentAllocs;
00385         }
00386         ++_nAllocs;
00387         ++_nUntracked;
00388         return result;
00389     }
00390     
00391     virtual void Free( void* mem ) {
00392         if ( !mem ) {
00393             return;
00394         }
00395         --_currentAllocs;
00396         Item* item = static_cast<Item*>( mem );
00397 #ifdef TINYXML2_DEBUG
00398         memset( item, 0xfe, sizeof( *item ) );
00399 #endif
00400         item->next = _root;
00401         _root = item;
00402     }
00403     void Trace( const char* name ) {
00404         printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00405                 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
00406                 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
00407     }
00408 
00409     void SetTracked() {
00410         --_nUntracked;
00411     }
00412 
00413     int Untracked() const {
00414         return _nUntracked;
00415     }
00416 
00417         // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
00418         // The test file is large, 170k.
00419         // Release:             VS2010 gcc(no opt)
00420         //              1k:             4000
00421         //              2k:             4000
00422         //              4k:             3900    21000
00423         //              16k:    5200
00424         //              32k:    4300
00425         //              64k:    4000    21000
00426     // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
00427     // in private part if ITEMS_PER_BLOCK is private
00428     enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
00429 
00430 private:
00431     MemPoolT( const MemPoolT& ); // not supported
00432     void operator=( const MemPoolT& ); // not supported
00433 
00434     union Item {
00435         Item*   next;
00436         char    itemData[ITEM_SIZE];
00437     };
00438     struct Block {
00439         Item items[ITEMS_PER_BLOCK];
00440     };
00441     DynArray< Block*, 10 > _blockPtrs;
00442     Item* _root;
00443 
00444     int _currentAllocs;
00445     int _nAllocs;
00446     int _maxAllocs;
00447     int _nUntracked;
00448 };
00449 
00450 
00451 
00471 class TINYXML2_LIB XMLVisitor
00472 {
00473 public:
00474     virtual ~XMLVisitor() {}
00475 
00477     virtual bool VisitEnter( const XMLDocument& /*doc*/ )                       {
00478         return true;
00479     }
00481     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
00482         return true;
00483     }
00484 
00486     virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    {
00487         return true;
00488     }
00490     virtual bool VisitExit( const XMLElement& /*element*/ )                     {
00491         return true;
00492     }
00493 
00495     virtual bool Visit( const XMLDeclaration& /*declaration*/ )         {
00496         return true;
00497     }
00499     virtual bool Visit( const XMLText& /*text*/ )                                       {
00500         return true;
00501     }
00503     virtual bool Visit( const XMLComment& /*comment*/ )                         {
00504         return true;
00505     }
00507     virtual bool Visit( const XMLUnknown& /*unknown*/ )                         {
00508         return true;
00509     }
00510 };
00511 
00512 // WARNING: must match XMLDocument::_errorNames[]
00513 enum XMLError {
00514     XML_SUCCESS = 0,
00515     XML_NO_ATTRIBUTE,
00516     XML_WRONG_ATTRIBUTE_TYPE,
00517     XML_ERROR_FILE_NOT_FOUND,
00518     XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00519     XML_ERROR_FILE_READ_ERROR,
00520     UNUSED_XML_ERROR_ELEMENT_MISMATCH,  // remove at next major version
00521     XML_ERROR_PARSING_ELEMENT,
00522     XML_ERROR_PARSING_ATTRIBUTE,
00523     UNUSED_XML_ERROR_IDENTIFYING_TAG,   // remove at next major version
00524     XML_ERROR_PARSING_TEXT,
00525     XML_ERROR_PARSING_CDATA,
00526     XML_ERROR_PARSING_COMMENT,
00527     XML_ERROR_PARSING_DECLARATION,
00528     XML_ERROR_PARSING_UNKNOWN,
00529     XML_ERROR_EMPTY_DOCUMENT,
00530     XML_ERROR_MISMATCHED_ELEMENT,
00531     XML_ERROR_PARSING,
00532     XML_CAN_NOT_CONVERT_TEXT,
00533     XML_NO_TEXT_NODE,
00534         XML_ELEMENT_DEPTH_EXCEEDED,
00535 
00536         XML_ERROR_COUNT
00537 };
00538 
00539 
00540 /*
00541         Utility functionality.
00542 */
00543 class TINYXML2_LIB XMLUtil
00544 {
00545 public:
00546     static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr )      {
00547         TIXMLASSERT( p );
00548 
00549         while( IsWhiteSpace(*p) ) {
00550             if (curLineNumPtr && *p == '\n') {
00551                 ++(*curLineNumPtr);
00552             }
00553             ++p;
00554         }
00555         TIXMLASSERT( p );
00556         return p;
00557     }
00558     static char* SkipWhiteSpace( char* p, int* curLineNumPtr )                          {
00559         return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
00560     }
00561 
00562     // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
00563     // correct, but simple, and usually works.
00564     static bool IsWhiteSpace( char p )                                  {
00565         return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00566     }
00567     
00568     inline static bool IsNameStartChar( unsigned char ch ) {
00569         if ( ch >= 128 ) {
00570             // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
00571             return true;
00572         }
00573         if ( isalpha( ch ) ) {
00574             return true;
00575         }
00576         return ch == ':' || ch == '_';
00577     }
00578     
00579     inline static bool IsNameChar( unsigned char ch ) {
00580         return IsNameStartChar( ch )
00581                || isdigit( ch )
00582                || ch == '.'
00583                || ch == '-';
00584     }
00585 
00586     inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
00587         if ( p == q ) {
00588             return true;
00589         }
00590         TIXMLASSERT( p );
00591         TIXMLASSERT( q );
00592         TIXMLASSERT( nChar >= 0 );
00593         return strncmp( p, q, nChar ) == 0;
00594     }
00595     
00596     inline static bool IsUTF8Continuation( char p ) {
00597         return ( p & 0x80 ) != 0;
00598     }
00599 
00600     static const char* ReadBOM( const char* p, bool* hasBOM );
00601     // p is the starting location,
00602     // the UTF-8 value of the entity will be placed in value, and length filled in.
00603     static const char* GetCharacterRef( const char* p, char* value, int* length );
00604     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00605 
00606     // converts primitive types to strings
00607     static void ToStr( int v, char* buffer, int bufferSize );
00608     static void ToStr( unsigned v, char* buffer, int bufferSize );
00609     static void ToStr( bool v, char* buffer, int bufferSize );
00610     static void ToStr( float v, char* buffer, int bufferSize );
00611     static void ToStr( double v, char* buffer, int bufferSize );
00612         static void ToStr(int64_t v, char* buffer, int bufferSize);
00613 
00614     // converts strings to primitive types
00615     static bool ToInt( const char* str, int* value );
00616     static bool ToUnsigned( const char* str, unsigned* value );
00617     static bool ToBool( const char* str, bool* value );
00618     static bool ToFloat( const char* str, float* value );
00619     static bool ToDouble( const char* str, double* value );
00620         static bool ToInt64(const char* str, int64_t* value);
00621 
00622         // Changes what is serialized for a boolean value.
00623         // Default to "true" and "false". Shouldn't be changed
00624         // unless you have a special testing or compatibility need.
00625         // Be careful: static, global, & not thread safe.
00626         // Be sure to set static const memory as parameters.
00627         static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
00628 
00629 private:
00630         static const char* writeBoolTrue;
00631         static const char* writeBoolFalse;
00632 };
00633 
00634 
00660 class TINYXML2_LIB XMLNode
00661 {
00662     friend class XMLDocument;
00663     friend class XMLElement;
00664 public:
00665 
00667     const XMLDocument* GetDocument() const      {
00668         TIXMLASSERT( _document );
00669         return _document;
00670     }
00672     XMLDocument* GetDocument()                          {
00673         TIXMLASSERT( _document );
00674         return _document;
00675     }
00676 
00678     virtual XMLElement*         ToElement()             {
00679         return 0;
00680     }
00682     virtual XMLText*            ToText()                {
00683         return 0;
00684     }
00686     virtual XMLComment*         ToComment()             {
00687         return 0;
00688     }
00690     virtual XMLDocument*        ToDocument()    {
00691         return 0;
00692     }
00694     virtual XMLDeclaration*     ToDeclaration() {
00695         return 0;
00696     }
00698     virtual XMLUnknown*         ToUnknown()             {
00699         return 0;
00700     }
00701 
00702     virtual const XMLElement*           ToElement() const               {
00703         return 0;
00704     }
00705     virtual const XMLText*                      ToText() const                  {
00706         return 0;
00707     }
00708     virtual const XMLComment*           ToComment() const               {
00709         return 0;
00710     }
00711     virtual const XMLDocument*          ToDocument() const              {
00712         return 0;
00713     }
00714     virtual const XMLDeclaration*       ToDeclaration() const   {
00715         return 0;
00716     }
00717     virtual const XMLUnknown*           ToUnknown() const               {
00718         return 0;
00719     }
00720 
00730     const char* Value() const;
00731 
00735     void SetValue( const char* val, bool staticMem=false );
00736 
00738     int GetLineNum() const { return _parseLineNum; }
00739 
00741     const XMLNode*      Parent() const                  {
00742         return _parent;
00743     }
00744 
00745     XMLNode* Parent()                                           {
00746         return _parent;
00747     }
00748 
00750     bool NoChildren() const                                     {
00751         return !_firstChild;
00752     }
00753 
00755     const XMLNode*  FirstChild() const          {
00756         return _firstChild;
00757     }
00758 
00759     XMLNode*            FirstChild()                    {
00760         return _firstChild;
00761     }
00762 
00766     const XMLElement* FirstChildElement( const char* name = 0 ) const;
00767 
00768     XMLElement* FirstChildElement( const char* name = 0 )       {
00769         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
00770     }
00771 
00773     const XMLNode*      LastChild() const                                               {
00774         return _lastChild;
00775     }
00776 
00777     XMLNode*            LastChild()                                                             {
00778         return _lastChild;
00779     }
00780 
00784     const XMLElement* LastChildElement( const char* name = 0 ) const;
00785 
00786     XMLElement* LastChildElement( const char* name = 0 )        {
00787         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
00788     }
00789 
00791     const XMLNode*      PreviousSibling() const                                 {
00792         return _prev;
00793     }
00794 
00795     XMLNode*    PreviousSibling()                                                       {
00796         return _prev;
00797     }
00798 
00800     const XMLElement*   PreviousSiblingElement( const char* name = 0 ) const ;
00801 
00802     XMLElement* PreviousSiblingElement( const char* name = 0 ) {
00803         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
00804     }
00805 
00807     const XMLNode*      NextSibling() const                                             {
00808         return _next;
00809     }
00810 
00811     XMLNode*    NextSibling()                                                           {
00812         return _next;
00813     }
00814 
00816     const XMLElement*   NextSiblingElement( const char* name = 0 ) const;
00817 
00818     XMLElement* NextSiblingElement( const char* name = 0 )      {
00819         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
00820     }
00821 
00829     XMLNode* InsertEndChild( XMLNode* addThis );
00830 
00831     XMLNode* LinkEndChild( XMLNode* addThis )   {
00832         return InsertEndChild( addThis );
00833     }
00841     XMLNode* InsertFirstChild( XMLNode* addThis );
00850     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00851 
00855     void DeleteChildren();
00856 
00860     void DeleteChild( XMLNode* node );
00861 
00871     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00872 
00886         XMLNode* DeepClone( XMLDocument* target ) const;
00887 
00894     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00895 
00918     virtual bool Accept( XMLVisitor* visitor ) const = 0;
00919 
00925         void SetUserData(void* userData)        { _userData = userData; }
00926 
00932         void* GetUserData() const                       { return _userData; }
00933 
00934 protected:
00935     XMLNode( XMLDocument* );
00936     virtual ~XMLNode();
00937 
00938     virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
00939 
00940     XMLDocument*        _document;
00941     XMLNode*            _parent;
00942     mutable StrPair     _value;
00943     int             _parseLineNum;
00944 
00945     XMLNode*            _firstChild;
00946     XMLNode*            _lastChild;
00947 
00948     XMLNode*            _prev;
00949     XMLNode*            _next;
00950 
00951         void*                   _userData;
00952 
00953 private:
00954     MemPool*            _memPool;
00955     void Unlink( XMLNode* child );
00956     static void DeleteNode( XMLNode* node );
00957     void InsertChildPreamble( XMLNode* insertThis ) const;
00958     const XMLElement* ToElementWithName( const char* name ) const;
00959 
00960     XMLNode( const XMLNode& );  // not supported
00961     XMLNode& operator=( const XMLNode& );       // not supported
00962 };
00963 
00964 
00977 class TINYXML2_LIB XMLText : public XMLNode
00978 {
00979     friend class XMLDocument;
00980 public:
00981     virtual bool Accept( XMLVisitor* visitor ) const;
00982 
00983     virtual XMLText* ToText()                   {
00984         return this;
00985     }
00986     virtual const XMLText* ToText() const       {
00987         return this;
00988     }
00989 
00991     void SetCData( bool isCData )                       {
00992         _isCData = isCData;
00993     }
00995     bool CData() const                                          {
00996         return _isCData;
00997     }
00998 
00999     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01000     virtual bool ShallowEqual( const XMLNode* compare ) const;
01001 
01002 protected:
01003     XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false )     {}
01004     virtual ~XMLText()                                                                                          {}
01005 
01006     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01007 
01008 private:
01009     bool _isCData;
01010 
01011     XMLText( const XMLText& );  // not supported
01012     XMLText& operator=( const XMLText& );       // not supported
01013 };
01014 
01015 
01017 class TINYXML2_LIB XMLComment : public XMLNode
01018 {
01019     friend class XMLDocument;
01020 public:
01021     virtual XMLComment* ToComment()                                     {
01022         return this;
01023     }
01024     virtual const XMLComment* ToComment() const         {
01025         return this;
01026     }
01027 
01028     virtual bool Accept( XMLVisitor* visitor ) const;
01029 
01030     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01031     virtual bool ShallowEqual( const XMLNode* compare ) const;
01032 
01033 protected:
01034     XMLComment( XMLDocument* doc );
01035     virtual ~XMLComment();
01036 
01037     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
01038 
01039 private:
01040     XMLComment( const XMLComment& );    // not supported
01041     XMLComment& operator=( const XMLComment& ); // not supported
01042 };
01043 
01044 
01056 class TINYXML2_LIB XMLDeclaration : public XMLNode
01057 {
01058     friend class XMLDocument;
01059 public:
01060     virtual XMLDeclaration*     ToDeclaration()                                 {
01061         return this;
01062     }
01063     virtual const XMLDeclaration* ToDeclaration() const         {
01064         return this;
01065     }
01066 
01067     virtual bool Accept( XMLVisitor* visitor ) const;
01068 
01069     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01070     virtual bool ShallowEqual( const XMLNode* compare ) const;
01071 
01072 protected:
01073     XMLDeclaration( XMLDocument* doc );
01074     virtual ~XMLDeclaration();
01075 
01076     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01077 
01078 private:
01079     XMLDeclaration( const XMLDeclaration& );    // not supported
01080     XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
01081 };
01082 
01083 
01091 class TINYXML2_LIB XMLUnknown : public XMLNode
01092 {
01093     friend class XMLDocument;
01094 public:
01095     virtual XMLUnknown* ToUnknown()                                     {
01096         return this;
01097     }
01098     virtual const XMLUnknown* ToUnknown() const         {
01099         return this;
01100     }
01101 
01102     virtual bool Accept( XMLVisitor* visitor ) const;
01103 
01104     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01105     virtual bool ShallowEqual( const XMLNode* compare ) const;
01106 
01107 protected:
01108     XMLUnknown( XMLDocument* doc );
01109     virtual ~XMLUnknown();
01110 
01111     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01112 
01113 private:
01114     XMLUnknown( const XMLUnknown& );    // not supported
01115     XMLUnknown& operator=( const XMLUnknown& ); // not supported
01116 };
01117 
01118 
01119 
01126 class TINYXML2_LIB XMLAttribute
01127 {
01128     friend class XMLElement;
01129 public:
01131     const char* Name() const;
01132 
01134     const char* Value() const;
01135 
01137     int GetLineNum() const { return _parseLineNum; }
01138 
01140     const XMLAttribute* Next() const {
01141         return _next;
01142     }
01143 
01148         int     IntValue() const {
01149                 int i = 0;
01150                 QueryIntValue(&i);
01151                 return i;
01152         }
01153 
01154         int64_t Int64Value() const {
01155                 int64_t i = 0;
01156                 QueryInt64Value(&i);
01157                 return i;
01158         }
01159 
01161     unsigned UnsignedValue() const                      {
01162         unsigned i=0;
01163         QueryUnsignedValue( &i );
01164         return i;
01165     }
01167     bool         BoolValue() const                              {
01168         bool b=false;
01169         QueryBoolValue( &b );
01170         return b;
01171     }
01173     double       DoubleValue() const                    {
01174         double d=0;
01175         QueryDoubleValue( &d );
01176         return d;
01177     }
01179     float        FloatValue() const                             {
01180         float f=0;
01181         QueryFloatValue( &f );
01182         return f;
01183     }
01184 
01189     XMLError QueryIntValue( int* value ) const;
01191     XMLError QueryUnsignedValue( unsigned int* value ) const;
01193         XMLError QueryInt64Value(int64_t* value) const;
01195     XMLError QueryBoolValue( bool* value ) const;
01197     XMLError QueryDoubleValue( double* value ) const;
01199     XMLError QueryFloatValue( float* value ) const;
01200 
01202     void SetAttribute( const char* value );
01204     void SetAttribute( int value );
01206     void SetAttribute( unsigned value );
01208         void SetAttribute(int64_t value);
01210     void SetAttribute( bool value );
01212     void SetAttribute( double value );
01214     void SetAttribute( float value );
01215 
01216 private:
01217     enum { BUF_SIZE = 200 };
01218 
01219     XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
01220     virtual ~XMLAttribute()     {}
01221 
01222     XMLAttribute( const XMLAttribute& );        // not supported
01223     void operator=( const XMLAttribute& );      // not supported
01224     void SetName( const char* name );
01225 
01226     char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
01227 
01228     mutable StrPair _name;
01229     mutable StrPair _value;
01230     int             _parseLineNum;
01231     XMLAttribute*   _next;
01232     MemPool*        _memPool;
01233 };
01234 
01235 
01240 class TINYXML2_LIB XMLElement : public XMLNode
01241 {
01242     friend class XMLDocument;
01243 public:
01245     const char* Name() const            {
01246         return Value();
01247     }
01249     void SetName( const char* str, bool staticMem=false )       {
01250         SetValue( str, staticMem );
01251     }
01252 
01253     virtual XMLElement* ToElement()                             {
01254         return this;
01255     }
01256     virtual const XMLElement* ToElement() const {
01257         return this;
01258     }
01259     virtual bool Accept( XMLVisitor* visitor ) const;
01260 
01284     const char* Attribute( const char* name, const char* value=0 ) const;
01285 
01292         int IntAttribute(const char* name, int defaultValue = 0) const;
01294         unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
01296         int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
01298         bool BoolAttribute(const char* name, bool defaultValue = false) const;
01300         double DoubleAttribute(const char* name, double defaultValue = 0) const;
01302         float FloatAttribute(const char* name, float defaultValue = 0) const;
01303 
01317     XMLError QueryIntAttribute( const char* name, int* value ) const                            {
01318         const XMLAttribute* a = FindAttribute( name );
01319         if ( !a ) {
01320             return XML_NO_ATTRIBUTE;
01321         }
01322         return a->QueryIntValue( value );
01323     }
01324 
01326     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const      {
01327         const XMLAttribute* a = FindAttribute( name );
01328         if ( !a ) {
01329             return XML_NO_ATTRIBUTE;
01330         }
01331         return a->QueryUnsignedValue( value );
01332     }
01333 
01335         XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
01336                 const XMLAttribute* a = FindAttribute(name);
01337                 if (!a) {
01338                         return XML_NO_ATTRIBUTE;
01339                 }
01340                 return a->QueryInt64Value(value);
01341         }
01342 
01344     XMLError QueryBoolAttribute( const char* name, bool* value ) const                          {
01345         const XMLAttribute* a = FindAttribute( name );
01346         if ( !a ) {
01347             return XML_NO_ATTRIBUTE;
01348         }
01349         return a->QueryBoolValue( value );
01350     }
01352     XMLError QueryDoubleAttribute( const char* name, double* value ) const                      {
01353         const XMLAttribute* a = FindAttribute( name );
01354         if ( !a ) {
01355             return XML_NO_ATTRIBUTE;
01356         }
01357         return a->QueryDoubleValue( value );
01358     }
01360     XMLError QueryFloatAttribute( const char* name, float* value ) const                        {
01361         const XMLAttribute* a = FindAttribute( name );
01362         if ( !a ) {
01363             return XML_NO_ATTRIBUTE;
01364         }
01365         return a->QueryFloatValue( value );
01366     }
01367 
01369         XMLError QueryStringAttribute(const char* name, const char** value) const {
01370                 const XMLAttribute* a = FindAttribute(name);
01371                 if (!a) {
01372                         return XML_NO_ATTRIBUTE;
01373                 }
01374                 *value = a->Value();
01375                 return XML_SUCCESS;
01376         }
01377 
01378 
01379         
01397         int QueryAttribute( const char* name, int* value ) const {
01398                 return QueryIntAttribute( name, value );
01399         }
01400 
01401         int QueryAttribute( const char* name, unsigned int* value ) const {
01402                 return QueryUnsignedAttribute( name, value );
01403         }
01404 
01405         int QueryAttribute(const char* name, int64_t* value) const {
01406                 return QueryInt64Attribute(name, value);
01407         }
01408 
01409         int QueryAttribute( const char* name, bool* value ) const {
01410                 return QueryBoolAttribute( name, value );
01411         }
01412 
01413         int QueryAttribute( const char* name, double* value ) const {
01414                 return QueryDoubleAttribute( name, value );
01415         }
01416 
01417         int QueryAttribute( const char* name, float* value ) const {
01418                 return QueryFloatAttribute( name, value );
01419         }
01420 
01422     void SetAttribute( const char* name, const char* value )    {
01423         XMLAttribute* a = FindOrCreateAttribute( name );
01424         a->SetAttribute( value );
01425     }
01427     void SetAttribute( const char* name, int value )                    {
01428         XMLAttribute* a = FindOrCreateAttribute( name );
01429         a->SetAttribute( value );
01430     }
01432     void SetAttribute( const char* name, unsigned value )               {
01433         XMLAttribute* a = FindOrCreateAttribute( name );
01434         a->SetAttribute( value );
01435     }
01436 
01438         void SetAttribute(const char* name, int64_t value) {
01439                 XMLAttribute* a = FindOrCreateAttribute(name);
01440                 a->SetAttribute(value);
01441         }
01442 
01444     void SetAttribute( const char* name, bool value )                   {
01445         XMLAttribute* a = FindOrCreateAttribute( name );
01446         a->SetAttribute( value );
01447     }
01449     void SetAttribute( const char* name, double value )         {
01450         XMLAttribute* a = FindOrCreateAttribute( name );
01451         a->SetAttribute( value );
01452     }
01454     void SetAttribute( const char* name, float value )          {
01455         XMLAttribute* a = FindOrCreateAttribute( name );
01456         a->SetAttribute( value );
01457     }
01458 
01462     void DeleteAttribute( const char* name );
01463 
01465     const XMLAttribute* FirstAttribute() const {
01466         return _rootAttribute;
01467     }
01469     const XMLAttribute* FindAttribute( const char* name ) const;
01470 
01499     const char* GetText() const;
01500 
01535         void SetText( const char* inText );
01537     void SetText( int value );
01539     void SetText( unsigned value );  
01541         void SetText(int64_t value);
01543     void SetText( bool value );  
01545     void SetText( double value );  
01547     void SetText( float value );  
01548 
01575     XMLError QueryIntText( int* ival ) const;
01577     XMLError QueryUnsignedText( unsigned* uval ) const;
01579         XMLError QueryInt64Text(int64_t* uval) const;
01581     XMLError QueryBoolText( bool* bval ) const;
01583     XMLError QueryDoubleText( double* dval ) const;
01585     XMLError QueryFloatText( float* fval ) const;
01586 
01587         int IntText(int defaultValue = 0) const;
01588 
01590         unsigned UnsignedText(unsigned defaultValue = 0) const;
01592         int64_t Int64Text(int64_t defaultValue = 0) const;
01594         bool BoolText(bool defaultValue = false) const;
01596         double DoubleText(double defaultValue = 0) const;
01598         float FloatText(float defaultValue = 0) const;
01599 
01600     // internal:
01601     enum ElementClosingType {
01602         OPEN,           // <foo>
01603         CLOSED,         // <foo/>
01604         CLOSING         // </foo>
01605     };
01606     ElementClosingType ClosingType() const {
01607         return _closingType;
01608     }
01609     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01610     virtual bool ShallowEqual( const XMLNode* compare ) const;
01611 
01612 protected:
01613     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01614 
01615 private:
01616     XMLElement( XMLDocument* doc );
01617     virtual ~XMLElement();
01618     XMLElement( const XMLElement& );    // not supported
01619     void operator=( const XMLElement& );        // not supported
01620 
01621     XMLAttribute* FindAttribute( const char* name ) {
01622         return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
01623     }
01624     XMLAttribute* FindOrCreateAttribute( const char* name );
01625     //void LinkAttribute( XMLAttribute* attrib );
01626     char* ParseAttributes( char* p, int* curLineNumPtr );
01627     static void DeleteAttribute( XMLAttribute* attribute );
01628     XMLAttribute* CreateAttribute();
01629 
01630     enum { BUF_SIZE = 200 };
01631     ElementClosingType _closingType;
01632     // The attribute list is ordered; there is no 'lastAttribute'
01633     // because the list needs to be scanned for dupes before adding
01634     // a new attribute.
01635     XMLAttribute* _rootAttribute;
01636 };
01637 
01638 
01639 enum Whitespace {
01640     PRESERVE_WHITESPACE,
01641     COLLAPSE_WHITESPACE
01642 };
01643 
01644 
01650 class TINYXML2_LIB XMLDocument : public XMLNode
01651 {
01652     friend class XMLElement;
01653     // Gives access to SetError and Push/PopDepth, but over-access for everything else.
01654     // Wishing C++ had "internal" scope.
01655     friend class XMLNode;       
01656     friend class XMLText;
01657     friend class XMLComment;
01658     friend class XMLDeclaration;
01659     friend class XMLUnknown;
01660 public:
01662     XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
01663     ~XMLDocument();
01664 
01665     virtual XMLDocument* ToDocument()                           {
01666         TIXMLASSERT( this == _document );
01667         return this;
01668     }
01669     virtual const XMLDocument* ToDocument() const       {
01670         TIXMLASSERT( this == _document );
01671         return this;
01672     }
01673 
01684     XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01685 
01691     XMLError LoadFile( const char* filename );
01692 
01704     XMLError LoadFile( FILE* );
01705 
01711     XMLError SaveFile( const char* filename, bool compact = false );
01712 
01720     XMLError SaveFile( FILE* fp, bool compact = false );
01721 
01722     bool ProcessEntities() const                {
01723         return _processEntities;
01724     }
01725     Whitespace WhitespaceMode() const   {
01726         return _whitespaceMode;
01727     }
01728 
01732     bool HasBOM() const {
01733         return _writeBOM;
01734     }
01737     void SetBOM( bool useBOM ) {
01738         _writeBOM = useBOM;
01739     }
01740 
01744     XMLElement* RootElement()                           {
01745         return FirstChildElement();
01746     }
01747     const XMLElement* RootElement() const       {
01748         return FirstChildElement();
01749     }
01750 
01765     void Print( XMLPrinter* streamer=0 ) const;
01766     virtual bool Accept( XMLVisitor* visitor ) const;
01767 
01773     XMLElement* NewElement( const char* name );
01779     XMLComment* NewComment( const char* comment );
01785     XMLText* NewText( const char* text );
01797     XMLDeclaration* NewDeclaration( const char* text=0 );
01803     XMLUnknown* NewUnknown( const char* text );
01804 
01809     void DeleteNode( XMLNode* node );
01810 
01811     void ClearError() {
01812         SetError(XML_SUCCESS, 0, 0);
01813     }
01814 
01816     bool Error() const {
01817         return _errorID != XML_SUCCESS;
01818     }
01820     XMLError  ErrorID() const {
01821         return _errorID;
01822     }
01823         const char* ErrorName() const;
01824     static const char* ErrorIDToName(XMLError errorID);
01825 
01829         const char* ErrorStr() const;
01830 
01832     void PrintError() const;
01833 
01835     int ErrorLineNum() const
01836     {
01837         return _errorLineNum;
01838     }
01839     
01841     void Clear();
01842 
01850         void DeepCopy(XMLDocument* target) const;
01851 
01852         // internal
01853     char* Identify( char* p, XMLNode** node );
01854 
01855         // internal
01856         void MarkInUse(XMLNode*);
01857 
01858     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    {
01859         return 0;
01860     }
01861     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const       {
01862         return false;
01863     }
01864 
01865 private:
01866     XMLDocument( const XMLDocument& );  // not supported
01867     void operator=( const XMLDocument& );       // not supported
01868 
01869     bool                        _writeBOM;
01870     bool                        _processEntities;
01871     XMLError            _errorID;
01872     Whitespace          _whitespaceMode;
01873     mutable StrPair     _errorStr;
01874     int             _errorLineNum;
01875     char*                       _charBuffer;
01876     int                         _parseCurLineNum;
01877         int                             _parsingDepth;
01878         // Memory tracking does add some overhead.
01879         // However, the code assumes that you don't
01880         // have a bunch of unlinked nodes around.
01881         // Therefore it takes less memory to track
01882         // in the document vs. a linked list in the XMLNode,
01883         // and the performance is the same.
01884         DynArray<XMLNode*, 10> _unlinked;
01885 
01886     MemPoolT< sizeof(XMLElement) >       _elementPool;
01887     MemPoolT< sizeof(XMLAttribute) > _attributePool;
01888     MemPoolT< sizeof(XMLText) >          _textPool;
01889     MemPoolT< sizeof(XMLComment) >       _commentPool;
01890 
01891         static const char* _errorNames[XML_ERROR_COUNT];
01892 
01893     void Parse();
01894 
01895     void SetError( XMLError error, int lineNum, const char* format, ... );
01896 
01897         // Something of an obvious security hole, once it was discovered.
01898         // Either an ill-formed XML or an excessively deep one can overflow
01899         // the stack. Track stack depth, and error out if needed.
01900         class DepthTracker {
01901         public:
01902                 DepthTracker(XMLDocument * document) { 
01903                         this->_document = document; 
01904                         document->PushDepth();
01905                 }
01906                 ~DepthTracker() {
01907                         _document->PopDepth();
01908                 }
01909         private:
01910                 XMLDocument * _document;
01911         };
01912         void PushDepth();
01913         void PopDepth();
01914 
01915     template<class NodeType, int PoolElementSize>
01916     NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
01917 };
01918 
01919 template<class NodeType, int PoolElementSize>
01920 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
01921 {
01922     TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
01923     TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
01924     NodeType* returnNode = new (pool.Alloc()) NodeType( this );
01925     TIXMLASSERT( returnNode );
01926     returnNode->_memPool = &pool;
01927 
01928         _unlinked.Push(returnNode);
01929     return returnNode;
01930 }
01931 
01987 class TINYXML2_LIB XMLHandle
01988 {
01989 public:
01991     XMLHandle( XMLNode* node ) : _node( node ) {
01992     }
01994     XMLHandle( XMLNode& node ) : _node( &node ) {
01995     }
01997     XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
01998     }
02000     XMLHandle& operator=( const XMLHandle& ref )                                                        {
02001         _node = ref._node;
02002         return *this;
02003     }
02004 
02006     XMLHandle FirstChild()                                                                                                      {
02007         return XMLHandle( _node ? _node->FirstChild() : 0 );
02008     }
02010     XMLHandle FirstChildElement( const char* name = 0 )                                         {
02011         return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
02012     }
02014     XMLHandle LastChild()                                                                                                       {
02015         return XMLHandle( _node ? _node->LastChild() : 0 );
02016     }
02018     XMLHandle LastChildElement( const char* name = 0 )                                          {
02019         return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
02020     }
02022     XMLHandle PreviousSibling()                                                                                         {
02023         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
02024     }
02026     XMLHandle PreviousSiblingElement( const char* name = 0 )                            {
02027         return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02028     }
02030     XMLHandle NextSibling()                                                                                                     {
02031         return XMLHandle( _node ? _node->NextSibling() : 0 );
02032     }
02034     XMLHandle NextSiblingElement( const char* name = 0 )                                        {
02035         return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02036     }
02037 
02039     XMLNode* ToNode()                                                   {
02040         return _node;
02041     }
02043     XMLElement* ToElement()                                     {
02044         return ( _node ? _node->ToElement() : 0 );
02045     }
02047     XMLText* ToText()                                                   {
02048         return ( _node ? _node->ToText() : 0 );
02049     }
02051     XMLUnknown* ToUnknown()                                     {
02052         return ( _node ? _node->ToUnknown() : 0 );
02053     }
02055     XMLDeclaration* ToDeclaration()                     {
02056         return ( _node ? _node->ToDeclaration() : 0 );
02057     }
02058 
02059 private:
02060     XMLNode* _node;
02061 };
02062 
02063 
02068 class TINYXML2_LIB XMLConstHandle
02069 {
02070 public:
02071     XMLConstHandle( const XMLNode* node ) : _node( node ) {
02072     }
02073     XMLConstHandle( const XMLNode& node ) : _node( &node ) {
02074     }
02075     XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
02076     }
02077 
02078     XMLConstHandle& operator=( const XMLConstHandle& ref )                                                      {
02079         _node = ref._node;
02080         return *this;
02081     }
02082 
02083     const XMLConstHandle FirstChild() const                                                                                     {
02084         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
02085     }
02086     const XMLConstHandle FirstChildElement( const char* name = 0 ) const                                {
02087         return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
02088     }
02089     const XMLConstHandle LastChild()    const                                                                           {
02090         return XMLConstHandle( _node ? _node->LastChild() : 0 );
02091     }
02092     const XMLConstHandle LastChildElement( const char* name = 0 ) const                         {
02093         return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
02094     }
02095     const XMLConstHandle PreviousSibling() const                                                                        {
02096         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
02097     }
02098     const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const           {
02099         return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02100     }
02101     const XMLConstHandle NextSibling() const                                                                            {
02102         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
02103     }
02104     const XMLConstHandle NextSiblingElement( const char* name = 0 ) const                       {
02105         return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02106     }
02107 
02108 
02109     const XMLNode* ToNode() const                               {
02110         return _node;
02111     }
02112     const XMLElement* ToElement() const                 {
02113         return ( _node ? _node->ToElement() : 0 );
02114     }
02115     const XMLText* ToText() const                               {
02116         return ( _node ? _node->ToText() : 0 );
02117     }
02118     const XMLUnknown* ToUnknown() const                 {
02119         return ( _node ? _node->ToUnknown() : 0 );
02120     }
02121     const XMLDeclaration* ToDeclaration() const {
02122         return ( _node ? _node->ToDeclaration() : 0 );
02123     }
02124 
02125 private:
02126     const XMLNode* _node;
02127 };
02128 
02129 
02172 class TINYXML2_LIB XMLPrinter : public XMLVisitor
02173 {
02174 public:
02181     XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
02182     virtual ~XMLPrinter()       {}
02183 
02185     void PushHeader( bool writeBOM, bool writeDeclaration );
02189     void OpenElement( const char* name, bool compactMode=false );
02191     void PushAttribute( const char* name, const char* value );
02192     void PushAttribute( const char* name, int value );
02193     void PushAttribute( const char* name, unsigned value );
02194         void PushAttribute(const char* name, int64_t value);
02195         void PushAttribute( const char* name, bool value );
02196     void PushAttribute( const char* name, double value );
02198     virtual void CloseElement( bool compactMode=false );
02199 
02201     void PushText( const char* text, bool cdata=false );
02203     void PushText( int value );
02205     void PushText( unsigned value );
02207         void PushText(int64_t value);
02209     void PushText( bool value );
02211     void PushText( float value );
02213     void PushText( double value );
02214 
02216     void PushComment( const char* comment );
02217 
02218     void PushDeclaration( const char* value );
02219     void PushUnknown( const char* value );
02220 
02221     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
02222     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
02223         return true;
02224     }
02225 
02226     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
02227     virtual bool VisitExit( const XMLElement& element );
02228 
02229     virtual bool Visit( const XMLText& text );
02230     virtual bool Visit( const XMLComment& comment );
02231     virtual bool Visit( const XMLDeclaration& declaration );
02232     virtual bool Visit( const XMLUnknown& unknown );
02233 
02238     const char* CStr() const {
02239         return _buffer.Mem();
02240     }
02246     int CStrSize() const {
02247         return _buffer.Size();
02248     }
02253     void ClearBuffer() {
02254         _buffer.Clear();
02255         _buffer.Push(0);
02256                 _firstElement = true;
02257     }
02258 
02259 protected:
02260         virtual bool CompactMode( const XMLElement& )   { return _compactMode; }
02261 
02265     virtual void PrintSpace( int depth );
02266     void Print( const char* format, ... );
02267     void Write( const char* data, size_t size );
02268     inline void Write( const char* data )           { Write( data, strlen( data ) ); }
02269     void Putc( char ch );
02270 
02271     void SealElementIfJustOpened();
02272     bool _elementJustOpened;
02273     DynArray< const char*, 10 > _stack;
02274 
02275 private:
02276     void PrintString( const char*, bool restrictedEntitySet );  // prints out, after detecting entities.
02277 
02278     bool _firstElement;
02279     FILE* _fp;
02280     int _depth;
02281     int _textDepth;
02282     bool _processEntities;
02283         bool _compactMode;
02284 
02285     enum {
02286         ENTITY_RANGE = 64,
02287         BUF_SIZE = 200
02288     };
02289     bool _entityFlag[ENTITY_RANGE];
02290     bool _restrictedEntityFlag[ENTITY_RANGE];
02291 
02292     DynArray< char, 20 > _buffer;
02293 
02294     // Prohibit cloning, intentionally not implemented
02295     XMLPrinter( const XMLPrinter& );
02296     XMLPrinter& operator=( const XMLPrinter& );
02297 };
02298 
02299 
02300 }       // tinyxml2
02301 
02302 #if defined(_MSC_VER)
02303 #   pragma warning(pop)
02304 #endif
02305 
02306 #endif // TINYXML2_INCLUDED


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 03:50:10