Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:19:52

0001 /*

0002 Original code by Lee Thomason (www.grinninglizard.com)

0003 

0004 This software is provided 'as-is', without any express or implied

0005 warranty. In no event will the authors be held liable for any

0006 damages arising from the use of this software.

0007 

0008 Permission is granted to anyone to use this software for any

0009 purpose, including commercial applications, and to alter it and

0010 redistribute it freely, subject to the following restrictions:

0011 

0012 1. The origin of this software must not be misrepresented; you must

0013 not claim that you wrote the original software. If you use this

0014 software in a product, an acknowledgment in the product documentation

0015 would be appreciated but is not required.

0016 

0017 2. Altered source versions must be plainly marked as such, and

0018 must not be misrepresented as being the original software.

0019 

0020 3. This notice may not be removed or altered from any source

0021 distribution.

0022 */
0023 
0024 #ifndef TINYXML2_INCLUDED
0025 #define TINYXML2_INCLUDED
0026 
0027 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
0028 #   include <ctype.h>
0029 #   include <limits.h>
0030 #   include <stdio.h>
0031 #   include <stdlib.h>
0032 #   include <string.h>
0033 #   if defined(__PS3__)
0034 #       include <stddef.h>
0035 #   endif
0036 #else
0037 #   include <cctype>
0038 #   include <climits>
0039 #   include <cstdio>
0040 #   include <cstdlib>
0041 #   include <cstring>
0042 #endif
0043 #include <stdint.h>
0044 
0045 /*

0046    TODO: intern strings instead of allocation.

0047 */
0048 /*

0049     gcc:

0050         g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe

0051 

0052     Formatting, Artistic Style:

0053         AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h

0054 */
0055 
0056 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
0057 #   ifndef DEBUG
0058 #       define DEBUG
0059 #   endif
0060 #endif
0061 
0062 #ifdef _MSC_VER
0063 #   pragma warning(push)
0064 #   pragma warning(disable: 4251)
0065 #endif
0066 
0067 #ifdef _WIN32
0068 #   ifdef TINYXML2_EXPORT
0069 #       define TINYXML2_LIB __declspec(dllexport)
0070 #   elif defined(TINYXML2_IMPORT)
0071 #       define TINYXML2_LIB __declspec(dllimport)
0072 #   else
0073 #       define TINYXML2_LIB
0074 #   endif
0075 #elif __GNUC__ >= 4
0076 #   define TINYXML2_LIB __attribute__((visibility("default")))
0077 #else
0078 #   define TINYXML2_LIB
0079 #endif
0080 
0081 
0082 #if defined(DEBUG)
0083 #   if defined(_MSC_VER)
0084 #       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like

0085 #       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
0086 #   elif defined (ANDROID_NDK)
0087 #       include <android/log.h>
0088 #       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
0089 #   else
0090 #       include <assert.h>
0091 #       define TIXMLASSERT                assert
0092 #   endif
0093 #else
0094 #   define TIXMLASSERT( x )               {}
0095 #endif
0096 
0097 
0098 /* Versioning, past 1.0.14:

0099     http://semver.org/

0100 */
0101 static const int TIXML2_MAJOR_VERSION = 4;
0102 static const int TIXML2_MINOR_VERSION = 0;
0103 static const int TIXML2_PATCH_VERSION = 1;
0104 
0105 namespace tinyxml2
0106 {
0107 class XMLDocument;
0108 class XMLElement;
0109 class XMLAttribute;
0110 class XMLComment;
0111 class XMLText;
0112 class XMLDeclaration;
0113 class XMLUnknown;
0114 class XMLPrinter;
0115 
0116 /*

0117     A class that wraps strings. Normally stores the start and end

0118     pointers into the XML file itself, and will apply normalization

0119     and entity translation if actually read. Can also store (and memory

0120     manage) a traditional char[]

0121 */
0122 class StrPair
0123 {
0124 public:
0125     enum {
0126         NEEDS_ENTITY_PROCESSING         = 0x01,
0127         NEEDS_NEWLINE_NORMALIZATION     = 0x02,
0128         NEEDS_WHITESPACE_COLLAPSING     = 0x04,
0129 
0130         TEXT_ELEMENT                    = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
0131         TEXT_ELEMENT_LEAVE_ENTITIES     = NEEDS_NEWLINE_NORMALIZATION,
0132         ATTRIBUTE_NAME                  = 0,
0133         ATTRIBUTE_VALUE                 = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
0134         ATTRIBUTE_VALUE_LEAVE_ENTITIES  = NEEDS_NEWLINE_NORMALIZATION,
0135         COMMENT                         = NEEDS_NEWLINE_NORMALIZATION
0136     };
0137 
0138     StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
0139     ~StrPair();
0140 
0141     void Set( char* start, char* end, int flags ) {
0142         TIXMLASSERT( start );
0143         TIXMLASSERT( end );
0144         Reset();
0145         _start  = start;
0146         _end    = end;
0147         _flags  = flags | NEEDS_FLUSH;
0148     }
0149 
0150     const char* GetStr();
0151 
0152     bool Empty() const {
0153         return _start == _end;
0154     }
0155 
0156     void SetInternedStr( const char* str ) {
0157         Reset();
0158         _start = const_cast<char*>(str);
0159     }
0160 
0161     void SetStr( const char* str, int flags=0 );
0162 
0163     char* ParseText( char* in, const char* endTag, int strFlags );
0164     char* ParseName( char* in );
0165 
0166     void TransferTo( StrPair* other );
0167     void Reset();
0168 
0169 private:
0170     void CollapseWhitespace();
0171 
0172     enum {
0173         NEEDS_FLUSH = 0x100,
0174         NEEDS_DELETE = 0x200
0175     };
0176 
0177     int     _flags;
0178     char*   _start;
0179     char*   _end;
0180 
0181     StrPair( const StrPair& other );    // not supported

0182     void operator=( StrPair& other );   // not supported, use TransferTo()

0183 };
0184 
0185 
0186 /*

0187     A dynamic array of Plain Old Data. Doesn't support constructors, etc.

0188     Has a small initial memory pool, so that low or no usage will not

0189     cause a call to new/delete

0190 */
0191 template <class T, int INITIAL_SIZE_XML>
0192 class DynArray
0193 {
0194 public:
0195     DynArray() {
0196         _mem = _pool;
0197         _allocated = INITIAL_SIZE_XML;
0198         _size = 0;
0199     }
0200 
0201     ~DynArray() {
0202         if ( _mem != _pool ) {
0203             delete [] _mem;
0204         }
0205     }
0206 
0207     void Clear() {
0208         _size = 0;
0209     }
0210 
0211     void Push( T t ) {
0212         TIXMLASSERT( _size < INT_MAX );
0213         EnsureCapacity( _size+1 );
0214         _mem[_size] = t;
0215         ++_size;
0216     }
0217 
0218     T* PushArr( int count ) {
0219         TIXMLASSERT( count >= 0 );
0220         TIXMLASSERT( _size <= INT_MAX - count );
0221         EnsureCapacity( _size+count );
0222         T* ret = &_mem[_size];
0223         _size += count;
0224         return ret;
0225     }
0226 
0227     T Pop() {
0228         TIXMLASSERT( _size > 0 );
0229         --_size;
0230         return _mem[_size];
0231     }
0232 
0233     void PopArr( int count ) {
0234         TIXMLASSERT( _size >= count );
0235         _size -= count;
0236     }
0237 
0238     bool Empty() const                  {
0239         return _size == 0;
0240     }
0241 
0242     T& operator[](int i)                {
0243         TIXMLASSERT( i>= 0 && i < _size );
0244         return _mem[i];
0245     }
0246 
0247     const T& operator[](int i) const    {
0248         TIXMLASSERT( i>= 0 && i < _size );
0249         return _mem[i];
0250     }
0251 
0252     const T& PeekTop() const            {
0253         TIXMLASSERT( _size > 0 );
0254         return _mem[ _size - 1];
0255     }
0256 
0257     int Size() const                    {
0258         TIXMLASSERT( _size >= 0 );
0259         return _size;
0260     }
0261 
0262     int Capacity() const                {
0263         TIXMLASSERT( _allocated >= INITIAL_SIZE_XML );
0264         return _allocated;
0265     }
0266 
0267     const T* Mem() const                {
0268         TIXMLASSERT( _mem );
0269         return _mem;
0270     }
0271 
0272     T* Mem()                            {
0273         TIXMLASSERT( _mem );
0274         return _mem;
0275     }
0276 
0277 private:
0278     DynArray( const DynArray& ); // not supported

0279     void operator=( const DynArray& ); // not supported

0280 
0281     void EnsureCapacity( int cap ) {
0282         TIXMLASSERT( cap > 0 );
0283         if ( cap > _allocated ) {
0284             TIXMLASSERT( cap <= INT_MAX / 2 );
0285             int newAllocated = cap * 2;
0286             T* newMem = new T[newAllocated];
0287             memcpy( newMem, _mem, sizeof(T)*_size );    // warning: not using constructors, only works for PODs

0288             if ( _mem != _pool ) {
0289                 delete [] _mem;
0290             }
0291             _mem = newMem;
0292             _allocated = newAllocated;
0293         }
0294     }
0295 
0296     T*  _mem;
0297     T   _pool[INITIAL_SIZE_XML];
0298     int _allocated;     // objects allocated

0299     int _size;          // number objects in use

0300 };
0301 
0302 
0303 /*

0304     Parent virtual class of a pool for fast allocation

0305     and deallocation of objects.

0306 */
0307 class MemPool
0308 {
0309 public:
0310     MemPool() {}
0311     virtual ~MemPool() {}
0312 
0313     virtual int ItemSize() const = 0;
0314     virtual void* Alloc() = 0;
0315     virtual void Free( void* ) = 0;
0316     virtual void SetTracked() = 0;
0317     virtual void Clear() = 0;
0318 };
0319 
0320 
0321 /*

0322     Template child class to create pools of the correct type.

0323 */
0324 template< int ITEM_SIZE >
0325 class MemPoolT : public MemPool
0326 {
0327 public:
0328     MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)    {}
0329     ~MemPoolT() {
0330         Clear();
0331     }
0332     
0333     void Clear() {
0334         // Delete the blocks.

0335         while( !_blockPtrs.Empty()) {
0336             Block* b  = _blockPtrs.Pop();
0337             delete b;
0338         }
0339         _root = 0;
0340         _currentAllocs = 0;
0341         _nAllocs = 0;
0342         _maxAllocs = 0;
0343         _nUntracked = 0;
0344     }
0345 
0346     virtual int ItemSize() const    {
0347         return ITEM_SIZE;
0348     }
0349     int CurrentAllocs() const       {
0350         return _currentAllocs;
0351     }
0352 
0353     virtual void* Alloc() {
0354         if ( !_root ) {
0355             // Need a new block.

0356             Block* block = new Block();
0357             _blockPtrs.Push( block );
0358 
0359             Item* blockItems = block->items;
0360             for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
0361                 blockItems[i].next = &(blockItems[i + 1]);
0362             }
0363             blockItems[ITEMS_PER_BLOCK - 1].next = 0;
0364             _root = blockItems;
0365         }
0366         Item* const result = _root;
0367         TIXMLASSERT( result != 0 );
0368         _root = _root->next;
0369 
0370         ++_currentAllocs;
0371         if ( _currentAllocs > _maxAllocs ) {
0372             _maxAllocs = _currentAllocs;
0373         }
0374         ++_nAllocs;
0375         ++_nUntracked;
0376         return result;
0377     }
0378     
0379     virtual void Free( void* mem ) {
0380         if ( !mem ) {
0381             return;
0382         }
0383         --_currentAllocs;
0384         Item* item = static_cast<Item*>( mem );
0385 #ifdef DEBUG
0386         memset( item, 0xfe, sizeof( *item ) );
0387 #endif
0388         item->next = _root;
0389         _root = item;
0390     }
0391     void Trace( const char* name ) {
0392         printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
0393                 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
0394                 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
0395     }
0396 
0397     void SetTracked() {
0398         --_nUntracked;
0399     }
0400 
0401     int Untracked() const {
0402         return _nUntracked;
0403     }
0404 
0405     // This number is perf sensitive. 4k seems like a good tradeoff on my machine.

