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