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 BT_TINYXML2_INCLUDED
00025 #define BT_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 #ifdef _WIN32
00068 #   ifdef TINYXML2_EXPORT
00069 #       define TINYXML2_LIB __declspec(dllexport)
00070 #   elif defined(TINYXML2_IMPORT)
00071 #       define TINYXML2_LIB __declspec(dllimport)
00072 #   else
00073 #       define TINYXML2_LIB
00074 #   endif
00075 #elif __GNUC__ >= 4
00076 #   define TINYXML2_LIB __attribute__((visibility("hidden")))
00077 #else
00078 #   define TINYXML2_LIB
00079 #endif
00080 
00081 
00082 #if defined(TINYXML2_DEBUG)
00083 #   if defined(_MSC_VER)
00084 #       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
00085 #       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
00086 #   elif defined (ANDROID_NDK)
00087 #       include <android/log.h>
00088 #       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
00089 #   else
00090 #       include <assert.h>
00091 #       define TIXMLASSERT                assert
00092 #   endif
00093 #else
00094 #   define TIXMLASSERT( x )               {}
00095 #endif
00096 
00097 
00098 /* Versioning, past 1.0.14:
00099         http://semver.org/
00100 */
00101 static const int TIXML2_MAJOR_VERSION = 7;
00102 static const int TIXML2_MINOR_VERSION = 0;
00103 static const int TIXML2_PATCH_VERSION = 1;
00104 
00105 #define TINYXML2_MAJOR_VERSION 7
00106 #define TINYXML2_MINOR_VERSION 0
00107 #define TINYXML2_PATCH_VERSION 1
00108 
00109 // A fixed element depth limit is problematic. There needs to be a
00110 // limit to avoid a stack overflow. However, that limit varies per
00111 // system, and the capacity of the stack. On the other hand, it's a trivial
00112 // attack that can result from ill, malicious, or even correctly formed XML,
00113 // so there needs to be a limit in place.
00114 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
00115 
00116 namespace BT_TinyXML2
00117 {
00118 class XMLDocument;
00119 class XMLElement;
00120 class XMLAttribute;
00121 class XMLComment;
00122 class XMLText;
00123 class XMLDeclaration;
00124 class XMLUnknown;
00125 class XMLPrinter;
00126 
00127 /*
00128         A class that wraps strings. Normally stores the start and end
00129         pointers into the XML file itself, and will apply normalization
00130         and entity translation if actually read. Can also store (and memory
00131         manage) a traditional char[]
00132 
00133     Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
00134 */
00135 class TINYXML2_LIB StrPair
00136 {
00137 public:
00138     enum {
00139         NEEDS_ENTITY_PROCESSING                 = 0x01,
00140         NEEDS_NEWLINE_NORMALIZATION             = 0x02,
00141         NEEDS_WHITESPACE_COLLAPSING     = 0x04,
00142 
00143         TEXT_ELEMENT                        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00144         TEXT_ELEMENT_LEAVE_ENTITIES             = NEEDS_NEWLINE_NORMALIZATION,
00145         ATTRIBUTE_NAME                      = 0,
00146         ATTRIBUTE_VALUE                     = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
00147         ATTRIBUTE_VALUE_LEAVE_ENTITIES  = NEEDS_NEWLINE_NORMALIZATION,
00148         COMMENT                                                 = NEEDS_NEWLINE_NORMALIZATION
00149     };
00150 
00151     StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
00152     ~StrPair();
00153 
00154     void Set( char* start, char* end, int flags ) {
00155         TIXMLASSERT( start );
00156         TIXMLASSERT( end );
00157         Reset();
00158         _start  = start;
00159         _end    = end;
00160         _flags  = flags | NEEDS_FLUSH;
00161     }
00162 
00163     const char* GetStr();
00164 
00165     bool Empty() const {
00166         return _start == _end;
00167     }
00168 
00169     void SetInternedStr( const char* str ) {
00170         Reset();
00171         _start = const_cast<char*>(str);
00172     }
00173 
00174     void SetStr( const char* str, int flags=0 );
00175 
00176     char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
00177     char* ParseName( char* in );
00178 
00179     void TransferTo( StrPair* other );
00180         void Reset();
00181 
00182 private:
00183     void CollapseWhitespace();
00184 
00185     enum {
00186         NEEDS_FLUSH = 0x100,
00187         NEEDS_DELETE = 0x200
00188     };
00189 
00190     int     _flags;
00191     char*   _start;
00192     char*   _end;
00193 
00194     StrPair( const StrPair& other );    // not supported
00195     void operator=( const StrPair& other );     // not supported, use TransferTo()
00196 };
00197 
00198 
00199 /*
00200         A dynamic array of Plain Old Data. Doesn't support constructors, etc.
00201         Has a small initial memory pool, so that low or no usage will not
00202         cause a call to new/delete
00203 */
00204 template <class T, int INITIAL_SIZE>
00205 class DynArray
00206 {
00207 public:
00208     DynArray() :
00209         _mem( _pool ),
00210         _allocated( INITIAL_SIZE ),
00211         _size( 0 )
00212     {
00213     }
00214 
00215     ~DynArray() {
00216         if ( _mem != _pool ) {
00217             delete [] _mem;
00218         }
00219     }
00220 
00221     void Clear() {
00222         _size = 0;
00223     }
00224 
00225     void Push( T t ) {
00226         TIXMLASSERT( _size < INT_MAX );
00227         EnsureCapacity( _size+1 );
00228         _mem[_size] = t;
00229         ++_size;
00230     }
00231 
00232     T* PushArr( int count ) {
00233         TIXMLASSERT( count >= 0 );
00234         TIXMLASSERT( _size <= INT_MAX - count );
00235         EnsureCapacity( _size+count );
00236         T* ret = &_mem[_size];
00237         _size += count;
00238         return ret;
00239     }
00240 
00241     T Pop() {
00242         TIXMLASSERT( _size > 0 );
00243         --_size;
00244         return _mem[_size];
00245     }
00246 
00247     void PopArr( int count ) {
00248         TIXMLASSERT( _size >= count );
00249         _size -= count;
00250     }
00251 
00252     bool Empty() const                                  {
00253         return _size == 0;
00254     }
00255 
00256     T& operator[](int i)                                {
00257         TIXMLASSERT( i>= 0 && i < _size );
00258         return _mem[i];
00259     }
00260 
00261     const T& operator[](int i) const    {
00262         TIXMLASSERT( i>= 0 && i < _size );
00263         return _mem[i];
00264     }
00265 
00266     const T& PeekTop() const            {
00267         TIXMLASSERT( _size > 0 );
00268         return _mem[ _size - 1];
00269     }
00270 
00271     int Size() const                                    {
00272         TIXMLASSERT( _size >= 0 );
00273         return _size;
00274     }
00275 
00276     int Capacity() const                                {
00277         TIXMLASSERT( _allocated >= INITIAL_SIZE );
00278         return _allocated;
00279     }
00280 
00281         void SwapRemove(int i) {
00282                 TIXMLASSERT(i >= 0 && i < _size);
00283                 TIXMLASSERT(_size > 0);
00284                 _mem[i] = _mem[_size - 1];
00285                 --_size;
00286         }
00287 
00288     const T* Mem() const                                {
00289         TIXMLASSERT( _mem );
00290         return _mem;
00291     }
00292 
00293     T* Mem() {
00294         TIXMLASSERT( _mem );
00295         return _mem;
00296     }
00297 
00298 private:
00299     DynArray( const DynArray& ); // not supported
00300     void operator=( const DynArray& ); // not supported
00301 
00302     void EnsureCapacity( int cap ) {
00303         TIXMLASSERT( cap > 0 );
00304         if ( cap > _allocated ) {
00305             TIXMLASSERT( cap <= INT_MAX / 2 );
00306             int newAllocated = cap * 2;
00307             T* newMem = new T[newAllocated];
00308             TIXMLASSERT( newAllocated >= _size );
00309             memcpy( newMem, _mem, sizeof(T)*_size );    // warning: not using constructors, only works for PODs
00310             if ( _mem != _pool ) {
00311                 delete [] _mem;
00312             }
00313             _mem = newMem;
00314             _allocated = newAllocated;
00315         }
00316     }
00317 
00318     T*  _mem;
00319     T   _pool[INITIAL_SIZE];
00320     int _allocated;             // objects allocated
00321     int _size;                  // number objects in use
00322 };
00323 
00324 
00325 /*
00326         Parent virtual class of a pool for fast allocation
00327         and deallocation of objects.
00328 */
00329 class MemPool
00330 {
00331 public:
00332     MemPool() {}
00333     virtual ~MemPool() {}
00334 
00335     virtual int ItemSize() const = 0;
00336     virtual void* Alloc() = 0;
00337     virtual void Free( void* ) = 0;
00338     virtual void SetTracked() = 0;
00339 };
00340 
00341 
00342 /*
00343         Template child class to create pools of the correct type.
00344 */
00345 template< int ITEM_SIZE >
00346 class MemPoolT : public MemPool
00347 {
00348 public:
00349     MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)  {}
00350     ~MemPoolT() {
00351         MemPoolT< ITEM_SIZE >::Clear();
00352     }
00353 
00354     void Clear() {
00355         // Delete the blocks.
00356         while( !_blockPtrs.Empty()) {
00357             Block* lastBlock = _blockPtrs.Pop();
00358             delete lastBlock;
00359         }
00360         _root = 0;
00361         _currentAllocs = 0;
00362         _nAllocs = 0;
00363         _maxAllocs = 0;
00364         _nUntracked = 0;
00365     }
00366 
00367     virtual int ItemSize() const        {
00368         return ITEM_SIZE;
00369     }
00370     int CurrentAllocs() const           {
00371         return _currentAllocs;
00372     }
00373 
00374     virtual void* Alloc() {
00375         if ( !_root ) {
00376             // Need a new block.
00377             Block* block = new Block();
00378             _blockPtrs.Push( block );
00379 
00380             Item* blockItems = block->items;
00381             for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
00382                 blockItems[i].next = &(blockItems[i + 1]);
00383             }
00384             blockItems[ITEMS_PER_BLOCK - 1].next = 0;
00385             _root = blockItems;
00386         }
00387         Item* const result = _root;
00388         TIXMLASSERT( result != 0 );
00389         _root = _root->next;
00390 
00391         ++_currentAllocs;
00392         if ( _currentAllocs > _maxAllocs ) {
00393             _maxAllocs = _currentAllocs;
00394         }
00395         ++_nAllocs;
00396         ++_nUntracked;
00397         return result;
00398     }
00399 
00400     virtual void Free( void* mem ) {
00401         if ( !mem ) {
00402             return;
00403         }
00404         --_currentAllocs;
00405         Item* item = static_cast<Item*>( mem );
00406 #ifdef TINYXML2_DEBUG
00407         memset( item, 0xfe, sizeof( *item ) );
00408 #endif
00409         item->next = _root;
00410         _root = item;
00411     }
00412     void Trace( const char* name ) {
00413         printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
00414                 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
00415                 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
00416     }
00417 
00418     void SetTracked() {
00419         --_nUntracked;
00420     }
00421 
00422     int Untracked() const {
00423         return _nUntracked;
00424     }
00425 
00426         // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
00427         // The test file is large, 170k.
00428         // Release:             VS2010 gcc(no opt)
00429         //              1k:             4000
00430         //              2k:             4000
00431         //              4k:             3900    21000
00432         //              16k:    5200
00433         //              32k:    4300
00434         //              64k:    4000    21000
00435     // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
00436     // in private part if ITEMS_PER_BLOCK is private
00437     enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
00438 
00439 private:
00440     MemPoolT( const MemPoolT& ); // not supported
00441     void operator=( const MemPoolT& ); // not supported
00442 
00443     union Item {
00444         Item*   next;
00445         char    itemData[ITEM_SIZE];
00446     };
00447     struct Block {
00448         Item items[ITEMS_PER_BLOCK];
00449     };
00450     DynArray< Block*, 10 > _blockPtrs;
00451     Item* _root;
00452 
00453     int _currentAllocs;
00454     int _nAllocs;
00455     int _maxAllocs;
00456     int _nUntracked;
00457 };
00458 
00459 
00460 
00480 class TINYXML2_LIB XMLVisitor
00481 {
00482 public:
00483     virtual ~XMLVisitor() {}
00484 
00486     virtual bool VisitEnter( const XMLDocument& /*doc*/ )                       {
00487         return true;
00488     }
00490     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
00491         return true;
00492     }
00493 
00495     virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    {
00496         return true;
00497     }
00499     virtual bool VisitExit( const XMLElement& /*element*/ )                     {
00500         return true;
00501     }
00502 
00504     virtual bool Visit( const XMLDeclaration& /*declaration*/ )         {
00505         return true;
00506     }
00508     virtual bool Visit( const XMLText& /*text*/ )                                       {
00509         return true;
00510     }
00512     virtual bool Visit( const XMLComment& /*comment*/ )                         {
00513         return true;
00514     }
00516     virtual bool Visit( const XMLUnknown& /*unknown*/ )                         {
00517         return true;
00518     }
00519 };
00520 
00521 // WARNING: must match XMLDocument::_errorNames[]
00522 enum XMLError {
00523     XML_SUCCESS = 0,
00524     XML_NO_ATTRIBUTE,
00525     XML_WRONG_ATTRIBUTE_TYPE,
00526     XML_ERROR_FILE_NOT_FOUND,
00527     XML_ERROR_FILE_COULD_NOT_BE_OPENED,
00528     XML_ERROR_FILE_READ_ERROR,
00529     XML_ERROR_PARSING_ELEMENT,
00530     XML_ERROR_PARSING_ATTRIBUTE,
00531     XML_ERROR_PARSING_TEXT,
00532     XML_ERROR_PARSING_CDATA,
00533     XML_ERROR_PARSING_COMMENT,
00534     XML_ERROR_PARSING_DECLARATION,
00535     XML_ERROR_PARSING_UNKNOWN,
00536     XML_ERROR_EMPTY_DOCUMENT,
00537     XML_ERROR_MISMATCHED_ELEMENT,
00538     XML_ERROR_PARSING,
00539     XML_CAN_NOT_CONVERT_TEXT,
00540     XML_NO_TEXT_NODE,
00541         XML_ELEMENT_DEPTH_EXCEEDED,
00542 
00543         XML_ERROR_COUNT
00544 };
00545 
00546 
00547 /*
00548         Utility functionality.
00549 */
00550 class TINYXML2_LIB XMLUtil
00551 {
00552 public:
00553     static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr )      {
00554         TIXMLASSERT( p );
00555 
00556         while( IsWhiteSpace(*p) ) {
00557             if (curLineNumPtr && *p == '\n') {
00558                 ++(*curLineNumPtr);
00559             }
00560             ++p;
00561         }
00562         TIXMLASSERT( p );
00563         return p;
00564     }
00565     static char* SkipWhiteSpace( char* p, int* curLineNumPtr )                          {
00566         return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
00567     }
00568 
00569     // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
00570     // correct, but simple, and usually works.
00571     static bool IsWhiteSpace( char p )                                  {
00572         return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
00573     }
00574 
00575     inline static bool IsNameStartChar( unsigned char ch ) {
00576         if ( ch >= 128 ) {
00577             // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
00578             return true;
00579         }
00580         if ( isalpha( ch ) ) {
00581             return true;
00582         }
00583         return ch == ':' || ch == '_';
00584     }
00585 
00586     inline static bool IsNameChar( unsigned char ch ) {
00587         return IsNameStartChar( ch )
00588                || isdigit( ch )
00589                || ch == '.'
00590                || ch == '-';
00591     }
00592 
00593     inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
00594         if ( p == q ) {
00595             return true;
00596         }
00597         TIXMLASSERT( p );
00598         TIXMLASSERT( q );
00599         TIXMLASSERT( nChar >= 0 );
00600         return strncmp( p, q, nChar ) == 0;
00601     }
00602 
00603     inline static bool IsUTF8Continuation( char p ) {
00604         return ( p & 0x80 ) != 0;
00605     }
00606 
00607     static const char* ReadBOM( const char* p, bool* hasBOM );
00608     // p is the starting location,
00609     // the UTF-8 value of the entity will be placed in value, and length filled in.
00610     static const char* GetCharacterRef( const char* p, char* value, int* length );
00611     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00612 
00613     // converts primitive types to strings
00614     static void ToStr( int v, char* buffer, int bufferSize );
00615     static void ToStr( unsigned v, char* buffer, int bufferSize );
00616     static void ToStr( bool v, char* buffer, int bufferSize );
00617     static void ToStr( float v, char* buffer, int bufferSize );
00618     static void ToStr( double v, char* buffer, int bufferSize );
00619         static void ToStr(int64_t v, char* buffer, int bufferSize);
00620 
00621     // converts strings to primitive types
00622     static bool ToInt( const char* str, int* value );
00623     static bool ToUnsigned( const char* str, unsigned* value );
00624     static bool ToBool( const char* str, bool* value );
00625     static bool ToFloat( const char* str, float* value );
00626     static bool ToDouble( const char* str, double* value );
00627         static bool ToInt64(const char* str, int64_t* value);
00628 
00629         // Changes what is serialized for a boolean value.
00630         // Default to "true" and "false". Shouldn't be changed
00631         // unless you have a special testing or compatibility need.
00632         // Be careful: static, global, & not thread safe.
00633         // Be sure to set static const memory as parameters.
00634         static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
00635 
00636 private:
00637         static const char* writeBoolTrue;
00638         static const char* writeBoolFalse;
00639 };
00640 
00641 
00667 class TINYXML2_LIB XMLNode
00668 {
00669     friend class XMLDocument;
00670     friend class XMLElement;
00671 public:
00672 
00674     const XMLDocument* GetDocument() const      {
00675         TIXMLASSERT( _document );
00676         return _document;
00677     }
00679     XMLDocument* GetDocument()                          {
00680         TIXMLASSERT( _document );
00681         return _document;
00682     }
00683 
00685     virtual XMLElement*         ToElement()             {
00686         return 0;
00687     }
00689     virtual XMLText*            ToText()                {
00690         return 0;
00691     }
00693     virtual XMLComment*         ToComment()             {
00694         return 0;
00695     }
00697     virtual XMLDocument*        ToDocument()    {
00698         return 0;
00699     }
00701     virtual XMLDeclaration*     ToDeclaration() {
00702         return 0;
00703     }
00705     virtual XMLUnknown*         ToUnknown()             {
00706         return 0;
00707     }
00708 
00709     virtual const XMLElement*           ToElement() const               {
00710         return 0;
00711     }
00712     virtual const XMLText*                      ToText() const                  {
00713         return 0;
00714     }
00715     virtual const XMLComment*           ToComment() const               {
00716         return 0;
00717     }
00718     virtual const XMLDocument*          ToDocument() const              {
00719         return 0;
00720     }
00721     virtual const XMLDeclaration*       ToDeclaration() const   {
00722         return 0;
00723     }
00724     virtual const XMLUnknown*           ToUnknown() const               {
00725         return 0;
00726     }
00727 
00737     const char* Value() const;
00738 
00742     void SetValue( const char* val, bool staticMem=false );
00743 
00745     int GetLineNum() const { return _parseLineNum; }
00746 
00748     const XMLNode*      Parent() const                  {
00749         return _parent;
00750     }
00751 
00752     XMLNode* Parent()                                           {
00753         return _parent;
00754     }
00755 
00757     bool NoChildren() const                                     {
00758         return !_firstChild;
00759     }
00760 
00762     const XMLNode*  FirstChild() const          {
00763         return _firstChild;
00764     }
00765 
00766     XMLNode*            FirstChild()                    {
00767         return _firstChild;
00768     }
00769 
00773     const XMLElement* FirstChildElement( const char* name = 0 ) const;
00774 
00775     XMLElement* FirstChildElement( const char* name = 0 )       {
00776         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
00777     }
00778 
00780     const XMLNode*      LastChild() const                                               {
00781         return _lastChild;
00782     }
00783 
00784     XMLNode*            LastChild()                                                             {
00785         return _lastChild;
00786     }
00787 
00791     const XMLElement* LastChildElement( const char* name = 0 ) const;
00792 
00793     XMLElement* LastChildElement( const char* name = 0 )        {
00794         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
00795     }
00796 
00798     const XMLNode*      PreviousSibling() const                                 {
00799         return _prev;
00800     }
00801 
00802     XMLNode*    PreviousSibling()                                                       {
00803         return _prev;
00804     }
00805 
00807     const XMLElement*   PreviousSiblingElement( const char* name = 0 ) const ;
00808 
00809     XMLElement* PreviousSiblingElement( const char* name = 0 ) {
00810         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
00811     }
00812 
00814     const XMLNode*      NextSibling() const                                             {
00815         return _next;
00816     }
00817 
00818     XMLNode*    NextSibling()                                                           {
00819         return _next;
00820     }
00821 
00823     const XMLElement*   NextSiblingElement( const char* name = 0 ) const;
00824 
00825     XMLElement* NextSiblingElement( const char* name = 0 )      {
00826         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
00827     }
00828 
00836     XMLNode* InsertEndChild( XMLNode* addThis );
00837 
00838     XMLNode* LinkEndChild( XMLNode* addThis )   {
00839         return InsertEndChild( addThis );
00840     }
00848     XMLNode* InsertFirstChild( XMLNode* addThis );
00857     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
00858 
00862     void DeleteChildren();
00863 
00867     void DeleteChild( XMLNode* node );
00868 
00878     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
00879 
00893         XMLNode* DeepClone( XMLDocument* target ) const;
00894 
00901     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
00902 
00925     virtual bool Accept( XMLVisitor* visitor ) const = 0;
00926 
00932         void SetUserData(void* userData)        { _userData = userData; }
00933 
00939         void* GetUserData() const                       { return _userData; }
00940 
00941 protected:
00942     explicit XMLNode( XMLDocument* );
00943     virtual ~XMLNode();
00944 
00945     virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
00946 
00947     XMLDocument*        _document;
00948     XMLNode*            _parent;
00949     mutable StrPair     _value;
00950     int             _parseLineNum;
00951 
00952     XMLNode*            _firstChild;
00953     XMLNode*            _lastChild;
00954 
00955     XMLNode*            _prev;
00956     XMLNode*            _next;
00957 
00958         void*                   _userData;
00959 
00960 private:
00961     MemPool*            _memPool;
00962     void Unlink( XMLNode* child );
00963     static void DeleteNode( XMLNode* node );
00964     void InsertChildPreamble( XMLNode* insertThis ) const;
00965     const XMLElement* ToElementWithName( const char* name ) const;
00966 
00967     XMLNode( const XMLNode& );  // not supported
00968     XMLNode& operator=( const XMLNode& );       // not supported
00969 };
00970 
00971 
00984 class TINYXML2_LIB XMLText : public XMLNode
00985 {
00986     friend class XMLDocument;
00987 public:
00988     virtual bool Accept( XMLVisitor* visitor ) const;
00989 
00990     virtual XMLText* ToText()                   {
00991         return this;
00992     }
00993     virtual const XMLText* ToText() const       {
00994         return this;
00995     }
00996 
00998     void SetCData( bool isCData )                       {
00999         _isCData = isCData;
01000     }
01002     bool CData() const                                          {
01003         return _isCData;
01004     }
01005 
01006     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01007     virtual bool ShallowEqual( const XMLNode* compare ) const;
01008 
01009 protected:
01010     explicit XMLText( XMLDocument* doc )        : XMLNode( doc ), _isCData( false )     {}
01011     virtual ~XMLText()                                                                                          {}
01012 
01013     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01014 
01015 private:
01016     bool _isCData;
01017 
01018     XMLText( const XMLText& );  // not supported
01019     XMLText& operator=( const XMLText& );       // not supported
01020 };
01021 
01022 
01024 class TINYXML2_LIB XMLComment : public XMLNode
01025 {
01026     friend class XMLDocument;
01027 public:
01028     virtual XMLComment* ToComment()                                     {
01029         return this;
01030     }
01031     virtual const XMLComment* ToComment() const         {
01032         return this;
01033     }
01034 
01035     virtual bool Accept( XMLVisitor* visitor ) const;
01036 
01037     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01038     virtual bool ShallowEqual( const XMLNode* compare ) const;
01039 
01040 protected:
01041     explicit XMLComment( XMLDocument* doc );
01042     virtual ~XMLComment();
01043 
01044     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
01045 
01046 private:
01047     XMLComment( const XMLComment& );    // not supported
01048     XMLComment& operator=( const XMLComment& ); // not supported
01049 };
01050 
01051 
01063 class TINYXML2_LIB XMLDeclaration : public XMLNode
01064 {
01065     friend class XMLDocument;
01066 public:
01067     virtual XMLDeclaration*     ToDeclaration()                                 {
01068         return this;
01069     }
01070     virtual const XMLDeclaration* ToDeclaration() const         {
01071         return this;
01072     }
01073 
01074     virtual bool Accept( XMLVisitor* visitor ) const;
01075 
01076     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01077     virtual bool ShallowEqual( const XMLNode* compare ) const;
01078 
01079 protected:
01080     explicit XMLDeclaration( XMLDocument* doc );
01081     virtual ~XMLDeclaration();
01082 
01083     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01084 
01085 private:
01086     XMLDeclaration( const XMLDeclaration& );    // not supported
01087     XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
01088 };
01089 
01090 
01098 class TINYXML2_LIB XMLUnknown : public XMLNode
01099 {
01100     friend class XMLDocument;
01101 public:
01102     virtual XMLUnknown* ToUnknown()                                     {
01103         return this;
01104     }
01105     virtual const XMLUnknown* ToUnknown() const         {
01106         return this;
01107     }
01108 
01109     virtual bool Accept( XMLVisitor* visitor ) const;
01110 
01111     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01112     virtual bool ShallowEqual( const XMLNode* compare ) const;
01113 
01114 protected:
01115     explicit XMLUnknown( XMLDocument* doc );
01116     virtual ~XMLUnknown();
01117 
01118     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01119 
01120 private:
01121     XMLUnknown( const XMLUnknown& );    // not supported
01122     XMLUnknown& operator=( const XMLUnknown& ); // not supported
01123 };
01124 
01125 
01126 
01133 class TINYXML2_LIB XMLAttribute
01134 {
01135     friend class XMLElement;
01136 public:
01138     const char* Name() const;
01139 
01141     const char* Value() const;
01142 
01144     int GetLineNum() const { return _parseLineNum; }
01145 
01147     const XMLAttribute* Next() const {
01148         return _next;
01149     }
01150 
01155         int     IntValue() const {
01156                 int i = 0;
01157                 QueryIntValue(&i);
01158                 return i;
01159         }
01160 
01161         int64_t Int64Value() const {
01162                 int64_t i = 0;
01163                 QueryInt64Value(&i);
01164                 return i;
01165         }
01166 
01168     unsigned UnsignedValue() const                      {
01169         unsigned i=0;
01170         QueryUnsignedValue( &i );
01171         return i;
01172     }
01174     bool         BoolValue() const                              {
01175         bool b=false;
01176         QueryBoolValue( &b );
01177         return b;
01178     }
01180     double       DoubleValue() const                    {
01181         double d=0;
01182         QueryDoubleValue( &d );
01183         return d;
01184     }
01186     float        FloatValue() const                             {
01187         float f=0;
01188         QueryFloatValue( &f );
01189         return f;
01190     }
01191 
01196     XMLError QueryIntValue( int* value ) const;
01198     XMLError QueryUnsignedValue( unsigned int* value ) const;
01200         XMLError QueryInt64Value(int64_t* value) const;
01202     XMLError QueryBoolValue( bool* value ) const;
01204     XMLError QueryDoubleValue( double* value ) const;
01206     XMLError QueryFloatValue( float* value ) const;
01207 
01209     void SetAttribute( const char* value );
01211     void SetAttribute( int value );
01213     void SetAttribute( unsigned value );
01215         void SetAttribute(int64_t value);
01217     void SetAttribute( bool value );
01219     void SetAttribute( double value );
01221     void SetAttribute( float value );
01222 
01223 private:
01224     enum { BUF_SIZE = 200 };
01225 
01226     XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
01227     virtual ~XMLAttribute()     {}
01228 
01229     XMLAttribute( const XMLAttribute& );        // not supported
01230     void operator=( const XMLAttribute& );      // not supported
01231     void SetName( const char* name );
01232 
01233     char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
01234 
01235     mutable StrPair _name;
01236     mutable StrPair _value;
01237     int             _parseLineNum;
01238     XMLAttribute*   _next;
01239     MemPool*        _memPool;
01240 };
01241 
01242 
01247 class TINYXML2_LIB XMLElement : public XMLNode
01248 {
01249     friend class XMLDocument;
01250 public:
01252     const char* Name() const            {
01253         return Value();
01254     }
01256     void SetName( const char* str, bool staticMem=false )       {
01257         SetValue( str, staticMem );
01258     }
01259 
01260     virtual XMLElement* ToElement()                             {
01261         return this;
01262     }
01263     virtual const XMLElement* ToElement() const {
01264         return this;
01265     }
01266     virtual bool Accept( XMLVisitor* visitor ) const;
01267 
01291     const char* Attribute( const char* name, const char* value=0 ) const;
01292 
01299         int IntAttribute(const char* name, int defaultValue = 0) const;
01301         unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
01303         int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
01305         bool BoolAttribute(const char* name, bool defaultValue = false) const;
01307         double DoubleAttribute(const char* name, double defaultValue = 0) const;
01309         float FloatAttribute(const char* name, float defaultValue = 0) const;
01310 
01324     XMLError QueryIntAttribute( const char* name, int* value ) const                            {
01325         const XMLAttribute* a = FindAttribute( name );
01326         if ( !a ) {
01327             return XML_NO_ATTRIBUTE;
01328         }
01329         return a->QueryIntValue( value );
01330     }
01331 
01333     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const      {
01334         const XMLAttribute* a = FindAttribute( name );
01335         if ( !a ) {
01336             return XML_NO_ATTRIBUTE;
01337         }
01338         return a->QueryUnsignedValue( value );
01339     }
01340 
01342         XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
01343                 const XMLAttribute* a = FindAttribute(name);
01344                 if (!a) {
01345                         return XML_NO_ATTRIBUTE;
01346                 }
01347                 return a->QueryInt64Value(value);
01348         }
01349 
01351     XMLError QueryBoolAttribute( const char* name, bool* value ) const                          {
01352         const XMLAttribute* a = FindAttribute( name );
01353         if ( !a ) {
01354             return XML_NO_ATTRIBUTE;
01355         }
01356         return a->QueryBoolValue( value );
01357     }
01359     XMLError QueryDoubleAttribute( const char* name, double* value ) const                      {
01360         const XMLAttribute* a = FindAttribute( name );
01361         if ( !a ) {
01362             return XML_NO_ATTRIBUTE;
01363         }
01364         return a->QueryDoubleValue( value );
01365     }
01367     XMLError QueryFloatAttribute( const char* name, float* value ) const                        {
01368         const XMLAttribute* a = FindAttribute( name );
01369         if ( !a ) {
01370             return XML_NO_ATTRIBUTE;
01371         }
01372         return a->QueryFloatValue( value );
01373     }
01374 
01376         XMLError QueryStringAttribute(const char* name, const char** value) const {
01377                 const XMLAttribute* a = FindAttribute(name);
01378                 if (!a) {
01379                         return XML_NO_ATTRIBUTE;
01380                 }
01381                 *value = a->Value();
01382                 return XML_SUCCESS;
01383         }
01384 
01385 
01386 
01404         XMLError QueryAttribute( const char* name, int* value ) const {
01405                 return QueryIntAttribute( name, value );
01406         }
01407 
01408         XMLError QueryAttribute( const char* name, unsigned int* value ) const {
01409                 return QueryUnsignedAttribute( name, value );
01410         }
01411 
01412         XMLError QueryAttribute(const char* name, int64_t* value) const {
01413                 return QueryInt64Attribute(name, value);
01414         }
01415 
01416         XMLError QueryAttribute( const char* name, bool* value ) const {
01417                 return QueryBoolAttribute( name, value );
01418         }
01419 
01420         XMLError QueryAttribute( const char* name, double* value ) const {
01421                 return QueryDoubleAttribute( name, value );
01422         }
01423 
01424         XMLError QueryAttribute( const char* name, float* value ) const {
01425                 return QueryFloatAttribute( name, value );
01426         }
01427 
01429     void SetAttribute( const char* name, const char* value )    {
01430         XMLAttribute* a = FindOrCreateAttribute( name );
01431         a->SetAttribute( value );
01432     }
01434     void SetAttribute( const char* name, int value )                    {
01435         XMLAttribute* a = FindOrCreateAttribute( name );
01436         a->SetAttribute( value );
01437     }
01439     void SetAttribute( const char* name, unsigned value )               {
01440         XMLAttribute* a = FindOrCreateAttribute( name );
01441         a->SetAttribute( value );
01442     }
01443 
01445         void SetAttribute(const char* name, int64_t value) {
01446                 XMLAttribute* a = FindOrCreateAttribute(name);
01447                 a->SetAttribute(value);
01448         }
01449 
01451     void SetAttribute( const char* name, bool value )                   {
01452         XMLAttribute* a = FindOrCreateAttribute( name );
01453         a->SetAttribute( value );
01454     }
01456     void SetAttribute( const char* name, double value )         {
01457         XMLAttribute* a = FindOrCreateAttribute( name );
01458         a->SetAttribute( value );
01459     }
01461     void SetAttribute( const char* name, float value )          {
01462         XMLAttribute* a = FindOrCreateAttribute( name );
01463         a->SetAttribute( value );
01464     }
01465 
01469     void DeleteAttribute( const char* name );
01470 
01472     const XMLAttribute* FirstAttribute() const {
01473         return _rootAttribute;
01474     }
01476     const XMLAttribute* FindAttribute( const char* name ) const;
01477 
01506     const char* GetText() const;
01507 
01542         void SetText( const char* inText );
01544     void SetText( int value );
01546     void SetText( unsigned value );
01548         void SetText(int64_t value);
01550     void SetText( bool value );
01552     void SetText( double value );
01554     void SetText( float value );
01555 
01582     XMLError QueryIntText( int* ival ) const;
01584     XMLError QueryUnsignedText( unsigned* uval ) const;
01586         XMLError QueryInt64Text(int64_t* uval) const;
01588     XMLError QueryBoolText( bool* bval ) const;
01590     XMLError QueryDoubleText( double* dval ) const;
01592     XMLError QueryFloatText( float* fval ) const;
01593 
01594         int IntText(int defaultValue = 0) const;
01595 
01597         unsigned UnsignedText(unsigned defaultValue = 0) const;
01599         int64_t Int64Text(int64_t defaultValue = 0) const;
01601         bool BoolText(bool defaultValue = false) const;
01603         double DoubleText(double defaultValue = 0) const;
01605         float FloatText(float defaultValue = 0) const;
01606 
01607     // internal:
01608     enum ElementClosingType {
01609         OPEN,           // <foo>
01610         CLOSED,         // <foo/>
01611         CLOSING         // </foo>
01612     };
01613     ElementClosingType ClosingType() const {
01614         return _closingType;
01615     }
01616     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
01617     virtual bool ShallowEqual( const XMLNode* compare ) const;
01618 
01619 protected:
01620     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
01621 
01622 private:
01623     XMLElement( XMLDocument* doc );
01624     virtual ~XMLElement();
01625     XMLElement( const XMLElement& );    // not supported
01626     void operator=( const XMLElement& );        // not supported
01627 
01628     XMLAttribute* FindOrCreateAttribute( const char* name );
01629     char* ParseAttributes( char* p, int* curLineNumPtr );
01630     static void DeleteAttribute( XMLAttribute* attribute );
01631     XMLAttribute* CreateAttribute();
01632 
01633     enum { BUF_SIZE = 200 };
01634     ElementClosingType _closingType;
01635     // The attribute list is ordered; there is no 'lastAttribute'
01636     // because the list needs to be scanned for dupes before adding
01637     // a new attribute.
01638     XMLAttribute* _rootAttribute;
01639 };
01640 
01641 
01642 enum Whitespace {
01643     PRESERVE_WHITESPACE,
01644     COLLAPSE_WHITESPACE
01645 };
01646 
01647 
01653 class TINYXML2_LIB XMLDocument : public XMLNode
01654 {
01655     friend class XMLElement;
01656     // Gives access to SetError and Push/PopDepth, but over-access for everything else.
01657     // Wishing C++ had "internal" scope.
01658     friend class XMLNode;
01659     friend class XMLText;
01660     friend class XMLComment;
01661     friend class XMLDeclaration;
01662     friend class XMLUnknown;
01663 public:
01665     XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
01666     ~XMLDocument();
01667 
01668     virtual XMLDocument* ToDocument()                           {
01669         TIXMLASSERT( this == _document );
01670         return this;
01671     }
01672     virtual const XMLDocument* ToDocument() const       {
01673         TIXMLASSERT( this == _document );
01674         return this;
01675     }
01676 
01687     XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
01688 
01694     XMLError LoadFile( const char* filename );
01695 
01707     XMLError LoadFile( FILE* );
01708 
01714     XMLError SaveFile( const char* filename, bool compact = false );
01715 
01723     XMLError SaveFile( FILE* fp, bool compact = false );
01724 
01725     bool ProcessEntities() const                {
01726         return _processEntities;
01727     }
01728     Whitespace WhitespaceMode() const   {
01729         return _whitespaceMode;
01730     }
01731 
01735     bool HasBOM() const {
01736         return _writeBOM;
01737     }
01740     void SetBOM( bool useBOM ) {
01741         _writeBOM = useBOM;
01742     }
01743 
01747     XMLElement* RootElement()                           {
01748         return FirstChildElement();
01749     }
01750     const XMLElement* RootElement() const       {
01751         return FirstChildElement();
01752     }
01753 
01768     void Print( XMLPrinter* streamer=0 ) const;
01769     virtual bool Accept( XMLVisitor* visitor ) const;
01770 
01776     XMLElement* NewElement( const char* name );
01782     XMLComment* NewComment( const char* comment );
01788     XMLText* NewText( const char* text );
01800     XMLDeclaration* NewDeclaration( const char* text=0 );
01806     XMLUnknown* NewUnknown( const char* text );
01807 
01812     void DeleteNode( XMLNode* node );
01813 
01814     void ClearError() {
01815         SetError(XML_SUCCESS, 0, 0);
01816     }
01817 
01819     bool Error() const {
01820         return _errorID != XML_SUCCESS;
01821     }
01823     XMLError  ErrorID() const {
01824         return _errorID;
01825     }
01826         const char* ErrorName() const;
01827     static const char* ErrorIDToName(XMLError errorID);
01828 
01832         const char* ErrorStr() const;
01833 
01835     void PrintError() const;
01836 
01838     int ErrorLineNum() const
01839     {
01840         return _errorLineNum;
01841     }
01842 
01844     void Clear();
01845 
01853         void DeepCopy(XMLDocument* target) const;
01854 
01855         // internal
01856     char* Identify( char* p, XMLNode** node );
01857 
01858         // internal
01859         void MarkInUse(XMLNode*);
01860 
01861     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    {
01862         return 0;
01863     }
01864     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const       {
01865         return false;
01866     }
01867 
01868 private:
01869     XMLDocument( const XMLDocument& );  // not supported
01870     void operator=( const XMLDocument& );       // not supported
01871 
01872     bool                        _writeBOM;
01873     bool                        _processEntities;
01874     XMLError            _errorID;
01875     Whitespace          _whitespaceMode;
01876     mutable StrPair     _errorStr;
01877     int             _errorLineNum;
01878     char*                       _charBuffer;
01879     int                         _parseCurLineNum;
01880         int                             _parsingDepth;
01881         // Memory tracking does add some overhead.
01882         // However, the code assumes that you don't
01883         // have a bunch of unlinked nodes around.
01884         // Therefore it takes less memory to track
01885         // in the document vs. a linked list in the XMLNode,
01886         // and the performance is the same.
01887         DynArray<XMLNode*, 10> _unlinked;
01888 
01889     MemPoolT< sizeof(XMLElement) >       _elementPool;
01890     MemPoolT< sizeof(XMLAttribute) > _attributePool;
01891     MemPoolT< sizeof(XMLText) >          _textPool;
01892     MemPoolT< sizeof(XMLComment) >       _commentPool;
01893 
01894         static const char* _errorNames[XML_ERROR_COUNT];
01895 
01896     void Parse();
01897 
01898     void SetError( XMLError error, int lineNum, const char* format, ... );
01899 
01900         // Something of an obvious security hole, once it was discovered.
01901         // Either an ill-formed XML or an excessively deep one can overflow
01902         // the stack. Track stack depth, and error out if needed.
01903         class DepthTracker {
01904         public:
01905                 explicit DepthTracker(XMLDocument * document) {
01906                         this->_document = document;
01907                         document->PushDepth();
01908                 }
01909                 ~DepthTracker() {
01910                         _document->PopDepth();
01911                 }
01912         private:
01913                 XMLDocument * _document;
01914         };
01915         void PushDepth();
01916         void PopDepth();
01917 
01918     template<class NodeType, int PoolElementSize>
01919     NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
01920 };
01921 
01922 template<class NodeType, int PoolElementSize>
01923 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
01924 {
01925     TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
01926     TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
01927     NodeType* returnNode = new (pool.Alloc()) NodeType( this );
01928     TIXMLASSERT( returnNode );
01929     returnNode->_memPool = &pool;
01930 
01931         _unlinked.Push(returnNode);
01932     return returnNode;
01933 }
01934 
01990 class TINYXML2_LIB XMLHandle
01991 {
01992 public:
01994     explicit XMLHandle( XMLNode* node ) : _node( node ) {
01995     }
01997     explicit XMLHandle( XMLNode& node ) : _node( &node ) {
01998     }
02000     XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
02001     }
02003     XMLHandle& operator=( const XMLHandle& ref )                                                        {
02004         _node = ref._node;
02005         return *this;
02006     }
02007 
02009     XMLHandle FirstChild()                                                                                                      {
02010         return XMLHandle( _node ? _node->FirstChild() : 0 );
02011     }
02013     XMLHandle FirstChildElement( const char* name = 0 )                                         {
02014         return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
02015     }
02017     XMLHandle LastChild()                                                                                                       {
02018         return XMLHandle( _node ? _node->LastChild() : 0 );
02019     }
02021     XMLHandle LastChildElement( const char* name = 0 )                                          {
02022         return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
02023     }
02025     XMLHandle PreviousSibling()                                                                                         {
02026         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
02027     }
02029     XMLHandle PreviousSiblingElement( const char* name = 0 )                            {
02030         return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02031     }
02033     XMLHandle NextSibling()                                                                                                     {
02034         return XMLHandle( _node ? _node->NextSibling() : 0 );
02035     }
02037     XMLHandle NextSiblingElement( const char* name = 0 )                                        {
02038         return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02039     }
02040 
02042     XMLNode* ToNode()                                                   {
02043         return _node;
02044     }
02046     XMLElement* ToElement()                                     {
02047         return ( _node ? _node->ToElement() : 0 );
02048     }
02050     XMLText* ToText()                                                   {
02051         return ( _node ? _node->ToText() : 0 );
02052     }
02054     XMLUnknown* ToUnknown()                                     {
02055         return ( _node ? _node->ToUnknown() : 0 );
02056     }
02058     XMLDeclaration* ToDeclaration()                     {
02059         return ( _node ? _node->ToDeclaration() : 0 );
02060     }
02061 
02062 private:
02063     XMLNode* _node;
02064 };
02065 
02066 
02071 class TINYXML2_LIB XMLConstHandle
02072 {
02073 public:
02074     explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
02075     }
02076     explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
02077     }
02078     XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
02079     }
02080 
02081     XMLConstHandle& operator=( const XMLConstHandle& ref )                                                      {
02082         _node = ref._node;
02083         return *this;
02084     }
02085 
02086     const XMLConstHandle FirstChild() const                                                                                     {
02087         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
02088     }
02089     const XMLConstHandle FirstChildElement( const char* name = 0 ) const                                {
02090         return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
02091     }
02092     const XMLConstHandle LastChild()    const                                                                           {
02093         return XMLConstHandle( _node ? _node->LastChild() : 0 );
02094     }
02095     const XMLConstHandle LastChildElement( const char* name = 0 ) const                         {
02096         return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
02097     }
02098     const XMLConstHandle PreviousSibling() const                                                                        {
02099         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
02100     }
02101     const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const           {
02102         return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
02103     }
02104     const XMLConstHandle NextSibling() const                                                                            {
02105         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
02106     }
02107     const XMLConstHandle NextSiblingElement( const char* name = 0 ) const                       {
02108         return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
02109     }
02110 
02111 
02112     const XMLNode* ToNode() const                               {
02113         return _node;
02114     }
02115     const XMLElement* ToElement() const                 {
02116         return ( _node ? _node->ToElement() : 0 );
02117     }
02118     const XMLText* ToText() const                               {
02119         return ( _node ? _node->ToText() : 0 );
02120     }
02121     const XMLUnknown* ToUnknown() const                 {
02122         return ( _node ? _node->ToUnknown() : 0 );
02123     }
02124     const XMLDeclaration* ToDeclaration() const {
02125         return ( _node ? _node->ToDeclaration() : 0 );
02126     }
02127 
02128 private:
02129     const XMLNode* _node;
02130 };
02131 
02132 
02175 class TINYXML2_LIB XMLPrinter : public XMLVisitor
02176 {
02177 public:
02184     XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
02185     virtual ~XMLPrinter()       {}
02186 
02188     void PushHeader( bool writeBOM, bool writeDeclaration );
02192     void OpenElement( const char* name, bool compactMode=false );
02194     void PushAttribute( const char* name, const char* value );
02195     void PushAttribute( const char* name, int value );
02196     void PushAttribute( const char* name, unsigned value );
02197         void PushAttribute(const char* name, int64_t value);
02198         void PushAttribute( const char* name, bool value );
02199     void PushAttribute( const char* name, double value );
02201     virtual void CloseElement( bool compactMode=false );
02202 
02204     void PushText( const char* text, bool cdata=false );
02206     void PushText( int value );
02208     void PushText( unsigned value );
02210         void PushText(int64_t value);
02212     void PushText( bool value );
02214     void PushText( float value );
02216     void PushText( double value );
02217 
02219     void PushComment( const char* comment );
02220 
02221     void PushDeclaration( const char* value );
02222     void PushUnknown( const char* value );
02223 
02224     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
02225     virtual bool VisitExit( const XMLDocument& /*doc*/ )                        {
02226         return true;
02227     }
02228 
02229     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
02230     virtual bool VisitExit( const XMLElement& element );
02231 
02232     virtual bool Visit( const XMLText& text );
02233     virtual bool Visit( const XMLComment& comment );
02234     virtual bool Visit( const XMLDeclaration& declaration );
02235     virtual bool Visit( const XMLUnknown& unknown );
02236 
02241     const char* CStr() const {
02242         return _buffer.Mem();
02243     }
02249     int CStrSize() const {
02250         return _buffer.Size();
02251     }
02256     void ClearBuffer() {
02257         _buffer.Clear();
02258         _buffer.Push(0);
02259                 _firstElement = true;
02260     }
02261 
02262 protected:
02263         virtual bool CompactMode( const XMLElement& )   { return _compactMode; }
02264 
02268     virtual void PrintSpace( int depth );
02269     void Print( const char* format, ... );
02270     void Write( const char* data, size_t size );
02271     inline void Write( const char* data )           { Write( data, strlen( data ) ); }
02272     void Putc( char ch );
02273 
02274     void SealElementIfJustOpened();
02275     bool _elementJustOpened;
02276     DynArray< const char*, 10 > _stack;
02277 
02278 private:
02279     void PrintString( const char*, bool restrictedEntitySet );  // prints out, after detecting entities.
02280 
02281     bool _firstElement;
02282     FILE* _fp;
02283     int _depth;
02284     int _textDepth;
02285     bool _processEntities;
02286         bool _compactMode;
02287 
02288     enum {
02289         ENTITY_RANGE = 64,
02290         BUF_SIZE = 200
02291     };
02292     bool _entityFlag[ENTITY_RANGE];
02293     bool _restrictedEntityFlag[ENTITY_RANGE];
02294 
02295     DynArray< char, 20 > _buffer;
02296 
02297     // Prohibit cloning, intentionally not implemented
02298     XMLPrinter( const XMLPrinter& );
02299     XMLPrinter& operator=( const XMLPrinter& );
02300 };
02301 
02302 
02303 }       // tinyxml2
02304 
02305 #if defined(_MSC_VER)
02306 #   pragma warning(pop)
02307 #endif
02308 
02309 #endif // BT_TINYXML2_INCLUDED


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 20:17:15