0406     // The test file is large, 170k.

0407     // Release:     VS2010 gcc(no opt)

0408     //      1k:     4000

0409     //      2k:     4000

0410     //      4k:     3900    21000

0411     //      16k:    5200

0412     //      32k:    4300

0413     //      64k:    4000    21000

0414     // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK

0415     // in private part if ITEMS_PER_BLOCK is private

0416     enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
0417 
0418 private:
0419     MemPoolT( const MemPoolT& ); // not supported

0420     void operator=( const MemPoolT& ); // not supported

0421 
0422     union Item {
0423         Item*   next;
0424         char    itemData[ITEM_SIZE];
0425     };
0426     struct Block {
0427         Item items[ITEMS_PER_BLOCK];
0428     };
0429     DynArray< Block*, 10 > _blockPtrs;
0430     Item* _root;
0431 
0432     int _currentAllocs;
0433     int _nAllocs;
0434     int _maxAllocs;
0435     int _nUntracked;
0436 };
0437 
0438 
0439 
0440 /**

0441     Implements the interface to the "Visitor pattern" (see the Accept() method.)

0442     If you call the Accept() method, it requires being passed a XMLVisitor

0443     class to handle callbacks. For nodes that contain other nodes (Document, Element)

0444     you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs

0445     are simply called with Visit().

0446 

0447     If you return 'true' from a Visit method, recursive parsing will continue. If you return

0448     false, <b>no children of this node or its siblings</b> will be visited.

0449 

0450     All flavors of Visit methods have a default implementation that returns 'true' (continue

0451     visiting). You need to only override methods that are interesting to you.

0452 

0453     Generally Accept() is called on the XMLDocument, although all nodes support visiting.

0454 

0455     You should never change the document from a callback.

0456 

0457     @sa XMLNode::Accept()

0458 */
0459 class TINYXML2_LIB XMLVisitor
0460 {
0461 public:
0462     virtual ~XMLVisitor() {}
0463 
0464     /// Visit a document.

0465     virtual bool VisitEnter( const XMLDocument& /*doc*/ )           {
0466         return true;
0467     }
0468     /// Visit a document.

0469     virtual bool VisitExit( const XMLDocument& /*doc*/ )            {
0470         return true;
0471     }
0472 
0473     /// Visit an element.

0474     virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    {
0475         return true;
0476     }
0477     /// Visit an element.

0478     virtual bool VisitExit( const XMLElement& /*element*/ )         {
0479         return true;
0480     }
0481 
0482     /// Visit a declaration.

0483     virtual bool Visit( const XMLDeclaration& /*declaration*/ )     {
0484         return true;
0485     }
0486     /// Visit a text node.

0487     virtual bool Visit( const XMLText& /*text*/ )                   {
0488         return true;
0489     }
0490     /// Visit a comment node.

0491     virtual bool Visit( const XMLComment& /*comment*/ )             {
0492         return true;
0493     }
0494     /// Visit an unknown node.

0495     virtual bool Visit( const XMLUnknown& /*unknown*/ )             {
0496         return true;
0497     }
0498 };
0499 
0500 // WARNING: must match XMLDocument::_errorNames[]

0501 enum XMLError {
0502     XML_SUCCESS = 0,
0503     XML_NO_ATTRIBUTE,
0504     XML_WRONG_ATTRIBUTE_TYPE,
0505     XML_ERROR_FILE_NOT_FOUND,
0506     XML_ERROR_FILE_COULD_NOT_BE_OPENED,
0507     XML_ERROR_FILE_READ_ERROR,
0508     XML_ERROR_ELEMENT_MISMATCH,
0509     XML_ERROR_PARSING_ELEMENT,
0510     XML_ERROR_PARSING_ATTRIBUTE,
0511     XML_ERROR_IDENTIFYING_TAG,
0512     XML_ERROR_PARSING_TEXT,
0513     XML_ERROR_PARSING_CDATA,
0514     XML_ERROR_PARSING_COMMENT,
0515     XML_ERROR_PARSING_DECLARATION,
0516     XML_ERROR_PARSING_UNKNOWN,
0517     XML_ERROR_EMPTY_DOCUMENT,
0518     XML_ERROR_MISMATCHED_ELEMENT,
0519     XML_ERROR_PARSING,
0520     XML_CAN_NOT_CONVERT_TEXT,
0521     XML_NO_TEXT_NODE,
0522 
0523     XML_ERROR_COUNT
0524 };
0525 
0526 
0527 /*

0528     Utility functionality.

0529 */
0530 class XMLUtil
0531 {
0532 public:
0533     static const char* SkipWhiteSpace( const char* p )  {
0534         TIXMLASSERT( p );
0535         while( IsWhiteSpace(*p) ) {
0536             ++p;
0537         }
0538         TIXMLASSERT( p );
0539         return p;
0540     }
0541     static char* SkipWhiteSpace( char* p )              {
0542         return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
0543     }
0544 
0545     // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't

0546     // correct, but simple, and usually works.

0547     static bool IsWhiteSpace( char p )                  {
0548         return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
0549     }
0550     
0551     inline static bool IsNameStartChar( unsigned char ch ) {
0552         if ( ch >= 128 ) {
0553             // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()

0554             return true;
0555         }
0556         if ( isalpha( ch ) ) {
0557             return true;
0558         }
0559         return ch == ':' || ch == '_';
0560     }
0561     
0562     inline static bool IsNameChar( unsigned char ch ) {
0563         return IsNameStartChar( ch )
0564                || isdigit( ch )
0565                || ch == '.'
0566                || ch == '-';
0567     }
0568 
0569     inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
0570         if ( p == q ) {
0571             return true;
0572         }
0573         TIXMLASSERT( p );
0574         TIXMLASSERT( q );
0575         TIXMLASSERT( nChar >= 0 );
0576         return strncmp( p, q, nChar ) == 0;
0577     }
0578     
0579     inline static bool IsUTF8Continuation( char p ) {
0580         return ( p & 0x80 ) != 0;
0581     }
0582 
0583     static const char* ReadBOM( const char* p, bool* hasBOM );
0584     // p is the starting location,

