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