TinyXML-2  11.0.0
tinyxml2.h
1 /*
2 Original code by Lee Thomason (www.grinninglizard.com)
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any
6 damages arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any
9 purpose, including commercial applications, and to alter it and
10 redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must
13 not claim that you wrote the original software. If you use this
14 software in a product, an acknowledgment in the product documentation
15 would be appreciated but is not required.
16 
17 2. Altered source versions must be plainly marked as such, and
18 must not be misrepresented as being the original software.
19 
20 3. This notice may not be removed or altered from any source
21 distribution.
22 */
23 
24 #ifndef TINYXML2_INCLUDED
25 #define TINYXML2_INCLUDED
26 
27 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
28 # include <ctype.h>
29 # include <limits.h>
30 # include <stdio.h>
31 # include <stdlib.h>
32 # include <string.h>
33 # if defined(__PS3__)
34 # include <stddef.h>
35 # endif
36 #else
37 # include <cctype>
38 # include <climits>
39 # include <cstdio>
40 # include <cstdlib>
41 # include <cstring>
42 #endif
43 #include <stdint.h>
44 
45 /*
46  gcc:
47  g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
48 
49  Formatting, Artistic Style:
50  AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
51 */
52 
53 #if defined( _DEBUG ) || defined (__DEBUG__)
54 # ifndef TINYXML2_DEBUG
55 # define TINYXML2_DEBUG
56 # endif
57 #endif
58 
59 #ifdef _MSC_VER
60 # pragma warning(push)
61 # pragma warning(disable: 4251)
62 #endif
63 
64 #ifdef _MSC_VER
65 # ifdef TINYXML2_EXPORT
66 # define TINYXML2_LIB __declspec(dllexport)
67 # elif defined(TINYXML2_IMPORT)
68 # define TINYXML2_LIB __declspec(dllimport)
69 # else
70 # define TINYXML2_LIB
71 # endif
72 #elif __GNUC__ >= 4
73 # define TINYXML2_LIB __attribute__((visibility("default")))
74 #else
75 # define TINYXML2_LIB
76 #endif
77 
78 
79 #if !defined(TIXMLASSERT)
80 #if defined(TINYXML2_DEBUG)
81 # if defined(_MSC_VER)
82 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
83 # define TIXMLASSERT( x ) do { if ( !((void)0,(x))) { __debugbreak(); } } while(false)
84 # elif defined (ANDROID_NDK)
85 # include <android/log.h>
86 # define TIXMLASSERT( x ) do { if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } } while(false)
87 # else
88 # include <assert.h>
89 # define TIXMLASSERT assert
90 # endif
91 #else
92 # define TIXMLASSERT( x ) do {} while(false)
93 #endif
94 #endif
95 
96 /* Versioning, past 1.0.14:
97  http://semver.org/
98 */
99 static const int TIXML2_MAJOR_VERSION = 11;
100 static const int TIXML2_MINOR_VERSION = 0;
101 static const int TIXML2_PATCH_VERSION = 0;
102 
103 #define TINYXML2_MAJOR_VERSION 11
104 #define TINYXML2_MINOR_VERSION 0
105 #define TINYXML2_PATCH_VERSION 0
106 
107 // A fixed element depth limit is problematic. There needs to be a
108 // limit to avoid a stack overflow. However, that limit varies per
109 // system, and the capacity of the stack. On the other hand, it's a trivial
110 // attack that can result from ill, malicious, or even correctly formed XML,
111 // so there needs to be a limit in place.
112 static const int TINYXML2_MAX_ELEMENT_DEPTH = 500;
113 
114 namespace tinyxml2
115 {
116 class XMLDocument;
117 class XMLElement;
118 class XMLAttribute;
119 class XMLComment;
120 class XMLText;
121 class XMLDeclaration;
122 class XMLUnknown;
123 class XMLPrinter;
124 
125 /*
126  A class that wraps strings. Normally stores the start and end
127  pointers into the XML file itself, and will apply normalization
128  and entity translation if actually read. Can also store (and memory
129  manage) a traditional char[]
130 
131  Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
132 */
133 class TINYXML2_LIB StrPair
134 {
135 public:
136  enum Mode {
137  NEEDS_ENTITY_PROCESSING = 0x01,
138  NEEDS_NEWLINE_NORMALIZATION = 0x02,
139  NEEDS_WHITESPACE_COLLAPSING = 0x04,
140 
141  TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
142  TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
143  ATTRIBUTE_NAME = 0,
144  ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
145  ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
146  COMMENT = NEEDS_NEWLINE_NORMALIZATION
147  };
148 
149  StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
150  ~StrPair();
151 
152  void Set( char* start, char* end, int flags ) {
153  TIXMLASSERT( start );
154  TIXMLASSERT( end );
155  Reset();
156  _start = start;
157  _end = end;
158  _flags = flags | NEEDS_FLUSH;
159  }
160 
161  const char* GetStr();
162 
163  bool Empty() const {
164  return _start == _end;
165  }
166 
167  void SetInternedStr( const char* str ) {
168  Reset();
169  _start = const_cast<char*>(str);
170  }
171 
172  void SetStr( const char* str, int flags=0 );
173 
174  char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
175  char* ParseName( char* in );
176 
177  void TransferTo( StrPair* other );
178  void Reset();
179 
180 private:
181  void CollapseWhitespace();
182 
183  enum {
184  NEEDS_FLUSH = 0x100,
185  NEEDS_DELETE = 0x200
186  };
187 
188  int _flags;
189  char* _start;
190  char* _end;
191 
192  StrPair( const StrPair& other ); // not supported
193  void operator=( const StrPair& other ); // not supported, use TransferTo()
194 };
195 
196 
197 /*
198  A dynamic array of Plain Old Data. Doesn't support constructors, etc.
199  Has a small initial memory pool, so that low or no usage will not
200  cause a call to new/delete
201 */
202 template <class T, size_t INITIAL_SIZE>
203 class DynArray
204 {
205 public:
206  DynArray() :
207  _mem( _pool ),
208  _allocated( INITIAL_SIZE ),
209  _size( 0 )
210  {
211  }
212 
213  ~DynArray() {
214  if ( _mem != _pool ) {
215  delete [] _mem;
216  }
217  }
218 
219  void Clear() {
220  _size = 0;
221  }
222 
223  void Push( T t ) {
224  TIXMLASSERT( _size < INT_MAX );
225  EnsureCapacity( _size+1 );
226  _mem[_size] = t;
227  ++_size;
228  }
229 
230  T* PushArr( size_t count ) {
231  TIXMLASSERT( _size <= SIZE_MAX - count );
232  EnsureCapacity( _size+count );
233  T* ret = &_mem[_size];
234  _size += count;
235  return ret;
236  }
237 
238  T Pop() {
239  TIXMLASSERT( _size > 0 );
240  --_size;
241  return _mem[_size];
242  }
243 
244  void PopArr( size_t count ) {
245  TIXMLASSERT( _size >= count );
246  _size -= count;
247  }
248 
249  bool Empty() const {
250  return _size == 0;
251  }
252 
253  T& operator[](size_t i) {
254  TIXMLASSERT( i < _size );
255  return _mem[i];
256  }
257 
258  const T& operator[](size_t i) const {
259  TIXMLASSERT( i < _size );
260  return _mem[i];
261  }
262 
263  const T& PeekTop() const {
264  TIXMLASSERT( _size > 0 );
265  return _mem[ _size - 1];
266  }
267 
268  size_t Size() const {
269  TIXMLASSERT( _size >= 0 );
270  return _size;
271  }
272 
273  size_t Capacity() const {
274  TIXMLASSERT( _allocated >= INITIAL_SIZE );
275  return _allocated;
276  }
277 
278  void SwapRemove(size_t i) {
279  TIXMLASSERT(i < _size);
280  TIXMLASSERT(_size > 0);
281  _mem[i] = _mem[_size - 1];
282  --_size;
283  }
284 
285  const T* Mem() const {
286  TIXMLASSERT( _mem );
287  return _mem;
288  }
289 
290  T* Mem() {
291  TIXMLASSERT( _mem );
292  return _mem;
293  }
294 
295 private:
296  DynArray( const DynArray& ); // not supported
297  void operator=( const DynArray& ); // not supported
298 
299  void EnsureCapacity( size_t cap ) {
300  TIXMLASSERT( cap > 0 );
301  if ( cap > _allocated ) {
302  TIXMLASSERT( cap <= SIZE_MAX / 2 / sizeof(T));
303  const size_t newAllocated = cap * 2;
304  T* newMem = new T[newAllocated];
305  TIXMLASSERT( newAllocated >= _size );
306  memcpy( newMem, _mem, sizeof(T) * _size ); // warning: not using constructors, only works for PODs
307  if ( _mem != _pool ) {
308  delete [] _mem;
309  }
310  _mem = newMem;
311  _allocated = newAllocated;
312  }
313  }
314 
315  T* _mem;
316  T _pool[INITIAL_SIZE];
317  size_t _allocated; // objects allocated
318  size_t _size; // number objects in use
319 };
320 
321 
322 /*
323  Parent virtual class of a pool for fast allocation
324  and deallocation of objects.
325 */
326 class MemPool
327 {
328 public:
329  MemPool() {}
330  virtual ~MemPool() {}
331 
332  virtual size_t ItemSize() const = 0;
333  virtual void* Alloc() = 0;
334  virtual void Free( void* ) = 0;
335  virtual void SetTracked() = 0;
336 };
337 
338 
339 /*
340  Template child class to create pools of the correct type.
341 */
342 template< size_t ITEM_SIZE >
343 class MemPoolT : public MemPool
344 {
345 public:
346  MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
347  ~MemPoolT() {
348  MemPoolT< ITEM_SIZE >::Clear();
349  }
350 
351  void Clear() {
352  // Delete the blocks.
353  while( !_blockPtrs.Empty()) {
354  Block* lastBlock = _blockPtrs.Pop();
355  delete lastBlock;
356  }
357  _root = 0;
358  _currentAllocs = 0;
359  _nAllocs = 0;
360  _maxAllocs = 0;
361  _nUntracked = 0;
362  }
363 
364  virtual size_t ItemSize() const override {
365  return ITEM_SIZE;
366  }
367  size_t CurrentAllocs() const {
368  return _currentAllocs;
369  }
370 
371  virtual void* Alloc() override{
372  if ( !_root ) {
373  // Need a new block.
374  Block* block = new Block;
375  _blockPtrs.Push( block );
376 
377  Item* blockItems = block->items;
378  for( size_t i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
379  blockItems[i].next = &(blockItems[i + 1]);
380  }
381  blockItems[ITEMS_PER_BLOCK - 1].next = 0;
382  _root = blockItems;
383  }
384  Item* const result = _root;
385  TIXMLASSERT( result != 0 );
386  _root = _root->next;
387 
388  ++_currentAllocs;
389  if ( _currentAllocs > _maxAllocs ) {
390  _maxAllocs = _currentAllocs;
391  }
392  ++_nAllocs;
393  ++_nUntracked;
394  return result;
395  }
396 
397  virtual void Free( void* mem ) override {
398  if ( !mem ) {
399  return;
400  }
401  --_currentAllocs;
402  Item* item = static_cast<Item*>( mem );
403 #ifdef TINYXML2_DEBUG
404  memset( item, 0xfe, sizeof( *item ) );
405 #endif
406  item->next = _root;
407  _root = item;
408  }
409  void Trace( const char* name ) {
410  printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
411  name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
412  ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
413  }
414 
415  void SetTracked() override {
416  --_nUntracked;
417  }
418 
419  size_t Untracked() const {
420  return _nUntracked;
421  }
422 
423  // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
424  // The test file is large, 170k.
425  // Release: VS2010 gcc(no opt)
426  // 1k: 4000
427  // 2k: 4000
428  // 4k: 3900 21000
429  // 16k: 5200
430  // 32k: 4300
431  // 64k: 4000 21000
432  // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
433  // in private part if ITEMS_PER_BLOCK is private
434  enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
435 
436 private:
437  MemPoolT( const MemPoolT& ); // not supported
438  void operator=( const MemPoolT& ); // not supported
439 
440  union Item {
441  Item* next;
442  char itemData[static_cast<size_t>(ITEM_SIZE)];
443  };
444  struct Block {
445  Item items[ITEMS_PER_BLOCK];
446  };
447  DynArray< Block*, 10 > _blockPtrs;
448  Item* _root;
449 
450  size_t _currentAllocs;
451  size_t _nAllocs;
452  size_t _maxAllocs;
453  size_t _nUntracked;
454 };
455 
456 
457 
477 class TINYXML2_LIB XMLVisitor
478 {
479 public:
480  virtual ~XMLVisitor() {}
481 
483  virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
484  return true;
485  }
487  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
488  return true;
489  }
490 
492  virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
493  return true;
494  }
496  virtual bool VisitExit( const XMLElement& /*element*/ ) {
497  return true;
498  }
499 
501  virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
502  return true;
503  }
505  virtual bool Visit( const XMLText& /*text*/ ) {
506  return true;
507  }
509  virtual bool Visit( const XMLComment& /*comment*/ ) {
510  return true;
511  }
513  virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
514  return true;
515  }
516 };
517 
518 // WARNING: must match XMLDocument::_errorNames[]
519 enum XMLError {
520  XML_SUCCESS = 0,
521  XML_NO_ATTRIBUTE,
522  XML_WRONG_ATTRIBUTE_TYPE,
523  XML_ERROR_FILE_NOT_FOUND,
524  XML_ERROR_FILE_COULD_NOT_BE_OPENED,
525  XML_ERROR_FILE_READ_ERROR,
526  XML_ERROR_PARSING_ELEMENT,
527  XML_ERROR_PARSING_ATTRIBUTE,
528  XML_ERROR_PARSING_TEXT,
529  XML_ERROR_PARSING_CDATA,
530  XML_ERROR_PARSING_COMMENT,
531  XML_ERROR_PARSING_DECLARATION,
532  XML_ERROR_PARSING_UNKNOWN,
533  XML_ERROR_EMPTY_DOCUMENT,
534  XML_ERROR_MISMATCHED_ELEMENT,
535  XML_ERROR_PARSING,
536  XML_CAN_NOT_CONVERT_TEXT,
537  XML_NO_TEXT_NODE,
538  XML_ELEMENT_DEPTH_EXCEEDED,
539 
540  XML_ERROR_COUNT
541 };
542 
543 
544 /*
545  Utility functionality.
546 */
547 class TINYXML2_LIB XMLUtil
548 {
549 public:
550  static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
551  TIXMLASSERT( p );
552 
553  while( IsWhiteSpace(*p) ) {
554  if (curLineNumPtr && *p == '\n') {
555  ++(*curLineNumPtr);
556  }
557  ++p;
558  }
559  TIXMLASSERT( p );
560  return p;
561  }
562  static char* SkipWhiteSpace( char* const p, int* curLineNumPtr ) {
563  return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
564  }
565 
566  // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
567  // correct, but simple, and usually works.
568  static bool IsWhiteSpace( char p ) {
569  return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
570  }
571 
572  inline static bool IsNameStartChar( unsigned char ch ) {
573  if ( ch >= 128 ) {
574  // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
575  return true;
576  }
577  if ( isalpha( ch ) ) {
578  return true;
579  }
580  return ch == ':' || ch == '_';
581  }
582 
583  inline static bool IsNameChar( unsigned char ch ) {
584  return IsNameStartChar( ch )
585  || isdigit( ch )
586  || ch == '.'
587  || ch == '-';
588  }
589 
590  inline static bool IsPrefixHex( const char* p) {
591  p = SkipWhiteSpace(p, 0);
592  return p && *p == '0' && ( *(p + 1) == 'x' || *(p + 1) == 'X');
593  }
594 
595  inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
596  if ( p == q ) {
597  return true;
598  }
599  TIXMLASSERT( p );
600  TIXMLASSERT( q );
601  TIXMLASSERT( nChar >= 0 );
602  return strncmp( p, q, static_cast<size_t>(nChar) ) == 0;
603  }
604 
605  inline static bool IsUTF8Continuation( const char p ) {
606  return ( p & 0x80 ) != 0;
607  }
608 
609  static const char* ReadBOM( const char* p, bool* hasBOM );
610  // p is the starting location,
611  // the UTF-8 value of the entity will be placed in value, and length filled in.
612  static const char* GetCharacterRef( const char* p, char* value, int* length );
613  static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
614 
615  // converts primitive types to strings
616  static void ToStr( int v, char* buffer, int bufferSize );
617  static void ToStr( unsigned v, char* buffer, int bufferSize );
618  static void ToStr( bool v, char* buffer, int bufferSize );
619  static void ToStr( float v, char* buffer, int bufferSize );
620  static void ToStr( double v, char* buffer, int bufferSize );
621  static void ToStr(int64_t v, char* buffer, int bufferSize);
622  static void ToStr(uint64_t v, char* buffer, int bufferSize);
623 
624  // converts strings to primitive types
625  static bool ToInt( const char* str, int* value );
626  static bool ToUnsigned( const char* str, unsigned* value );
627  static bool ToBool( const char* str, bool* value );
628  static bool ToFloat( const char* str, float* value );
629  static bool ToDouble( const char* str, double* value );
630  static bool ToInt64(const char* str, int64_t* value);
631  static bool ToUnsigned64(const char* str, uint64_t* value);
632  // Changes what is serialized for a boolean value.
633  // Default to "true" and "false". Shouldn't be changed
634  // unless you have a special testing or compatibility need.
635  // Be careful: static, global, & not thread safe.
636  // Be sure to set static const memory as parameters.
637  static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
638 
639 private:
640  static const char* writeBoolTrue;
641  static const char* writeBoolFalse;
642 };
643 
644 
670 class TINYXML2_LIB XMLNode
671 {
672  friend class XMLDocument;
673  friend class XMLElement;
674 public:
675 
677  const XMLDocument* GetDocument() const {
678  TIXMLASSERT( _document );
679  return _document;
680  }
683  TIXMLASSERT( _document );
684  return _document;
685  }
686 
688  virtual XMLElement* ToElement() {
689  return 0;
690  }
692  virtual XMLText* ToText() {
693  return 0;
694  }
696  virtual XMLComment* ToComment() {
697  return 0;
698  }
700  virtual XMLDocument* ToDocument() {
701  return 0;
702  }
705  return 0;
706  }
708  virtual XMLUnknown* ToUnknown() {
709  return 0;
710  }
711 
712  virtual const XMLElement* ToElement() const {
713  return 0;
714  }
715  virtual const XMLText* ToText() const {
716  return 0;
717  }
718  virtual const XMLComment* ToComment() const {
719  return 0;
720  }
721  virtual const XMLDocument* ToDocument() const {
722  return 0;
723  }
724  virtual const XMLDeclaration* ToDeclaration() const {
725  return 0;
726  }
727  virtual const XMLUnknown* ToUnknown() const {
728  return 0;
729  }
730 
731  // ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
732 
733  int ChildElementCount(const char *value) const;
734 
735  int ChildElementCount() const;
736 
746  const char* Value() const;
747 
751  void SetValue( const char* val, bool staticMem=false );
752 
754  int GetLineNum() const { return _parseLineNum; }
755 
757  const XMLNode* Parent() const {
758  return _parent;
759  }
760 
761  XMLNode* Parent() {
762  return _parent;
763  }
764 
766  bool NoChildren() const {
767  return !_firstChild;
768  }
769 
771  const XMLNode* FirstChild() const {
772  return _firstChild;
773  }
774 
775  XMLNode* FirstChild() {
776  return _firstChild;
777  }
778 
782  const XMLElement* FirstChildElement( const char* name = 0 ) const;
783 
784  XMLElement* FirstChildElement( const char* name = 0 ) {
785  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
786  }
787 
789  const XMLNode* LastChild() const {
790  return _lastChild;
791  }
792 
793  XMLNode* LastChild() {
794  return _lastChild;
795  }
796 
800  const XMLElement* LastChildElement( const char* name = 0 ) const;
801 
802  XMLElement* LastChildElement( const char* name = 0 ) {
803  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
804  }
805 
807  const XMLNode* PreviousSibling() const {
808  return _prev;
809  }
810 
811  XMLNode* PreviousSibling() {
812  return _prev;
813  }
814 
816  const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
817 
818  XMLElement* PreviousSiblingElement( const char* name = 0 ) {
819  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
820  }
821 
823  const XMLNode* NextSibling() const {
824  return _next;
825  }
826 
827  XMLNode* NextSibling() {
828  return _next;
829  }
830 
832  const XMLElement* NextSiblingElement( const char* name = 0 ) const;
833 
834  XMLElement* NextSiblingElement( const char* name = 0 ) {
835  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
836  }
837 
846 
847  XMLNode* LinkEndChild( XMLNode* addThis ) {
848  return InsertEndChild( addThis );
849  }
866  XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
867 
872 
876  void DeleteChild( XMLNode* node );
877 
887  virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
888 
902  XMLNode* DeepClone( XMLDocument* target ) const;
903 
910  virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
911 
934  virtual bool Accept( XMLVisitor* visitor ) const = 0;
935 
941  void SetUserData(void* userData) { _userData = userData; }
942 
948  void* GetUserData() const { return _userData; }
949 
950 protected:
951  explicit XMLNode( XMLDocument* );
952  virtual ~XMLNode();
953 
954  virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
955 
956  XMLDocument* _document;
957  XMLNode* _parent;
958  mutable StrPair _value;
959  int _parseLineNum;
960 
961  XMLNode* _firstChild;
962  XMLNode* _lastChild;
963 
964  XMLNode* _prev;
965  XMLNode* _next;
966 
967  void* _userData;
968 
969 private:
970  MemPool* _memPool;
971  void Unlink( XMLNode* child );
972  static void DeleteNode( XMLNode* node );
973  void InsertChildPreamble( XMLNode* insertThis ) const;
974  const XMLElement* ToElementWithName( const char* name ) const;
975 
976  XMLNode( const XMLNode& ); // not supported
977  XMLNode& operator=( const XMLNode& ); // not supported
978 };
979 
980 
993 class TINYXML2_LIB XMLText : public XMLNode
994 {
995  friend class XMLDocument;
996 public:
997  virtual bool Accept( XMLVisitor* visitor ) const override;
998 
999  virtual XMLText* ToText() override {
1000  return this;
1001  }
1002  virtual const XMLText* ToText() const override {
1003  return this;
1004  }
1005 
1007  void SetCData( bool isCData ) {
1008  _isCData = isCData;
1009  }
1011  bool CData() const {
1012  return _isCData;
1013  }
1014 
1015  virtual XMLNode* ShallowClone( XMLDocument* document ) const override;
1016  virtual bool ShallowEqual( const XMLNode* compare ) const override;
1017 
1018 protected:
1019  explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
1020  virtual ~XMLText() {}
1021 
1022  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
1023 
1024 private:
1025  bool _isCData;
1026 
1027  XMLText( const XMLText& ); // not supported
1028  XMLText& operator=( const XMLText& ); // not supported
1029 };
1030 
1031 
1033 class TINYXML2_LIB XMLComment : public XMLNode
1034 {
1035  friend class XMLDocument;
1036 public:
1037  virtual XMLComment* ToComment() override {
1038  return this;
1039  }
1040  virtual const XMLComment* ToComment() const override {
1041  return this;
1042  }
1043 
1044  virtual bool Accept( XMLVisitor* visitor ) const override;
1045 
1046  virtual XMLNode* ShallowClone( XMLDocument* document ) const override;
1047  virtual bool ShallowEqual( const XMLNode* compare ) const override;
1048 
1049 protected:
1050  explicit XMLComment( XMLDocument* doc );
1051  virtual ~XMLComment();
1052 
1053  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
1054 
1055 private:
1056  XMLComment( const XMLComment& ); // not supported
1057  XMLComment& operator=( const XMLComment& ); // not supported
1058 };
1059 
1060 
1072 class TINYXML2_LIB XMLDeclaration : public XMLNode
1073 {
1074  friend class XMLDocument;
1075 public:
1076  virtual XMLDeclaration* ToDeclaration() override {
1077  return this;
1078  }
1079  virtual const XMLDeclaration* ToDeclaration() const override {
1080  return this;
1081  }
1082 
1083  virtual bool Accept( XMLVisitor* visitor ) const override;
1084 
1085  virtual XMLNode* ShallowClone( XMLDocument* document ) const override;
1086  virtual bool ShallowEqual( const XMLNode* compare ) const override;
1087 
1088 protected:
1089  explicit XMLDeclaration( XMLDocument* doc );
1090  virtual ~XMLDeclaration();
1091 
1092  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
1093 
1094 private:
1095  XMLDeclaration( const XMLDeclaration& ); // not supported
1096  XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1097 };
1098 
1099 
1107 class TINYXML2_LIB XMLUnknown : public XMLNode
1108 {
1109  friend class XMLDocument;
1110 public:
1111  virtual XMLUnknown* ToUnknown() override {
1112  return this;
1113  }
1114  virtual const XMLUnknown* ToUnknown() const override {
1115  return this;
1116  }
1117 
1118  virtual bool Accept( XMLVisitor* visitor ) const override;
1119 
1120  virtual XMLNode* ShallowClone( XMLDocument* document ) const override;
1121  virtual bool ShallowEqual( const XMLNode* compare ) const override;
1122 
1123 protected:
1124  explicit XMLUnknown( XMLDocument* doc );
1125  virtual ~XMLUnknown();
1126 
1127  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
1128 
1129 private:
1130  XMLUnknown( const XMLUnknown& ); // not supported
1131  XMLUnknown& operator=( const XMLUnknown& ); // not supported
1132 };
1133 
1134 
1135 
1142 class TINYXML2_LIB XMLAttribute
1143 {
1144  friend class XMLElement;
1145 public:
1147  const char* Name() const;
1148 
1150  const char* Value() const;
1151 
1153  int GetLineNum() const { return _parseLineNum; }
1154 
1156  const XMLAttribute* Next() const {
1157  return _next;
1158  }
1159 
1164  int IntValue() const {
1165  int i = 0;
1166  QueryIntValue(&i);
1167  return i;
1168  }
1169 
1170  int64_t Int64Value() const {
1171  int64_t i = 0;
1172  QueryInt64Value(&i);
1173  return i;
1174  }
1175 
1176  uint64_t Unsigned64Value() const {
1177  uint64_t i = 0;
1178  QueryUnsigned64Value(&i);
1179  return i;
1180  }
1181 
1183  unsigned UnsignedValue() const {
1184  unsigned i=0;
1185  QueryUnsignedValue( &i );
1186  return i;
1187  }
1189  bool BoolValue() const {
1190  bool b=false;
1191  QueryBoolValue( &b );
1192  return b;
1193  }
1195  double DoubleValue() const {
1196  double d=0;
1197  QueryDoubleValue( &d );
1198  return d;
1199  }
1201  float FloatValue() const {
1202  float f=0;
1203  QueryFloatValue( &f );
1204  return f;
1205  }
1206 
1211  XMLError QueryIntValue( int* value ) const;
1213  XMLError QueryUnsignedValue( unsigned int* value ) const;
1215  XMLError QueryInt64Value(int64_t* value) const;
1217  XMLError QueryUnsigned64Value(uint64_t* value) const;
1219  XMLError QueryBoolValue( bool* value ) const;
1221  XMLError QueryDoubleValue( double* value ) const;
1223  XMLError QueryFloatValue( float* value ) const;
1224 
1226  void SetAttribute( const char* value );
1228  void SetAttribute( int value );
1230  void SetAttribute( unsigned value );
1232  void SetAttribute(int64_t value);
1234  void SetAttribute(uint64_t value);
1236  void SetAttribute( bool value );
1238  void SetAttribute( double value );
1240  void SetAttribute( float value );
1241 
1242 private:
1243  enum { BUF_SIZE = 200 };
1244 
1245  XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
1246  virtual ~XMLAttribute() {}
1247 
1248  XMLAttribute( const XMLAttribute& ); // not supported
1249  void operator=( const XMLAttribute& ); // not supported
1250  void SetName( const char* name );
1251 
1252  char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
1253 
1254  mutable StrPair _name;
1255  mutable StrPair _value;
1256  int _parseLineNum;
1257  XMLAttribute* _next;
1258  MemPool* _memPool;
1259 };
1260 
1261 
1266 class TINYXML2_LIB XMLElement : public XMLNode
1267 {
1268  friend class XMLDocument;
1269 public:
1271  const char* Name() const {
1272  return Value();
1273  }
1275  void SetName( const char* str, bool staticMem=false ) {
1276  SetValue( str, staticMem );
1277  }
1278 
1279  virtual XMLElement* ToElement() override {
1280  return this;
1281  }
1282  virtual const XMLElement* ToElement() const override {
1283  return this;
1284  }
1285  virtual bool Accept( XMLVisitor* visitor ) const override;
1286 
1310  const char* Attribute( const char* name, const char* value=0 ) const;
1311 
1318  int IntAttribute(const char* name, int defaultValue = 0) const;
1320  unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1322  int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1324  uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
1326  bool BoolAttribute(const char* name, bool defaultValue = false) const;
1328  double DoubleAttribute(const char* name, double defaultValue = 0) const;
1330  float FloatAttribute(const char* name, float defaultValue = 0) const;
1331 
1345  XMLError QueryIntAttribute( const char* name, int* value ) const {
1346  const XMLAttribute* a = FindAttribute( name );
1347  if ( !a ) {
1348  return XML_NO_ATTRIBUTE;
1349  }
1350  return a->QueryIntValue( value );
1351  }
1352 
1354  XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
1355  const XMLAttribute* a = FindAttribute( name );
1356  if ( !a ) {
1357  return XML_NO_ATTRIBUTE;
1358  }
1359  return a->QueryUnsignedValue( value );
1360  }
1361 
1363  XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1364  const XMLAttribute* a = FindAttribute(name);
1365  if (!a) {
1366  return XML_NO_ATTRIBUTE;
1367  }
1368  return a->QueryInt64Value(value);
1369  }
1370 
1372  XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const {
1373  const XMLAttribute* a = FindAttribute(name);
1374  if(!a) {
1375  return XML_NO_ATTRIBUTE;
1376  }
1377  return a->QueryUnsigned64Value(value);
1378  }
1379 
1381  XMLError QueryBoolAttribute( const char* name, bool* value ) const {
1382  const XMLAttribute* a = FindAttribute( name );
1383  if ( !a ) {
1384  return XML_NO_ATTRIBUTE;
1385  }
1386  return a->QueryBoolValue( value );
1387  }
1389  XMLError QueryDoubleAttribute( const char* name, double* value ) const {
1390  const XMLAttribute* a = FindAttribute( name );
1391  if ( !a ) {
1392  return XML_NO_ATTRIBUTE;
1393  }
1394  return a->QueryDoubleValue( value );
1395  }
1397  XMLError QueryFloatAttribute( const char* name, float* value ) const {
1398  const XMLAttribute* a = FindAttribute( name );
1399  if ( !a ) {
1400  return XML_NO_ATTRIBUTE;
1401  }
1402  return a->QueryFloatValue( value );
1403  }
1404 
1406  XMLError QueryStringAttribute(const char* name, const char** value) const {
1407  const XMLAttribute* a = FindAttribute(name);
1408  if (!a) {
1409  return XML_NO_ATTRIBUTE;
1410  }
1411  *value = a->Value();
1412  return XML_SUCCESS;
1413  }
1414 
1415 
1416 
1434  XMLError QueryAttribute( const char* name, int* value ) const {
1435  return QueryIntAttribute( name, value );
1436  }
1437 
1438  XMLError QueryAttribute( const char* name, unsigned int* value ) const {
1439  return QueryUnsignedAttribute( name, value );
1440  }
1441 
1442  XMLError QueryAttribute(const char* name, int64_t* value) const {
1443  return QueryInt64Attribute(name, value);
1444  }
1445 
1446  XMLError QueryAttribute(const char* name, uint64_t* value) const {
1447  return QueryUnsigned64Attribute(name, value);
1448  }
1449 
1450  XMLError QueryAttribute( const char* name, bool* value ) const {
1451  return QueryBoolAttribute( name, value );
1452  }
1453 
1454  XMLError QueryAttribute( const char* name, double* value ) const {
1455  return QueryDoubleAttribute( name, value );
1456  }
1457 
1458  XMLError QueryAttribute( const char* name, float* value ) const {
1459  return QueryFloatAttribute( name, value );
1460  }
1461 
1462  XMLError QueryAttribute(const char* name, const char** value) const {
1463  return QueryStringAttribute(name, value);
1464  }
1465 
1467  void SetAttribute( const char* name, const char* value ) {
1468  XMLAttribute* a = FindOrCreateAttribute( name );
1469  a->SetAttribute( value );
1470  }
1472  void SetAttribute( const char* name, int value ) {
1473  XMLAttribute* a = FindOrCreateAttribute( name );
1474  a->SetAttribute( value );
1475  }
1477  void SetAttribute( const char* name, unsigned value ) {
1478  XMLAttribute* a = FindOrCreateAttribute( name );
1479  a->SetAttribute( value );
1480  }
1481 
1483  void SetAttribute(const char* name, int64_t value) {
1484  XMLAttribute* a = FindOrCreateAttribute(name);
1485  a->SetAttribute(value);
1486  }
1487 
1489  void SetAttribute(const char* name, uint64_t value) {
1490  XMLAttribute* a = FindOrCreateAttribute(name);
1491  a->SetAttribute(value);
1492  }
1493 
1495  void SetAttribute( const char* name, bool value ) {
1496  XMLAttribute* a = FindOrCreateAttribute( name );
1497  a->SetAttribute( value );
1498  }
1500  void SetAttribute( const char* name, double value ) {
1501  XMLAttribute* a = FindOrCreateAttribute( name );
1502  a->SetAttribute( value );
1503  }
1505  void SetAttribute( const char* name, float value ) {
1506  XMLAttribute* a = FindOrCreateAttribute( name );
1507  a->SetAttribute( value );
1508  }
1509 
1513  void DeleteAttribute( const char* name );
1514 
1516  const XMLAttribute* FirstAttribute() const {
1517  return _rootAttribute;
1518  }
1520  const XMLAttribute* FindAttribute( const char* name ) const;
1521 
1550  const char* GetText() const;
1551 
1586  void SetText( const char* inText );
1588  void SetText( int value );
1590  void SetText( unsigned value );
1592  void SetText(int64_t value);
1594  void SetText(uint64_t value);
1596  void SetText( bool value );
1598  void SetText( double value );
1600  void SetText( float value );
1601 
1628  XMLError QueryIntText( int* ival ) const;
1630  XMLError QueryUnsignedText( unsigned* uval ) const;
1632  XMLError QueryInt64Text(int64_t* uval) const;
1634  XMLError QueryUnsigned64Text(uint64_t* uval) const;
1636  XMLError QueryBoolText( bool* bval ) const;
1638  XMLError QueryDoubleText( double* dval ) const;
1640  XMLError QueryFloatText( float* fval ) const;
1641 
1642  int IntText(int defaultValue = 0) const;
1643 
1645  unsigned UnsignedText(unsigned defaultValue = 0) const;
1647  int64_t Int64Text(int64_t defaultValue = 0) const;
1649  uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
1651  bool BoolText(bool defaultValue = false) const;
1653  double DoubleText(double defaultValue = 0) const;
1655  float FloatText(float defaultValue = 0) const;
1656 
1661  XMLElement* InsertNewChildElement(const char* name);
1663  XMLComment* InsertNewComment(const char* comment);
1665  XMLText* InsertNewText(const char* text);
1669  XMLUnknown* InsertNewUnknown(const char* text);
1670 
1671 
1672  // internal:
1673  enum ElementClosingType {
1674  OPEN, // <foo>
1675  CLOSED, // <foo/>
1676  CLOSING // </foo>
1677  };
1678  ElementClosingType ClosingType() const {
1679  return _closingType;
1680  }
1681  virtual XMLNode* ShallowClone( XMLDocument* document ) const override;
1682  virtual bool ShallowEqual( const XMLNode* compare ) const override;
1683 
1684 protected:
1685  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override;
1686 
1687 private:
1688  XMLElement( XMLDocument* doc );
1689  virtual ~XMLElement();
1690  XMLElement( const XMLElement& ); // not supported
1691  void operator=( const XMLElement& ); // not supported
1692 
1693  XMLAttribute* FindOrCreateAttribute( const char* name );
1694  char* ParseAttributes( char* p, int* curLineNumPtr );
1695  static void DeleteAttribute( XMLAttribute* attribute );
1696  XMLAttribute* CreateAttribute();
1697 
1698  enum { BUF_SIZE = 200 };
1699  ElementClosingType _closingType;
1700  // The attribute list is ordered; there is no 'lastAttribute'
1701  // because the list needs to be scanned for dupes before adding
1702  // a new attribute.
1703  XMLAttribute* _rootAttribute;
1704 };
1705 
1706 
1707 enum Whitespace {
1708  PRESERVE_WHITESPACE,
1709  COLLAPSE_WHITESPACE,
1710  PEDANTIC_WHITESPACE
1711 };
1712 
1713 
1719 class TINYXML2_LIB XMLDocument : public XMLNode
1720 {
1721  friend class XMLElement;
1722  // Gives access to SetError and Push/PopDepth, but over-access for everything else.
1723  // Wishing C++ had "internal" scope.
1724  friend class XMLNode;
1725  friend class XMLText;
1726  friend class XMLComment;
1727  friend class XMLDeclaration;
1728  friend class XMLUnknown;
1729 public:
1731  XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1732  ~XMLDocument();
1733 
1734  virtual XMLDocument* ToDocument() override {
1735  TIXMLASSERT( this == _document );
1736  return this;
1737  }
1738  virtual const XMLDocument* ToDocument() const override {
1739  TIXMLASSERT( this == _document );
1740  return this;
1741  }
1742 
1753  XMLError Parse( const char* xml, size_t nBytes=static_cast<size_t>(-1) );
1754 
1760  XMLError LoadFile( const char* filename );
1761 
1773  XMLError LoadFile( FILE* );
1774 
1780  XMLError SaveFile( const char* filename, bool compact = false );
1781 
1789  XMLError SaveFile( FILE* fp, bool compact = false );
1790 
1791  bool ProcessEntities() const {
1792  return _processEntities;
1793  }
1794  Whitespace WhitespaceMode() const {
1795  return _whitespaceMode;
1796  }
1797 
1801  bool HasBOM() const {
1802  return _writeBOM;
1803  }
1806  void SetBOM( bool useBOM ) {
1807  _writeBOM = useBOM;
1808  }
1809 
1814  return FirstChildElement();
1815  }
1816  const XMLElement* RootElement() const {
1817  return FirstChildElement();
1818  }
1819 
1834  void Print( XMLPrinter* streamer=0 ) const;
1835  virtual bool Accept( XMLVisitor* visitor ) const override;
1836 
1842  XMLElement* NewElement( const char* name );
1848  XMLComment* NewComment( const char* comment );
1854  XMLText* NewText( const char* text );
1866  XMLDeclaration* NewDeclaration( const char* text=0 );
1872  XMLUnknown* NewUnknown( const char* text );
1873 
1878  void DeleteNode( XMLNode* node );
1879 
1881  void ClearError();
1882 
1884  bool Error() const {
1885  return _errorID != XML_SUCCESS;
1886  }
1888  XMLError ErrorID() const {
1889  return _errorID;
1890  }
1891  const char* ErrorName() const;
1892  static const char* ErrorIDToName(XMLError errorID);
1893 
1897  const char* ErrorStr() const;
1898 
1900  void PrintError() const;
1901 
1903  int ErrorLineNum() const
1904  {
1905  return _errorLineNum;
1906  }
1907 
1909  void Clear();
1910 
1918  void DeepCopy(XMLDocument* target) const;
1919 
1920  // internal
1921  char* Identify( char* p, XMLNode** node, bool first );
1922 
1923  // internal
1924  void MarkInUse(const XMLNode* const);
1925 
1926  virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const override{
1927  return 0;
1928  }
1929  virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const override{
1930  return false;
1931  }
1932 
1933 private:
1934  XMLDocument( const XMLDocument& ); // not supported
1935  void operator=( const XMLDocument& ); // not supported
1936 
1937  bool _writeBOM;
1938  bool _processEntities;
1939  XMLError _errorID;
1940  Whitespace _whitespaceMode;
1941  mutable StrPair _errorStr;
1942  int _errorLineNum;
1943  char* _charBuffer;
1944  int _parseCurLineNum;
1945  int _parsingDepth;
1946  // Memory tracking does add some overhead.
1947  // However, the code assumes that you don't
1948  // have a bunch of unlinked nodes around.
1949  // Therefore it takes less memory to track
1950  // in the document vs. a linked list in the XMLNode,
1951  // and the performance is the same.
1952  DynArray<XMLNode*, 10> _unlinked;
1953 
1954  MemPoolT< sizeof(XMLElement) > _elementPool;
1955  MemPoolT< sizeof(XMLAttribute) > _attributePool;
1956  MemPoolT< sizeof(XMLText) > _textPool;
1957  MemPoolT< sizeof(XMLComment) > _commentPool;
1958 
1959  static const char* _errorNames[XML_ERROR_COUNT];
1960 
1961  void Parse();
1962 
1963  void SetError( XMLError error, int lineNum, const char* format, ... );
1964 
1965  // Something of an obvious security hole, once it was discovered.
1966  // Either an ill-formed XML or an excessively deep one can overflow
1967  // the stack. Track stack depth, and error out if needed.
1968  class DepthTracker {
1969  public:
1970  explicit DepthTracker(XMLDocument * document) {
1971  this->_document = document;
1972  document->PushDepth();
1973  }
1974  ~DepthTracker() {
1975  _document->PopDepth();
1976  }
1977  private:
1978  XMLDocument * _document;
1979  };
1980  void PushDepth();
1981  void PopDepth();
1982 
1983  template<class NodeType, size_t PoolElementSize>
1984  NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
1985 };
1986 
1987 template<class NodeType, size_t PoolElementSize>
1988 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
1989 {
1990  TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
1991  TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
1992  NodeType* returnNode = new (pool.Alloc()) NodeType( this );
1993  TIXMLASSERT( returnNode );
1994  returnNode->_memPool = &pool;
1995 
1996  _unlinked.Push(returnNode);
1997  return returnNode;
1998 }
1999 
2055 class TINYXML2_LIB XMLHandle
2056 {
2057 public:
2059  explicit XMLHandle( XMLNode* node ) : _node( node ) {
2060  }
2062  explicit XMLHandle( XMLNode& node ) : _node( &node ) {
2063  }
2065  XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
2066  }
2068  XMLHandle& operator=( const XMLHandle& ref ) {
2069  _node = ref._node;
2070  return *this;
2071  }
2072 
2075  return XMLHandle( _node ? _node->FirstChild() : 0 );
2076  }
2078  XMLHandle FirstChildElement( const char* name = 0 ) {
2079  return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
2080  }
2083  return XMLHandle( _node ? _node->LastChild() : 0 );
2084  }
2086  XMLHandle LastChildElement( const char* name = 0 ) {
2087  return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
2088  }
2091  return XMLHandle( _node ? _node->PreviousSibling() : 0 );
2092  }
2094  XMLHandle PreviousSiblingElement( const char* name = 0 ) {
2095  return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2096  }
2099  return XMLHandle( _node ? _node->NextSibling() : 0 );
2100  }
2102  XMLHandle NextSiblingElement( const char* name = 0 ) {
2103  return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2104  }
2105 
2108  return _node;
2109  }
2112  return ( _node ? _node->ToElement() : 0 );
2113  }
2116  return ( _node ? _node->ToText() : 0 );
2117  }
2120  return ( _node ? _node->ToUnknown() : 0 );
2121  }
2124  return ( _node ? _node->ToDeclaration() : 0 );
2125  }
2126 
2127 private:
2128  XMLNode* _node;
2129 };
2130 
2131 
2136 class TINYXML2_LIB XMLConstHandle
2137 {
2138 public:
2139  explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
2140  }
2141  explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
2142  }
2143  XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
2144  }
2145 
2146  XMLConstHandle& operator=( const XMLConstHandle& ref ) {
2147  _node = ref._node;
2148  return *this;
2149  }
2150 
2151  const XMLConstHandle FirstChild() const {
2152  return XMLConstHandle( _node ? _node->FirstChild() : 0 );
2153  }
2154  const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
2155  return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
2156  }
2157  const XMLConstHandle LastChild() const {
2158  return XMLConstHandle( _node ? _node->LastChild() : 0 );
2159  }
2160  const XMLConstHandle LastChildElement( const char* name = 0 ) const {
2161  return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
2162  }
2163  const XMLConstHandle PreviousSibling() const {
2164  return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
2165  }
2166  const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
2167  return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2168  }
2169  const XMLConstHandle NextSibling() const {
2170  return XMLConstHandle( _node ? _node->NextSibling() : 0 );
2171  }
2172  const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
2173  return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2174  }
2175 
2176 
2177  const XMLNode* ToNode() const {
2178  return _node;
2179  }
2180  const XMLElement* ToElement() const {
2181  return ( _node ? _node->ToElement() : 0 );
2182  }
2183  const XMLText* ToText() const {
2184  return ( _node ? _node->ToText() : 0 );
2185  }
2186  const XMLUnknown* ToUnknown() const {
2187  return ( _node ? _node->ToUnknown() : 0 );
2188  }
2189  const XMLDeclaration* ToDeclaration() const {
2190  return ( _node ? _node->ToDeclaration() : 0 );
2191  }
2192 
2193 private:
2194  const XMLNode* _node;
2195 };
2196 
2197 
2240 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2241 {
2242 public:
2249  XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2250  virtual ~XMLPrinter() {}
2251 
2253  void PushHeader( bool writeBOM, bool writeDeclaration );
2257  void OpenElement( const char* name, bool compactMode=false );
2259  void PushAttribute( const char* name, const char* value );
2260  void PushAttribute( const char* name, int value );
2261  void PushAttribute( const char* name, unsigned value );
2262  void PushAttribute( const char* name, int64_t value );
2263  void PushAttribute( const char* name, uint64_t value );
2264  void PushAttribute( const char* name, bool value );
2265  void PushAttribute( const char* name, double value );
2267  virtual void CloseElement( bool compactMode=false );
2268 
2270  void PushText( const char* text, bool cdata=false );
2272  void PushText( int value );
2274  void PushText( unsigned value );
2276  void PushText( int64_t value );
2278  void PushText( uint64_t value );
2280  void PushText( bool value );
2282  void PushText( float value );
2284  void PushText( double value );
2285 
2287  void PushComment( const char* comment );
2288 
2289  void PushDeclaration( const char* value );
2290  void PushUnknown( const char* value );
2291 
2292  virtual bool VisitEnter( const XMLDocument& /*doc*/ ) override;
2293  virtual bool VisitExit( const XMLDocument& /*doc*/ ) override {
2294  return true;
2295  }
2296 
2297  virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) override;
2298  virtual bool VisitExit( const XMLElement& element ) override;
2299 
2300  virtual bool Visit( const XMLText& text ) override;
2301  virtual bool Visit( const XMLComment& comment ) override;
2302  virtual bool Visit( const XMLDeclaration& declaration ) override;
2303  virtual bool Visit( const XMLUnknown& unknown ) override;
2304 
2309  const char* CStr() const {
2310  return _buffer.Mem();
2311  }
2317  size_t CStrSize() const {
2318  return _buffer.Size();
2319  }
2324  void ClearBuffer( bool resetToFirstElement = true ) {
2325  _buffer.Clear();
2326  _buffer.Push(0);
2327  _firstElement = resetToFirstElement;
2328  }
2329 
2330 protected:
2331  virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2332 
2336  virtual void PrintSpace( int depth );
2337  virtual void Print( const char* format, ... );
2338  virtual void Write( const char* data, size_t size );
2339  virtual void Putc( char ch );
2340 
2341  inline void Write(const char* data) { Write(data, strlen(data)); }
2342 
2343  void SealElementIfJustOpened();
2344  bool _elementJustOpened;
2345  DynArray< const char*, 10 > _stack;
2346 
2347 private:
2352  void PrepareForNewNode( bool compactMode );
2353  void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2354 
2355  bool _firstElement;
2356  FILE* _fp;
2357  int _depth;
2358  int _textDepth;
2359  bool _processEntities;
2360  bool _compactMode;
2361 
2362  enum {
2363  ENTITY_RANGE = 64,
2364  BUF_SIZE = 200
2365  };
2366  bool _entityFlag[ENTITY_RANGE];
2367  bool _restrictedEntityFlag[ENTITY_RANGE];
2368 
2369  DynArray< char, 20 > _buffer;
2370 
2371  // Prohibit cloning, intentionally not implemented
2372  XMLPrinter( const XMLPrinter& );
2373  XMLPrinter& operator=( const XMLPrinter& );
2374 };
2375 
2376 
2377 } // namespace tinyxml2
2378 
2379 #if defined(_MSC_VER)
2380 # pragma warning(pop)
2381 #endif
2382 
2383 #endif // TINYXML2_INCLUDED
Definition: tinyxml2.h:1143
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file.
Definition: tinyxml2.h:1153
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1183
void SetAttribute(uint64_t value)
Set the attribute to value.
const char * Value() const
The value of the attribute.
float FloatValue() const
Query as a float. See IntValue()
Definition: tinyxml2.h:1201
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
void SetAttribute(const char *value)
Set the attribute to a string value.
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
double DoubleValue() const
Query as a double. See IntValue()
Definition: tinyxml2.h:1195
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
XMLError QueryIntValue(int *value) const
void SetAttribute(int64_t value)
Set the attribute to value.
bool BoolValue() const
Query as a boolean. See IntValue()
Definition: tinyxml2.h:1189
void SetAttribute(double value)
Set the attribute to value.
void SetAttribute(bool value)
Set the attribute to value.
const char * Name() const
The name of the attribute.
void SetAttribute(int value)
Set the attribute to value.
int IntValue() const
Definition: tinyxml2.h:1164
void SetAttribute(unsigned value)
Set the attribute to value.
void SetAttribute(float value)
Set the attribute to value.
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1156
XMLError QueryUnsigned64Value(uint64_t *value) const
See QueryIntValue.
Definition: tinyxml2.h:1034
virtual bool Accept(XMLVisitor *visitor) const override
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLComment * ToComment() override
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1037
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.h:2137
Definition: tinyxml2.h:1073
virtual XMLDeclaration * ToDeclaration() override
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1076
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLNode * ShallowClone(XMLDocument *document) const override
virtual bool Accept(XMLVisitor *visitor) const override
Definition: tinyxml2.h:1720
void SetBOM(bool useBOM)
Definition: tinyxml2.h:1806
void PrintError() const
A (trivial) utility function that prints the ErrorStr() to stdout.
virtual XMLNode * ShallowClone(XMLDocument *) const override
Definition: tinyxml2.h:1926
XMLError LoadFile(const char *filename)
bool HasBOM() const
Definition: tinyxml2.h:1801
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1884
void ClearError()
Clears the error flags.
XMLUnknown * NewUnknown(const char *text)
int ErrorLineNum() const
Return the line where the error occurred, or zero if unknown.
Definition: tinyxml2.h:1903
XMLDocument(bool processEntities=true, Whitespace whitespaceMode=PRESERVE_WHITESPACE)
constructor
XMLError LoadFile(FILE *)
void Clear()
Clear the document, resetting it to the initial state.
XMLError SaveFile(const char *filename, bool compact=false)
virtual bool Accept(XMLVisitor *visitor) const override
void Print(XMLPrinter *streamer=0) const
XMLElement * NewElement(const char *name)
XMLError SaveFile(FILE *fp, bool compact=false)
XMLText * NewText(const char *text)
void DeleteNode(XMLNode *node)
virtual bool ShallowEqual(const XMLNode *) const override
Definition: tinyxml2.h:1929
virtual XMLDocument * ToDocument() override
Safely cast to a Document, or null.
Definition: tinyxml2.h:1734
XMLElement * RootElement()
Definition: tinyxml2.h:1813
const char * ErrorStr() const
XMLComment * NewComment(const char *comment)
XMLDeclaration * NewDeclaration(const char *text=0)
XMLError Parse(const char *xml, size_t nBytes=static_cast< size_t >(-1))
void DeepCopy(XMLDocument *target) const
XMLError ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1888
Definition: tinyxml2.h:1267
double DoubleAttribute(const char *name, double defaultValue=0) const
See IntAttribute()
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1467
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
XMLError QueryUnsigned64Attribute(const char *name, uint64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1372
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1381
XMLError QueryUnsignedText(unsigned *uval) const
See QueryIntText()
XMLText * InsertNewText(const char *text)
See InsertNewChildElement()
void SetText(const char *inText)
uint64_t Unsigned64Attribute(const char *name, uint64_t defaultValue=0) const
See IntAttribute()
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition: tinyxml2.h:1500
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1354
const XMLAttribute * FindAttribute(const char *name) const
Query a specific attribute in the list.
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1516
XMLError QueryBoolText(bool *bval) const
See QueryIntText()
float FloatText(float defaultValue=0) const
See QueryIntText()
unsigned UnsignedText(unsigned defaultValue=0) const
See QueryIntText()
void SetText(float value)
Convenience method for setting text inside an element. See SetText() for important limitations.
bool BoolAttribute(const char *name, bool defaultValue=false) const
See IntAttribute()
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition: tinyxml2.h:1505
XMLError QueryAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1434
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1389
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1271
int64_t Int64Attribute(const char *name, int64_t defaultValue=0) const
See IntAttribute()
void SetText(double value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryDoubleText(double *dval) const
See QueryIntText()
bool BoolText(bool defaultValue=false) const
See QueryIntText()
const char * GetText() const
void SetText(uint64_t value)
Convenience method for setting text inside an element. See SetText() for important limitations.
const char * Attribute(const char *name, const char *value=0) const
virtual XMLNode * ShallowClone(XMLDocument *document) const override
void SetText(int64_t value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(unsigned value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1363
double DoubleText(double defaultValue=0) const
See QueryIntText()
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1345
XMLError QueryIntText(int *ival) const
int IntAttribute(const char *name, int defaultValue=0) const
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1275
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1495
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
virtual bool ShallowEqual(const XMLNode *compare) const override
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1472
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1483
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
virtual XMLElement * ToElement() override
Safely cast to an Element, or null.
Definition: tinyxml2.h:1279
XMLElement * InsertNewChildElement(const char *name)
XMLError QueryUnsigned64Text(uint64_t *uval) const
See QueryIntText()
XMLUnknown * InsertNewUnknown(const char *text)
See InsertNewChildElement()
virtual bool Accept(XMLVisitor *visitor) const override
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1397
void SetAttribute(const char *name, uint64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1489
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1406
XMLDeclaration * InsertNewDeclaration(const char *text)
See InsertNewChildElement()
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1477
void SetText(bool value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLComment * InsertNewComment(const char *comment)
See InsertNewChildElement()
void SetText(int value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void DeleteAttribute(const char *name)
uint64_t Unsigned64Text(uint64_t defaultValue=0) const
See QueryIntText()
XMLError QueryFloatText(float *fval) const
See QueryIntText()
unsigned UnsignedAttribute(const char *name, unsigned defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.h:2056
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2107
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2123
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:2090
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition: tinyxml2.h:2086
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:2074
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2111
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2115
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition: tinyxml2.h:2078
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition: tinyxml2.h:2068
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:2094
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:2059
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:2082
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:2062
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2119
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:2098
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2102
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:2065
Definition: tinyxml2.h:671
void SetUserData(void *userData)
Definition: tinyxml2.h:941
void SetValue(const char *val, bool staticMem=false)
const XMLElement * NextSiblingElement(const char *name=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
const XMLElement * LastChildElement(const char *name=0) const
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:704
const XMLElement * FirstChildElement(const char *name=0) const
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:677
void DeleteChild(XMLNode *node)
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:692
XMLNode * DeepClone(XMLDocument *target) const
const char * Value() const
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:823
virtual bool ShallowEqual(const XMLNode *compare) const =0
void * GetUserData() const
Definition: tinyxml2.h:948
virtual bool Accept(XMLVisitor *visitor) const =0
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:700
virtual XMLNode * ShallowClone(XMLDocument *document) const =0
XMLNode * InsertAfterChild(XMLNode *afterThis, XMLNode *addThis)
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:708
const XMLElement * PreviousSiblingElement(const char *name=0) const
Get the previous (left) sibling element of this node, with an optionally supplied name.
XMLNode * InsertFirstChild(XMLNode *addThis)
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition: tinyxml2.h:754
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:789
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:688
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition: tinyxml2.h:807
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:766
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:757
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:771
XMLNode * InsertEndChild(XMLNode *addThis)
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:682
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:696
Definition: tinyxml2.h:2241
virtual void PrintSpace(int depth)
void PushHeader(bool writeBOM, bool writeDeclaration)
const char * CStr() const
Definition: tinyxml2.h:2309
void PushText(const char *text, bool cdata=false)
Add a text node.
void PushText(float value)
Add a text node from a float.
void OpenElement(const char *name, bool compactMode=false)
virtual bool VisitExit(const XMLDocument &) override
Visit a document.
Definition: tinyxml2.h:2293
virtual bool Visit(const XMLUnknown &unknown) override
Visit an unknown node.
void PushText(int value)
Add a text node from an integer.
void PushText(bool value)
Add a text node from a bool.
virtual bool VisitEnter(const XMLElement &element, const XMLAttribute *attribute) override
Visit an element.
void PushText(uint64_t value)
Add a text node from an unsigned 64bit integer.
virtual bool Visit(const XMLDeclaration &declaration) override
Visit a declaration.
void PushText(unsigned value)
Add a text node from an unsigned.
void ClearBuffer(bool resetToFirstElement=true)
Definition: tinyxml2.h:2324
virtual bool VisitEnter(const XMLDocument &) override
Visit a document.
virtual bool Visit(const XMLComment &comment) override
Visit a comment node.
size_t CStrSize() const
Definition: tinyxml2.h:2317
void PushText(int64_t value)
Add a text node from a signed 64bit integer.
virtual bool VisitExit(const XMLElement &element) override
Visit an element.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
XMLPrinter(FILE *file=0, bool compact=false, int depth=0)
void PushText(double value)
Add a text node from a double.
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
virtual bool Visit(const XMLText &text) override
Visit a text node.
void PushComment(const char *comment)
Add a comment.
Definition: tinyxml2.h:994
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLText * ToText() override
Safely cast to Text, or null.
Definition: tinyxml2.h:999
virtual bool Accept(XMLVisitor *visitor) const override
virtual XMLNode * ShallowClone(XMLDocument *document) const override
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:1011
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:1007
Definition: tinyxml2.h:1108
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLUnknown * ToUnknown() override
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1111
virtual bool Accept(XMLVisitor *visitor) const override
virtual XMLNode * ShallowClone(XMLDocument *document) const override
Definition: tinyxml2.h:478
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:513
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:487
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:496
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:483
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:509
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:501
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:505
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:492