0585     // the UTF-8 value of the entity will be placed in value, and length filled in.

0586     static const char* GetCharacterRef( const char* p, char* value, int* length );
0587     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
0588 
0589     // converts primitive types to strings

0590     static void ToStr( int v, char* buffer, int bufferSize );
0591     static void ToStr( unsigned v, char* buffer, int bufferSize );
0592     static void ToStr( bool v, char* buffer, int bufferSize );
0593     static void ToStr( float v, char* buffer, int bufferSize );
0594     static void ToStr( double v, char* buffer, int bufferSize );
0595     static void ToStr(int64_t v, char* buffer, int bufferSize);
0596 
0597     // converts strings to primitive types

0598     static bool ToInt( const char* str, int* value );
0599     static bool ToUnsigned( const char* str, unsigned* value );
0600     static bool ToBool( const char* str, bool* value );
0601     static bool ToFloat( const char* str, float* value );
0602     static bool ToDouble( const char* str, double* value );
0603     static bool ToInt64(const char* str, int64_t* value);
0604 };
0605 
0606 
0607 /** XMLNode is a base class for every object that is in the

0608     XML Document Object Model (DOM), except XMLAttributes.

0609     Nodes have siblings, a parent, and children which can

0610     be navigated. A node is always in a XMLDocument.

0611     The type of a XMLNode can be queried, and it can

0612     be cast to its more defined type.

0613 

0614     A XMLDocument allocates memory for all its Nodes.

0615     When the XMLDocument gets deleted, all its Nodes

0616     will also be deleted.

0617 

0618     @verbatim

0619     A Document can contain: Element (container or leaf)

0620                             Comment (leaf)

0621                             Unknown (leaf)

0622                             Declaration( leaf )

0623 

0624     An Element can contain: Element (container or leaf)

0625                             Text    (leaf)

0626                             Attributes (not on tree)

0627                             Comment (leaf)

0628                             Unknown (leaf)

0629 

0630     @endverbatim

0631 */
0632 class TINYXML2_LIB XMLNode
0633 {
0634     friend class XMLDocument;
0635     friend class XMLElement;
0636 public:
0637 
0638     /// Get the XMLDocument that owns this XMLNode.

0639     const XMLDocument* GetDocument() const  {
0640         TIXMLASSERT( _document );
0641         return _document;
0642     }
0643     /// Get the XMLDocument that owns this XMLNode.

0644     XMLDocument* GetDocument()              {
0645         TIXMLASSERT( _document );
0646         return _document;
0647     }
0648 
0649     /// Safely cast to an Element, or null.

0650     virtual XMLElement*     ToElement()     {
0651         return 0;
0652     }
0653     /// Safely cast to Text, or null.

0654     virtual XMLText*        ToText()        {
0655         return 0;
0656     }
0657     /// Safely cast to a Comment, or null.

0658     virtual XMLComment*     ToComment()     {
0659         return 0;
0660     }
0661     /// Safely cast to a Document, or null.

0662     virtual XMLDocument*    ToDocument()    {
0663         return 0;
0664     }
0665     /// Safely cast to a Declaration, or null.

0666     virtual XMLDeclaration* ToDeclaration() {
0667         return 0;
0668     }
0669     /// Safely cast to an Unknown, or null.

0670     virtual XMLUnknown*     ToUnknown()     {
0671         return 0;
0672     }
0673 
0674     virtual const XMLElement*       ToElement() const       {
0675         return 0;
0676     }
0677     virtual const XMLText*          ToText() const          {
0678         return 0;
0679     }
0680     virtual const XMLComment*       ToComment() const       {
0681         return 0;
0682     }
0683     virtual const XMLDocument*      ToDocument() const      {
0684         return 0;
0685     }
0686     virtual const XMLDeclaration*   ToDeclaration() const   {
0687         return 0;
0688     }
0689     virtual const XMLUnknown*       ToUnknown() const       {
0690         return 0;
0691     }
0692 
0693     /** The meaning of 'value' changes for the specific type.

0694         @verbatim

0695         Document:   empty (NULL is returned, not an empty string)

0696         Element:    name of the element

0697         Comment:    the comment text

0698         Unknown:    the tag contents

0699         Text:       the text string

0700         @endverbatim

0701     */
0702     const char* Value() const;
0703 
0704     /** Set the Value of an XML node.

0705         @sa Value()

0706     */
0707     void SetValue( const char* val, bool staticMem=false );
0708 
0709     /// Get the parent of this node on the DOM.

0710     const XMLNode*  Parent() const          {
0711         return _parent;
0712     }
0713 
0714     XMLNode* Parent()                       {
0715         return _parent;
0716     }
0717 
0718     /// Returns true if this node has no children.

0719     bool NoChildren() const                 {
0720         return !_firstChild;
0721     }
0722 
0723     /// Get the first child node, or null if none exists.

0724     const XMLNode*  FirstChild() const      {
0725         return _firstChild;
0726     }
0727 
0728     XMLNode*        FirstChild()            {
0729         return _firstChild;
0730     }
0731 
0732     /** Get the first child element, or optionally the first child

0733         element with the specified name.

0734     */
0735     const XMLElement* FirstChildElement( const char* name = 0 ) const;
0736 
0737     XMLElement* FirstChildElement( const char* name = 0 )   {
0738         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
0739     }
0740 
0741     /// Get the last child node, or null if none exists.

0742     const XMLNode*  LastChild() const                       {
0743         return _lastChild;
0744     }
0745 
0746     XMLNode*        LastChild()                             {
0747         return _lastChild;
0748     }
0749 
0750     /** Get the last child element or optionally the last child

0751         element with the specified name.

0752     */
0753     const XMLElement* LastChildElement( const char* name = 0 ) const;
0754 
0755     XMLElement* LastChildElement( const char* name = 0 )    {
0756         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
0757     }
0758 
0759     /// Get the previous (left) sibling node of this node.

0760     const XMLNode*  PreviousSibling() const                 {
0761         return _prev;
0762     }
0763 
0764     XMLNode*    PreviousSibling()                           {
0765         return _prev;
0766     }
0767 
0768     /// Get the previous (left) sibling element of this node, with an optionally supplied name.

0769     const XMLElement*   PreviousSiblingElement( const char* name = 0 ) const ;
0770 
0771     XMLElement* PreviousSiblingElement( const char* name = 0 ) {
0772         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
0773     }
0774 
0775     /// Get the next (right) sibling node of this node.

0776     const XMLNode*  NextSibling() const                     {
0777         return _next;
0778     }
0779 
0780     XMLNode*    NextSibling()                               {
0781         return _next;
0782     }
0783 
0784     /// Get the next (right) sibling element of this node, with an optionally supplied name.

0785     const XMLElement*   NextSiblingElement( const char* name = 0 ) const;
0786 
0787     XMLElement* NextSiblingElement( const char* name = 0 )  {
0788         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
0789     }
0790 
0791     /**

0792         Add a child node as the last (right) child.

0793         If the child node is already part of the document,

0794         it is moved from its old location to the new location.

0795         Returns the addThis argument or 0 if the node does not

0796         belong to the same document.

0797     */
0798     XMLNode* InsertEndChild( XMLNode* addThis );
0799 
0800     XMLNode* LinkEndChild( XMLNode* addThis )   {
0801         return InsertEndChild( addThis );
0802     }
0803     /**

0804         Add a child node as the first (left) child.

0805         If the child node is already part of the document,

0806         it is moved from its old location to the new location.

0807         Returns the addThis argument or 0 if the node does not

0808         belong to the same document.

0809     */
0810     XMLNode* InsertFirstChild( XMLNode* addThis );
0811     /**

0812         Add a node after the specified child node.

0813         If the child node is already part of the document,

0814         it is moved from its old location to the new location.

0815         Returns the addThis argument or 0 if the afterThis node

0816         is not a child of this node, or if the node does not

0817         belong to the same document.

0818     */
0819     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
0820 
0821     /**

0822         Delete all the children of this node.

0823     */
0824     void DeleteChildren();
0825 
0826     /**

0827         Delete a child of this node.

0828     */
0829     void DeleteChild( XMLNode* node );
0830 
0831     /**

0832         Make a copy of this node, but not its children.

0833         You may pass in a Document pointer that will be

0834         the owner of the new Node. If the 'document' is

0835         null, then the node returned will be allocated

0836         from the current Document. (this->GetDocument())

0837 

0838         Note: if called on a XMLDocument, this will return null.

0839     */
0840     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
0841 
0842     /**

0843         Test if 2 nodes are the same, but don't test children.

0844         The 2 nodes do not need to be in the same Document.

0845 

0846         Note: if called on a XMLDocument, this will return false.

0847     */
0848     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
0849 
0850     /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the

0851         XML tree will be conditionally visited and the host will be called back

0852         via the XMLVisitor interface.

0853 

0854         This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse

0855         the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this

0856         interface versus any other.)

