tinyxml2

FORK: TinyXML2 is a simple, small, efficient, C++ XML parser that can be easily integrated into other programs.
git clone https://git.neptards.moe/neptards/tinyxml2.git
Log | Files | Refs

tinyxml2.h (73173B)


      1 /*
      2 Original code by Lee Thomason (www.grinninglizard.com)
      3 
      4 This software is provided 'as-is', without any express or implied
      5 warranty. In no event will the authors be held liable for any
      6 damages arising from the use of this software.
      7 
      8 Permission is granted to anyone to use this software for any
      9 purpose, including commercial applications, and to alter it and
     10 redistribute it freely, subject to the following restrictions:
     11 
     12 1. The origin of this software must not be misrepresented; you must
     13 not claim that you wrote the original software. If you use this
     14 software in a product, an acknowledgment in the product documentation
     15 would be appreciated but is not required.
     16 
     17 2. Altered source versions must be plainly marked as such, and
     18 must not be misrepresented as being the original software.
     19 
     20 3. This notice may not be removed or altered from any source
     21 distribution.
     22 */
     23 
     24 #ifndef TINYXML2_INCLUDED
     25 #define TINYXML2_INCLUDED
     26 
     27 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
     28 #   include <ctype.h>
     29 #   include <limits.h>
     30 #   include <stdio.h>
     31 #   include <stdlib.h>
     32 #   include <string.h>
     33 #	if defined(__PS3__)
     34 #		include <stddef.h>
     35 #	endif
     36 #else
     37 #   include <cctype>
     38 #   include <climits>
     39 #   include <cstdio>
     40 #   include <cstdlib>
     41 #   include <cstring>
     42 #endif
     43 #include <stdint.h>
     44 
     45 /*
     46    TODO: intern strings instead of allocation.
     47 */
     48 /*
     49 	gcc:
     50         g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
     51 
     52     Formatting, Artistic Style:
     53         AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
     54 */
     55 
     56 #if defined( _DEBUG ) || defined (__DEBUG__)
     57 #   ifndef TINYXML2_DEBUG
     58 #       define TINYXML2_DEBUG
     59 #   endif
     60 #endif
     61 
     62 #ifdef _MSC_VER
     63 #   pragma warning(push)
     64 #   pragma warning(disable: 4251)
     65 #endif
     66 
     67 #ifdef _WIN32
     68 #   ifdef TINYXML2_EXPORT
     69 #       define TINYXML2_LIB __declspec(dllexport)
     70 #   elif defined(TINYXML2_IMPORT)
     71 #       define TINYXML2_LIB __declspec(dllimport)
     72 #   else
     73 #       define TINYXML2_LIB
     74 #   endif
     75 #elif __GNUC__ >= 4
     76 #   define TINYXML2_LIB __attribute__((visibility("default")))
     77 #else
     78 #   define TINYXML2_LIB
     79 #endif
     80 
     81 
     82 #if defined(TINYXML2_DEBUG)
     83 #   if defined(_MSC_VER)
     84 #       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
     85 #       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); }
     86 #   elif defined (ANDROID_NDK)
     87 #       include <android/log.h>
     88 #       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
     89 #   else
     90 #       include <assert.h>
     91 #       define TIXMLASSERT                assert
     92 #   endif
     93 #else
     94 #   define TIXMLASSERT( x )               {}
     95 #endif
     96 
     97 
     98 /* Versioning, past 1.0.14:
     99 	http://semver.org/
    100 */
    101 static const int TIXML2_MAJOR_VERSION = 8;
    102 static const int TIXML2_MINOR_VERSION = 0;
    103 static const int TIXML2_PATCH_VERSION = 0;
    104 
    105 #define TINYXML2_MAJOR_VERSION 8
    106 #define TINYXML2_MINOR_VERSION 0
    107 #define TINYXML2_PATCH_VERSION 0
    108 
    109 // A fixed element depth limit is problematic. There needs to be a
    110 // limit to avoid a stack overflow. However, that limit varies per
    111 // system, and the capacity of the stack. On the other hand, it's a trivial
    112 // attack that can result from ill, malicious, or even correctly formed XML,
    113 // so there needs to be a limit in place.
    114 static const int TINYXML2_MAX_ELEMENT_DEPTH = 200;
    115 
    116 namespace tinyxml2
    117 {
    118 class XMLDocument;
    119 class XMLElement;
    120 class XMLAttribute;
    121 class XMLComment;
    122 class XMLText;
    123 class XMLDeclaration;
    124 class XMLUnknown;
    125 class XMLPrinter;
    126 
    127 /*
    128 	A class that wraps strings. Normally stores the start and end
    129 	pointers into the XML file itself, and will apply normalization
    130 	and entity translation if actually read. Can also store (and memory
    131 	manage) a traditional char[]
    132 
    133     Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
    134 */
    135 class TINYXML2_LIB StrPair
    136 {
    137 public:
    138     enum {
    139         NEEDS_ENTITY_PROCESSING			= 0x01,
    140         NEEDS_NEWLINE_NORMALIZATION		= 0x02,
    141         NEEDS_WHITESPACE_COLLAPSING     = 0x04,
    142 
    143         TEXT_ELEMENT		            = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
    144         TEXT_ELEMENT_LEAVE_ENTITIES		= NEEDS_NEWLINE_NORMALIZATION,
    145         ATTRIBUTE_NAME		            = 0,
    146         ATTRIBUTE_VALUE		            = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
    147         ATTRIBUTE_VALUE_LEAVE_ENTITIES  = NEEDS_NEWLINE_NORMALIZATION,
    148         COMMENT							= NEEDS_NEWLINE_NORMALIZATION
    149     };
    150 
    151     StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
    152     ~StrPair();
    153 
    154     void Set( char* start, char* end, int flags ) {
    155         TIXMLASSERT( start );
    156         TIXMLASSERT( end );
    157         Reset();
    158         _start  = start;
    159         _end    = end;
    160         _flags  = flags | NEEDS_FLUSH;
    161     }
    162 
    163     const char* GetStr();
    164 
    165     bool Empty() const {
    166         return _start == _end;
    167     }
    168 
    169     void SetInternedStr( const char* str ) {
    170         Reset();
    171         _start = const_cast<char*>(str);
    172     }
    173 
    174     void SetStr( const char* str, int flags=0 );
    175 
    176     char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
    177     char* ParseName( char* in );
    178 
    179     void TransferTo( StrPair* other );
    180 	void Reset();
    181 
    182 private:
    183     void CollapseWhitespace();
    184 
    185     enum {
    186         NEEDS_FLUSH = 0x100,
    187         NEEDS_DELETE = 0x200
    188     };
    189 
    190     int     _flags;
    191     char*   _start;
    192     char*   _end;
    193 
    194     StrPair( const StrPair& other );	// not supported
    195     void operator=( const StrPair& other );	// not supported, use TransferTo()
    196 };
    197 
    198 
    199 /*
    200 	A dynamic array of Plain Old Data. Doesn't support constructors, etc.
    201 	Has a small initial memory pool, so that low or no usage will not
    202 	cause a call to new/delete
    203 */
    204 template <class T, int INITIAL_SIZE>
    205 class DynArray
    206 {
    207 public:
    208     DynArray() :
    209         _mem( _pool ),
    210         _allocated( INITIAL_SIZE ),
    211         _size( 0 )
    212     {
    213     }
    214 
    215     ~DynArray() {
    216         if ( _mem != _pool ) {
    217             delete [] _mem;
    218         }
    219     }
    220 
    221     void Clear() {
    222         _size = 0;
    223     }
    224 
    225     void Push( T t ) {
    226         TIXMLASSERT( _size < INT_MAX );
    227         EnsureCapacity( _size+1 );
    228         _mem[_size] = t;
    229         ++_size;
    230     }
    231 
    232     T* PushArr( int count ) {
    233         TIXMLASSERT( count >= 0 );
    234         TIXMLASSERT( _size <= INT_MAX - count );
    235         EnsureCapacity( _size+count );
    236         T* ret = &_mem[_size];
    237         _size += count;
    238         return ret;
    239     }
    240 
    241     T Pop() {
    242         TIXMLASSERT( _size > 0 );
    243         --_size;
    244         return _mem[_size];
    245     }
    246 
    247     void PopArr( int count ) {
    248         TIXMLASSERT( _size >= count );
    249         _size -= count;
    250     }
    251 
    252     bool Empty() const					{
    253         return _size == 0;
    254     }
    255 
    256     T& operator[](int i)				{
    257         TIXMLASSERT( i>= 0 && i < _size );
    258         return _mem[i];
    259     }
    260 
    261     const T& operator[](int i) const	{
    262         TIXMLASSERT( i>= 0 && i < _size );
    263         return _mem[i];
    264     }
    265 
    266     const T& PeekTop() const            {
    267         TIXMLASSERT( _size > 0 );
    268         return _mem[ _size - 1];
    269     }
    270 
    271     int Size() const					{
    272         TIXMLASSERT( _size >= 0 );
    273         return _size;
    274     }
    275 
    276     int Capacity() const				{
    277         TIXMLASSERT( _allocated >= INITIAL_SIZE );
    278         return _allocated;
    279     }
    280 
    281 	void SwapRemove(int i) {
    282 		TIXMLASSERT(i >= 0 && i < _size);
    283 		TIXMLASSERT(_size > 0);
    284 		_mem[i] = _mem[_size - 1];
    285 		--_size;
    286 	}
    287 
    288     const T* Mem() const				{
    289         TIXMLASSERT( _mem );
    290         return _mem;
    291     }
    292 
    293     T* Mem() {
    294         TIXMLASSERT( _mem );
    295         return _mem;
    296     }
    297 
    298 private:
    299     DynArray( const DynArray& ); // not supported
    300     void operator=( const DynArray& ); // not supported
    301 
    302     void EnsureCapacity( int cap ) {
    303         TIXMLASSERT( cap > 0 );
    304         if ( cap > _allocated ) {
    305             TIXMLASSERT( cap <= INT_MAX / 2 );
    306             const int newAllocated = cap * 2;
    307             T* newMem = new T[newAllocated];
    308             TIXMLASSERT( newAllocated >= _size );
    309             memcpy( newMem, _mem, sizeof(T)*_size );	// warning: not using constructors, only works for PODs
    310             if ( _mem != _pool ) {
    311                 delete [] _mem;
    312             }
    313             _mem = newMem;
    314             _allocated = newAllocated;
    315         }
    316     }
    317 
    318     T*  _mem;
    319     T   _pool[INITIAL_SIZE];
    320     int _allocated;		// objects allocated
    321     int _size;			// number objects in use
    322 };
    323 
    324 
    325 /*
    326 	Parent virtual class of a pool for fast allocation
    327 	and deallocation of objects.
    328 */
    329 class MemPool
    330 {
    331 public:
    332     MemPool() {}
    333     virtual ~MemPool() {}
    334 
    335     virtual int ItemSize() const = 0;
    336     virtual void* Alloc() = 0;
    337     virtual void Free( void* ) = 0;
    338     virtual void SetTracked() = 0;
    339 };
    340 
    341 
    342 /*
    343 	Template child class to create pools of the correct type.
    344 */
    345 template< int ITEM_SIZE >
    346 class MemPoolT : public MemPool
    347 {
    348 public:
    349     MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)	{}
    350     ~MemPoolT() {
    351         MemPoolT< ITEM_SIZE >::Clear();
    352     }
    353 
    354     void Clear() {
    355         // Delete the blocks.
    356         while( !_blockPtrs.Empty()) {
    357             Block* lastBlock = _blockPtrs.Pop();
    358             delete lastBlock;
    359         }
    360         _root = 0;
    361         _currentAllocs = 0;
    362         _nAllocs = 0;
    363         _maxAllocs = 0;
    364         _nUntracked = 0;
    365     }
    366 
    367     virtual int ItemSize() const	{
    368         return ITEM_SIZE;
    369     }
    370     int CurrentAllocs() const		{
    371         return _currentAllocs;
    372     }
    373 
    374     virtual void* Alloc() {
    375         if ( !_root ) {
    376             // Need a new block.
    377             Block* block = new Block();
    378             _blockPtrs.Push( block );
    379 
    380             Item* blockItems = block->items;
    381             for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
    382                 blockItems[i].next = &(blockItems[i + 1]);
    383             }
    384             blockItems[ITEMS_PER_BLOCK - 1].next = 0;
    385             _root = blockItems;
    386         }
    387         Item* const result = _root;
    388         TIXMLASSERT( result != 0 );
    389         _root = _root->next;
    390 
    391         ++_currentAllocs;
    392         if ( _currentAllocs > _maxAllocs ) {
    393             _maxAllocs = _currentAllocs;
    394         }
    395         ++_nAllocs;
    396         ++_nUntracked;
    397         return result;
    398     }
    399 
    400     virtual void Free( void* mem ) {
    401         if ( !mem ) {
    402             return;
    403         }
    404         --_currentAllocs;
    405         Item* item = static_cast<Item*>( mem );
    406 #ifdef TINYXML2_DEBUG
    407         memset( item, 0xfe, sizeof( *item ) );
    408 #endif
    409         item->next = _root;
    410         _root = item;
    411     }
    412     void Trace( const char* name ) {
    413         printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
    414                 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
    415                 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
    416     }
    417 
    418     void SetTracked() {
    419         --_nUntracked;
    420     }
    421 
    422     int Untracked() const {
    423         return _nUntracked;
    424     }
    425 
    426 	// This number is perf sensitive. 4k seems like a good tradeoff on my machine.
    427 	// The test file is large, 170k.
    428 	// Release:		VS2010 gcc(no opt)
    429 	//		1k:		4000
    430 	//		2k:		4000
    431 	//		4k:		3900	21000
    432 	//		16k:	5200
    433 	//		32k:	4300
    434 	//		64k:	4000	21000
    435     // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
    436     // in private part if ITEMS_PER_BLOCK is private
    437     enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
    438 
    439 private:
    440     MemPoolT( const MemPoolT& ); // not supported
    441     void operator=( const MemPoolT& ); // not supported
    442 
    443     union Item {
    444         Item*   next;
    445         char    itemData[ITEM_SIZE];
    446     };
    447     struct Block {
    448         Item items[ITEMS_PER_BLOCK];
    449     };
    450     DynArray< Block*, 10 > _blockPtrs;
    451     Item* _root;
    452 
    453     int _currentAllocs;
    454     int _nAllocs;
    455     int _maxAllocs;
    456     int _nUntracked;
    457 };
    458 
    459 
    460 
    461 /**
    462 	Implements the interface to the "Visitor pattern" (see the Accept() method.)
    463 	If you call the Accept() method, it requires being passed a XMLVisitor
    464 	class to handle callbacks. For nodes that contain other nodes (Document, Element)
    465 	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
    466 	are simply called with Visit().
    467 
    468 	If you return 'true' from a Visit method, recursive parsing will continue. If you return
    469 	false, <b>no children of this node or its siblings</b> will be visited.
    470 
    471 	All flavors of Visit methods have a default implementation that returns 'true' (continue
    472 	visiting). You need to only override methods that are interesting to you.
    473 
    474 	Generally Accept() is called on the XMLDocument, although all nodes support visiting.
    475 
    476 	You should never change the document from a callback.
    477 
    478 	@sa XMLNode::Accept()
    479 */
    480 class TINYXML2_LIB XMLVisitor
    481 {
    482 public:
    483     virtual ~XMLVisitor() {}
    484 
    485     /// Visit a document.
    486     virtual bool VisitEnter( const XMLDocument& /*doc*/ )			{
    487         return true;
    488     }
    489     /// Visit a document.
    490     virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
    491         return true;
    492     }
    493 
    494     /// Visit an element.
    495     virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )	{
    496         return true;
    497     }
    498     /// Visit an element.
    499     virtual bool VisitExit( const XMLElement& /*element*/ )			{
    500         return true;
    501     }
    502 
    503     /// Visit a declaration.
    504     virtual bool Visit( const XMLDeclaration& /*declaration*/ )		{
    505         return true;
    506     }
    507     /// Visit a text node.
    508     virtual bool Visit( const XMLText& /*text*/ )					{
    509         return true;
    510     }
    511     /// Visit a comment node.
    512     virtual bool Visit( const XMLComment& /*comment*/ )				{
    513         return true;
    514     }
    515     /// Visit an unknown node.
    516     virtual bool Visit( const XMLUnknown& /*unknown*/ )				{
    517         return true;
    518     }
    519 };
    520 
    521 // WARNING: must match XMLDocument::_errorNames[]
    522 enum XMLError {
    523     XML_SUCCESS = 0,
    524     XML_NO_ATTRIBUTE,
    525     XML_WRONG_ATTRIBUTE_TYPE,
    526     XML_ERROR_FILE_NOT_FOUND,
    527     XML_ERROR_FILE_COULD_NOT_BE_OPENED,
    528     XML_ERROR_FILE_READ_ERROR,
    529     XML_ERROR_PARSING_ELEMENT,
    530     XML_ERROR_PARSING_ATTRIBUTE,
    531     XML_ERROR_PARSING_TEXT,
    532     XML_ERROR_PARSING_CDATA,
    533     XML_ERROR_PARSING_COMMENT,
    534     XML_ERROR_PARSING_DECLARATION,
    535     XML_ERROR_PARSING_UNKNOWN,
    536     XML_ERROR_EMPTY_DOCUMENT,
    537     XML_ERROR_MISMATCHED_ELEMENT,
    538     XML_ERROR_PARSING,
    539     XML_CAN_NOT_CONVERT_TEXT,
    540     XML_NO_TEXT_NODE,
    541 	XML_ELEMENT_DEPTH_EXCEEDED,
    542 
    543 	XML_ERROR_COUNT
    544 };
    545 
    546 
    547 /*
    548 	Utility functionality.
    549 */
    550 class TINYXML2_LIB XMLUtil
    551 {
    552 public:
    553     static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr )	{
    554         TIXMLASSERT( p );
    555 
    556         while( IsWhiteSpace(*p) ) {
    557             if (curLineNumPtr && *p == '\n') {
    558                 ++(*curLineNumPtr);
    559             }
    560             ++p;
    561         }
    562         TIXMLASSERT( p );
    563         return p;
    564     }
    565     static char* SkipWhiteSpace( char* const p, int* curLineNumPtr ) {
    566         return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
    567     }
    568 
    569     // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
    570     // correct, but simple, and usually works.
    571     static bool IsWhiteSpace( char p )					{
    572         return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
    573     }
    574 
    575     inline static bool IsNameStartChar( unsigned char ch ) {
    576         if ( ch >= 128 ) {
    577             // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
    578             return true;
    579         }
    580         if ( isalpha( ch ) ) {
    581             return true;
    582         }
    583         return ch == ':' || ch == '_';
    584     }
    585 
    586     inline static bool IsNameChar( unsigned char ch ) {
    587         return IsNameStartChar( ch )
    588                || isdigit( ch )
    589                || ch == '.'
    590                || ch == '-';
    591     }
    592 
    593     inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {
    594         if ( p == q ) {
    595             return true;
    596         }
    597         TIXMLASSERT( p );
    598         TIXMLASSERT( q );
    599         TIXMLASSERT( nChar >= 0 );
    600         return strncmp( p, q, nChar ) == 0;
    601     }
    602 
    603     inline static bool IsUTF8Continuation( const char p ) {
    604         return ( p & 0x80 ) != 0;
    605     }
    606 
    607     static const char* ReadBOM( const char* p, bool* hasBOM );
    608     // p is the starting location,
    609     // the UTF-8 value of the entity will be placed in value, and length filled in.
    610     static const char* GetCharacterRef( const char* p, char* value, int* length );
    611     static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
    612 
    613     // converts primitive types to strings
    614     static void ToStr( int v, char* buffer, int bufferSize );
    615     static void ToStr( unsigned v, char* buffer, int bufferSize );
    616     static void ToStr( bool v, char* buffer, int bufferSize );
    617     static void ToStr( float v, char* buffer, int bufferSize );
    618     static void ToStr( double v, char* buffer, int bufferSize );
    619 	static void ToStr(int64_t v, char* buffer, int bufferSize);
    620     static void ToStr(uint64_t v, char* buffer, int bufferSize);
    621 
    622     // converts strings to primitive types
    623     static bool	ToInt( const char* str, int* value );
    624     static bool ToUnsigned( const char* str, unsigned* value );
    625     static bool	ToBool( const char* str, bool* value );
    626     static bool	ToFloat( const char* str, float* value );
    627     static bool ToDouble( const char* str, double* value );
    628 	static bool ToInt64(const char* str, int64_t* value);
    629     static bool ToUnsigned64(const char* str, uint64_t* value);
    630 	// Changes what is serialized for a boolean value.
    631 	// Default to "true" and "false". Shouldn't be changed
    632 	// unless you have a special testing or compatibility need.
    633 	// Be careful: static, global, & not thread safe.
    634 	// Be sure to set static const memory as parameters.
    635 	static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
    636 
    637 private:
    638 	static const char* writeBoolTrue;
    639 	static const char* writeBoolFalse;
    640 };
    641 
    642 
    643 /** XMLNode is a base class for every object that is in the
    644 	XML Document Object Model (DOM), except XMLAttributes.
    645 	Nodes have siblings, a parent, and children which can
    646 	be navigated. A node is always in a XMLDocument.
    647 	The type of a XMLNode can be queried, and it can
    648 	be cast to its more defined type.
    649 
    650 	A XMLDocument allocates memory for all its Nodes.
    651 	When the XMLDocument gets deleted, all its Nodes
    652 	will also be deleted.
    653 
    654 	@verbatim
    655 	A Document can contain:	Element	(container or leaf)
    656 							Comment (leaf)
    657 							Unknown (leaf)
    658 							Declaration( leaf )
    659 
    660 	An Element can contain:	Element (container or leaf)
    661 							Text	(leaf)
    662 							Attributes (not on tree)
    663 							Comment (leaf)
    664 							Unknown (leaf)
    665 
    666 	@endverbatim
    667 */
    668 class TINYXML2_LIB XMLNode
    669 {
    670     friend class XMLDocument;
    671     friend class XMLElement;
    672 public:
    673 
    674     /// Get the XMLDocument that owns this XMLNode.
    675     const XMLDocument* GetDocument() const	{
    676         TIXMLASSERT( _document );
    677         return _document;
    678     }
    679     /// Get the XMLDocument that owns this XMLNode.
    680     XMLDocument* GetDocument()				{
    681         TIXMLASSERT( _document );
    682         return _document;
    683     }
    684 
    685     /// Safely cast to an Element, or null.
    686     virtual XMLElement*		ToElement()		{
    687         return 0;
    688     }
    689     /// Safely cast to Text, or null.
    690     virtual XMLText*		ToText()		{
    691         return 0;
    692     }
    693     /// Safely cast to a Comment, or null.
    694     virtual XMLComment*		ToComment()		{
    695         return 0;
    696     }
    697     /// Safely cast to a Document, or null.
    698     virtual XMLDocument*	ToDocument()	{
    699         return 0;
    700     }
    701     /// Safely cast to a Declaration, or null.
    702     virtual XMLDeclaration*	ToDeclaration()	{
    703         return 0;
    704     }
    705     /// Safely cast to an Unknown, or null.
    706     virtual XMLUnknown*		ToUnknown()		{
    707         return 0;
    708     }
    709 
    710     virtual const XMLElement*		ToElement() const		{
    711         return 0;
    712     }
    713     virtual const XMLText*			ToText() const			{
    714         return 0;
    715     }
    716     virtual const XMLComment*		ToComment() const		{
    717         return 0;
    718     }
    719     virtual const XMLDocument*		ToDocument() const		{
    720         return 0;
    721     }
    722     virtual const XMLDeclaration*	ToDeclaration() const	{
    723         return 0;
    724     }
    725     virtual const XMLUnknown*		ToUnknown() const		{
    726         return 0;
    727     }
    728 
    729     /** The meaning of 'value' changes for the specific type.
    730     	@verbatim
    731     	Document:	empty (NULL is returned, not an empty string)
    732     	Element:	name of the element
    733     	Comment:	the comment text
    734     	Unknown:	the tag contents
    735     	Text:		the text string
    736     	@endverbatim
    737     */
    738     const char* Value() const;
    739 
    740     /** Set the Value of an XML node.
    741     	@sa Value()
    742     */
    743     void SetValue( const char* val, bool staticMem=false );
    744 
    745     /// Gets the line number the node is in, if the document was parsed from a file.
    746     int GetLineNum() const { return _parseLineNum; }
    747 
    748     /// Get the parent of this node on the DOM.
    749     const XMLNode*	Parent() const			{
    750         return _parent;
    751     }
    752 
    753     XMLNode* Parent()						{
    754         return _parent;
    755     }
    756 
    757     /// Returns true if this node has no children.
    758     bool NoChildren() const					{
    759         return !_firstChild;
    760     }
    761 
    762     /// Get the first child node, or null if none exists.
    763     const XMLNode*  FirstChild() const		{
    764         return _firstChild;
    765     }
    766 
    767     XMLNode*		FirstChild()			{
    768         return _firstChild;
    769     }
    770 
    771     /** Get the first child element, or optionally the first child
    772         element with the specified name.
    773     */
    774     const XMLElement* FirstChildElement( const char* name = 0 ) const;
    775 
    776     XMLElement* FirstChildElement( const char* name = 0 )	{
    777         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
    778     }
    779 
    780     /// Get the last child node, or null if none exists.
    781     const XMLNode*	LastChild() const						{
    782         return _lastChild;
    783     }
    784 
    785     XMLNode*		LastChild()								{
    786         return _lastChild;
    787     }
    788 
    789     /** Get the last child element or optionally the last child
    790         element with the specified name.
    791     */
    792     const XMLElement* LastChildElement( const char* name = 0 ) const;
    793 
    794     XMLElement* LastChildElement( const char* name = 0 )	{
    795         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
    796     }
    797 
    798     /// Get the previous (left) sibling node of this node.
    799     const XMLNode*	PreviousSibling() const					{
    800         return _prev;
    801     }
    802 
    803     XMLNode*	PreviousSibling()							{
    804         return _prev;
    805     }
    806 
    807     /// Get the previous (left) sibling element of this node, with an optionally supplied name.
    808     const XMLElement*	PreviousSiblingElement( const char* name = 0 ) const ;
    809 
    810     XMLElement*	PreviousSiblingElement( const char* name = 0 ) {
    811         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
    812     }
    813 
    814     /// Get the next (right) sibling node of this node.
    815     const XMLNode*	NextSibling() const						{
    816         return _next;
    817     }
    818 
    819     XMLNode*	NextSibling()								{
    820         return _next;
    821     }
    822 
    823     /// Get the next (right) sibling element of this node, with an optionally supplied name.
    824     const XMLElement*	NextSiblingElement( const char* name = 0 ) const;
    825 
    826     XMLElement*	NextSiblingElement( const char* name = 0 )	{
    827         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
    828     }
    829 
    830     /**
    831     	Add a child node as the last (right) child.
    832 		If the child node is already part of the document,
    833 		it is moved from its old location to the new location.
    834 		Returns the addThis argument or 0 if the node does not
    835 		belong to the same document.
    836     */
    837     XMLNode* InsertEndChild( XMLNode* addThis );
    838 
    839     XMLNode* LinkEndChild( XMLNode* addThis )	{
    840         return InsertEndChild( addThis );
    841     }
    842     /**
    843     	Add a child node as the first (left) child.
    844 		If the child node is already part of the document,
    845 		it is moved from its old location to the new location.
    846 		Returns the addThis argument or 0 if the node does not
    847 		belong to the same document.
    848     */
    849     XMLNode* InsertFirstChild( XMLNode* addThis );
    850     /**
    851     	Add a node after the specified child node.
    852 		If the child node is already part of the document,
    853 		it is moved from its old location to the new location.
    854 		Returns the addThis argument or 0 if the afterThis node
    855 		is not a child of this node, or if the node does not
    856 		belong to the same document.
    857     */
    858     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
    859 
    860     /**
    861     	Delete all the children of this node.
    862     */
    863     void DeleteChildren();
    864 
    865     /**
    866     	Delete a child of this node.
    867     */
    868     void DeleteChild( XMLNode* node );
    869 
    870     /**
    871     	Make a copy of this node, but not its children.
    872     	You may pass in a Document pointer that will be
    873     	the owner of the new Node. If the 'document' is
    874     	null, then the node returned will be allocated
    875     	from the current Document. (this->GetDocument())
    876 
    877     	Note: if called on a XMLDocument, this will return null.
    878     */
    879     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
    880 
    881 	/**
    882 		Make a copy of this node and all its children.
    883 
    884 		If the 'target' is null, then the nodes will
    885 		be allocated in the current document. If 'target'
    886         is specified, the memory will be allocated is the
    887         specified XMLDocument.
    888 
    889 		NOTE: This is probably not the correct tool to
    890 		copy a document, since XMLDocuments can have multiple
    891 		top level XMLNodes. You probably want to use
    892         XMLDocument::DeepCopy()
    893 	*/
    894 	XMLNode* DeepClone( XMLDocument* target ) const;
    895 
    896     /**
    897     	Test if 2 nodes are the same, but don't test children.
    898     	The 2 nodes do not need to be in the same Document.
    899 
    900     	Note: if called on a XMLDocument, this will return false.
    901     */
    902     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
    903 
    904     /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
    905     	XML tree will be conditionally visited and the host will be called back
    906     	via the XMLVisitor interface.
    907 
    908     	This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
    909     	the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
    910     	interface versus any other.)
    911 
    912     	The interface has been based on ideas from:
    913 
    914     	- http://www.saxproject.org/
    915     	- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
    916 
    917     	Which are both good references for "visiting".
    918 
    919     	An example of using Accept():
    920     	@verbatim
    921     	XMLPrinter printer;
    922     	tinyxmlDoc.Accept( &printer );
    923     	const char* xmlcstr = printer.CStr();
    924     	@endverbatim
    925     */
    926     virtual bool Accept( XMLVisitor* visitor ) const = 0;
    927 
    928 	/**
    929 		Set user data into the XMLNode. TinyXML-2 in
    930 		no way processes or interprets user data.
    931 		It is initially 0.
    932 	*/
    933 	void SetUserData(void* userData)	{ _userData = userData; }
    934 
    935 	/**
    936 		Get user data set into the XMLNode. TinyXML-2 in
    937 		no way processes or interprets user data.
    938 		It is initially 0.
    939 	*/
    940 	void* GetUserData() const			{ return _userData; }
    941 
    942 protected:
    943     explicit XMLNode( XMLDocument* );
    944     virtual ~XMLNode();
    945 
    946     virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
    947 
    948     XMLDocument*	_document;
    949     XMLNode*		_parent;
    950     mutable StrPair	_value;
    951     int             _parseLineNum;
    952 
    953     XMLNode*		_firstChild;
    954     XMLNode*		_lastChild;
    955 
    956     XMLNode*		_prev;
    957     XMLNode*		_next;
    958 
    959 	void*			_userData;
    960 
    961 private:
    962     MemPool*		_memPool;
    963     void Unlink( XMLNode* child );
    964     static void DeleteNode( XMLNode* node );
    965     void InsertChildPreamble( XMLNode* insertThis ) const;
    966     const XMLElement* ToElementWithName( const char* name ) const;
    967 
    968     XMLNode( const XMLNode& );	// not supported
    969     XMLNode& operator=( const XMLNode& );	// not supported
    970 };
    971 
    972 
    973 /** XML text.
    974 
    975 	Note that a text node can have child element nodes, for example:
    976 	@verbatim
    977 	<root>This is <b>bold</b></root>
    978 	@endverbatim
    979 
    980 	A text node can have 2 ways to output the next. "normal" output
    981 	and CDATA. It will default to the mode it was parsed from the XML file and
    982 	you generally want to leave it alone, but you can change the output mode with
    983 	SetCData() and query it with CData().
    984 */
    985 class TINYXML2_LIB XMLText : public XMLNode
    986 {
    987     friend class XMLDocument;
    988 public:
    989     virtual bool Accept( XMLVisitor* visitor ) const;
    990 
    991     virtual XMLText* ToText()			{
    992         return this;
    993     }
    994     virtual const XMLText* ToText() const	{
    995         return this;
    996     }
    997 
    998     /// Declare whether this should be CDATA or standard text.
    999     void SetCData( bool isCData )			{
   1000         _isCData = isCData;
   1001     }
   1002     /// Returns true if this is a CDATA text element.
   1003     bool CData() const						{
   1004         return _isCData;
   1005     }
   1006 
   1007     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1008     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1009 
   1010 protected:
   1011     explicit XMLText( XMLDocument* doc )	: XMLNode( doc ), _isCData( false )	{}
   1012     virtual ~XMLText()												{}
   1013 
   1014     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1015 
   1016 private:
   1017     bool _isCData;
   1018 
   1019     XMLText( const XMLText& );	// not supported
   1020     XMLText& operator=( const XMLText& );	// not supported
   1021 };
   1022 
   1023 
   1024 /** An XML Comment. */
   1025 class TINYXML2_LIB XMLComment : public XMLNode
   1026 {
   1027     friend class XMLDocument;
   1028 public:
   1029     virtual XMLComment*	ToComment()					{
   1030         return this;
   1031     }
   1032     virtual const XMLComment* ToComment() const		{
   1033         return this;
   1034     }
   1035 
   1036     virtual bool Accept( XMLVisitor* visitor ) const;
   1037 
   1038     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1039     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1040 
   1041 protected:
   1042     explicit XMLComment( XMLDocument* doc );
   1043     virtual ~XMLComment();
   1044 
   1045     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
   1046 
   1047 private:
   1048     XMLComment( const XMLComment& );	// not supported
   1049     XMLComment& operator=( const XMLComment& );	// not supported
   1050 };
   1051 
   1052 
   1053 /** In correct XML the declaration is the first entry in the file.
   1054 	@verbatim
   1055 		<?xml version="1.0" standalone="yes"?>
   1056 	@endverbatim
   1057 
   1058 	TinyXML-2 will happily read or write files without a declaration,
   1059 	however.
   1060 
   1061 	The text of the declaration isn't interpreted. It is parsed
   1062 	and written as a string.
   1063 */
   1064 class TINYXML2_LIB XMLDeclaration : public XMLNode
   1065 {
   1066     friend class XMLDocument;
   1067 public:
   1068     virtual XMLDeclaration*	ToDeclaration()					{
   1069         return this;
   1070     }
   1071     virtual const XMLDeclaration* ToDeclaration() const		{
   1072         return this;
   1073     }
   1074 
   1075     virtual bool Accept( XMLVisitor* visitor ) const;
   1076 
   1077     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1078     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1079 
   1080 protected:
   1081     explicit XMLDeclaration( XMLDocument* doc );
   1082     virtual ~XMLDeclaration();
   1083 
   1084     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1085 
   1086 private:
   1087     XMLDeclaration( const XMLDeclaration& );	// not supported
   1088     XMLDeclaration& operator=( const XMLDeclaration& );	// not supported
   1089 };
   1090 
   1091 
   1092 /** Any tag that TinyXML-2 doesn't recognize is saved as an
   1093 	unknown. It is a tag of text, but should not be modified.
   1094 	It will be written back to the XML, unchanged, when the file
   1095 	is saved.
   1096 
   1097 	DTD tags get thrown into XMLUnknowns.
   1098 */
   1099 class TINYXML2_LIB XMLUnknown : public XMLNode
   1100 {
   1101     friend class XMLDocument;
   1102 public:
   1103     virtual XMLUnknown*	ToUnknown()					{
   1104         return this;
   1105     }
   1106     virtual const XMLUnknown* ToUnknown() const		{
   1107         return this;
   1108     }
   1109 
   1110     virtual bool Accept( XMLVisitor* visitor ) const;
   1111 
   1112     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1113     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1114 
   1115 protected:
   1116     explicit XMLUnknown( XMLDocument* doc );
   1117     virtual ~XMLUnknown();
   1118 
   1119     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1120 
   1121 private:
   1122     XMLUnknown( const XMLUnknown& );	// not supported
   1123     XMLUnknown& operator=( const XMLUnknown& );	// not supported
   1124 };
   1125 
   1126 
   1127 
   1128 /** An attribute is a name-value pair. Elements have an arbitrary
   1129 	number of attributes, each with a unique name.
   1130 
   1131 	@note The attributes are not XMLNodes. You may only query the
   1132 	Next() attribute in a list.
   1133 */
   1134 class TINYXML2_LIB XMLAttribute
   1135 {
   1136     friend class XMLElement;
   1137 public:
   1138     /// The name of the attribute.
   1139     const char* Name() const;
   1140 
   1141     /// The value of the attribute.
   1142     const char* Value() const;
   1143 
   1144     /// Gets the line number the attribute is in, if the document was parsed from a file.
   1145     int GetLineNum() const { return _parseLineNum; }
   1146 
   1147     /// The next attribute in the list.
   1148     const XMLAttribute* Next() const {
   1149         return _next;
   1150     }
   1151 
   1152     /** IntValue interprets the attribute as an integer, and returns the value.
   1153         If the value isn't an integer, 0 will be returned. There is no error checking;
   1154     	use QueryIntValue() if you need error checking.
   1155     */
   1156 	int	IntValue() const {
   1157 		int i = 0;
   1158 		QueryIntValue(&i);
   1159 		return i;
   1160 	}
   1161 
   1162 	int64_t Int64Value() const {
   1163 		int64_t i = 0;
   1164 		QueryInt64Value(&i);
   1165 		return i;
   1166 	}
   1167 
   1168     uint64_t Unsigned64Value() const {
   1169         uint64_t i = 0;
   1170         QueryUnsigned64Value(&i);
   1171         return i;
   1172     }
   1173 
   1174     /// Query as an unsigned integer. See IntValue()
   1175     unsigned UnsignedValue() const			{
   1176         unsigned i=0;
   1177         QueryUnsignedValue( &i );
   1178         return i;
   1179     }
   1180     /// Query as a boolean. See IntValue()
   1181     bool	 BoolValue() const				{
   1182         bool b=false;
   1183         QueryBoolValue( &b );
   1184         return b;
   1185     }
   1186     /// Query as a double. See IntValue()
   1187     double 	 DoubleValue() const			{
   1188         double d=0;
   1189         QueryDoubleValue( &d );
   1190         return d;
   1191     }
   1192     /// Query as a float. See IntValue()
   1193     float	 FloatValue() const				{
   1194         float f=0;
   1195         QueryFloatValue( &f );
   1196         return f;
   1197     }
   1198 
   1199     /** QueryIntValue interprets the attribute as an integer, and returns the value
   1200     	in the provided parameter. The function will return XML_SUCCESS on success,
   1201     	and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
   1202     */
   1203     XMLError QueryIntValue( int* value ) const;
   1204     /// See QueryIntValue
   1205     XMLError QueryUnsignedValue( unsigned int* value ) const;
   1206 	/// See QueryIntValue
   1207 	XMLError QueryInt64Value(int64_t* value) const;
   1208     /// See QueryIntValue
   1209     XMLError QueryUnsigned64Value(uint64_t* value) const;
   1210 	/// See QueryIntValue
   1211     XMLError QueryBoolValue( bool* value ) const;
   1212     /// See QueryIntValue
   1213     XMLError QueryDoubleValue( double* value ) const;
   1214     /// See QueryIntValue
   1215     XMLError QueryFloatValue( float* value ) const;
   1216 
   1217     /// Set the attribute to a string value.
   1218     void SetAttribute( const char* value );
   1219     /// Set the attribute to value.
   1220     void SetAttribute( int value );
   1221     /// Set the attribute to value.
   1222     void SetAttribute( unsigned value );
   1223 	/// Set the attribute to value.
   1224 	void SetAttribute(int64_t value);
   1225     /// Set the attribute to value.
   1226     void SetAttribute(uint64_t value);
   1227     /// Set the attribute to value.
   1228     void SetAttribute( bool value );
   1229     /// Set the attribute to value.
   1230     void SetAttribute( double value );
   1231     /// Set the attribute to value.
   1232     void SetAttribute( float value );
   1233 
   1234 private:
   1235     enum { BUF_SIZE = 200 };
   1236 
   1237     XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
   1238     virtual ~XMLAttribute()	{}
   1239 
   1240     XMLAttribute( const XMLAttribute& );	// not supported
   1241     void operator=( const XMLAttribute& );	// not supported
   1242     void SetName( const char* name );
   1243 
   1244     char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
   1245 
   1246     mutable StrPair _name;
   1247     mutable StrPair _value;
   1248     int             _parseLineNum;
   1249     XMLAttribute*   _next;
   1250     MemPool*        _memPool;
   1251 };
   1252 
   1253 
   1254 /** The element is a container class. It has a value, the element name,
   1255 	and can contain other elements, text, comments, and unknowns.
   1256 	Elements also contain an arbitrary number of attributes.
   1257 */
   1258 class TINYXML2_LIB XMLElement : public XMLNode
   1259 {
   1260     friend class XMLDocument;
   1261 public:
   1262     /// Get the name of an element (which is the Value() of the node.)
   1263     const char* Name() const		{
   1264         return Value();
   1265     }
   1266     /// Set the name of the element.
   1267     void SetName( const char* str, bool staticMem=false )	{
   1268         SetValue( str, staticMem );
   1269     }
   1270 
   1271     virtual XMLElement* ToElement()				{
   1272         return this;
   1273     }
   1274     virtual const XMLElement* ToElement() const {
   1275         return this;
   1276     }
   1277     virtual bool Accept( XMLVisitor* visitor ) const;
   1278 
   1279     /** Given an attribute name, Attribute() returns the value
   1280     	for the attribute of that name, or null if none
   1281     	exists. For example:
   1282 
   1283     	@verbatim
   1284     	const char* value = ele->Attribute( "foo" );
   1285     	@endverbatim
   1286 
   1287     	The 'value' parameter is normally null. However, if specified,
   1288     	the attribute will only be returned if the 'name' and 'value'
   1289     	match. This allow you to write code:
   1290 
   1291     	@verbatim
   1292     	if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
   1293     	@endverbatim
   1294 
   1295     	rather than:
   1296     	@verbatim
   1297     	if ( ele->Attribute( "foo" ) ) {
   1298     		if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
   1299     	}
   1300     	@endverbatim
   1301     */
   1302     const char* Attribute( const char* name, const char* value=0 ) const;
   1303 
   1304     /** Given an attribute name, IntAttribute() returns the value
   1305     	of the attribute interpreted as an integer. The default
   1306         value will be returned if the attribute isn't present,
   1307         or if there is an error. (For a method with error
   1308     	checking, see QueryIntAttribute()).
   1309     */
   1310 	int IntAttribute(const char* name, int defaultValue = 0) const;
   1311     /// See IntAttribute()
   1312 	unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
   1313 	/// See IntAttribute()
   1314 	int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
   1315     /// See IntAttribute()
   1316     uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
   1317 	/// See IntAttribute()
   1318 	bool BoolAttribute(const char* name, bool defaultValue = false) const;
   1319     /// See IntAttribute()
   1320 	double DoubleAttribute(const char* name, double defaultValue = 0) const;
   1321     /// See IntAttribute()
   1322 	float FloatAttribute(const char* name, float defaultValue = 0) const;
   1323 
   1324     /** Given an attribute name, QueryIntAttribute() returns
   1325     	XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
   1326     	can't be performed, or XML_NO_ATTRIBUTE if the attribute
   1327     	doesn't exist. If successful, the result of the conversion
   1328     	will be written to 'value'. If not successful, nothing will
   1329     	be written to 'value'. This allows you to provide default
   1330     	value:
   1331 
   1332     	@verbatim
   1333     	int value = 10;
   1334     	QueryIntAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
   1335     	@endverbatim
   1336     */
   1337     XMLError QueryIntAttribute( const char* name, int* value ) const				{
   1338         const XMLAttribute* a = FindAttribute( name );
   1339         if ( !a ) {
   1340             return XML_NO_ATTRIBUTE;
   1341         }
   1342         return a->QueryIntValue( value );
   1343     }
   1344 
   1345 	/// See QueryIntAttribute()
   1346     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const	{
   1347         const XMLAttribute* a = FindAttribute( name );
   1348         if ( !a ) {
   1349             return XML_NO_ATTRIBUTE;
   1350         }
   1351         return a->QueryUnsignedValue( value );
   1352     }
   1353 
   1354 	/// See QueryIntAttribute()
   1355 	XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
   1356 		const XMLAttribute* a = FindAttribute(name);
   1357 		if (!a) {
   1358 			return XML_NO_ATTRIBUTE;
   1359 		}
   1360 		return a->QueryInt64Value(value);
   1361 	}
   1362 
   1363     /// See QueryIntAttribute()
   1364     XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const {
   1365         const XMLAttribute* a = FindAttribute(name);
   1366         if(!a) {
   1367             return XML_NO_ATTRIBUTE;
   1368         }
   1369         return a->QueryUnsigned64Value(value);
   1370     }
   1371 
   1372 	/// See QueryIntAttribute()
   1373     XMLError QueryBoolAttribute( const char* name, bool* value ) const				{
   1374         const XMLAttribute* a = FindAttribute( name );
   1375         if ( !a ) {
   1376             return XML_NO_ATTRIBUTE;
   1377         }
   1378         return a->QueryBoolValue( value );
   1379     }
   1380     /// See QueryIntAttribute()
   1381     XMLError QueryDoubleAttribute( const char* name, double* value ) const			{
   1382         const XMLAttribute* a = FindAttribute( name );
   1383         if ( !a ) {
   1384             return XML_NO_ATTRIBUTE;
   1385         }
   1386         return a->QueryDoubleValue( value );
   1387     }
   1388     /// See QueryIntAttribute()
   1389     XMLError QueryFloatAttribute( const char* name, float* value ) const			{
   1390         const XMLAttribute* a = FindAttribute( name );
   1391         if ( !a ) {
   1392             return XML_NO_ATTRIBUTE;
   1393         }
   1394         return a->QueryFloatValue( value );
   1395     }
   1396 
   1397 	/// See QueryIntAttribute()
   1398 	XMLError QueryStringAttribute(const char* name, const char** value) const {
   1399 		const XMLAttribute* a = FindAttribute(name);
   1400 		if (!a) {
   1401 			return XML_NO_ATTRIBUTE;
   1402 		}
   1403 		*value = a->Value();
   1404 		return XML_SUCCESS;
   1405 	}
   1406 
   1407 
   1408 
   1409     /** Given an attribute name, QueryAttribute() returns
   1410     	XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
   1411     	can't be performed, or XML_NO_ATTRIBUTE if the attribute
   1412     	doesn't exist. It is overloaded for the primitive types,
   1413 		and is a generally more convenient replacement of
   1414 		QueryIntAttribute() and related functions.
   1415 
   1416 		If successful, the result of the conversion
   1417     	will be written to 'value'. If not successful, nothing will
   1418     	be written to 'value'. This allows you to provide default
   1419     	value:
   1420 
   1421     	@verbatim
   1422     	int value = 10;
   1423     	QueryAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
   1424     	@endverbatim
   1425     */
   1426 	XMLError QueryAttribute( const char* name, int* value ) const {
   1427 		return QueryIntAttribute( name, value );
   1428 	}
   1429 
   1430 	XMLError QueryAttribute( const char* name, unsigned int* value ) const {
   1431 		return QueryUnsignedAttribute( name, value );
   1432 	}
   1433 
   1434 	XMLError QueryAttribute(const char* name, int64_t* value) const {
   1435 		return QueryInt64Attribute(name, value);
   1436 	}
   1437 
   1438     XMLError QueryAttribute(const char* name, uint64_t* value) const {
   1439         return QueryUnsigned64Attribute(name, value);
   1440     }
   1441 
   1442     XMLError QueryAttribute( const char* name, bool* value ) const {
   1443 		return QueryBoolAttribute( name, value );
   1444 	}
   1445 
   1446 	XMLError QueryAttribute( const char* name, double* value ) const {
   1447 		return QueryDoubleAttribute( name, value );
   1448 	}
   1449 
   1450 	XMLError QueryAttribute( const char* name, float* value ) const {
   1451 		return QueryFloatAttribute( name, value );
   1452 	}
   1453 
   1454 	/// Sets the named attribute to value.
   1455     void SetAttribute( const char* name, const char* value )	{
   1456         XMLAttribute* a = FindOrCreateAttribute( name );
   1457         a->SetAttribute( value );
   1458     }
   1459     /// Sets the named attribute to value.
   1460     void SetAttribute( const char* name, int value )			{
   1461         XMLAttribute* a = FindOrCreateAttribute( name );
   1462         a->SetAttribute( value );
   1463     }
   1464     /// Sets the named attribute to value.
   1465     void SetAttribute( const char* name, unsigned value )		{
   1466         XMLAttribute* a = FindOrCreateAttribute( name );
   1467         a->SetAttribute( value );
   1468     }
   1469 
   1470 	/// Sets the named attribute to value.
   1471 	void SetAttribute(const char* name, int64_t value) {
   1472 		XMLAttribute* a = FindOrCreateAttribute(name);
   1473 		a->SetAttribute(value);
   1474 	}
   1475 
   1476     /// Sets the named attribute to value.
   1477     void SetAttribute(const char* name, uint64_t value) {
   1478         XMLAttribute* a = FindOrCreateAttribute(name);
   1479         a->SetAttribute(value);
   1480     }
   1481     
   1482     /// Sets the named attribute to value.
   1483     void SetAttribute( const char* name, bool value )			{
   1484         XMLAttribute* a = FindOrCreateAttribute( name );
   1485         a->SetAttribute( value );
   1486     }
   1487     /// Sets the named attribute to value.
   1488     void SetAttribute( const char* name, double value )		{
   1489         XMLAttribute* a = FindOrCreateAttribute( name );
   1490         a->SetAttribute( value );
   1491     }
   1492     /// Sets the named attribute to value.
   1493     void SetAttribute( const char* name, float value )		{
   1494         XMLAttribute* a = FindOrCreateAttribute( name );
   1495         a->SetAttribute( value );
   1496     }
   1497 
   1498     /**
   1499     	Delete an attribute.
   1500     */
   1501     void DeleteAttribute( const char* name );
   1502 
   1503     /// Return the first attribute in the list.
   1504     const XMLAttribute* FirstAttribute() const {
   1505         return _rootAttribute;
   1506     }
   1507     /// Query a specific attribute in the list.
   1508     const XMLAttribute* FindAttribute( const char* name ) const;
   1509 
   1510     /** Convenience function for easy access to the text inside an element. Although easy
   1511     	and concise, GetText() is limited compared to getting the XMLText child
   1512     	and accessing it directly.
   1513 
   1514     	If the first child of 'this' is a XMLText, the GetText()
   1515     	returns the character string of the Text node, else null is returned.
   1516 
   1517     	This is a convenient method for getting the text of simple contained text:
   1518     	@verbatim
   1519     	<foo>This is text</foo>
   1520     		const char* str = fooElement->GetText();
   1521     	@endverbatim
   1522 
   1523     	'str' will be a pointer to "This is text".
   1524 
   1525     	Note that this function can be misleading. If the element foo was created from
   1526     	this XML:
   1527     	@verbatim
   1528     		<foo><b>This is text</b></foo>
   1529     	@endverbatim
   1530 
   1531     	then the value of str would be null. The first child node isn't a text node, it is
   1532     	another element. From this XML:
   1533     	@verbatim
   1534     		<foo>This is <b>text</b></foo>
   1535     	@endverbatim
   1536     	GetText() will return "This is ".
   1537     */
   1538     const char* GetText() const;
   1539 
   1540     /** Convenience function for easy access to the text inside an element. Although easy
   1541     	and concise, SetText() is limited compared to creating an XMLText child
   1542     	and mutating it directly.
   1543 
   1544     	If the first child of 'this' is a XMLText, SetText() sets its value to
   1545 		the given string, otherwise it will create a first child that is an XMLText.
   1546 
   1547     	This is a convenient method for setting the text of simple contained text:
   1548     	@verbatim
   1549     	<foo>This is text</foo>
   1550     		fooElement->SetText( "Hullaballoo!" );
   1551      	<foo>Hullaballoo!</foo>
   1552 		@endverbatim
   1553 
   1554     	Note that this function can be misleading. If the element foo was created from
   1555     	this XML:
   1556     	@verbatim
   1557     		<foo><b>This is text</b></foo>
   1558     	@endverbatim
   1559 
   1560     	then it will not change "This is text", but rather prefix it with a text element:
   1561     	@verbatim
   1562     		<foo>Hullaballoo!<b>This is text</b></foo>
   1563     	@endverbatim
   1564 
   1565 		For this XML:
   1566     	@verbatim
   1567     		<foo />
   1568     	@endverbatim
   1569     	SetText() will generate
   1570     	@verbatim
   1571     		<foo>Hullaballoo!</foo>
   1572     	@endverbatim
   1573     */
   1574 	void SetText( const char* inText );
   1575     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1576     void SetText( int value );
   1577     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1578     void SetText( unsigned value );
   1579 	/// Convenience method for setting text inside an element. See SetText() for important limitations.
   1580 	void SetText(int64_t value);
   1581     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1582     void SetText(uint64_t value);
   1583 	/// Convenience method for setting text inside an element. See SetText() for important limitations.
   1584     void SetText( bool value );
   1585     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1586     void SetText( double value );
   1587     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1588     void SetText( float value );
   1589 
   1590     /**
   1591     	Convenience method to query the value of a child text node. This is probably best
   1592     	shown by example. Given you have a document is this form:
   1593     	@verbatim
   1594     		<point>
   1595     			<x>1</x>
   1596     			<y>1.4</y>
   1597     		</point>
   1598     	@endverbatim
   1599 
   1600     	The QueryIntText() and similar functions provide a safe and easier way to get to the
   1601     	"value" of x and y.
   1602 
   1603     	@verbatim
   1604     		int x = 0;
   1605     		float y = 0;	// types of x and y are contrived for example
   1606     		const XMLElement* xElement = pointElement->FirstChildElement( "x" );
   1607     		const XMLElement* yElement = pointElement->FirstChildElement( "y" );
   1608     		xElement->QueryIntText( &x );
   1609     		yElement->QueryFloatText( &y );
   1610     	@endverbatim
   1611 
   1612     	@returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
   1613     			 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
   1614 
   1615     */
   1616     XMLError QueryIntText( int* ival ) const;
   1617     /// See QueryIntText()
   1618     XMLError QueryUnsignedText( unsigned* uval ) const;
   1619 	/// See QueryIntText()
   1620 	XMLError QueryInt64Text(int64_t* uval) const;
   1621 	/// See QueryIntText()
   1622 	XMLError QueryUnsigned64Text(uint64_t* uval) const;
   1623 	/// See QueryIntText()
   1624     XMLError QueryBoolText( bool* bval ) const;
   1625     /// See QueryIntText()
   1626     XMLError QueryDoubleText( double* dval ) const;
   1627     /// See QueryIntText()
   1628     XMLError QueryFloatText( float* fval ) const;
   1629 
   1630 	int IntText(int defaultValue = 0) const;
   1631 
   1632 	/// See QueryIntText()
   1633 	unsigned UnsignedText(unsigned defaultValue = 0) const;
   1634 	/// See QueryIntText()
   1635 	int64_t Int64Text(int64_t defaultValue = 0) const;
   1636     /// See QueryIntText()
   1637     uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
   1638 	/// See QueryIntText()
   1639 	bool BoolText(bool defaultValue = false) const;
   1640 	/// See QueryIntText()
   1641 	double DoubleText(double defaultValue = 0) const;
   1642 	/// See QueryIntText()
   1643     float FloatText(float defaultValue = 0) const;
   1644 
   1645     /**
   1646         Convenience method to create a new XMLElement and add it as last (right)
   1647         child of this node. Returns the created and inserted element.
   1648     */
   1649     XMLElement* InsertNewChildElement(const char* name);
   1650     /// See InsertNewChildElement()
   1651     XMLComment* InsertNewComment(const char* comment);
   1652     /// See InsertNewChildElement()
   1653     XMLText* InsertNewText(const char* text);
   1654     /// See InsertNewChildElement()
   1655     XMLDeclaration* InsertNewDeclaration(const char* text);
   1656     /// See InsertNewChildElement()
   1657     XMLUnknown* InsertNewUnknown(const char* text);
   1658 
   1659 
   1660     // internal:
   1661     enum ElementClosingType {
   1662         OPEN,		// <foo>
   1663         CLOSED,		// <foo/>
   1664         CLOSING		// </foo>
   1665     };
   1666     ElementClosingType ClosingType() const {
   1667         return _closingType;
   1668     }
   1669     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1670     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1671 
   1672 protected:
   1673     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1674 
   1675 private:
   1676     XMLElement( XMLDocument* doc );
   1677     virtual ~XMLElement();
   1678     XMLElement( const XMLElement& );	// not supported
   1679     void operator=( const XMLElement& );	// not supported
   1680 
   1681     XMLAttribute* FindOrCreateAttribute( const char* name );
   1682     char* ParseAttributes( char* p, int* curLineNumPtr );
   1683     static void DeleteAttribute( XMLAttribute* attribute );
   1684     XMLAttribute* CreateAttribute();
   1685 
   1686     enum { BUF_SIZE = 200 };
   1687     ElementClosingType _closingType;
   1688     // The attribute list is ordered; there is no 'lastAttribute'
   1689     // because the list needs to be scanned for dupes before adding
   1690     // a new attribute.
   1691     XMLAttribute* _rootAttribute;
   1692 };
   1693 
   1694 
   1695 enum Whitespace {
   1696     PRESERVE_WHITESPACE,
   1697     COLLAPSE_WHITESPACE
   1698 };
   1699 
   1700 
   1701 /** A Document binds together all the functionality.
   1702 	It can be saved, loaded, and printed to the screen.
   1703 	All Nodes are connected and allocated to a Document.
   1704 	If the Document is deleted, all its Nodes are also deleted.
   1705 */
   1706 class TINYXML2_LIB XMLDocument : public XMLNode
   1707 {
   1708     friend class XMLElement;
   1709     // Gives access to SetError and Push/PopDepth, but over-access for everything else.
   1710     // Wishing C++ had "internal" scope.
   1711     friend class XMLNode;
   1712     friend class XMLText;
   1713     friend class XMLComment;
   1714     friend class XMLDeclaration;
   1715     friend class XMLUnknown;
   1716 public:
   1717     /// constructor
   1718     XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
   1719     ~XMLDocument();
   1720 
   1721     virtual XMLDocument* ToDocument()				{
   1722         TIXMLASSERT( this == _document );
   1723         return this;
   1724     }
   1725     virtual const XMLDocument* ToDocument() const	{
   1726         TIXMLASSERT( this == _document );
   1727         return this;
   1728     }
   1729 
   1730     /**
   1731     	Parse an XML file from a character string.
   1732     	Returns XML_SUCCESS (0) on success, or
   1733     	an errorID.
   1734 
   1735     	You may optionally pass in the 'nBytes', which is
   1736     	the number of bytes which will be parsed. If not
   1737     	specified, TinyXML-2 will assume 'xml' points to a
   1738     	null terminated string.
   1739     */
   1740     XMLError Parse( const char* xml, size_t nBytes=static_cast<size_t>(-1) );
   1741 
   1742     /**
   1743     	Load an XML file from disk.
   1744     	Returns XML_SUCCESS (0) on success, or
   1745     	an errorID.
   1746     */
   1747     XMLError LoadFile( const char* filename );
   1748 
   1749     /**
   1750     	Load an XML file from disk. You are responsible
   1751     	for providing and closing the FILE*.
   1752 
   1753         NOTE: The file should be opened as binary ("rb")
   1754         not text in order for TinyXML-2 to correctly
   1755         do newline normalization.
   1756 
   1757     	Returns XML_SUCCESS (0) on success, or
   1758     	an errorID.
   1759     */
   1760     XMLError LoadFile( FILE* );
   1761 
   1762     /**
   1763     	Save the XML file to disk.
   1764     	Returns XML_SUCCESS (0) on success, or
   1765     	an errorID.
   1766     */
   1767     XMLError SaveFile( const char* filename, bool compact = false );
   1768 
   1769     /**
   1770     	Save the XML file to disk. You are responsible
   1771     	for providing and closing the FILE*.
   1772 
   1773     	Returns XML_SUCCESS (0) on success, or
   1774     	an errorID.
   1775     */
   1776     XMLError SaveFile( FILE* fp, bool compact = false );
   1777 
   1778     bool ProcessEntities() const		{
   1779         return _processEntities;
   1780     }
   1781     Whitespace WhitespaceMode() const	{
   1782         return _whitespaceMode;
   1783     }
   1784 
   1785     /**
   1786     	Returns true if this document has a leading Byte Order Mark of UTF8.
   1787     */
   1788     bool HasBOM() const {
   1789         return _writeBOM;
   1790     }
   1791     /** Sets whether to write the BOM when writing the file.
   1792     */
   1793     void SetBOM( bool useBOM ) {
   1794         _writeBOM = useBOM;
   1795     }
   1796 
   1797     /** Return the root element of DOM. Equivalent to FirstChildElement().
   1798         To get the first node, use FirstChild().
   1799     */
   1800     XMLElement* RootElement()				{
   1801         return FirstChildElement();
   1802     }
   1803     const XMLElement* RootElement() const	{
   1804         return FirstChildElement();
   1805     }
   1806 
   1807     /** Print the Document. If the Printer is not provided, it will
   1808         print to stdout. If you provide Printer, this can print to a file:
   1809     	@verbatim
   1810     	XMLPrinter printer( fp );
   1811     	doc.Print( &printer );
   1812     	@endverbatim
   1813 
   1814     	Or you can use a printer to print to memory:
   1815     	@verbatim
   1816     	XMLPrinter printer;
   1817     	doc.Print( &printer );
   1818     	// printer.CStr() has a const char* to the XML
   1819     	@endverbatim
   1820     */
   1821     void Print( XMLPrinter* streamer=0 ) const;
   1822     virtual bool Accept( XMLVisitor* visitor ) const;
   1823 
   1824     /**
   1825     	Create a new Element associated with
   1826     	this Document. The memory for the Element
   1827     	is managed by the Document.
   1828     */
   1829     XMLElement* NewElement( const char* name );
   1830     /**
   1831     	Create a new Comment associated with
   1832     	this Document. The memory for the Comment
   1833     	is managed by the Document.
   1834     */
   1835     XMLComment* NewComment( const char* comment );
   1836     /**
   1837     	Create a new Text associated with
   1838     	this Document. The memory for the Text
   1839     	is managed by the Document.
   1840     */
   1841     XMLText* NewText( const char* text );
   1842     /**
   1843     	Create a new Declaration associated with
   1844     	this Document. The memory for the object
   1845     	is managed by the Document.
   1846 
   1847     	If the 'text' param is null, the standard
   1848     	declaration is used.:
   1849     	@verbatim
   1850     		<?xml version="1.0" encoding="UTF-8"?>
   1851     	@endverbatim
   1852     */
   1853     XMLDeclaration* NewDeclaration( const char* text=0 );
   1854     /**
   1855     	Create a new Unknown associated with
   1856     	this Document. The memory for the object
   1857     	is managed by the Document.
   1858     */
   1859     XMLUnknown* NewUnknown( const char* text );
   1860 
   1861     /**
   1862     	Delete a node associated with this document.
   1863     	It will be unlinked from the DOM.
   1864     */
   1865     void DeleteNode( XMLNode* node );
   1866 
   1867     void ClearError() {
   1868         SetError(XML_SUCCESS, 0, 0);
   1869     }
   1870 
   1871     /// Return true if there was an error parsing the document.
   1872     bool Error() const {
   1873         return _errorID != XML_SUCCESS;
   1874     }
   1875     /// Return the errorID.
   1876     XMLError  ErrorID() const {
   1877         return _errorID;
   1878     }
   1879 	const char* ErrorName() const;
   1880     static const char* ErrorIDToName(XMLError errorID);
   1881 
   1882     /** Returns a "long form" error description. A hopefully helpful
   1883         diagnostic with location, line number, and/or additional info.
   1884     */
   1885 	const char* ErrorStr() const;
   1886 
   1887     /// A (trivial) utility function that prints the ErrorStr() to stdout.
   1888     void PrintError() const;
   1889 
   1890     /// Return the line where the error occurred, or zero if unknown.
   1891     int ErrorLineNum() const
   1892     {
   1893         return _errorLineNum;
   1894     }
   1895 
   1896     /// Clear the document, resetting it to the initial state.
   1897     void Clear();
   1898 
   1899 	/**
   1900 		Copies this document to a target document.
   1901 		The target will be completely cleared before the copy.
   1902 		If you want to copy a sub-tree, see XMLNode::DeepClone().
   1903 
   1904 		NOTE: that the 'target' must be non-null.
   1905 	*/
   1906 	void DeepCopy(XMLDocument* target) const;
   1907 
   1908 	// internal
   1909     char* Identify( char* p, XMLNode** node );
   1910 
   1911 	// internal
   1912 	void MarkInUse(const XMLNode* const);
   1913 
   1914     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const	{
   1915         return 0;
   1916     }
   1917     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const	{
   1918         return false;
   1919     }
   1920 
   1921 private:
   1922     XMLDocument( const XMLDocument& );	// not supported
   1923     void operator=( const XMLDocument& );	// not supported
   1924 
   1925     bool			_writeBOM;
   1926     bool			_processEntities;
   1927     XMLError		_errorID;
   1928     Whitespace		_whitespaceMode;
   1929     mutable StrPair	_errorStr;
   1930     int             _errorLineNum;
   1931     char*			_charBuffer;
   1932     int				_parseCurLineNum;
   1933 	int				_parsingDepth;
   1934 	// Memory tracking does add some overhead.
   1935 	// However, the code assumes that you don't
   1936 	// have a bunch of unlinked nodes around.
   1937 	// Therefore it takes less memory to track
   1938 	// in the document vs. a linked list in the XMLNode,
   1939 	// and the performance is the same.
   1940 	DynArray<XMLNode*, 10> _unlinked;
   1941 
   1942     MemPoolT< sizeof(XMLElement) >	 _elementPool;
   1943     MemPoolT< sizeof(XMLAttribute) > _attributePool;
   1944     MemPoolT< sizeof(XMLText) >		 _textPool;
   1945     MemPoolT< sizeof(XMLComment) >	 _commentPool;
   1946 
   1947 	static const char* _errorNames[XML_ERROR_COUNT];
   1948 
   1949     void Parse();
   1950 
   1951     void SetError( XMLError error, int lineNum, const char* format, ... );
   1952 
   1953 	// Something of an obvious security hole, once it was discovered.
   1954 	// Either an ill-formed XML or an excessively deep one can overflow
   1955 	// the stack. Track stack depth, and error out if needed.
   1956 	class DepthTracker {
   1957 	public:
   1958 		explicit DepthTracker(XMLDocument * document) {
   1959 			this->_document = document;
   1960 			document->PushDepth();
   1961 		}
   1962 		~DepthTracker() {
   1963 			_document->PopDepth();
   1964 		}
   1965 	private:
   1966 		XMLDocument * _document;
   1967 	};
   1968 	void PushDepth();
   1969 	void PopDepth();
   1970 
   1971     template<class NodeType, int PoolElementSize>
   1972     NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
   1973 };
   1974 
   1975 template<class NodeType, int PoolElementSize>
   1976 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
   1977 {
   1978     TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
   1979     TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
   1980     NodeType* returnNode = new (pool.Alloc()) NodeType( this );
   1981     TIXMLASSERT( returnNode );
   1982     returnNode->_memPool = &pool;
   1983 
   1984 	_unlinked.Push(returnNode);
   1985     return returnNode;
   1986 }
   1987 
   1988 /**
   1989 	A XMLHandle is a class that wraps a node pointer with null checks; this is
   1990 	an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
   1991 	DOM structure. It is a separate utility class.
   1992 
   1993 	Take an example:
   1994 	@verbatim
   1995 	<Document>
   1996 		<Element attributeA = "valueA">
   1997 			<Child attributeB = "value1" />
   1998 			<Child attributeB = "value2" />
   1999 		</Element>
   2000 	</Document>
   2001 	@endverbatim
   2002 
   2003 	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
   2004 	easy to write a *lot* of code that looks like:
   2005 
   2006 	@verbatim
   2007 	XMLElement* root = document.FirstChildElement( "Document" );
   2008 	if ( root )
   2009 	{
   2010 		XMLElement* element = root->FirstChildElement( "Element" );
   2011 		if ( element )
   2012 		{
   2013 			XMLElement* child = element->FirstChildElement( "Child" );
   2014 			if ( child )
   2015 			{
   2016 				XMLElement* child2 = child->NextSiblingElement( "Child" );
   2017 				if ( child2 )
   2018 				{
   2019 					// Finally do something useful.
   2020 	@endverbatim
   2021 
   2022 	And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
   2023 	of such code. A XMLHandle checks for null pointers so it is perfectly safe
   2024 	and correct to use:
   2025 
   2026 	@verbatim
   2027 	XMLHandle docHandle( &document );
   2028 	XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
   2029 	if ( child2 )
   2030 	{
   2031 		// do something useful
   2032 	@endverbatim
   2033 
   2034 	Which is MUCH more concise and useful.
   2035 
   2036 	It is also safe to copy handles - internally they are nothing more than node pointers.
   2037 	@verbatim
   2038 	XMLHandle handleCopy = handle;
   2039 	@endverbatim
   2040 
   2041 	See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
   2042 */
   2043 class TINYXML2_LIB XMLHandle
   2044 {
   2045 public:
   2046     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
   2047     explicit XMLHandle( XMLNode* node ) : _node( node ) {
   2048     }
   2049     /// Create a handle from a node.
   2050     explicit XMLHandle( XMLNode& node ) : _node( &node ) {
   2051     }
   2052     /// Copy constructor
   2053     XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
   2054     }
   2055     /// Assignment
   2056     XMLHandle& operator=( const XMLHandle& ref )							{
   2057         _node = ref._node;
   2058         return *this;
   2059     }
   2060 
   2061     /// Get the first child of this handle.
   2062     XMLHandle FirstChild() 													{
   2063         return XMLHandle( _node ? _node->FirstChild() : 0 );
   2064     }
   2065     /// Get the first child element of this handle.
   2066     XMLHandle FirstChildElement( const char* name = 0 )						{
   2067         return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
   2068     }
   2069     /// Get the last child of this handle.
   2070     XMLHandle LastChild()													{
   2071         return XMLHandle( _node ? _node->LastChild() : 0 );
   2072     }
   2073     /// Get the last child element of this handle.
   2074     XMLHandle LastChildElement( const char* name = 0 )						{
   2075         return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
   2076     }
   2077     /// Get the previous sibling of this handle.
   2078     XMLHandle PreviousSibling()												{
   2079         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
   2080     }
   2081     /// Get the previous sibling element of this handle.
   2082     XMLHandle PreviousSiblingElement( const char* name = 0 )				{
   2083         return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
   2084     }
   2085     /// Get the next sibling of this handle.
   2086     XMLHandle NextSibling()													{
   2087         return XMLHandle( _node ? _node->NextSibling() : 0 );
   2088     }
   2089     /// Get the next sibling element of this handle.
   2090     XMLHandle NextSiblingElement( const char* name = 0 )					{
   2091         return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
   2092     }
   2093 
   2094     /// Safe cast to XMLNode. This can return null.
   2095     XMLNode* ToNode()							{
   2096         return _node;
   2097     }
   2098     /// Safe cast to XMLElement. This can return null.
   2099     XMLElement* ToElement() 					{
   2100         return ( _node ? _node->ToElement() : 0 );
   2101     }
   2102     /// Safe cast to XMLText. This can return null.
   2103     XMLText* ToText() 							{
   2104         return ( _node ? _node->ToText() : 0 );
   2105     }
   2106     /// Safe cast to XMLUnknown. This can return null.
   2107     XMLUnknown* ToUnknown() 					{
   2108         return ( _node ? _node->ToUnknown() : 0 );
   2109     }
   2110     /// Safe cast to XMLDeclaration. This can return null.
   2111     XMLDeclaration* ToDeclaration() 			{
   2112         return ( _node ? _node->ToDeclaration() : 0 );
   2113     }
   2114 
   2115 private:
   2116     XMLNode* _node;
   2117 };
   2118 
   2119 
   2120 /**
   2121 	A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
   2122 	same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
   2123 */
   2124 class TINYXML2_LIB XMLConstHandle
   2125 {
   2126 public:
   2127     explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
   2128     }
   2129     explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
   2130     }
   2131     XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
   2132     }
   2133 
   2134     XMLConstHandle& operator=( const XMLConstHandle& ref )							{
   2135         _node = ref._node;
   2136         return *this;
   2137     }
   2138 
   2139     const XMLConstHandle FirstChild() const											{
   2140         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
   2141     }
   2142     const XMLConstHandle FirstChildElement( const char* name = 0 ) const				{
   2143         return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
   2144     }
   2145     const XMLConstHandle LastChild()	const										{
   2146         return XMLConstHandle( _node ? _node->LastChild() : 0 );
   2147     }
   2148     const XMLConstHandle LastChildElement( const char* name = 0 ) const				{
   2149         return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
   2150     }
   2151     const XMLConstHandle PreviousSibling() const									{
   2152         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
   2153     }
   2154     const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const		{
   2155         return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
   2156     }
   2157     const XMLConstHandle NextSibling() const										{
   2158         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
   2159     }
   2160     const XMLConstHandle NextSiblingElement( const char* name = 0 ) const			{
   2161         return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
   2162     }
   2163 
   2164 
   2165     const XMLNode* ToNode() const				{
   2166         return _node;
   2167     }
   2168     const XMLElement* ToElement() const			{
   2169         return ( _node ? _node->ToElement() : 0 );
   2170     }
   2171     const XMLText* ToText() const				{
   2172         return ( _node ? _node->ToText() : 0 );
   2173     }
   2174     const XMLUnknown* ToUnknown() const			{
   2175         return ( _node ? _node->ToUnknown() : 0 );
   2176     }
   2177     const XMLDeclaration* ToDeclaration() const	{
   2178         return ( _node ? _node->ToDeclaration() : 0 );
   2179     }
   2180 
   2181 private:
   2182     const XMLNode* _node;
   2183 };
   2184 
   2185 
   2186 /**
   2187 	Printing functionality. The XMLPrinter gives you more
   2188 	options than the XMLDocument::Print() method.
   2189 
   2190 	It can:
   2191 	-# Print to memory.
   2192 	-# Print to a file you provide.
   2193 	-# Print XML without a XMLDocument.
   2194 
   2195 	Print to Memory
   2196 
   2197 	@verbatim
   2198 	XMLPrinter printer;
   2199 	doc.Print( &printer );
   2200 	SomeFunction( printer.CStr() );
   2201 	@endverbatim
   2202 
   2203 	Print to a File
   2204 
   2205 	You provide the file pointer.
   2206 	@verbatim
   2207 	XMLPrinter printer( fp );
   2208 	doc.Print( &printer );
   2209 	@endverbatim
   2210 
   2211 	Print without a XMLDocument
   2212 
   2213 	When loading, an XML parser is very useful. However, sometimes
   2214 	when saving, it just gets in the way. The code is often set up
   2215 	for streaming, and constructing the DOM is just overhead.
   2216 
   2217 	The Printer supports the streaming case. The following code
   2218 	prints out a trivially simple XML file without ever creating
   2219 	an XML document.
   2220 
   2221 	@verbatim
   2222 	XMLPrinter printer( fp );
   2223 	printer.OpenElement( "foo" );
   2224 	printer.PushAttribute( "foo", "bar" );
   2225 	printer.CloseElement();
   2226 	@endverbatim
   2227 */
   2228 class TINYXML2_LIB XMLPrinter : public XMLVisitor
   2229 {
   2230 public:
   2231     /** Construct the printer. If the FILE* is specified,
   2232     	this will print to the FILE. Else it will print
   2233     	to memory, and the result is available in CStr().
   2234     	If 'compact' is set to true, then output is created
   2235     	with only required whitespace and newlines.
   2236     */
   2237     XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
   2238     virtual ~XMLPrinter()	{}
   2239 
   2240     /** If streaming, write the BOM and declaration. */
   2241     void PushHeader( bool writeBOM, bool writeDeclaration );
   2242     /** If streaming, start writing an element.
   2243         The element must be closed with CloseElement()
   2244     */
   2245     void OpenElement( const char* name, bool compactMode=false );
   2246     /// If streaming, add an attribute to an open element.
   2247     void PushAttribute( const char* name, const char* value );
   2248     void PushAttribute( const char* name, int value );
   2249     void PushAttribute( const char* name, unsigned value );
   2250 	void PushAttribute( const char* name, int64_t value );
   2251 	void PushAttribute( const char* name, uint64_t value );
   2252 	void PushAttribute( const char* name, bool value );
   2253     void PushAttribute( const char* name, double value );
   2254     /// If streaming, close the Element.
   2255     virtual void CloseElement( bool compactMode=false );
   2256 
   2257     /// Add a text node.
   2258     void PushText( const char* text, bool cdata=false );
   2259     /// Add a text node from an integer.
   2260     void PushText( int value );
   2261     /// Add a text node from an unsigned.
   2262     void PushText( unsigned value );
   2263 	/// Add a text node from a signed 64bit integer.
   2264 	void PushText( int64_t value );
   2265 	/// Add a text node from an unsigned 64bit integer.
   2266 	void PushText( uint64_t value );
   2267 	/// Add a text node from a bool.
   2268     void PushText( bool value );
   2269     /// Add a text node from a float.
   2270     void PushText( float value );
   2271     /// Add a text node from a double.
   2272     void PushText( double value );
   2273 
   2274     /// Add a comment
   2275     void PushComment( const char* comment );
   2276 
   2277     void PushDeclaration( const char* value );
   2278     void PushUnknown( const char* value );
   2279 
   2280     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
   2281     virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
   2282         return true;
   2283     }
   2284 
   2285     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
   2286     virtual bool VisitExit( const XMLElement& element );
   2287 
   2288     virtual bool Visit( const XMLText& text );
   2289     virtual bool Visit( const XMLComment& comment );
   2290     virtual bool Visit( const XMLDeclaration& declaration );
   2291     virtual bool Visit( const XMLUnknown& unknown );
   2292 
   2293     /**
   2294     	If in print to memory mode, return a pointer to
   2295     	the XML file in memory.
   2296     */
   2297     const char* CStr() const {
   2298         return _buffer.Mem();
   2299     }
   2300     /**
   2301     	If in print to memory mode, return the size
   2302     	of the XML file in memory. (Note the size returned
   2303     	includes the terminating null.)
   2304     */
   2305     int CStrSize() const {
   2306         return _buffer.Size();
   2307     }
   2308     /**
   2309     	If in print to memory mode, reset the buffer to the
   2310     	beginning.
   2311     */
   2312     void ClearBuffer( bool resetToFirstElement = true ) {
   2313         _buffer.Clear();
   2314         _buffer.Push(0);
   2315 		_firstElement = resetToFirstElement;
   2316     }
   2317 
   2318 protected:
   2319 	virtual bool CompactMode( const XMLElement& )	{ return _compactMode; }
   2320 
   2321 	/** Prints out the space before an element. You may override to change
   2322 	    the space and tabs used. A PrintSpace() override should call Print().
   2323 	*/
   2324     virtual void PrintSpace( int depth );
   2325     void Print( const char* format, ... );
   2326     void Write( const char* data, size_t size );
   2327     inline void Write( const char* data )           { Write( data, strlen( data ) ); }
   2328     void Putc( char ch );
   2329 
   2330     void SealElementIfJustOpened();
   2331     bool _elementJustOpened;
   2332     DynArray< const char*, 10 > _stack;
   2333 
   2334 private:
   2335     void PrintString( const char*, bool restrictedEntitySet );	// prints out, after detecting entities.
   2336 
   2337     bool _firstElement;
   2338     FILE* _fp;
   2339     int _depth;
   2340     int _textDepth;
   2341     bool _processEntities;
   2342 	bool _compactMode;
   2343 
   2344     enum {
   2345         ENTITY_RANGE = 64,
   2346         BUF_SIZE = 200
   2347     };
   2348     bool _entityFlag[ENTITY_RANGE];
   2349     bool _restrictedEntityFlag[ENTITY_RANGE];
   2350 
   2351     DynArray< char, 20 > _buffer;
   2352 
   2353     // Prohibit cloning, intentionally not implemented
   2354     XMLPrinter( const XMLPrinter& );
   2355     XMLPrinter& operator=( const XMLPrinter& );
   2356 };
   2357 
   2358 
   2359 }	// tinyxml2
   2360 
   2361 #if defined(_MSC_VER)
   2362 #   pragma warning(pop)
   2363 #endif
   2364 
   2365 #endif // TINYXML2_INCLUDED