TinyXML-2  9.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  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 ) if ( !((void)0,(x))) { __debugbreak(); }
87 # elif defined (ANDROID_NDK)
88 # include <android/log.h>
89 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
90 # else
91 # include <assert.h>
92 # define TIXMLASSERT assert
93 # endif
94 #else
95 # define TIXMLASSERT( x ) {}
96 #endif
97 #endif
98 
99 /* Versioning, past 1.0.14:
100  http://semver.org/
101 */
102 static const int TIXML2_MAJOR_VERSION = 9;
103 static const int TIXML2_MINOR_VERSION = 0;
104 static 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.
115 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
116 
117 namespace tinyxml2
118 {
119 class XMLDocument;
120 class XMLElement;
121 class XMLAttribute;
122 class XMLComment;
123 class XMLText;
124 class XMLDeclaration;
125 class XMLUnknown;
126 class 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 */
136 class TINYXML2_LIB StrPair
137 {
138 public:
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 
183 private:
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 */
205 template <class T, int INITIAL_SIZE>
206 class DynArray
207 {
208 public:
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( _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( _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 
299 private:
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 */
330 class MemPool
331 {
332 public:
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 */
346 template< int ITEM_SIZE >
347 class MemPoolT : public MemPool
348 {
349 public:
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 
440 private:
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 
481 class TINYXML2_LIB XMLVisitor
482 {
483 public:
484  virtual ~XMLVisitor() {}
485 
487  virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
488  return true;
489  }
491  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
492  return true;
493  }
494 
496  virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
497  return true;
498  }
500  virtual bool VisitExit( const XMLElement& /*element*/ ) {
501  return true;
502  }
503 
505  virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
506  return true;
507  }
509  virtual bool Visit( const XMLText& /*text*/ ) {
510  return true;
511  }
513  virtual bool Visit( const XMLComment& /*comment*/ ) {
514  return true;
515  }
517  virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
518  return true;
519  }
520 };
521 
522 // WARNING: must match XMLDocument::_errorNames[]
523 enum 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 */
551 class TINYXML2_LIB XMLUtil
552 {
553 public:
554  static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
555  TIXMLASSERT( p );
556 
557  while( IsWhiteSpace(*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( 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, 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( p, q, 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 
643 private:
644  static const char* writeBoolTrue;
645  static const char* writeBoolFalse;
646 };
647 
648 
674 class TINYXML2_LIB XMLNode
675 {
676  friend class XMLDocument;
677  friend class XMLElement;
678 public:
679 
681  const XMLDocument* GetDocument() const {
682  TIXMLASSERT( _document );
683  return _document;
684  }
687  TIXMLASSERT( _document );
688  return _document;
689  }
690 
692  virtual XMLElement* ToElement() {
693  return 0;
694  }
696  virtual XMLText* ToText() {
697  return 0;
698  }
700  virtual XMLComment* ToComment() {
701  return 0;
702  }
704  virtual XMLDocument* ToDocument() {
705  return 0;
706  }
709  return 0;
710  }
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 
744  const char* Value() const;
745 
749  void SetValue( const char* val, bool staticMem=false );
750 
752  int GetLineNum() const { return _parseLineNum; }
753 
755  const XMLNode* Parent() const {
756  return _parent;
757  }
758 
759  XMLNode* Parent() {
760  return _parent;
761  }
762 
764  bool NoChildren() const {
765  return !_firstChild;
766  }
767 
769  const XMLNode* FirstChild() const {
770  return _firstChild;
771  }
772 
773  XMLNode* FirstChild() {
774  return _firstChild;
775  }
776 
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 
787  const XMLNode* LastChild() const {
788  return _lastChild;
789  }
790 
791  XMLNode* LastChild() {
792  return _lastChild;
793  }
794 
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 
805  const XMLNode* PreviousSibling() const {
806  return _prev;
807  }
808 
809  XMLNode* PreviousSibling() {
810  return _prev;
811  }
812 
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 
821  const XMLNode* NextSibling() const {
822  return _next;
823  }
824 
825  XMLNode* NextSibling() {
826  return _next;
827  }
828 
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 
844 
845  XMLNode* LinkEndChild( XMLNode* addThis ) {
846  return InsertEndChild( addThis );
847  }
864  XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
865 
870 
874  void DeleteChild( XMLNode* node );
875 
885  virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
886 
900  XMLNode* DeepClone( XMLDocument* target ) const;
901 
908  virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
909 
932  virtual bool Accept( XMLVisitor* visitor ) const = 0;
933 
939  void SetUserData(void* userData) { _userData = userData; }
940 
946  void* GetUserData() const { return _userData; }
947 
948 protected:
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 
967 private:
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 
991 class TINYXML2_LIB XMLText : public XMLNode
992 {
993  friend class XMLDocument;
994 public:
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 
1005  void SetCData( bool isCData ) {
1006  _isCData = isCData;
1007  }
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 
1016 protected:
1017  explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
1018  virtual ~XMLText() {}
1019 
1020  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1021 
1022 private:
1023  bool _isCData;
1024 
1025  XMLText( const XMLText& ); // not supported
1026  XMLText& operator=( const XMLText& ); // not supported
1027 };
1028 
1029 
1031 class TINYXML2_LIB XMLComment : public XMLNode
1032 {
1033  friend class XMLDocument;
1034 public:
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 
1047 protected:
1048  explicit XMLComment( XMLDocument* doc );
1049  virtual ~XMLComment();
1050 
1051  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
1052 
1053 private:
1054  XMLComment( const XMLComment& ); // not supported
1055  XMLComment& operator=( const XMLComment& ); // not supported
1056 };
1057 
1058 
1070 class TINYXML2_LIB XMLDeclaration : public XMLNode
1071 {
1072  friend class XMLDocument;
1073 public:
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 
1086 protected:
1087  explicit XMLDeclaration( XMLDocument* doc );
1088  virtual ~XMLDeclaration();
1089 
1090  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1091 
1092 private:
1093  XMLDeclaration( const XMLDeclaration& ); // not supported
1094  XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1095 };
1096 
1097 
1105 class TINYXML2_LIB XMLUnknown : public XMLNode
1106 {
1107  friend class XMLDocument;
1108 public:
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 
1121 protected:
1122  explicit XMLUnknown( XMLDocument* doc );
1123  virtual ~XMLUnknown();
1124 
1125  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1126 
1127 private:
1128  XMLUnknown( const XMLUnknown& ); // not supported
1129  XMLUnknown& operator=( const XMLUnknown& ); // not supported
1130 };
1131 
1132 
1133 
1140 class TINYXML2_LIB XMLAttribute
1141 {
1142  friend class XMLElement;
1143 public:
1145  const char* Name() const;
1146 
1148  const char* Value() const;
1149 
1151  int GetLineNum() const { return _parseLineNum; }
1152 
1154  const XMLAttribute* Next() const {
1155  return _next;
1156  }
1157 
1162  int IntValue() const {
1163  int i = 0;
1164  QueryIntValue(&i);
1165  return i;
1166  }
1167 
1168  int64_t Int64Value() const {
1169  int64_t i = 0;
1170  QueryInt64Value(&i);
1171  return i;
1172  }
1173 
1174  uint64_t Unsigned64Value() const {
1175  uint64_t i = 0;
1176  QueryUnsigned64Value(&i);
1177  return i;
1178  }
1179 
1181  unsigned UnsignedValue() const {
1182  unsigned i=0;
1183  QueryUnsignedValue( &i );
1184  return i;
1185  }
1187  bool BoolValue() const {
1188  bool b=false;
1189  QueryBoolValue( &b );
1190  return b;
1191  }
1193  double DoubleValue() const {
1194  double d=0;
1195  QueryDoubleValue( &d );
1196  return d;
1197  }
1199  float FloatValue() const {
1200  float f=0;
1201  QueryFloatValue( &f );
1202  return f;
1203  }
1204 
1209  XMLError QueryIntValue( int* value ) const;
1211  XMLError QueryUnsignedValue( unsigned int* value ) const;
1213  XMLError QueryInt64Value(int64_t* value) const;
1215  XMLError QueryUnsigned64Value(uint64_t* value) const;
1217  XMLError QueryBoolValue( bool* value ) const;
1219  XMLError QueryDoubleValue( double* value ) const;
1221  XMLError QueryFloatValue( float* value ) const;
1222 
1224  void SetAttribute( const char* value );
1226  void SetAttribute( int value );
1228  void SetAttribute( unsigned value );
1230  void SetAttribute(int64_t value);
1232  void SetAttribute(uint64_t value);
1234  void SetAttribute( bool value );
1236  void SetAttribute( double value );
1238  void SetAttribute( float value );
1239 
1240 private:
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 
1264 class TINYXML2_LIB XMLElement : public XMLNode
1265 {
1266  friend class XMLDocument;
1267 public:
1269  const char* Name() const {
1270  return Value();
1271  }
1273  void SetName( const char* str, bool staticMem=false ) {
1274  SetValue( 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 
1308  const char* Attribute( const char* name, const char* value=0 ) const;
1309 
1316  int IntAttribute(const char* name, int defaultValue = 0) const;
1318  unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1320  int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1322  uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
1324  bool BoolAttribute(const char* name, bool defaultValue = false) const;
1326  double DoubleAttribute(const char* name, double defaultValue = 0) const;
1328  float FloatAttribute(const char* name, float defaultValue = 0) const;
1329 
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 
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 
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 
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 
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  }
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  }
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 
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 
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 
1465  void SetAttribute( const char* name, const char* value ) {
1466  XMLAttribute* a = FindOrCreateAttribute( name );
1467  a->SetAttribute( value );
1468  }
1470  void SetAttribute( const char* name, int value ) {
1471  XMLAttribute* a = FindOrCreateAttribute( name );
1472  a->SetAttribute( value );
1473  }
1475  void SetAttribute( const char* name, unsigned value ) {
1476  XMLAttribute* a = FindOrCreateAttribute( name );
1477  a->SetAttribute( value );
1478  }
1479 
1481  void SetAttribute(const char* name, int64_t value) {
1482  XMLAttribute* a = FindOrCreateAttribute(name);
1483  a->SetAttribute(value);
1484  }
1485 
1487  void SetAttribute(const char* name, uint64_t value) {
1488  XMLAttribute* a = FindOrCreateAttribute(name);
1489  a->SetAttribute(value);
1490  }
1491 
1493  void SetAttribute( const char* name, bool value ) {
1494  XMLAttribute* a = FindOrCreateAttribute( name );
1495  a->SetAttribute( value );
1496  }
1498  void SetAttribute( const char* name, double value ) {
1499  XMLAttribute* a = FindOrCreateAttribute( name );
1500  a->SetAttribute( value );
1501  }
1503  void SetAttribute( const char* name, float value ) {
1504  XMLAttribute* a = FindOrCreateAttribute( name );
1505  a->SetAttribute( value );
1506  }
1507 
1511  void DeleteAttribute( const char* name );
1512 
1514  const XMLAttribute* FirstAttribute() const {
1515  return _rootAttribute;
1516  }
1518  const XMLAttribute* FindAttribute( const char* name ) const;
1519 
1548  const char* GetText() const;
1549 
1584  void SetText( const char* inText );
1586  void SetText( int value );
1588  void SetText( unsigned value );
1590  void SetText(int64_t value);
1592  void SetText(uint64_t value);
1594  void SetText( bool value );
1596  void SetText( double value );
1598  void SetText( float value );
1599 
1626  XMLError QueryIntText( int* ival ) const;
1628  XMLError QueryUnsignedText( unsigned* uval ) const;
1630  XMLError QueryInt64Text(int64_t* uval) const;
1632  XMLError QueryUnsigned64Text(uint64_t* uval) const;
1634  XMLError QueryBoolText( bool* bval ) const;
1636  XMLError QueryDoubleText( double* dval ) const;
1638  XMLError QueryFloatText( float* fval ) const;
1639 
1640  int IntText(int defaultValue = 0) const;
1641 
1643  unsigned UnsignedText(unsigned defaultValue = 0) const;
1645  int64_t Int64Text(int64_t defaultValue = 0) const;
1647  uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
1649  bool BoolText(bool defaultValue = false) const;
1651  double DoubleText(double defaultValue = 0) const;
1653  float FloatText(float defaultValue = 0) const;
1654 
1659  XMLElement* InsertNewChildElement(const char* name);
1661  XMLComment* InsertNewComment(const char* comment);
1663  XMLText* InsertNewText(const char* text);
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 
1682 protected:
1683  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1684 
1685 private:
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 
1705 enum Whitespace {
1706  PRESERVE_WHITESPACE,
1707  COLLAPSE_WHITESPACE
1708 };
1709 
1710 
1716 class 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;
1726 public:
1728  XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1729  ~XMLDocument();
1730 
1732  TIXMLASSERT( this == _document );
1733  return this;
1734  }
1735  virtual const XMLDocument* ToDocument() const {
1736  TIXMLASSERT( this == _document );
1737  return this;
1738  }
1739 
1750  XMLError Parse( const char* xml, size_t nBytes=static_cast<size_t>(-1) );
1751 
1757  XMLError LoadFile( const char* filename );
1758 
1770  XMLError LoadFile( FILE* );
1771 
1777  XMLError SaveFile( const char* filename, bool compact = false );
1778 
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 
1798  bool HasBOM() const {
1799  return _writeBOM;
1800  }
1803  void SetBOM( bool useBOM ) {
1804  _writeBOM = useBOM;
1805  }
1806 
1811  return FirstChildElement();
1812  }
1813  const XMLElement* RootElement() const {
1814  return FirstChildElement();
1815  }
1816 
1831  void Print( XMLPrinter* streamer=0 ) const;
1832  virtual bool Accept( XMLVisitor* visitor ) const;
1833 
1839  XMLElement* NewElement( const char* name );
1845  XMLComment* NewComment( const char* comment );
1851  XMLText* NewText( const char* text );
1863  XMLDeclaration* NewDeclaration( const char* text=0 );
1869  XMLUnknown* NewUnknown( const char* text );
1870 
1875  void DeleteNode( XMLNode* node );
1876 
1878  void ClearError();
1879 
1881  bool Error() const {
1882  return _errorID != XML_SUCCESS;
1883  }
1885  XMLError ErrorID() const {
1886  return _errorID;
1887  }
1888  const char* ErrorName() const;
1889  static const char* ErrorIDToName(XMLError errorID);
1890 
1894  const char* ErrorStr() const;
1895 
1897  void PrintError() const;
1898 
1900  int ErrorLineNum() const
1901  {
1902  return _errorLineNum;
1903  }
1904 
1906  void Clear();
1907 
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 
1930 private:
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 
1984 template<class NodeType, int PoolElementSize>
1985 inline 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(returnNode);
1994  return returnNode;
1995 }
1996 
2052 class TINYXML2_LIB XMLHandle
2053 {
2054 public:
2056  explicit XMLHandle( XMLNode* node ) : _node( node ) {
2057  }
2059  explicit XMLHandle( XMLNode& node ) : _node( &node ) {
2060  }
2062  XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
2063  }
2065  XMLHandle& operator=( const XMLHandle& ref ) {
2066  _node = ref._node;
2067  return *this;
2068  }
2069 
2072  return XMLHandle( _node ? _node->FirstChild() : 0 );
2073  }
2075  XMLHandle FirstChildElement( const char* name = 0 ) {
2076  return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
2077  }
2080  return XMLHandle( _node ? _node->LastChild() : 0 );
2081  }
2083  XMLHandle LastChildElement( const char* name = 0 ) {
2084  return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
2085  }
2088  return XMLHandle( _node ? _node->PreviousSibling() : 0 );
2089  }
2091  XMLHandle PreviousSiblingElement( const char* name = 0 ) {
2092  return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2093  }
2096  return XMLHandle( _node ? _node->NextSibling() : 0 );
2097  }
2099  XMLHandle NextSiblingElement( const char* name = 0 ) {
2100  return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2101  }
2102 
2105  return _node;
2106  }
2109  return ( _node ? _node->ToElement() : 0 );
2110  }
2113  return ( _node ? _node->ToText() : 0 );
2114  }
2117  return ( _node ? _node->ToUnknown() : 0 );
2118  }
2121  return ( _node ? _node->ToDeclaration() : 0 );
2122  }
2123 
2124 private:
2125  XMLNode* _node;
2126 };
2127 
2128 
2133 class TINYXML2_LIB XMLConstHandle
2134 {
2135 public:
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 
2190 private:
2191  const XMLNode* _node;
2192 };
2193 
2194 
2237 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2238 {
2239 public:
2246  XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2247  virtual ~XMLPrinter() {}
2248 
2250  void PushHeader( bool writeBOM, bool writeDeclaration );
2254  void OpenElement( const char* name, bool compactMode=false );
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 );
2264  virtual void CloseElement( bool compactMode=false );
2265 
2267  void PushText( const char* text, bool cdata=false );
2269  void PushText( int value );
2271  void PushText( unsigned value );
2273  void PushText( int64_t value );
2275  void PushText( uint64_t value );
2277  void PushText( bool value );
2279  void PushText( float value );
2281  void PushText( double value );
2282 
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 
2306  const char* CStr() const {
2307  return _buffer.Mem();
2308  }
2314  int CStrSize() const {
2315  return _buffer.Size();
2316  }
2321  void ClearBuffer( bool resetToFirstElement = true ) {
2322  _buffer.Clear();
2323  _buffer.Push(0);
2324  _firstElement = resetToFirstElement;
2325  }
2326 
2327 protected:
2328  virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2329 
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, strlen(data)); }
2339 
2340  void SealElementIfJustOpened();
2341  bool _elementJustOpened;
2342  DynArray< const char*, 10 > _stack;
2343 
2344 private:
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
Definition: tinyxml2.h:1141
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file.
Definition: tinyxml2.h:1151
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1181
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:1199
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:1193
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:1187
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:1162
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:1154
XMLError QueryUnsigned64Value(uint64_t *value) const
See QueryIntValue.
Definition: tinyxml2.h:1032
virtual XMLNode * ShallowClone(XMLDocument *document) const
virtual bool Accept(XMLVisitor *visitor) const
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1035
Definition: tinyxml2.h:2134
Definition: tinyxml2.h:1071
virtual XMLNode * ShallowClone(XMLDocument *document) const
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1074
virtual bool Accept(XMLVisitor *visitor) const
virtual bool ShallowEqual(const XMLNode *compare) const
Definition: tinyxml2.h:1717
void SetBOM(bool useBOM)
Definition: tinyxml2.h:1803
void PrintError() const
A (trivial) utility function that prints the ErrorStr() to stdout.
XMLError LoadFile(const char *filename)
bool HasBOM() const
Definition: tinyxml2.h:1798
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1881
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:1731
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:1900
XMLDocument(bool processEntities=true, Whitespace whitespaceMode=PRESERVE_WHITESPACE)
constructor
XMLError LoadFile(FILE *)
void Clear()
Clear the document, resetting it to the initial state.
virtual bool ShallowEqual(const XMLNode *) const
Definition: tinyxml2.h:1926
XMLError SaveFile(const char *filename, bool compact=false)
void Print(XMLPrinter *streamer=0) const
XMLElement * NewElement(const char *name)
XMLError SaveFile(FILE *fp, bool compact=false)
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLNode * ShallowClone(XMLDocument *) const
Definition: tinyxml2.h:1923
XMLText * NewText(const char *text)
void DeleteNode(XMLNode *node)
XMLElement * RootElement()
Definition: tinyxml2.h:1810
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:1885
Definition: tinyxml2.h:1265
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:1465
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
XMLError QueryUnsigned64Attribute(const char *name, uint64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1370
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1379
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:1498
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1352
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:1514
virtual bool Accept(XMLVisitor *visitor) const
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:1503
XMLError QueryAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1432
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1387
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1269
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
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:1361
double DoubleText(double defaultValue=0) const
See QueryIntText()
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1343
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:1273
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1493
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1470
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1481
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
XMLElement * InsertNewChildElement(const char *name)
virtual XMLNode * ShallowClone(XMLDocument *document) const
XMLError QueryUnsigned64Text(uint64_t *uval) const
See QueryIntText()
XMLUnknown * InsertNewUnknown(const char *text)
See InsertNewChildElement()
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1395
void SetAttribute(const char *name, uint64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1487
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1277
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1404
XMLDeclaration * InsertNewDeclaration(const char *text)
See InsertNewChildElement()
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1475
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:2053
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2104
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2120
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:2087
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition: tinyxml2.h:2083
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:2071
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2108
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2112
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition: tinyxml2.h:2075
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition: tinyxml2.h:2065
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:2091
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:2056
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:2079
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:2059
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2116
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:2095
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2099
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:2062
Definition: tinyxml2.h:675
void SetUserData(void *userData)
Definition: tinyxml2.h:939
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:708
const XMLElement * FirstChildElement(const char *name=0) const
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:681
void DeleteChild(XMLNode *node)
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:696
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:821
virtual bool ShallowEqual(const XMLNode *compare) const =0
void * GetUserData() const
Definition: tinyxml2.h:946
virtual bool Accept(XMLVisitor *visitor) const =0
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:704
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:712
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:752
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:787
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:692
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition: tinyxml2.h:805
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:764
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:755
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:769
XMLNode * InsertEndChild(XMLNode *addThis)
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:686
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:700
Definition: tinyxml2.h:2238
virtual void PrintSpace(int depth)
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:2290
void PushHeader(bool writeBOM, bool writeDeclaration)
const char * CStr() const
Definition: tinyxml2.h:2306
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 Visit(const XMLText &text)
Visit a text node.
virtual bool VisitEnter(const XMLElement &element, const XMLAttribute *attribute)
Visit an element.
int CStrSize() const
Definition: tinyxml2.h:2314
void PushText(int value)
Add a text node from an integer.
virtual bool Visit(const XMLComment &comment)
Visit a comment node.
void PushText(bool value)
Add a text node from a bool.
void PushText(uint64_t value)
Add a text node from an unsigned 64bit integer.
void PushText(unsigned value)
Add a text node from an unsigned.
void ClearBuffer(bool resetToFirstElement=true)
Definition: tinyxml2.h:2321
void PushText(int64_t value)
Add a text node from a signed 64bit integer.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
virtual bool Visit(const XMLDeclaration &declaration)
Visit a declaration.
virtual bool Visit(const XMLUnknown &unknown)
Visit an unknown node.
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 VisitEnter(const XMLDocument &)
Visit a document.
virtual bool VisitExit(const XMLElement &element)
Visit an element.
void PushComment(const char *comment)
Add a comment.
Definition: tinyxml2.h:992
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:997
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:1009
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:1005
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLNode * ShallowClone(XMLDocument *document) const
Definition: tinyxml2.h:1106
virtual XMLNode * ShallowClone(XMLDocument *document) const
virtual bool ShallowEqual(const XMLNode *compare) const
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1109
Definition: tinyxml2.h:482
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:517
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:491
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:500
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:487
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:513
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:505
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:509
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:496