0857 

0858         The interface has been based on ideas from:

0859 

0860         - http://www.saxproject.org/

0861         - http://c2.com/cgi/wiki?HierarchicalVisitorPattern

0862 

0863         Which are both good references for "visiting".

0864 

0865         An example of using Accept():

0866         @verbatim

0867         XMLPrinter printer;

0868         tinyxmlDoc.Accept( &printer );

0869         const char* xmlcstr = printer.CStr();

0870         @endverbatim

0871     */
0872     virtual bool Accept( XMLVisitor* visitor ) const = 0;
0873 
0874     /** 

0875         Set user data into the XMLNode. TinyXML-2 in 

0876         no way processes or interprets user data.

0877         It is initially 0.

0878     */
0879     void SetUserData(void* userData)    { _userData = userData; }
0880 
0881     /**

0882         Get user data set into the XMLNode. TinyXML-2 in

0883         no way processes or interprets user data.

0884         It is initially 0.

0885     */
0886     void* GetUserData() const           { return _userData; }
0887 
0888 protected:
0889     XMLNode( XMLDocument* );
0890     virtual ~XMLNode();
0891 
0892     virtual char* ParseDeep( char*, StrPair* );
0893 
0894     XMLDocument*    _document;
0895     XMLNode*        _parent;
0896     mutable StrPair _value;
0897 
0898     XMLNode*        _firstChild;
0899     XMLNode*        _lastChild;
0900 
0901     XMLNode*        _prev;
0902     XMLNode*        _next;
0903 
0904     void*           _userData;
0905 
0906 private:
0907     MemPool*        _memPool;
0908     void Unlink( XMLNode* child );
0909     static void DeleteNode( XMLNode* node );
0910     void InsertChildPreamble( XMLNode* insertThis ) const;
0911     const XMLElement* ToElementWithName( const char* name ) const;
0912 
0913     XMLNode( const XMLNode& );  // not supported

0914     XMLNode& operator=( const XMLNode& );   // not supported

0915 };
0916 
0917 
0918 /** XML text.

0919 

0920     Note that a text node can have child element nodes, for example:

0921     @verbatim

0922     <root>This is <b>bold</b></root>

0923     @endverbatim

0924 

0925     A text node can have 2 ways to output the next. "normal" output

0926     and CDATA. It will default to the mode it was parsed from the XML file and

0927     you generally want to leave it alone, but you can change the output mode with

0928     SetCData() and query it with CData().

0929 */
0930 class TINYXML2_LIB XMLText : public XMLNode
0931 {
0932     friend class XMLDocument;
0933 public:
0934     virtual bool Accept( XMLVisitor* visitor ) const;
0935 
0936     virtual XMLText* ToText()           {
0937         return this;
0938     }
0939     virtual const XMLText* ToText() const   {
0940         return this;
0941     }
0942 
0943     /// Declare whether this should be CDATA or standard text.

0944     void SetCData( bool isCData )           {
0945         _isCData = isCData;
0946     }
0947     /// Returns true if this is a CDATA text element.

0948     bool CData() const                      {
0949         return _isCData;
0950     }
0951 
0952     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
0953     virtual bool ShallowEqual( const XMLNode* compare ) const;
0954 
0955 protected:
0956     XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
0957     virtual ~XMLText()                                              {}
0958 
0959     char* ParseDeep( char*, StrPair* endTag );
0960 
0961 private:
0962     bool _isCData;
0963 
0964     XMLText( const XMLText& );  // not supported

0965     XMLText& operator=( const XMLText& );   // not supported

0966 };
0967 
0968 
0969 /** An XML Comment. */
0970 class TINYXML2_LIB XMLComment : public XMLNode
0971 {
0972     friend class XMLDocument;
0973 public:
0974     virtual XMLComment* ToComment()                 {
0975         return this;
0976     }
0977     virtual const XMLComment* ToComment() const     {
0978         return this;
0979     }
0980 
0981     virtual bool Accept( XMLVisitor* visitor ) const;
0982 
0983     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
0984     virtual bool ShallowEqual( const XMLNode* compare ) const;
0985 
0986 protected:
0987     XMLComment( XMLDocument* doc );
0988     virtual ~XMLComment();
0989 
0990     char* ParseDeep( char*, StrPair* endTag );
0991 
0992 private:
0993     XMLComment( const XMLComment& );    // not supported

0994     XMLComment& operator=( const XMLComment& ); // not supported

0995 };
0996 
0997 
0998 /** In correct XML the declaration is the first entry in the file.

0999     @verbatim

1000         <?xml version="1.0" standalone="yes"?>

1001     @endverbatim

1002 

1003     TinyXML-2 will happily read or write files without a declaration,

1004     however.

1005 

1006     The text of the declaration isn't interpreted. It is parsed

1007     and written as a string.

1008 */
1009 class TINYXML2_LIB XMLDeclaration : public XMLNode
1010 {
1011     friend class XMLDocument;
1012 public:
1013     virtual XMLDeclaration* ToDeclaration()                 {
1014         return this;
1015     }
1016     virtual const XMLDeclaration* ToDeclaration() const     {
1017         return this;
1018     }
1019 
1020     virtual bool Accept( XMLVisitor* visitor ) const;
1021 
1022     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1023     virtual bool ShallowEqual( const XMLNode* compare ) const;
1024 
1025 protected:
1026     XMLDeclaration( XMLDocument* doc );
1027     virtual ~XMLDeclaration();
1028 
1029     char* ParseDeep( char*, StrPair* endTag );
1030 
1031 private:
1032     XMLDeclaration( const XMLDeclaration& );    // not supported

1033     XMLDeclaration& operator=( const XMLDeclaration& ); // not supported

1034 };
1035 
1036 
1037 /** Any tag that TinyXML-2 doesn't recognize is saved as an

1038     unknown. It is a tag of text, but should not be modified.

1039     It will be written back to the XML, unchanged, when the file

1040     is saved.

1041 

1042     DTD tags get thrown into XMLUnknowns.

1043 */
1044 class TINYXML2_LIB XMLUnknown : public XMLNode
1045 {
1046     friend class XMLDocument;
1047 public:
1048     virtual XMLUnknown* ToUnknown()                 {
1049         return this;
1050     }
1051     virtual const XMLUnknown* ToUnknown() const     {
1052         return this;
1053     }
1054 
1055     virtual bool Accept( XMLVisitor* visitor ) const;
1056 
1057     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1058     virtual bool ShallowEqual( const XMLNode* compare ) const;
1059 
1060 protected:
1061     XMLUnknown( XMLDocument* doc );
1062     virtual ~XMLUnknown();
1063 
1064     char* ParseDeep( char*, StrPair* endTag );
1065 
1066 private:
1067     XMLUnknown( const XMLUnknown& );    // not supported

1068     XMLUnknown& operator=( const XMLUnknown& ); // not supported

1069 };
1070 
1071 
1072 
1073 /** An attribute is a name-value pair. Elements have an arbitrary

1074     number of attributes, each with a unique name.

1075 

1076     @note The attributes are not XMLNodes. You may only query the

1077     Next() attribute in a list.

1078 */
1079 class TINYXML2_LIB XMLAttribute
1080 {
1081     friend class XMLElement;
1082 public:
1083     /// The name of the attribute.

1084     const char* Name() const;
1085 
1086     /// The value of the attribute.

1087     const char* Value() const;
1088 
1089     /// The next attribute in the list.

1090     const XMLAttribute* Next() const {
1091         return _next;
1092     }
1093 
1094     /** IntValue interprets the attribute as an integer, and returns the value.

1095         If the value isn't an integer, 0 will be returned. There is no error checking;

1096         use QueryIntValue() if you need error checking.

1097     */
1098     int IntValue() const {
1099         int i = 0;
1100         QueryIntValue(&i);
1101         return i;
1102     }
1103 
1104     int64_t Int64Value() const {
1105         int64_t i = 0;
1106         QueryInt64Value(&i);
1107         return i;
1108     }
1109 
1110     /// Query as an unsigned integer. See IntValue()

1111     unsigned UnsignedValue() const          {
1112         unsigned i=0;
1113         QueryUnsignedValue( &i );
1114         return i;
1115     }
1116     /// Query as a boolean. See IntValue()

1117     bool     BoolValue() const              {
1118         bool b=false;
1119         QueryBoolValue( &b );
1120         return b;
1121     }
1122     /// Query as a double. See IntValue()

1123     double   DoubleValue() const            {
1124         double d=0;
1125         QueryDoubleValue( &d );
1126         return d;
1127     }
1128     /// Query as a float. See IntValue()

1129     float    FloatValue() const             {
1130         float f=0;
1131         QueryFloatValue( &f );
1132         return f;
1133     }
1134 
1135     /** QueryIntValue interprets the attribute as an integer, and returns the value

1136         in the provided parameter. The function will return XML_SUCCESS on success,

1137         and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.

1138     */
1139     XMLError QueryIntValue( int* value ) const;
1140     /// See QueryIntValue

1141     XMLError QueryUnsignedValue( unsigned int* value ) const;
1142     /// See QueryIntValue

1143     XMLError QueryInt64Value(int64_t* value) const;
1144     /// See QueryIntValue

1145     XMLError QueryBoolValue( bool* value ) const;
1146     /// See QueryIntValue

1147     XMLError QueryDoubleValue( double* value ) const;
1148     /// See QueryIntValue

1149     XMLError QueryFloatValue( float* value ) const;
1150 
1151     /// Set the attribute to a string value.

1152     void SetAttribute( const char* value );
1153     /// Set the attribute to value.

1154     void SetAttribute( int value );
1155     /// Set the attribute to value.

1156     void SetAttribute( unsigned value );
1157     /// Set the attribute to value.

1158     void SetAttribute(int64_t value);
1159     /// Set the attribute to value.

1160     void SetAttribute( bool value );
1161     /// Set the attribute to value.

1162     void SetAttribute( double value );
1163     /// Set the attribute to value.

1164     void SetAttribute( float value );
1165 
1166 private:
1167     enum { BUF_SIZE = 200 };
1168 
1169     XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
1170     virtual ~XMLAttribute() {}
1171 
1172     XMLAttribute( const XMLAttribute& );    // not supported

1173     void operator=( const XMLAttribute& );  // not supported

1174     void SetName( const char* name );
1175 
1176     char* ParseDeep( char* p, bool processEntities );
1177 
1178     mutable StrPair _name;
1179     mutable StrPair _value;
1180     XMLAttribute*   _next;
1181     MemPool*        _memPool;
1182 };
1183 
1184 
1185 /** The element is a container class. It has a value, the element name,

1186     and can contain other elements, text, comments, and unknowns.

1187     Elements also contain an arbitrary number of attributes.

1188 */
1189 class TINYXML2_LIB XMLElement : public XMLNode
1190 {
1191     friend class XMLDocument;
1192 public:
1193     /// Get the name of an element (which is the Value() of the node.)

1194     const char* Name() const        {
1195         return Value();
1196     }
1197     /// Set the name of the element.

1198     void SetName( const char* str, bool staticMem=false )   {
1199         SetValue( str, staticMem );
1200     }
1201 
1202     virtual XMLElement* ToElement()             {
1203         return this;
1204     }
1205     virtual const XMLElement* ToElement() const {
1206         return this;
1207     }
1208     virtual bool Accept( XMLVisitor* visitor ) const;
1209 
1210     /** Given an attribute name, Attribute() returns the value

1211         for the attribute of that name, or null if none

1212         exists. For example:

1213 

1214         @verbatim

1215         const char* value = ele->Attribute( "foo" );

1216         @endverbatim

1217 

1218         The 'value' parameter is normally null. However, if specified,

1219         the attribute will only be returned if the 'name' and 'value'

1220         match. This allow you to write code:

1221 

1222         @verbatim

1223         if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();

1224         @endverbatim

1225 

1226         rather than:

1227         @verbatim

1228         if ( ele->Attribute( "foo" ) ) {

1229             if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();

1230         }

1231         @endverbatim

1232     */
1233     const char* Attribute( const char* name, const char* value=0 ) const;
1234 
1235     /** Given an attribute name, IntAttribute() returns the value

1236         of the attribute interpreted as an integer. The default

1237         value will be returned if the attribute isn't present,

1238         or if there is an error. (For a method with error

1239         checking, see QueryIntAttribute()).

1240     */
1241     int IntAttribute(const char* name, int defaultValue = 0) const;
1242     /// See IntAttribute()

1243     unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1244     /// See IntAttribute()

1245     int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1246     /// See IntAttribute()

1247     bool BoolAttribute(const char* name, bool defaultValue = false) const;
1248     /// See IntAttribute()

1249     double DoubleAttribute(const char* name, double defaultValue = 0) const;
1250     /// See IntAttribute()

1251     float FloatAttribute(const char* name, float defaultValue = 0) const;
1252 
1253     /** Given an attribute name, QueryIntAttribute() returns

1254         XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion

1255         can't be performed, or XML_NO_ATTRIBUTE if the attribute

1256         doesn't exist. If successful, the result of the conversion

1257         will be written to 'value'. If not successful, nothing will

1258         be written to 'value'. This allows you to provide default

1259         value:

1260 

1261         @verbatim

1262         int value = 10;

1263         QueryIntAttribute( "foo", &value );     // if "foo" isn't found, value will still be 10

1264         @endverbatim

1265     */
1266     XMLError QueryIntAttribute( const char* name, int* value ) const                {
1267         const XMLAttribute* a = FindAttribute( name );
1268         if ( !a ) {
1269             return XML_NO_ATTRIBUTE;
1270         }
1271         return a->QueryIntValue( value );
1272     }
1273 
1274     /// See QueryIntAttribute()

1275     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const  {
1276         const XMLAttribute* a = FindAttribute( name );
1277         if ( !a ) {
1278             return XML_NO_ATTRIBUTE;
1279         }
1280         return a->QueryUnsignedValue( value );
1281     }
1282 
1283     /// See QueryIntAttribute()

1284     XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1285         const XMLAttribute* a = FindAttribute(name);
1286         if (!a) {
1287             return XML_NO_ATTRIBUTE;
1288         }
1289         return a->QueryInt64Value(value);
1290     }
1291 
1292     /// See QueryIntAttribute()

