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