Home | History | Annotate | Download | only in tinyxml2
      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 = 7;
    102 static const int TIXML2_MINOR_VERSION = 0;
    103 static const int TIXML2_PATCH_VERSION = 1;
    104 
    105 #define TINYXML2_MAJOR_VERSION 7
    106 #define TINYXML2_MINOR_VERSION 0
    107 #define TINYXML2_PATCH_VERSION 1
    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 = 100;
    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             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* 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( 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 
    621     // converts strings to primitive types
    622     static bool	ToInt( const char* str, int* value );
    623     static bool ToUnsigned( const char* str, unsigned* value );
    624     static bool	ToBool( const char* str, bool* value );
    625     static bool	ToFloat( const char* str, float* value );
    626     static bool ToDouble( const char* str, double* value );
    627 	static bool ToInt64(const char* str, int64_t* value);
    628 
    629 	// Changes what is serialized for a boolean value.
    630 	// Default to "true" and "false". Shouldn't be changed
    631 	// unless you have a special testing or compatibility need.
    632 	// Be careful: static, global, & not thread safe.
    633 	// Be sure to set static const memory as parameters.
    634 	static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
    635 
    636 private:
    637 	static const char* writeBoolTrue;
    638 	static const char* writeBoolFalse;
    639 };
    640 
    641 
    642 /** XMLNode is a base class for every object that is in the
    643 	XML Document Object Model (DOM), except XMLAttributes.
    644 	Nodes have siblings, a parent, and children which can
    645 	be navigated. A node is always in a XMLDocument.
    646 	The type of a XMLNode can be queried, and it can
    647 	be cast to its more defined type.
    648 
    649 	A XMLDocument allocates memory for all its Nodes.
    650 	When the XMLDocument gets deleted, all its Nodes
    651 	will also be deleted.
    652 
    653 	@verbatim
    654 	A Document can contain:	Element	(container or leaf)
    655 							Comment (leaf)
    656 							Unknown (leaf)
    657 							Declaration( leaf )
    658 
    659 	An Element can contain:	Element (container or leaf)
    660 							Text	(leaf)
    661 							Attributes (not on tree)
    662 							Comment (leaf)
    663 							Unknown (leaf)
    664 
    665 	@endverbatim
    666 */
    667 class TINYXML2_LIB XMLNode
    668 {
    669     friend class XMLDocument;
    670     friend class XMLElement;
    671 public:
    672 
    673     /// Get the XMLDocument that owns this XMLNode.
    674     const XMLDocument* GetDocument() const	{
    675         TIXMLASSERT( _document );
    676         return _document;
    677     }
    678     /// Get the XMLDocument that owns this XMLNode.
    679     XMLDocument* GetDocument()				{
    680         TIXMLASSERT( _document );
    681         return _document;
    682     }
    683 
    684     /// Safely cast to an Element, or null.
    685     virtual XMLElement*		ToElement()		{
    686         return 0;
    687     }
    688     /// Safely cast to Text, or null.
    689     virtual XMLText*		ToText()		{
    690         return 0;
    691     }
    692     /// Safely cast to a Comment, or null.
    693     virtual XMLComment*		ToComment()		{
    694         return 0;
    695     }
    696     /// Safely cast to a Document, or null.
    697     virtual XMLDocument*	ToDocument()	{
    698         return 0;
    699     }
    700     /// Safely cast to a Declaration, or null.
    701     virtual XMLDeclaration*	ToDeclaration()	{
    702         return 0;
    703     }
    704     /// Safely cast to an Unknown, or null.
    705     virtual XMLUnknown*		ToUnknown()		{
    706         return 0;
    707     }
    708 
    709     virtual const XMLElement*		ToElement() const		{
    710         return 0;
    711     }
    712     virtual const XMLText*			ToText() const			{
    713         return 0;
    714     }
    715     virtual const XMLComment*		ToComment() const		{
    716         return 0;
    717     }
    718     virtual const XMLDocument*		ToDocument() const		{
    719         return 0;
    720     }
    721     virtual const XMLDeclaration*	ToDeclaration() const	{
    722         return 0;
    723     }
    724     virtual const XMLUnknown*		ToUnknown() const		{
    725         return 0;
    726     }
    727 
    728     /** The meaning of 'value' changes for the specific type.
    729     	@verbatim
    730     	Document:	empty (NULL is returned, not an empty string)
    731     	Element:	name of the element
    732     	Comment:	the comment text
    733     	Unknown:	the tag contents
    734     	Text:		the text string
    735     	@endverbatim
    736     */
    737     const char* Value() const;
    738 
    739     /** Set the Value of an XML node.
    740     	@sa Value()
    741     */
    742     void SetValue( const char* val, bool staticMem=false );
    743 
    744     /// Gets the line number the node is in, if the document was parsed from a file.
    745     int GetLineNum() const { return _parseLineNum; }
    746 
    747     /// Get the parent of this node on the DOM.
    748     const XMLNode*	Parent() const			{
    749         return _parent;
    750     }
    751 
    752     XMLNode* Parent()						{
    753         return _parent;
    754     }
    755 
    756     /// Returns true if this node has no children.
    757     bool NoChildren() const					{
    758         return !_firstChild;
    759     }
    760 
    761     /// Get the first child node, or null if none exists.
    762     const XMLNode*  FirstChild() const		{
    763         return _firstChild;
    764     }
    765 
    766     XMLNode*		FirstChild()			{
    767         return _firstChild;
    768     }
    769 
    770     /** Get the first child element, or optionally the first child
    771         element with the specified name.
    772     */
    773     const XMLElement* FirstChildElement( const char* name = 0 ) const;
    774 
    775     XMLElement* FirstChildElement( const char* name = 0 )	{
    776         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
    777     }
    778 
    779     /// Get the last child node, or null if none exists.
    780     const XMLNode*	LastChild() const						{
    781         return _lastChild;
    782     }
    783 
    784     XMLNode*		LastChild()								{
    785         return _lastChild;
    786     }
    787 
    788     /** Get the last child element or optionally the last child
    789         element with the specified name.
    790     */
    791     const XMLElement* LastChildElement( const char* name = 0 ) const;
    792 
    793     XMLElement* LastChildElement( const char* name = 0 )	{
    794         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
    795     }
    796 
    797     /// Get the previous (left) sibling node of this node.
    798     const XMLNode*	PreviousSibling() const					{
    799         return _prev;
    800     }
    801 
    802     XMLNode*	PreviousSibling()							{
    803         return _prev;
    804     }
    805 
    806     /// Get the previous (left) sibling element of this node, with an optionally supplied name.
    807     const XMLElement*	PreviousSiblingElement( const char* name = 0 ) const ;
    808 
    809     XMLElement*	PreviousSiblingElement( const char* name = 0 ) {
    810         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
    811     }
    812 
    813     /// Get the next (right) sibling node of this node.
    814     const XMLNode*	NextSibling() const						{
    815         return _next;
    816     }
    817 
    818     XMLNode*	NextSibling()								{
    819         return _next;
    820     }
    821 
    822     /// Get the next (right) sibling element of this node, with an optionally supplied name.
    823     const XMLElement*	NextSiblingElement( const char* name = 0 ) const;
    824 
    825     XMLElement*	NextSiblingElement( const char* name = 0 )	{
    826         return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
    827     }
    828 
    829     /**
    830     	Add a child node as the last (right) child.
    831 		If the child node is already part of the document,
    832 		it is moved from its old location to the new location.
    833 		Returns the addThis argument or 0 if the node does not
    834 		belong to the same document.
    835     */
    836     XMLNode* InsertEndChild( XMLNode* addThis );
    837 
    838     XMLNode* LinkEndChild( XMLNode* addThis )	{
    839         return InsertEndChild( addThis );
    840     }
    841     /**
    842     	Add a child node as the first (left) child.
    843 		If the child node is already part of the document,
    844 		it is moved from its old location to the new location.
    845 		Returns the addThis argument or 0 if the node does not
    846 		belong to the same document.
    847     */
    848     XMLNode* InsertFirstChild( XMLNode* addThis );
    849     /**
    850     	Add a node after the specified child node.
    851 		If the child node is already part of the document,
    852 		it is moved from its old location to the new location.
    853 		Returns the addThis argument or 0 if the afterThis node
    854 		is not a child of this node, or if the node does not
    855 		belong to the same document.
    856     */
    857     XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
    858 
    859     /**
    860     	Delete all the children of this node.
    861     */
    862     void DeleteChildren();
    863 
    864     /**
    865     	Delete a child of this node.
    866     */
    867     void DeleteChild( XMLNode* node );
    868 
    869     /**
    870     	Make a copy of this node, but not its children.
    871     	You may pass in a Document pointer that will be
    872     	the owner of the new Node. If the 'document' is
    873     	null, then the node returned will be allocated
    874     	from the current Document. (this->GetDocument())
    875 
    876     	Note: if called on a XMLDocument, this will return null.
    877     */
    878     virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
    879 
    880 	/**
    881 		Make a copy of this node and all its children.
    882 
    883 		If the 'target' is null, then the nodes will
    884 		be allocated in the current document. If 'target'
    885         is specified, the memory will be allocated is the
    886         specified XMLDocument.
    887 
    888 		NOTE: This is probably not the correct tool to
    889 		copy a document, since XMLDocuments can have multiple
    890 		top level XMLNodes. You probably want to use
    891         XMLDocument::DeepCopy()
    892 	*/
    893 	XMLNode* DeepClone( XMLDocument* target ) const;
    894 
    895     /**
    896     	Test if 2 nodes are the same, but don't test children.
    897     	The 2 nodes do not need to be in the same Document.
    898 
    899     	Note: if called on a XMLDocument, this will return false.
    900     */
    901     virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
    902 
    903     /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
    904     	XML tree will be conditionally visited and the host will be called back
    905     	via the XMLVisitor interface.
    906 
    907     	This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
    908     	the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
    909     	interface versus any other.)
    910 
    911     	The interface has been based on ideas from:
    912 
    913     	- http://www.saxproject.org/
    914     	- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
    915 
    916     	Which are both good references for "visiting".
    917 
    918     	An example of using Accept():
    919     	@verbatim
    920     	XMLPrinter printer;
    921     	tinyxmlDoc.Accept( &printer );
    922     	const char* xmlcstr = printer.CStr();
    923     	@endverbatim
    924     */
    925     virtual bool Accept( XMLVisitor* visitor ) const = 0;
    926 
    927 	/**
    928 		Set user data into the XMLNode. TinyXML-2 in
    929 		no way processes or interprets user data.
    930 		It is initially 0.
    931 	*/
    932 	void SetUserData(void* userData)	{ _userData = userData; }
    933 
    934 	/**
    935 		Get user data set into the XMLNode. TinyXML-2 in
    936 		no way processes or interprets user data.
    937 		It is initially 0.
    938 	*/
    939 	void* GetUserData() const			{ return _userData; }
    940 
    941 protected:
    942     explicit XMLNode( XMLDocument* );
    943     virtual ~XMLNode();
    944 
    945     virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
    946 
    947     XMLDocument*	_document;
    948     XMLNode*		_parent;
    949     mutable StrPair	_value;
    950     int             _parseLineNum;
    951 
    952     XMLNode*		_firstChild;
    953     XMLNode*		_lastChild;
    954 
    955     XMLNode*		_prev;
    956     XMLNode*		_next;
    957 
    958 	void*			_userData;
    959 
    960 private:
    961     MemPool*		_memPool;
    962     void Unlink( XMLNode* child );
    963     static void DeleteNode( XMLNode* node );
    964     void InsertChildPreamble( XMLNode* insertThis ) const;
    965     const XMLElement* ToElementWithName( const char* name ) const;
    966 
    967     XMLNode( const XMLNode& );	// not supported
    968     XMLNode& operator=( const XMLNode& );	// not supported
    969 };
    970 
    971 
    972 /** XML text.
    973 
    974 	Note that a text node can have child element nodes, for example:
    975 	@verbatim
    976 	<root>This is <b>bold</b></root>
    977 	@endverbatim
    978 
    979 	A text node can have 2 ways to output the next. "normal" output
    980 	and CDATA. It will default to the mode it was parsed from the XML file and
    981 	you generally want to leave it alone, but you can change the output mode with
    982 	SetCData() and query it with CData().
    983 */
    984 class TINYXML2_LIB XMLText : public XMLNode
    985 {
    986     friend class XMLDocument;
    987 public:
    988     virtual bool Accept( XMLVisitor* visitor ) const;
    989 
    990     virtual XMLText* ToText()			{
    991         return this;
    992     }
    993     virtual const XMLText* ToText() const	{
    994         return this;
    995     }
    996 
    997     /// Declare whether this should be CDATA or standard text.
    998     void SetCData( bool isCData )			{
    999         _isCData = isCData;
   1000     }
   1001     /// Returns true if this is a CDATA text element.
   1002     bool CData() const						{
   1003         return _isCData;
   1004     }
   1005 
   1006     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1007     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1008 
   1009 protected:
   1010     explicit XMLText( XMLDocument* doc )	: XMLNode( doc ), _isCData( false )	{}
   1011     virtual ~XMLText()												{}
   1012 
   1013     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1014 
   1015 private:
   1016     bool _isCData;
   1017 
   1018     XMLText( const XMLText& );	// not supported
   1019     XMLText& operator=( const XMLText& );	// not supported
   1020 };
   1021 
   1022 
   1023 /** An XML Comment. */
   1024 class TINYXML2_LIB XMLComment : public XMLNode
   1025 {
   1026     friend class XMLDocument;
   1027 public:
   1028     virtual XMLComment*	ToComment()					{
   1029         return this;
   1030     }
   1031     virtual const XMLComment* ToComment() const		{
   1032         return this;
   1033     }
   1034 
   1035     virtual bool Accept( XMLVisitor* visitor ) const;
   1036 
   1037     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1038     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1039 
   1040 protected:
   1041     explicit XMLComment( XMLDocument* doc );
   1042     virtual ~XMLComment();
   1043 
   1044     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
   1045 
   1046 private:
   1047     XMLComment( const XMLComment& );	// not supported
   1048     XMLComment& operator=( const XMLComment& );	// not supported
   1049 };
   1050 
   1051 
   1052 /** In correct XML the declaration is the first entry in the file.
   1053 	@verbatim
   1054 		<?xml version="1.0" standalone="yes"?>
   1055 	@endverbatim
   1056 
   1057 	TinyXML-2 will happily read or write files without a declaration,
   1058 	however.
   1059 
   1060 	The text of the declaration isn't interpreted. It is parsed
   1061 	and written as a string.
   1062 */
   1063 class TINYXML2_LIB XMLDeclaration : public XMLNode
   1064 {
   1065     friend class XMLDocument;
   1066 public:
   1067     virtual XMLDeclaration*	ToDeclaration()					{
   1068         return this;
   1069     }
   1070     virtual const XMLDeclaration* ToDeclaration() const		{
   1071         return this;
   1072     }
   1073 
   1074     virtual bool Accept( XMLVisitor* visitor ) const;
   1075 
   1076     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1077     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1078 
   1079 protected:
   1080     explicit XMLDeclaration( XMLDocument* doc );
   1081     virtual ~XMLDeclaration();
   1082 
   1083     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1084 
   1085 private:
   1086     XMLDeclaration( const XMLDeclaration& );	// not supported
   1087     XMLDeclaration& operator=( const XMLDeclaration& );	// not supported
   1088 };
   1089 
   1090 
   1091 /** Any tag that TinyXML-2 doesn't recognize is saved as an
   1092 	unknown. It is a tag of text, but should not be modified.
   1093 	It will be written back to the XML, unchanged, when the file
   1094 	is saved.
   1095 
   1096 	DTD tags get thrown into XMLUnknowns.
   1097 */
   1098 class TINYXML2_LIB XMLUnknown : public XMLNode
   1099 {
   1100     friend class XMLDocument;
   1101 public:
   1102     virtual XMLUnknown*	ToUnknown()					{
   1103         return this;
   1104     }
   1105     virtual const XMLUnknown* ToUnknown() const		{
   1106         return this;
   1107     }
   1108 
   1109     virtual bool Accept( XMLVisitor* visitor ) const;
   1110 
   1111     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1112     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1113 
   1114 protected:
   1115     explicit XMLUnknown( XMLDocument* doc );
   1116     virtual ~XMLUnknown();
   1117 
   1118     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1119 
   1120 private:
   1121     XMLUnknown( const XMLUnknown& );	// not supported
   1122     XMLUnknown& operator=( const XMLUnknown& );	// not supported
   1123 };
   1124 
   1125 
   1126 
   1127 /** An attribute is a name-value pair. Elements have an arbitrary
   1128 	number of attributes, each with a unique name.
   1129 
   1130 	@note The attributes are not XMLNodes. You may only query the
   1131 	Next() attribute in a list.
   1132 */
   1133 class TINYXML2_LIB XMLAttribute
   1134 {
   1135     friend class XMLElement;
   1136 public:
   1137     /// The name of the attribute.
   1138     const char* Name() const;
   1139 
   1140     /// The value of the attribute.
   1141     const char* Value() const;
   1142 
   1143     /// Gets the line number the attribute is in, if the document was parsed from a file.
   1144     int GetLineNum() const { return _parseLineNum; }
   1145 
   1146     /// The next attribute in the list.
   1147     const XMLAttribute* Next() const {
   1148         return _next;
   1149     }
   1150 
   1151     /** IntValue interprets the attribute as an integer, and returns the value.
   1152         If the value isn't an integer, 0 will be returned. There is no error checking;
   1153     	use QueryIntValue() if you need error checking.
   1154     */
   1155 	int	IntValue() const {
   1156 		int i = 0;
   1157 		QueryIntValue(&i);
   1158 		return i;
   1159 	}
   1160 
   1161 	int64_t Int64Value() const {
   1162 		int64_t i = 0;
   1163 		QueryInt64Value(&i);
   1164 		return i;
   1165 	}
   1166 
   1167     /// Query as an unsigned integer. See IntValue()
   1168     unsigned UnsignedValue() const			{
   1169         unsigned i=0;
   1170         QueryUnsignedValue( &i );
   1171         return i;
   1172     }
   1173     /// Query as a boolean. See IntValue()
   1174     bool	 BoolValue() const				{
   1175         bool b=false;
   1176         QueryBoolValue( &b );
   1177         return b;
   1178     }
   1179     /// Query as a double. See IntValue()
   1180     double 	 DoubleValue() const			{
   1181         double d=0;
   1182         QueryDoubleValue( &d );
   1183         return d;
   1184     }
   1185     /// Query as a float. See IntValue()
   1186     float	 FloatValue() const				{
   1187         float f=0;
   1188         QueryFloatValue( &f );
   1189         return f;
   1190     }
   1191 
   1192     /** QueryIntValue interprets the attribute as an integer, and returns the value
   1193     	in the provided parameter. The function will return XML_SUCCESS on success,
   1194     	and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
   1195     */
   1196     XMLError QueryIntValue( int* value ) const;
   1197     /// See QueryIntValue
   1198     XMLError QueryUnsignedValue( unsigned int* value ) const;
   1199 	/// See QueryIntValue
   1200 	XMLError QueryInt64Value(int64_t* value) const;
   1201 	/// See QueryIntValue
   1202     XMLError QueryBoolValue( bool* value ) const;
   1203     /// See QueryIntValue
   1204     XMLError QueryDoubleValue( double* value ) const;
   1205     /// See QueryIntValue
   1206     XMLError QueryFloatValue( float* value ) const;
   1207 
   1208     /// Set the attribute to a string value.
   1209     void SetAttribute( const char* value );
   1210     /// Set the attribute to value.
   1211     void SetAttribute( int value );
   1212     /// Set the attribute to value.
   1213     void SetAttribute( unsigned value );
   1214 	/// Set the attribute to value.
   1215 	void SetAttribute(int64_t value);
   1216 	/// Set the attribute to value.
   1217     void SetAttribute( bool value );
   1218     /// Set the attribute to value.
   1219     void SetAttribute( double value );
   1220     /// Set the attribute to value.
   1221     void SetAttribute( float value );
   1222 
   1223 private:
   1224     enum { BUF_SIZE = 200 };
   1225 
   1226     XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
   1227     virtual ~XMLAttribute()	{}
   1228 
   1229     XMLAttribute( const XMLAttribute& );	// not supported
   1230     void operator=( const XMLAttribute& );	// not supported
   1231     void SetName( const char* name );
   1232 
   1233     char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
   1234 
   1235     mutable StrPair _name;
   1236     mutable StrPair _value;
   1237     int             _parseLineNum;
   1238     XMLAttribute*   _next;
   1239     MemPool*        _memPool;
   1240 };
   1241 
   1242 
   1243 /** The element is a container class. It has a value, the element name,
   1244 	and can contain other elements, text, comments, and unknowns.
   1245 	Elements also contain an arbitrary number of attributes.
   1246 */
   1247 class TINYXML2_LIB XMLElement : public XMLNode
   1248 {
   1249     friend class XMLDocument;
   1250 public:
   1251     /// Get the name of an element (which is the Value() of the node.)
   1252     const char* Name() const		{
   1253         return Value();
   1254     }
   1255     /// Set the name of the element.
   1256     void SetName( const char* str, bool staticMem=false )	{
   1257         SetValue( str, staticMem );
   1258     }
   1259 
   1260     virtual XMLElement* ToElement()				{
   1261         return this;
   1262     }
   1263     virtual const XMLElement* ToElement() const {
   1264         return this;
   1265     }
   1266     virtual bool Accept( XMLVisitor* visitor ) const;
   1267 
   1268     /** Given an attribute name, Attribute() returns the value
   1269     	for the attribute of that name, or null if none
   1270     	exists. For example:
   1271 
   1272     	@verbatim
   1273     	const char* value = ele->Attribute( "foo" );
   1274     	@endverbatim
   1275 
   1276     	The 'value' parameter is normally null. However, if specified,
   1277     	the attribute will only be returned if the 'name' and 'value'
   1278     	match. This allow you to write code:
   1279 
   1280     	@verbatim
   1281     	if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
   1282     	@endverbatim
   1283 
   1284     	rather than:
   1285     	@verbatim
   1286     	if ( ele->Attribute( "foo" ) ) {
   1287     		if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
   1288     	}
   1289     	@endverbatim
   1290     */
   1291     const char* Attribute( const char* name, const char* value=0 ) const;
   1292 
   1293     /** Given an attribute name, IntAttribute() returns the value
   1294     	of the attribute interpreted as an integer. The default
   1295         value will be returned if the attribute isn't present,
   1296         or if there is an error. (For a method with error
   1297     	checking, see QueryIntAttribute()).
   1298     */
   1299 	int IntAttribute(const char* name, int defaultValue = 0) const;
   1300     /// See IntAttribute()
   1301 	unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
   1302 	/// See IntAttribute()
   1303 	int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
   1304 	/// See IntAttribute()
   1305 	bool BoolAttribute(const char* name, bool defaultValue = false) const;
   1306     /// See IntAttribute()
   1307 	double DoubleAttribute(const char* name, double defaultValue = 0) const;
   1308     /// See IntAttribute()
   1309 	float FloatAttribute(const char* name, float defaultValue = 0) const;
   1310 
   1311     /** Given an attribute name, QueryIntAttribute() returns
   1312     	XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
   1313     	can't be performed, or XML_NO_ATTRIBUTE if the attribute
   1314     	doesn't exist. If successful, the result of the conversion
   1315     	will be written to 'value'. If not successful, nothing will
   1316     	be written to 'value'. This allows you to provide default
   1317     	value:
   1318 
   1319     	@verbatim
   1320     	int value = 10;
   1321     	QueryIntAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
   1322     	@endverbatim
   1323     */
   1324     XMLError QueryIntAttribute( const char* name, int* value ) const				{
   1325         const XMLAttribute* a = FindAttribute( name );
   1326         if ( !a ) {
   1327             return XML_NO_ATTRIBUTE;
   1328         }
   1329         return a->QueryIntValue( value );
   1330     }
   1331 
   1332 	/// See QueryIntAttribute()
   1333     XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const	{
   1334         const XMLAttribute* a = FindAttribute( name );
   1335         if ( !a ) {
   1336             return XML_NO_ATTRIBUTE;
   1337         }
   1338         return a->QueryUnsignedValue( value );
   1339     }
   1340 
   1341 	/// See QueryIntAttribute()
   1342 	XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
   1343 		const XMLAttribute* a = FindAttribute(name);
   1344 		if (!a) {
   1345 			return XML_NO_ATTRIBUTE;
   1346 		}
   1347 		return a->QueryInt64Value(value);
   1348 	}
   1349 
   1350 	/// See QueryIntAttribute()
   1351     XMLError QueryBoolAttribute( const char* name, bool* value ) const				{
   1352         const XMLAttribute* a = FindAttribute( name );
   1353         if ( !a ) {
   1354             return XML_NO_ATTRIBUTE;
   1355         }
   1356         return a->QueryBoolValue( value );
   1357     }
   1358     /// See QueryIntAttribute()
   1359     XMLError QueryDoubleAttribute( const char* name, double* value ) const			{
   1360         const XMLAttribute* a = FindAttribute( name );
   1361         if ( !a ) {
   1362             return XML_NO_ATTRIBUTE;
   1363         }
   1364         return a->QueryDoubleValue( value );
   1365     }
   1366     /// See QueryIntAttribute()
   1367     XMLError QueryFloatAttribute( const char* name, float* value ) const			{
   1368         const XMLAttribute* a = FindAttribute( name );
   1369         if ( !a ) {
   1370             return XML_NO_ATTRIBUTE;
   1371         }
   1372         return a->QueryFloatValue( value );
   1373     }
   1374 
   1375 	/// See QueryIntAttribute()
   1376 	XMLError QueryStringAttribute(const char* name, const char** value) const {
   1377 		const XMLAttribute* a = FindAttribute(name);
   1378 		if (!a) {
   1379 			return XML_NO_ATTRIBUTE;
   1380 		}
   1381 		*value = a->Value();
   1382 		return XML_SUCCESS;
   1383 	}
   1384 
   1385 
   1386 
   1387     /** Given an attribute name, QueryAttribute() returns
   1388     	XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
   1389     	can't be performed, or XML_NO_ATTRIBUTE if the attribute
   1390     	doesn't exist. It is overloaded for the primitive types,
   1391 		and is a generally more convenient replacement of
   1392 		QueryIntAttribute() and related functions.
   1393 
   1394 		If successful, the result of the conversion
   1395     	will be written to 'value'. If not successful, nothing will
   1396     	be written to 'value'. This allows you to provide default
   1397     	value:
   1398 
   1399     	@verbatim
   1400     	int value = 10;
   1401     	QueryAttribute( "foo", &value );		// if "foo" isn't found, value will still be 10
   1402     	@endverbatim
   1403     */
   1404 	XMLError QueryAttribute( const char* name, int* value ) const {
   1405 		return QueryIntAttribute( name, value );
   1406 	}
   1407 
   1408 	XMLError QueryAttribute( const char* name, unsigned int* value ) const {
   1409 		return QueryUnsignedAttribute( name, value );
   1410 	}
   1411 
   1412 	XMLError QueryAttribute(const char* name, int64_t* value) const {
   1413 		return QueryInt64Attribute(name, value);
   1414 	}
   1415 
   1416 	XMLError QueryAttribute( const char* name, bool* value ) const {
   1417 		return QueryBoolAttribute( name, value );
   1418 	}
   1419 
   1420 	XMLError QueryAttribute( const char* name, double* value ) const {
   1421 		return QueryDoubleAttribute( name, value );
   1422 	}
   1423 
   1424 	XMLError QueryAttribute( const char* name, float* value ) const {
   1425 		return QueryFloatAttribute( name, value );
   1426 	}
   1427 
   1428 	/// Sets the named attribute to value.
   1429     void SetAttribute( const char* name, const char* value )	{
   1430         XMLAttribute* a = FindOrCreateAttribute( name );
   1431         a->SetAttribute( value );
   1432     }
   1433     /// Sets the named attribute to value.
   1434     void SetAttribute( const char* name, int value )			{
   1435         XMLAttribute* a = FindOrCreateAttribute( name );
   1436         a->SetAttribute( value );
   1437     }
   1438     /// Sets the named attribute to value.
   1439     void SetAttribute( const char* name, unsigned value )		{
   1440         XMLAttribute* a = FindOrCreateAttribute( name );
   1441         a->SetAttribute( value );
   1442     }
   1443 
   1444 	/// Sets the named attribute to value.
   1445 	void SetAttribute(const char* name, int64_t value) {
   1446 		XMLAttribute* a = FindOrCreateAttribute(name);
   1447 		a->SetAttribute(value);
   1448 	}
   1449 
   1450 	/// Sets the named attribute to value.
   1451     void SetAttribute( const char* name, bool value )			{
   1452         XMLAttribute* a = FindOrCreateAttribute( name );
   1453         a->SetAttribute( value );
   1454     }
   1455     /// Sets the named attribute to value.
   1456     void SetAttribute( const char* name, double value )		{
   1457         XMLAttribute* a = FindOrCreateAttribute( name );
   1458         a->SetAttribute( value );
   1459     }
   1460     /// Sets the named attribute to value.
   1461     void SetAttribute( const char* name, float value )		{
   1462         XMLAttribute* a = FindOrCreateAttribute( name );
   1463         a->SetAttribute( value );
   1464     }
   1465 
   1466     /**
   1467     	Delete an attribute.
   1468     */
   1469     void DeleteAttribute( const char* name );
   1470 
   1471     /// Return the first attribute in the list.
   1472     const XMLAttribute* FirstAttribute() const {
   1473         return _rootAttribute;
   1474     }
   1475     /// Query a specific attribute in the list.
   1476     const XMLAttribute* FindAttribute( const char* name ) const;
   1477 
   1478     /** Convenience function for easy access to the text inside an element. Although easy
   1479     	and concise, GetText() is limited compared to getting the XMLText child
   1480     	and accessing it directly.
   1481 
   1482     	If the first child of 'this' is a XMLText, the GetText()
   1483     	returns the character string of the Text node, else null is returned.
   1484 
   1485     	This is a convenient method for getting the text of simple contained text:
   1486     	@verbatim
   1487     	<foo>This is text</foo>
   1488     		const char* str = fooElement->GetText();
   1489     	@endverbatim
   1490 
   1491     	'str' will be a pointer to "This is text".
   1492 
   1493     	Note that this function can be misleading. If the element foo was created from
   1494     	this XML:
   1495     	@verbatim
   1496     		<foo><b>This is text</b></foo>
   1497     	@endverbatim
   1498 
   1499     	then the value of str would be null. The first child node isn't a text node, it is
   1500     	another element. From this XML:
   1501     	@verbatim
   1502     		<foo>This is <b>text</b></foo>
   1503     	@endverbatim
   1504     	GetText() will return "This is ".
   1505     */
   1506     const char* GetText() const;
   1507 
   1508     /** Convenience function for easy access to the text inside an element. Although easy
   1509     	and concise, SetText() is limited compared to creating an XMLText child
   1510     	and mutating it directly.
   1511 
   1512     	If the first child of 'this' is a XMLText, SetText() sets its value to
   1513 		the given string, otherwise it will create a first child that is an XMLText.
   1514 
   1515     	This is a convenient method for setting the text of simple contained text:
   1516     	@verbatim
   1517     	<foo>This is text</foo>
   1518     		fooElement->SetText( "Hullaballoo!" );
   1519      	<foo>Hullaballoo!</foo>
   1520 		@endverbatim
   1521 
   1522     	Note that this function can be misleading. If the element foo was created from
   1523     	this XML:
   1524     	@verbatim
   1525     		<foo><b>This is text</b></foo>
   1526     	@endverbatim
   1527 
   1528     	then it will not change "This is text", but rather prefix it with a text element:
   1529     	@verbatim
   1530     		<foo>Hullaballoo!<b>This is text</b></foo>
   1531     	@endverbatim
   1532 
   1533 		For this XML:
   1534     	@verbatim
   1535     		<foo />
   1536     	@endverbatim
   1537     	SetText() will generate
   1538     	@verbatim
   1539     		<foo>Hullaballoo!</foo>
   1540     	@endverbatim
   1541     */
   1542 	void SetText( const char* inText );
   1543     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1544     void SetText( int value );
   1545     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1546     void SetText( unsigned value );
   1547 	/// Convenience method for setting text inside an element. See SetText() for important limitations.
   1548 	void SetText(int64_t value);
   1549 	/// Convenience method for setting text inside an element. See SetText() for important limitations.
   1550     void SetText( bool value );
   1551     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1552     void SetText( double value );
   1553     /// Convenience method for setting text inside an element. See SetText() for important limitations.
   1554     void SetText( float value );
   1555 
   1556     /**
   1557     	Convenience method to query the value of a child text node. This is probably best
   1558     	shown by example. Given you have a document is this form:
   1559     	@verbatim
   1560     		<point>
   1561     			<x>1</x>
   1562     			<y>1.4</y>
   1563     		</point>
   1564     	@endverbatim
   1565 
   1566     	The QueryIntText() and similar functions provide a safe and easier way to get to the
   1567     	"value" of x and y.
   1568 
   1569     	@verbatim
   1570     		int x = 0;
   1571     		float y = 0;	// types of x and y are contrived for example
   1572     		const XMLElement* xElement = pointElement->FirstChildElement( "x" );
   1573     		const XMLElement* yElement = pointElement->FirstChildElement( "y" );
   1574     		xElement->QueryIntText( &x );
   1575     		yElement->QueryFloatText( &y );
   1576     	@endverbatim
   1577 
   1578     	@returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
   1579     			 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
   1580 
   1581     */
   1582     XMLError QueryIntText( int* ival ) const;
   1583     /// See QueryIntText()
   1584     XMLError QueryUnsignedText( unsigned* uval ) const;
   1585 	/// See QueryIntText()
   1586 	XMLError QueryInt64Text(int64_t* uval) const;
   1587 	/// See QueryIntText()
   1588     XMLError QueryBoolText( bool* bval ) const;
   1589     /// See QueryIntText()
   1590     XMLError QueryDoubleText( double* dval ) const;
   1591     /// See QueryIntText()
   1592     XMLError QueryFloatText( float* fval ) const;
   1593 
   1594 	int IntText(int defaultValue = 0) const;
   1595 
   1596 	/// See QueryIntText()
   1597 	unsigned UnsignedText(unsigned defaultValue = 0) const;
   1598 	/// See QueryIntText()
   1599 	int64_t Int64Text(int64_t defaultValue = 0) const;
   1600 	/// See QueryIntText()
   1601 	bool BoolText(bool defaultValue = false) const;
   1602 	/// See QueryIntText()
   1603 	double DoubleText(double defaultValue = 0) const;
   1604 	/// See QueryIntText()
   1605 	float FloatText(float defaultValue = 0) const;
   1606 
   1607     // internal:
   1608     enum ElementClosingType {
   1609         OPEN,		// <foo>
   1610         CLOSED,		// <foo/>
   1611         CLOSING		// </foo>
   1612     };
   1613     ElementClosingType ClosingType() const {
   1614         return _closingType;
   1615     }
   1616     virtual XMLNode* ShallowClone( XMLDocument* document ) const;
   1617     virtual bool ShallowEqual( const XMLNode* compare ) const;
   1618 
   1619 protected:
   1620     char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
   1621 
   1622 private:
   1623     XMLElement( XMLDocument* doc );
   1624     virtual ~XMLElement();
   1625     XMLElement( const XMLElement& );	// not supported
   1626     void operator=( const XMLElement& );	// not supported
   1627 
   1628     XMLAttribute* FindOrCreateAttribute( const char* name );
   1629     char* ParseAttributes( char* p, int* curLineNumPtr );
   1630     static void DeleteAttribute( XMLAttribute* attribute );
   1631     XMLAttribute* CreateAttribute();
   1632 
   1633     enum { BUF_SIZE = 200 };
   1634     ElementClosingType _closingType;
   1635     // The attribute list is ordered; there is no 'lastAttribute'
   1636     // because the list needs to be scanned for dupes before adding
   1637     // a new attribute.
   1638     XMLAttribute* _rootAttribute;
   1639 };
   1640 
   1641 
   1642 enum Whitespace {
   1643     PRESERVE_WHITESPACE,
   1644     COLLAPSE_WHITESPACE
   1645 };
   1646 
   1647 
   1648 /** A Document binds together all the functionality.
   1649 	It can be saved, loaded, and printed to the screen.
   1650 	All Nodes are connected and allocated to a Document.
   1651 	If the Document is deleted, all its Nodes are also deleted.
   1652 */
   1653 class TINYXML2_LIB XMLDocument : public XMLNode
   1654 {
   1655     friend class XMLElement;
   1656     // Gives access to SetError and Push/PopDepth, but over-access for everything else.
   1657     // Wishing C++ had "internal" scope.
   1658     friend class XMLNode;
   1659     friend class XMLText;
   1660     friend class XMLComment;
   1661     friend class XMLDeclaration;
   1662     friend class XMLUnknown;
   1663 public:
   1664     /// constructor
   1665     XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
   1666     ~XMLDocument();
   1667 
   1668     virtual XMLDocument* ToDocument()				{
   1669         TIXMLASSERT( this == _document );
   1670         return this;
   1671     }
   1672     virtual const XMLDocument* ToDocument() const	{
   1673         TIXMLASSERT( this == _document );
   1674         return this;
   1675     }
   1676 
   1677     /**
   1678     	Parse an XML file from a character string.
   1679     	Returns XML_SUCCESS (0) on success, or
   1680     	an errorID.
   1681 
   1682     	You may optionally pass in the 'nBytes', which is
   1683     	the number of bytes which will be parsed. If not
   1684     	specified, TinyXML-2 will assume 'xml' points to a
   1685     	null terminated string.
   1686     */
   1687     XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
   1688 
   1689     /**
   1690     	Load an XML file from disk.
   1691     	Returns XML_SUCCESS (0) on success, or
   1692     	an errorID.
   1693     */
   1694     XMLError LoadFile( const char* filename );
   1695 
   1696     /**
   1697     	Load an XML file from disk. You are responsible
   1698     	for providing and closing the FILE*.
   1699 
   1700         NOTE: The file should be opened as binary ("rb")
   1701         not text in order for TinyXML-2 to correctly
   1702         do newline normalization.
   1703 
   1704     	Returns XML_SUCCESS (0) on success, or
   1705     	an errorID.
   1706     */
   1707     XMLError LoadFile( FILE* );
   1708 
   1709     /**
   1710     	Save the XML file to disk.
   1711     	Returns XML_SUCCESS (0) on success, or
   1712     	an errorID.
   1713     */
   1714     XMLError SaveFile( const char* filename, bool compact = false );
   1715 
   1716     /**
   1717     	Save the XML file to disk. You are responsible
   1718     	for providing and closing the FILE*.
   1719 
   1720     	Returns XML_SUCCESS (0) on success, or
   1721     	an errorID.
   1722     */
   1723     XMLError SaveFile( FILE* fp, bool compact = false );
   1724 
   1725     bool ProcessEntities() const		{
   1726         return _processEntities;
   1727     }
   1728     Whitespace WhitespaceMode() const	{
   1729         return _whitespaceMode;
   1730     }
   1731 
   1732     /**
   1733     	Returns true if this document has a leading Byte Order Mark of UTF8.
   1734     */
   1735     bool HasBOM() const {
   1736         return _writeBOM;
   1737     }
   1738     /** Sets whether to write the BOM when writing the file.
   1739     */
   1740     void SetBOM( bool useBOM ) {
   1741         _writeBOM = useBOM;
   1742     }
   1743 
   1744     /** Return the root element of DOM. Equivalent to FirstChildElement().
   1745         To get the first node, use FirstChild().
   1746     */
   1747     XMLElement* RootElement()				{
   1748         return FirstChildElement();
   1749     }
   1750     const XMLElement* RootElement() const	{
   1751         return FirstChildElement();
   1752     }
   1753 
   1754     /** Print the Document. If the Printer is not provided, it will
   1755         print to stdout. If you provide Printer, this can print to a file:
   1756     	@verbatim
   1757     	XMLPrinter printer( fp );
   1758     	doc.Print( &printer );
   1759     	@endverbatim
   1760 
   1761     	Or you can use a printer to print to memory:
   1762     	@verbatim
   1763     	XMLPrinter printer;
   1764     	doc.Print( &printer );
   1765     	// printer.CStr() has a const char* to the XML
   1766     	@endverbatim
   1767     */
   1768     void Print( XMLPrinter* streamer=0 ) const;
   1769     virtual bool Accept( XMLVisitor* visitor ) const;
   1770 
   1771     /**
   1772     	Create a new Element associated with
   1773     	this Document. The memory for the Element
   1774     	is managed by the Document.
   1775     */
   1776     XMLElement* NewElement( const char* name );
   1777     /**
   1778     	Create a new Comment associated with
   1779     	this Document. The memory for the Comment
   1780     	is managed by the Document.
   1781     */
   1782     XMLComment* NewComment( const char* comment );
   1783     /**
   1784     	Create a new Text associated with
   1785     	this Document. The memory for the Text
   1786     	is managed by the Document.
   1787     */
   1788     XMLText* NewText( const char* text );
   1789     /**
   1790     	Create a new Declaration associated with
   1791     	this Document. The memory for the object
   1792     	is managed by the Document.
   1793 
   1794     	If the 'text' param is null, the standard
   1795     	declaration is used.:
   1796     	@verbatim
   1797     		<?xml version="1.0" encoding="UTF-8"?>
   1798     	@endverbatim
   1799     */
   1800     XMLDeclaration* NewDeclaration( const char* text=0 );
   1801     /**
   1802     	Create a new Unknown associated with
   1803     	this Document. The memory for the object
   1804     	is managed by the Document.
   1805     */
   1806     XMLUnknown* NewUnknown( const char* text );
   1807 
   1808     /**
   1809     	Delete a node associated with this document.
   1810     	It will be unlinked from the DOM.
   1811     */
   1812     void DeleteNode( XMLNode* node );
   1813 
   1814     void ClearError() {
   1815         SetError(XML_SUCCESS, 0, 0);
   1816     }
   1817 
   1818     /// Return true if there was an error parsing the document.
   1819     bool Error() const {
   1820         return _errorID != XML_SUCCESS;
   1821     }
   1822     /// Return the errorID.
   1823     XMLError  ErrorID() const {
   1824         return _errorID;
   1825     }
   1826 	const char* ErrorName() const;
   1827     static const char* ErrorIDToName(XMLError errorID);
   1828 
   1829     /** Returns a "long form" error description. A hopefully helpful
   1830         diagnostic with location, line number, and/or additional info.
   1831     */
   1832 	const char* ErrorStr() const;
   1833 
   1834     /// A (trivial) utility function that prints the ErrorStr() to stdout.
   1835     void PrintError() const;
   1836 
   1837     /// Return the line where the error occurred, or zero if unknown.
   1838     int ErrorLineNum() const
   1839     {
   1840         return _errorLineNum;
   1841     }
   1842 
   1843     /// Clear the document, resetting it to the initial state.
   1844     void Clear();
   1845 
   1846 	/**
   1847 		Copies this document to a target document.
   1848 		The target will be completely cleared before the copy.
   1849 		If you want to copy a sub-tree, see XMLNode::DeepClone().
   1850 
   1851 		NOTE: that the 'target' must be non-null.
   1852 	*/
   1853 	void DeepCopy(XMLDocument* target) const;
   1854 
   1855 	// internal
   1856     char* Identify( char* p, XMLNode** node );
   1857 
   1858 	// internal
   1859 	void MarkInUse(XMLNode*);
   1860 
   1861     virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const	{
   1862         return 0;
   1863     }
   1864     virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const	{
   1865         return false;
   1866     }
   1867 
   1868 private:
   1869     XMLDocument( const XMLDocument& );	// not supported
   1870     void operator=( const XMLDocument& );	// not supported
   1871 
   1872     bool			_writeBOM;
   1873     bool			_processEntities;
   1874     XMLError		_errorID;
   1875     Whitespace		_whitespaceMode;
   1876     mutable StrPair	_errorStr;
   1877     int             _errorLineNum;
   1878     char*			_charBuffer;
   1879     int				_parseCurLineNum;
   1880 	int				_parsingDepth;
   1881 	// Memory tracking does add some overhead.
   1882 	// However, the code assumes that you don't
   1883 	// have a bunch of unlinked nodes around.
   1884 	// Therefore it takes less memory to track
   1885 	// in the document vs. a linked list in the XMLNode,
   1886 	// and the performance is the same.
   1887 	DynArray<XMLNode*, 10> _unlinked;
   1888 
   1889     MemPoolT< sizeof(XMLElement) >	 _elementPool;
   1890     MemPoolT< sizeof(XMLAttribute) > _attributePool;
   1891     MemPoolT< sizeof(XMLText) >		 _textPool;
   1892     MemPoolT< sizeof(XMLComment) >	 _commentPool;
   1893 
   1894 	static const char* _errorNames[XML_ERROR_COUNT];
   1895 
   1896     void Parse();
   1897 
   1898     void SetError( XMLError error, int lineNum, const char* format, ... );
   1899 
   1900 	// Something of an obvious security hole, once it was discovered.
   1901 	// Either an ill-formed XML or an excessively deep one can overflow
   1902 	// the stack. Track stack depth, and error out if needed.
   1903 	class DepthTracker {
   1904 	public:
   1905 		explicit DepthTracker(XMLDocument * document) {
   1906 			this->_document = document;
   1907 			document->PushDepth();
   1908 		}
   1909 		~DepthTracker() {
   1910 			_document->PopDepth();
   1911 		}
   1912 	private:
   1913 		XMLDocument * _document;
   1914 	};
   1915 	void PushDepth();
   1916 	void PopDepth();
   1917 
   1918     template<class NodeType, int PoolElementSize>
   1919     NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
   1920 };
   1921 
   1922 template<class NodeType, int PoolElementSize>
   1923 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
   1924 {
   1925     TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
   1926     TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
   1927     NodeType* returnNode = new (pool.Alloc()) NodeType( this );
   1928     TIXMLASSERT( returnNode );
   1929     returnNode->_memPool = &pool;
   1930 
   1931 	_unlinked.Push(returnNode);
   1932     return returnNode;
   1933 }
   1934 
   1935 /**
   1936 	A XMLHandle is a class that wraps a node pointer with null checks; this is
   1937 	an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
   1938 	DOM structure. It is a separate utility class.
   1939 
   1940 	Take an example:
   1941 	@verbatim
   1942 	<Document>
   1943 		<Element attributeA = "valueA">
   1944 			<Child attributeB = "value1" />
   1945 			<Child attributeB = "value2" />
   1946 		</Element>
   1947 	</Document>
   1948 	@endverbatim
   1949 
   1950 	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
   1951 	easy to write a *lot* of code that looks like:
   1952 
   1953 	@verbatim
   1954 	XMLElement* root = document.FirstChildElement( "Document" );
   1955 	if ( root )
   1956 	{
   1957 		XMLElement* element = root->FirstChildElement( "Element" );
   1958 		if ( element )
   1959 		{
   1960 			XMLElement* child = element->FirstChildElement( "Child" );
   1961 			if ( child )
   1962 			{
   1963 				XMLElement* child2 = child->NextSiblingElement( "Child" );
   1964 				if ( child2 )
   1965 				{
   1966 					// Finally do something useful.
   1967 	@endverbatim
   1968 
   1969 	And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
   1970 	of such code. A XMLHandle checks for null pointers so it is perfectly safe
   1971 	and correct to use:
   1972 
   1973 	@verbatim
   1974 	XMLHandle docHandle( &document );
   1975 	XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
   1976 	if ( child2 )
   1977 	{
   1978 		// do something useful
   1979 	@endverbatim
   1980 
   1981 	Which is MUCH more concise and useful.
   1982 
   1983 	It is also safe to copy handles - internally they are nothing more than node pointers.
   1984 	@verbatim
   1985 	XMLHandle handleCopy = handle;
   1986 	@endverbatim
   1987 
   1988 	See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
   1989 */
   1990 class TINYXML2_LIB XMLHandle
   1991 {
   1992 public:
   1993     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
   1994     explicit XMLHandle( XMLNode* node ) : _node( node ) {
   1995     }
   1996     /// Create a handle from a node.
   1997     explicit XMLHandle( XMLNode& node ) : _node( &node ) {
   1998     }
   1999     /// Copy constructor
   2000     XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
   2001     }
   2002     /// Assignment
   2003     XMLHandle& operator=( const XMLHandle& ref )							{
   2004         _node = ref._node;
   2005         return *this;
   2006     }
   2007 
   2008     /// Get the first child of this handle.
   2009     XMLHandle FirstChild() 													{
   2010         return XMLHandle( _node ? _node->FirstChild() : 0 );
   2011     }
   2012     /// Get the first child element of this handle.
   2013     XMLHandle FirstChildElement( const char* name = 0 )						{
   2014         return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
   2015     }
   2016     /// Get the last child of this handle.
   2017     XMLHandle LastChild()													{
   2018         return XMLHandle( _node ? _node->LastChild() : 0 );
   2019     }
   2020     /// Get the last child element of this handle.
   2021     XMLHandle LastChildElement( const char* name = 0 )						{
   2022         return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
   2023     }
   2024     /// Get the previous sibling of this handle.
   2025     XMLHandle PreviousSibling()												{
   2026         return XMLHandle( _node ? _node->PreviousSibling() : 0 );
   2027     }
   2028     /// Get the previous sibling element of this handle.
   2029     XMLHandle PreviousSiblingElement( const char* name = 0 )				{
   2030         return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
   2031     }
   2032     /// Get the next sibling of this handle.
   2033     XMLHandle NextSibling()													{
   2034         return XMLHandle( _node ? _node->NextSibling() : 0 );
   2035     }
   2036     /// Get the next sibling element of this handle.
   2037     XMLHandle NextSiblingElement( const char* name = 0 )					{
   2038         return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
   2039     }
   2040 
   2041     /// Safe cast to XMLNode. This can return null.
   2042     XMLNode* ToNode()							{
   2043         return _node;
   2044     }
   2045     /// Safe cast to XMLElement. This can return null.
   2046     XMLElement* ToElement() 					{
   2047         return ( _node ? _node->ToElement() : 0 );
   2048     }
   2049     /// Safe cast to XMLText. This can return null.
   2050     XMLText* ToText() 							{
   2051         return ( _node ? _node->ToText() : 0 );
   2052     }
   2053     /// Safe cast to XMLUnknown. This can return null.
   2054     XMLUnknown* ToUnknown() 					{
   2055         return ( _node ? _node->ToUnknown() : 0 );
   2056     }
   2057     /// Safe cast to XMLDeclaration. This can return null.
   2058     XMLDeclaration* ToDeclaration() 			{
   2059         return ( _node ? _node->ToDeclaration() : 0 );
   2060     }
   2061 
   2062 private:
   2063     XMLNode* _node;
   2064 };
   2065 
   2066 
   2067 /**
   2068 	A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
   2069 	same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
   2070 */
   2071 class TINYXML2_LIB XMLConstHandle
   2072 {
   2073 public:
   2074     explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
   2075     }
   2076     explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
   2077     }
   2078     XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
   2079     }
   2080 
   2081     XMLConstHandle& operator=( const XMLConstHandle& ref )							{
   2082         _node = ref._node;
   2083         return *this;
   2084     }
   2085 
   2086     const XMLConstHandle FirstChild() const											{
   2087         return XMLConstHandle( _node ? _node->FirstChild() : 0 );
   2088     }
   2089     const XMLConstHandle FirstChildElement( const char* name = 0 ) const				{
   2090         return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
   2091     }
   2092     const XMLConstHandle LastChild()	const										{
   2093         return XMLConstHandle( _node ? _node->LastChild() : 0 );
   2094     }
   2095     const XMLConstHandle LastChildElement( const char* name = 0 ) const				{
   2096         return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
   2097     }
   2098     const XMLConstHandle PreviousSibling() const									{
   2099         return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
   2100     }
   2101     const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const		{
   2102         return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
   2103     }
   2104     const XMLConstHandle NextSibling() const										{
   2105         return XMLConstHandle( _node ? _node->NextSibling() : 0 );
   2106     }
   2107     const XMLConstHandle NextSiblingElement( const char* name = 0 ) const			{
   2108         return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
   2109     }
   2110 
   2111 
   2112     const XMLNode* ToNode() const				{
   2113         return _node;
   2114     }
   2115     const XMLElement* ToElement() const			{
   2116         return ( _node ? _node->ToElement() : 0 );
   2117     }
   2118     const XMLText* ToText() const				{
   2119         return ( _node ? _node->ToText() : 0 );
   2120     }
   2121     const XMLUnknown* ToUnknown() const			{
   2122         return ( _node ? _node->ToUnknown() : 0 );
   2123     }
   2124     const XMLDeclaration* ToDeclaration() const	{
   2125         return ( _node ? _node->ToDeclaration() : 0 );
   2126     }
   2127 
   2128 private:
   2129     const XMLNode* _node;
   2130 };
   2131 
   2132 
   2133 /**
   2134 	Printing functionality. The XMLPrinter gives you more
   2135 	options than the XMLDocument::Print() method.
   2136 
   2137 	It can:
   2138 	-# Print to memory.
   2139 	-# Print to a file you provide.
   2140 	-# Print XML without a XMLDocument.
   2141 
   2142 	Print to Memory
   2143 
   2144 	@verbatim
   2145 	XMLPrinter printer;
   2146 	doc.Print( &printer );
   2147 	SomeFunction( printer.CStr() );
   2148 	@endverbatim
   2149 
   2150 	Print to a File
   2151 
   2152 	You provide the file pointer.
   2153 	@verbatim
   2154 	XMLPrinter printer( fp );
   2155 	doc.Print( &printer );
   2156 	@endverbatim
   2157 
   2158 	Print without a XMLDocument
   2159 
   2160 	When loading, an XML parser is very useful. However, sometimes
   2161 	when saving, it just gets in the way. The code is often set up
   2162 	for streaming, and constructing the DOM is just overhead.
   2163 
   2164 	The Printer supports the streaming case. The following code
   2165 	prints out a trivially simple XML file without ever creating
   2166 	an XML document.
   2167 
   2168 	@verbatim
   2169 	XMLPrinter printer( fp );
   2170 	printer.OpenElement( "foo" );
   2171 	printer.PushAttribute( "foo", "bar" );
   2172 	printer.CloseElement();
   2173 	@endverbatim
   2174 */
   2175 class TINYXML2_LIB XMLPrinter : public XMLVisitor
   2176 {
   2177 public:
   2178     /** Construct the printer. If the FILE* is specified,
   2179     	this will print to the FILE. Else it will print
   2180     	to memory, and the result is available in CStr().
   2181     	If 'compact' is set to true, then output is created
   2182     	with only required whitespace and newlines.
   2183     */
   2184     XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
   2185     virtual ~XMLPrinter()	{}
   2186 
   2187     /** If streaming, write the BOM and declaration. */
   2188     void PushHeader( bool writeBOM, bool writeDeclaration );
   2189     /** If streaming, start writing an element.
   2190         The element must be closed with CloseElement()
   2191     */
   2192     void OpenElement( const char* name, bool compactMode=false );
   2193     /// If streaming, add an attribute to an open element.
   2194     void PushAttribute( const char* name, const char* value );
   2195     void PushAttribute( const char* name, int value );
   2196     void PushAttribute( const char* name, unsigned value );
   2197 	void PushAttribute(const char* name, int64_t value);
   2198 	void PushAttribute( const char* name, bool value );
   2199     void PushAttribute( const char* name, double value );
   2200     /// If streaming, close the Element.
   2201     virtual void CloseElement( bool compactMode=false );
   2202 
   2203     /// Add a text node.
   2204     void PushText( const char* text, bool cdata=false );
   2205     /// Add a text node from an integer.
   2206     void PushText( int value );
   2207     /// Add a text node from an unsigned.
   2208     void PushText( unsigned value );
   2209 	/// Add a text node from an unsigned.
   2210 	void PushText(int64_t value);
   2211 	/// Add a text node from a bool.
   2212     void PushText( bool value );
   2213     /// Add a text node from a float.
   2214     void PushText( float value );
   2215     /// Add a text node from a double.
   2216     void PushText( double value );
   2217 
   2218     /// Add a comment
   2219     void PushComment( const char* comment );
   2220 
   2221     void PushDeclaration( const char* value );
   2222     void PushUnknown( const char* value );
   2223 
   2224     virtual bool VisitEnter( const XMLDocument& /*doc*/ );
   2225     virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
   2226         return true;
   2227     }
   2228 
   2229     virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
   2230     virtual bool VisitExit( const XMLElement& element );
   2231 
   2232     virtual bool Visit( const XMLText& text );
   2233     virtual bool Visit( const XMLComment& comment );
   2234     virtual bool Visit( const XMLDeclaration& declaration );
   2235     virtual bool Visit( const XMLUnknown& unknown );
   2236 
   2237     /**
   2238     	If in print to memory mode, return a pointer to
   2239     	the XML file in memory.
   2240     */
   2241     const char* CStr() const {
   2242         return _buffer.Mem();
   2243     }
   2244     /**
   2245     	If in print to memory mode, return the size
   2246     	of the XML file in memory. (Note the size returned
   2247     	includes the terminating null.)
   2248     */
   2249     int CStrSize() const {
   2250         return _buffer.Size();
   2251     }
   2252     /**
   2253     	If in print to memory mode, reset the buffer to the
   2254     	beginning.
   2255     */
   2256     void ClearBuffer() {
   2257         _buffer.Clear();
   2258         _buffer.Push(0);
   2259 		_firstElement = true;
   2260     }
   2261 
   2262 protected:
   2263 	virtual bool CompactMode( const XMLElement& )	{ return _compactMode; }
   2264 
   2265 	/** Prints out the space before an element. You may override to change
   2266 	    the space and tabs used. A PrintSpace() override should call Print().
   2267 	*/
   2268     virtual void PrintSpace( int depth );
   2269     void Print( const char* format, ... );
   2270     void Write( const char* data, size_t size );
   2271     inline void Write( const char* data )           { Write( data, strlen( data ) ); }
   2272     void Putc( char ch );
   2273 
   2274     void SealElementIfJustOpened();
   2275     bool _elementJustOpened;
   2276     DynArray< const char*, 10 > _stack;
   2277 
   2278 private:
   2279     void PrintString( const char*, bool restrictedEntitySet );	// prints out, after detecting entities.
   2280 
   2281     bool _firstElement;
   2282     FILE* _fp;
   2283     int _depth;
   2284     int _textDepth;
   2285     bool _processEntities;
   2286 	bool _compactMode;
   2287 
   2288     enum {
   2289         ENTITY_RANGE = 64,
   2290         BUF_SIZE = 200
   2291     };
   2292     bool _entityFlag[ENTITY_RANGE];
   2293     bool _restrictedEntityFlag[ENTITY_RANGE];
   2294 
   2295     DynArray< char, 20 > _buffer;
   2296 
   2297     // Prohibit cloning, intentionally not implemented
   2298     XMLPrinter( const XMLPrinter& );
   2299     XMLPrinter& operator=( const XMLPrinter& );
   2300 };
   2301 
   2302 
   2303 }	// tinyxml2
   2304 
   2305 #if defined(_MSC_VER)
   2306 #   pragma warning(pop)
   2307 #endif
   2308 
   2309 #endif // TINYXML2_INCLUDED
   2310