1293     XMLError QueryBoolAttribute( const char* name, bool* value ) const              {
1294         const XMLAttribute* a = FindAttribute( name );
1295         if ( !a ) {
1296             return XML_NO_ATTRIBUTE;
1297         }
1298         return a->QueryBoolValue( value );
1299     }
1300     /// See QueryIntAttribute()

1301     XMLError QueryDoubleAttribute( const char* name, double* value ) const          {
1302         const XMLAttribute* a = FindAttribute( name );
1303         if ( !a ) {
1304             return XML_NO_ATTRIBUTE;
1305         }
1306         return a->QueryDoubleValue( value );
1307     }
1308     /// See QueryIntAttribute()

1309     XMLError QueryFloatAttribute( const char* name, float* value ) const            {
1310         const XMLAttribute* a = FindAttribute( name );
1311         if ( !a ) {
1312             return XML_NO_ATTRIBUTE;
1313         }
1314         return a->QueryFloatValue( value );
1315     }
1316 
1317     
1318     /** Given an attribute name, QueryAttribute() returns

1319         XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion

1320         can't be performed, or XML_NO_ATTRIBUTE if the attribute

1321         doesn't exist. It is overloaded for the primitive types,

1322         and is a generally more convenient replacement of

1323         QueryIntAttribute() and related functions.

1324         

1325         If successful, the result of the conversion

1326         will be written to 'value'. If not successful, nothing will

1327         be written to 'value'. This allows you to provide default

1328         value:

1329 

1330         @verbatim

1331         int value = 10;

1332         QueryAttribute( "foo", &value );        // if "foo" isn't found, value will still be 10

1333         @endverbatim

1334     */
1335     int QueryAttribute( const char* name, int* value ) const {
1336         return QueryIntAttribute( name, value );
1337     }
1338 
1339     int QueryAttribute( const char* name, unsigned int* value ) const {
1340         return QueryUnsignedAttribute( name, value );
1341     }
1342 
1343     int QueryAttribute(const char* name, int64_t* value) const {
1344         return QueryInt64Attribute(name, value);
1345     }
1346 
1347     int QueryAttribute( const char* name, bool* value ) const {
1348         return QueryBoolAttribute( name, value );
1349     }
1350 
1351     int QueryAttribute( const char* name, double* value ) const {
1352         return QueryDoubleAttribute( name, value );
1353     }
1354 
1355     int QueryAttribute( const char* name, float* value ) const {
1356         return QueryFloatAttribute( name, value );
1357     }
1358 
1359     /// Sets the named attribute to value.

1360     void SetAttribute( const char* name, const char* value )    {
1361         XMLAttribute* a = FindOrCreateAttribute( name );
1362         a->SetAttribute( value );
1363     }
1364     /// Sets the named attribute to value.

1365     void SetAttribute( const char* name, int value )            {
1366         XMLAttribute* a = FindOrCreateAttribute( name );
1367         a->SetAttribute( value );
1368     }
1369     /// Sets the named attribute to value.

1370     void SetAttribute( const char* name, unsigned value )       {
1371         XMLAttribute* a = FindOrCreateAttribute( name );
1372         a->SetAttribute( value );
1373     }
1374 
1375     /// Sets the named attribute to value.

1376     void SetAttribute(const char* name, int64_t value) {
1377         XMLAttribute* a = FindOrCreateAttribute(name);
1378         a->SetAttribute(value);
1379     }
1380 
1381     /// Sets the named attribute to value.

1382     void SetAttribute( const char* name, bool value )           {
1383         XMLAttribute* a = FindOrCreateAttribute( name );
1384         a->SetAttribute( value );
1385     }
1386     /// Sets the named attribute to value.

1387     void SetAttribute( const char* name, double value )     {
1388         XMLAttribute* a = FindOrCreateAttribute( name );
1389         a->SetAttribute( value );
1390     }
1391     /// Sets the named attribute to value.

1392     void SetAttribute( const char* name, float value )      {
1393         XMLAttribute* a = FindOrCreateAttribute( name );
1394         a->SetAttribute( value );
1395     }
1396 
1397     /**

1398         Delete an attribute.

1399     */
1400     void DeleteAttribute( const char* name );
1401 
1402     /// Return the first attribute in the list.

1403     const XMLAttribute* FirstAttribute() const {
1404         return _rootAttribute;
1405     }
1406     /// Query a specific attribute in the list.

1407     const XMLAttribute* FindAttribute( const char* name ) const;
1408 
1409     /** Convenience function for easy access to the text inside an element. Although easy

1410         and concise, GetText() is limited compared to getting the XMLText child

1411         and accessing it directly.

1412 

1413         If the first child of 'this' is a XMLText, the GetText()

1414         returns the character string of the Text node, else null is returned.

1415 

1416         This is a convenient method for getting the text of simple contained text:

1417         @verbatim

1418         <foo>This is text</foo>

1419             const char* str = fooElement->GetText();

1420         @endverbatim

1421 

1422         'str' will be a pointer to "This is text".

1423 

1424         Note that this function can be misleading. If the element foo was created from

1425         this XML:

1426         @verbatim

1427             <foo><b>This is text</b></foo>

1428         @endverbatim

1429 

1430         then the value of str would be null. The first child node isn't a text node, it is

1431         another element. From this XML:

1432         @verbatim

1433             <foo>This is <b>text</b></foo>

1434         @endverbatim

1435         GetText() will return "This is ".

1436     */
1437     const char* GetText() const;
1438 
1439     /** Convenience function for easy access to the text inside an element. Although easy

1440         and concise, SetText() is limited compared to creating an XMLText child

1441         and mutating it directly.

1442 

1443         If the first child of 'this' is a XMLText, SetText() sets its value to

1444         the given string, otherwise it will create a first child that is an XMLText.

1445 

1446         This is a convenient method for setting the text of simple contained text:

1447         @verbatim

1448         <foo>This is text</foo>

1449             fooElement->SetText( "Hullaballoo!" );

1450         <foo>Hullaballoo!</foo>

1451         @endverbatim

1452 

1453         Note that this function can be misleading. If the element foo was created from

1454         this XML:

1455         @verbatim

1456             <foo><b>This is text</b></foo>

1457         @endverbatim

1458 

1459         then it will not change "This is text", but rather prefix it with a text element:

1460         @verbatim

1461             <foo>Hullaballoo!<b>This is text</b></foo>

1462         @endverbatim

1463         

1464         For this XML:

1465         @verbatim

1466             <foo />

1467         @endverbatim

1468         SetText() will generate

1469         @verbatim

1470             <foo>Hullaballoo!</foo>

1471         @endverbatim

1472     */
1473     void SetText( const char* inText );
1474     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1475     void SetText( int value );
1476     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1477     void SetText( unsigned value );  
1478     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1479     void SetText(int64_t value);
1480     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1481     void SetText( bool value );  
1482     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1483     void SetText( double value );  
1484     /// Convenience method for setting text inside an element. See SetText() for important limitations.

1485     void SetText( float value );  
1486 
1487     /**

1488         Convenience method to query the value of a child text node. This is probably best

1489         shown by example. Given you have a document is this form:

1490         @verbatim

1491             <point>

1492                 <x>1</x>

1493                 <y>1.4</y>

1494             </point>

1495         @endverbatim

1496 

1497         The QueryIntText() and similar functions provide a safe and easier way to get to the

1498         "value" of x and y.

1499 

1500         @verbatim

1501             int x = 0;

1502             float y = 0;    // types of x and y are contrived for example

1503             const XMLElement* xElement = pointElement->FirstChildElement( "x" );

1504             const XMLElement* yElement = pointElement->FirstChildElement( "y" );

1505             xElement->QueryIntText( &x );

1506             yElement->QueryFloatText( &y );

1507         @endverbatim

1508 

1509         @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted

1510                  to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.

1511 

1512     */
1513     XMLError QueryIntText( int* ival ) const;
1514     /// See QueryIntText()

1515     XMLError QueryUnsignedText( unsigned* uval ) const;
1516     /// See QueryIntText()

1517     XMLError QueryInt64Text(int64_t* uval) const;
1518     /// See QueryIntText()

1519     XMLError QueryBoolText( bool* bval ) const;
1520     /// See QueryIntText()

1521     XMLError QueryDoubleText( double* dval ) const;
1522     /// See QueryIntText()

1523     XMLError QueryFloatText( float* fval ) const;
1524 
1525     int IntText(int defaultValue = 0) const;
1526 
1527     /// See QueryIntText()

1528     unsigned UnsignedText(unsigned defaultValue = 0) const;
1529     /// See QueryIntText()

1530     int64_t Int64Text(int64_t defaultValue = 0) const;
1531     /// See QueryIntText()

1532     bool BoolText(bool defaultValue = false) const;
1533     /// See QueryIntText()

1534     double DoubleText(double defaultValue = 0) const;
1535     /// See QueryIntText()

1536     float FloatText(float defaultValue = 0) const;
1537 
1538     // internal:

1539     enum {
1540         OPEN,       // <foo>

1541         CLOSED,     // <foo/>

1542         CLOSING     // </foo>

1543     };
1544     int ClosingType() const {
1545         return _closingType;
1546     }
1547     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1548     virtual bool ShallowEqual( const XMLNode* compare ) const;
1549 
1550 protected:
1551     char* ParseDeep( char* p, StrPair* endTag );
1552 
1553 private:
1554     XMLElement( XMLDocument* doc );
1555     virtual ~XMLElement();
1556     XMLElement( const XMLElement& );    // not supported

1557     void operator=( const XMLElement& );    // not supported

1558 
1559     XMLAttribute* FindAttribute( const char* name ) {
1560         return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
1561     }
1562     XMLAttribute* FindOrCreateAttribute( const char* name );
1563     //void LinkAttribute( XMLAttribute* attrib );

1564     char* ParseAttributes( char* p );
1565     static void DeleteAttribute( XMLAttribute* attribute );
1566     XMLAttribute* CreateAttribute();
1567 
1568     enum { BUF_SIZE = 200 };
1569     int _closingType;
1570     // The attribute list is ordered; there is no 'lastAttribute'

1571     // because the list needs to be scanned for dupes before adding

1572     // a new attribute.

1573     XMLAttribute* _rootAttribute;
1574 };
1575 
1576 
1577 enum Whitespace {
1578     PRESERVE_WHITESPACE,
1579     COLLAPSE_WHITESPACE
1580 };
1581 
1582 
1583 /** A Document binds together all the functionality.

1584     It can be saved, loaded, and printed to the screen.

1585     All Nodes are connected and allocated to a Document.

1586     If the Document is deleted, all its Nodes are also deleted.

1587 */
1588 class TINYXML2_LIB XMLDocument : public XMLNode
1589 {
1590     friend class XMLElement;
1591 public:
1592     /// constructor

1593     XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
1594     ~XMLDocument();
1595 
1596     virtual XMLDocument* ToDocument()               {
1597         TIXMLASSERT( this == _document );
1598         return this;
1599     }
1600     virtual const XMLDocument* ToDocument() const   {
1601         TIXMLASSERT( this == _document );
1602         return this;
1603     }
1604 
1605     /**

1606         Parse an XML file from a character string.

1607         Returns XML_SUCCESS (0) on success, or

1608         an errorID.

1609 

1610         You may optionally pass in the 'nBytes', which is

1611         the number of bytes which will be parsed. If not

1612         specified, TinyXML-2 will assume 'xml' points to a

1613         null terminated string.

1614     */
1615     XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
1616 
1617     /**

1618         Load an XML file from disk.

1619         Returns XML_SUCCESS (0) on success, or

1620         an errorID.

1621     */
1622     XMLError LoadFile( const char* filename );
1623 
1624     /**

1625         Load an XML file from disk. You are responsible

1626         for providing and closing the FILE*. 

1627      

1628         NOTE: The file should be opened as binary ("rb")

1629         not text in order for TinyXML-2 to correctly

1630         do newline normalization.

1631 

1632         Returns XML_SUCCESS (0) on success, or

1633         an errorID.

1634     */
1635     XMLError LoadFile( FILE* );
1636 
1637     /**

1638         Save the XML file to disk.

1639         Returns XML_SUCCESS (0) on success, or

1640         an errorID.

1641     */
1642     XMLError SaveFile( const char* filename, bool compact = false );
1643 
1644     /**

1645         Save the XML file to disk. You are responsible

1646         for providing and closing the FILE*.

1647 

1648         Returns XML_SUCCESS (0) on success, or

1649         an errorID.

1650     */
1651     XMLError SaveFile( FILE* fp, bool compact = false );
1652 
1653     bool ProcessEntities() const        {
1654         return _processEntities;
1655     }
1656     Whitespace WhitespaceMode() const   {
1657         return _whitespace;
1658     }
1659 
1660     /**

1661         Returns true if this document has a leading Byte Order Mark of UTF8.

1662     */
1663     bool HasBOM() const {
1664         return _writeBOM;
1665     }
1666     /** Sets whether to write the BOM when writing the file.

1667     */
1668     void SetBOM( bool useBOM ) {
1669         _writeBOM = useBOM;
1670     }
1671 
1672     /** Return the root element of DOM. Equivalent to FirstChildElement().

1673         To get the first node, use FirstChild().

1674     */
1675     XMLElement* RootElement()               {
1676         return FirstChildElement();
1677     }
1678     const XMLElement* RootElement() const   {
1679         return FirstChildElement();
1680     }
1681 
1682     /** Print the Document. If the Printer is not provided, it will

1683         print to stdout. If you provide Printer, this can print to a file:

1684         @verbatim

1685         XMLPrinter printer( fp );

1686         doc.Print( &printer );

1687         @endverbatim

1688 

1689         Or you can use a printer to print to memory:

1690         @verbatim

1691         XMLPrinter printer;

1692         doc.Print( &printer );

1693         // printer.CStr() has a const char* to the XML

1694         @endverbatim

1695     */
1696     void Print( XMLPrinter* streamer=0 ) const;
1697     virtual bool Accept( XMLVisitor* visitor ) const;
1698 
1699     /**

1700         Create a new Element associated with

1701         this Document. The memory for the Element

1702         is managed by the Document.

1703     */
1704     XMLElement* NewElement( const char* name );
1705     /**

1706         Create a new Comment associated with

1707         this Document. The memory for the Comment

1708         is managed by the Document.

1709     */
1710     XMLComment* NewComment( const char* comment );
1711     /**

1712         Create a new Text associated with

1713         this Document. The memory for the Text

1714         is managed by the Document.

1715     */
1716     XMLText* NewText( const char* text );
1717     /**

1718         Create a new Declaration associated with

1719         this Document. The memory for the object

1720         is managed by the Document.

1721 

1722         If the 'text' param is null, the standard

1723         declaration is used.:

1724         @verbatim

1725             <?xml version="1.0" encoding="UTF-8"?>

1726         @endverbatim

1727     */
1728     XMLDeclaration* NewDeclaration( const char* text=0 );
1729     /**

1730         Create a new Unknown associated with

1731         this Document. The memory for the object

1732         is managed by the Document.

1733     */
1734     XMLUnknown* NewUnknown( const char* text );
1735 
1736     /**

1737         Delete a node associated with this document.

1738         It will be unlinked from the DOM.

1739     */
1740     void DeleteNode( XMLNode* node );
1741 
1742     void SetError( XMLError error, const char* str1, const char* str2 );
1743 
1744     void ClearError() {
1745         SetError(XML_SUCCESS, 0, 0);
1746     }
1747 
1748     /// Return true if there was an error parsing the document.

1749     bool Error() const {
1750         return _errorID != XML_SUCCESS;
1751     }
1752     /// Return the errorID.

1753     XMLError  ErrorID() const {
1754         return _errorID;
1755     }
1756     const char* ErrorName() const;
1757 
1758     /// Return a possibly helpful diagnostic location or string.

1759     const char* GetErrorStr1() const {
1760         return _errorStr1.GetStr();
1761     }
1762     /// Return a possibly helpful secondary diagnostic location or string.

1763     const char* GetErrorStr2() const {
1764         return _errorStr2.GetStr();
1765     }
1766     /// If there is an error, print it to stdout.

1767     void PrintError() const;
1768     
1769     /// Clear the document, resetting it to the initial state.

1770     void Clear();
1771 
1772     // internal

1773     char* Identify( char* p, XMLNode** node );
1774 
1775     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    {
1776         return 0;
1777     }
1778     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const   {
1779         return false;
1780     }
1781 
1782 private:
1783     XMLDocument( const XMLDocument& );  // not supported

1784     void operator=( const XMLDocument& );   // not supported

1785 
1786     bool        _writeBOM;
1787     bool        _processEntities;
1788     XMLError    _errorID;
1789     Whitespace  _whitespace;
1790     mutable StrPair     _errorStr1;
1791     mutable StrPair     _errorStr2;
1792     char*       _charBuffer;
1793 
1794     MemPoolT< sizeof(XMLElement) >   _elementPool;
1795     MemPoolT< sizeof(XMLAttribute) > _attributePool;
1796     MemPoolT< sizeof(XMLText) >      _textPool;
1797     MemPoolT< sizeof(XMLComment) >   _commentPool;
1798 
1799     static const char* _errorNames[XML_ERROR_COUNT];
1800 
1801     void Parse();
1802 };
1803 
1804 
1805 /**

1806     A XMLHandle is a class that wraps a node pointer with null checks; this is

1807     an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2

1808     DOM structure. It is a separate utility class.

1809 

1810     Take an example:

1811     @verbatim

1812     <Document>

1813         <Element attributeA = "valueA">

1814             <Child attributeB = "value1" />

1815             <Child attributeB = "value2" />

1816         </Element>

1817     </Document>

1818     @endverbatim

1819 

1820     Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very

1821     easy to write a *lot* of code that looks like:

1822 

1823     @verbatim

1824     XMLElement* root = document.FirstChildElement( "Document" );

1825     if ( root )

1826     {

1827         XMLElement* element = root->FirstChildElement( "Element" );

1828         if ( element )

1829         {

1830             XMLElement* child = element->FirstChildElement( "Child" );

1831             if ( child )

1832             {

1833                 XMLElement* child2 = child->NextSiblingElement( "Child" );

1834                 if ( child2 )

1835                 {

1836                     // Finally do something useful.

1837     @endverbatim

1838 

1839     And that doesn't even cover "else" cases. XMLHandle addresses the verbosity

1840     of such code. A XMLHandle checks for null pointers so it is perfectly safe

1841     and correct to use:

1842 

1843     @verbatim

1844     XMLHandle docHandle( &document );

1845     XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();

1846     if ( child2 )

1847     {

1848         // do something useful

1849     @endverbatim

1850 

1851     Which is MUCH more concise and useful.

1852 

1853     It is also safe to copy handles - internally they are nothing more than node pointers.

1854     @verbatim

1855     XMLHandle handleCopy = handle;

1856     @endverbatim

1857 

1858     See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.

1859 */
1860 class TINYXML2_LIB XMLHandle
1861 {
1862 public:
1863     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.

1864     XMLHandle( XMLNode* node )                                              {
1865         _node = node;
1866     }
1867     /// Create a handle from a node.

1868     XMLHandle( XMLNode& node )                                              {
1869         _node = &node;
1870     }
1871     /// Copy constructor

1872     XMLHandle( const XMLHandle& ref )                                       {
1873         _node = ref._node;
1874     }
1875     /// Assignment

1876     XMLHandle& operator=( const XMLHandle& ref )                            {
1877         _node = ref._node;
1878         return *this;
1879     }
1880 
1881     /// Get the first child of this handle.

1882     XMLHandle FirstChild()                                                  {
1883         return XMLHandle( _node ? _node->FirstChild() : 0 );
1884     }
1885     /// Get the first child element of this handle.

1886     XMLHandle FirstChildElement( const char* name = 0 )                     {
1887         return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
1888     }
1889     /// Get the last child of this handle.

1890     XMLHandle LastChild()                                                   {
1891         return XMLHandle( _node ? _node->LastChild() : 0 );
1892     }
1893     /// Get the last child element of this handle.

1894     XMLHandle LastChildElement( const char* name = 0 )                      {
1895         return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
1896     }
1897     /// Get the previous sibling of this handle.

1898     XMLHandle PreviousSibling()                                             {
1899         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
1900     }
1901     /// Get the previous sibling element of this handle.

1902     XMLHandle PreviousSiblingElement( const char* name = 0 )                {
1903         return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
1904     }
1905     /// Get the next sibling of this handle.

1906     XMLHandle NextSibling()                                                 {
1907         return XMLHandle( _node ? _node->NextSibling() : 0 );
1908     }
1909     /// Get the next sibling element of this handle.

1910     XMLHandle NextSiblingElement( const char* name = 0 )                    {
1911         return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
1912     }
1913 
1914     /// Safe cast to XMLNode. This can return null.

1915     XMLNode* ToNode()                           {
1916         return _node;
1917     }
1918     /// Safe cast to XMLElement. This can return null.

1919     XMLElement* ToElement()                     {
1920         return ( _node ? _node->ToElement() : 0 );
1921     }
1922     /// Safe cast to XMLText. This can return null.

1923     XMLText* ToText()                           {
1924         return ( _node ? _node->ToText() : 0 );
1925     }
1926     /// Safe cast to XMLUnknown. This can return null.

1927     XMLUnknown* ToUnknown()                     {
1928         return ( _node ? _node->ToUnknown() : 0 );
1929     }
1930     /// Safe cast to XMLDeclaration. This can return null.

1931     XMLDeclaration* ToDeclaration()             {
1932         return ( _node ? _node->ToDeclaration() : 0 );
1933     }
1934 
1935 private:
1936     XMLNode* _node;
1937 };
1938 
1939 
1940 /**

1941     A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the

1942     same in all regards, except for the 'const' qualifiers. See XMLHandle for API.

1943 */
1944 class TINYXML2_LIB XMLConstHandle
1945 {
1946 public:
1947     XMLConstHandle( const XMLNode* node )                                           {
1948         _node = node;
1949     }
1950     XMLConstHandle( const XMLNode& node )                                           {
1951         _node = &node;
1952     }
1953     XMLConstHandle( const XMLConstHandle& ref )                                     {
1954         _node = ref._node;
1955     }
1956 
1957     XMLConstHandle& operator=( const XMLConstHandle& ref )                          {
1958         _node = ref._node;
1959         return *this;
1960     }
1961 
1962     const XMLConstHandle FirstChild() const                                         {
1963         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
1964     }
1965     const XMLConstHandle FirstChildElement( const char* name = 0 ) const                {
1966         return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
1967     }
1968     const XMLConstHandle LastChild()    const                                       {
1969         return XMLConstHandle( _node ? _node->LastChild() : 0 );
1970     }
1971     const XMLConstHandle LastChildElement( const char* name = 0 ) const             {
1972         return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
1973     }
1974     const XMLConstHandle PreviousSibling() const                                    {
1975         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
1976     }
1977     const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const       {
1978         return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
1979     }
1980     const XMLConstHandle NextSibling() const                                        {
1981         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
1982     }
1983     const XMLConstHandle NextSiblingElement( const char* name = 0 ) const           {
1984         return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
1985     }
1986 
1987 
1988     const XMLNode* ToNode() const               {
1989         return _node;
1990     }
1991     const XMLElement* ToElement() const         {
1992         return ( _node ? _node->ToElement() : 0 );
1993     }
1994     const XMLText* ToText() const               {
1995         return ( _node ? _node->ToText() : 0 );
1996     }
1997     const XMLUnknown* ToUnknown() const         {
1998         return ( _node ? _node->ToUnknown() : 0 );
1999     }
2000     const XMLDeclaration* ToDeclaration() const {
2001         return ( _node ? _node->ToDeclaration() : 0 );
2002     }
2003 
2004 private:
2005     const XMLNode* _node;
2006 };
2007 
2008 
2009 /**

2010     Printing functionality. The XMLPrinter gives you more

2011     options than the XMLDocument::Print() method.

2012 

2013     It can:

2014     -# Print to memory.

2015     -# Print to a file you provide.

2016     -# Print XML without a XMLDocument.

2017 

2018     Print to Memory

2019 

2020     @verbatim

2021     XMLPrinter printer;

2022     doc.Print( &printer );

2023     SomeFunction( printer.CStr() );

2024     @endverbatim

2025 

2026     Print to a File

2027 

2028     You provide the file pointer.

2029     @verbatim

2030     XMLPrinter printer( fp );

2031     doc.Print( &printer );

2032     @endverbatim

2033 

2034     Print without a XMLDocument

2035 

2036     When loading, an XML parser is very useful. However, sometimes

2037     when saving, it just gets in the way. The code is often set up

2038     for streaming, and constructing the DOM is just overhead.

2039 

2040     The Printer supports the streaming case. The following code

2041     prints out a trivially simple XML file without ever creating

2042     an XML document.

2043 

2044     @verbatim

2045     XMLPrinter printer( fp );

2046     printer.OpenElement( "foo" );

2047     printer.PushAttribute( "foo", "bar" );

2048     printer.CloseElement();

2049     @endverbatim

2050 */
2051 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2052 {
2053 public:
2054     /** Construct the printer. If the FILE* is specified,

2055         this will print to the FILE. Else it will print

2056         to memory, and the result is available in CStr().

2057         If 'compact' is set to true, then output is created

2058         with only required whitespace and newlines.

2059     */
2060     XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2061     virtual ~XMLPrinter()   {}
2062 
2063     /** If streaming, write the BOM and declaration. */
2064     void PushHeader( bool writeBOM, bool writeDeclaration );
2065     /** If streaming, start writing an element.

2066         The element must be closed with CloseElement()

2067     */
2068     void OpenElement( const char* name, bool compactMode=false );
2069     /// If streaming, add an attribute to an open element.

2070     void PushAttribute( const char* name, const char* value );
2071     void PushAttribute( const char* name, int value );
2072     void PushAttribute( const char* name, unsigned value );
2073     void PushAttribute(const char* name, int64_t value);
2074     void PushAttribute( const char* name, bool value );
2075     void PushAttribute( const char* name, double value );
2076     /// If streaming, close the Element.

2077     virtual void CloseElement( bool compactMode=false );
2078 
2079     /// Add a text node.

2080     void PushText( const char* text, bool cdata=false );
2081     /// Add a text node from an integer.

2082     void PushText( int value );
2083     /// Add a text node from an unsigned.

2084     void PushText( unsigned value );
2085     /// Add a text node from an unsigned.

2086     void PushText(int64_t value);
2087     /// Add a text node from a bool.

2088     void PushText( bool value );
2089     /// Add a text node from a float.

2090     void PushText( float value );
2091     /// Add a text node from a double.

2092     void PushText( double value );
2093 
2094     /// Add a comment

2095     void PushComment( const char* comment );
2096 
2097     void PushDeclaration( const char* value );
2098     void PushUnknown( const char* value );
2099 
2100     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
2101     virtual bool VisitExit( const XMLDocument& /*doc*/ )            {
2102         return true;
2103     }
2104 
2105     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
2106     virtual bool VisitExit( const XMLElement& element );
2107 
2108     virtual bool Visit( const XMLText& text );
2109     virtual bool Visit( const XMLComment& comment );
2110     virtual bool Visit( const XMLDeclaration& declaration );
2111     virtual bool Visit( const XMLUnknown& unknown );
2112 
2113     /**

2114         If in print to memory mode, return a pointer to

2115         the XML file in memory.

2116     */
2117     const char* CStr() const {
2118         return _buffer.Mem();
2119     }
2120     /**

2121         If in print to memory mode, return the size

2122         of the XML file in memory. (Note the size returned

2123         includes the terminating null.)

2124     */
2125     int CStrSize() const {
2126         return _buffer.Size();
2127     }
2128     /**

2129         If in print to memory mode, reset the buffer to the

2130         beginning.

2131     */
2132     void ClearBuffer() {
2133         _buffer.Clear();
2134         _buffer.Push(0);
2135     }
2136 
2137 protected:
2138     virtual bool CompactMode( const XMLElement& )   { return _compactMode; }
2139 
2140     /** Prints out the space before an element. You may override to change

2141         the space and tabs used. A PrintSpace() override should call Print().

2142     */
2143     virtual void PrintSpace( int depth );
2144     void Print( const char* format, ... );
2145 
2146     void SealElementIfJustOpened();
2147     bool _elementJustOpened;
2148     DynArray< const char*, 10 > _stack;
2149 
2150 private:
2151     void PrintString( const char*, bool restrictedEntitySet );  // prints out, after detecting entities.

2152 
2153     bool _firstElement;
2154     FILE* _fp;
2155     int _depth;
2156     int _textDepth;
2157     bool _processEntities;
2158     bool _compactMode;
2159 
2160     enum {
2161         ENTITY_RANGE = 64,
2162         BUF_SIZE = 200
2163     };
2164     bool _entityFlag[ENTITY_RANGE];
2165     bool _restrictedEntityFlag[ENTITY_RANGE];
2166 
2167     DynArray< char, 20 > _buffer;
2168 };
2169 
2170 
2171 }   // tinyxml2

2172 
2173 #if defined(_MSC_VER)
2174 #   pragma warning(pop)
2175 #endif
2176 
2177 #endif // TINYXML2_INCLUDED