NSCL DDAS  1.0
Support for XIA DDAS at the NSCL
 All Classes Namespaces Files Functions Variables Macros Pages
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(TINYXML2_DEBUG)
83 # if defined(_MSC_VER)
84 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
85 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); }
86 # elif defined (ANDROID_NDK)
87 # include <android/log.h>
88 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
89 # else
90 # include <assert.h>
91 # define TIXMLASSERT assert
92 # endif
93 #else
94 # define TIXMLASSERT( x ) {}
95 #endif
96 
97 
98 /* Versioning, past 1.0.14:
99  http://semver.org/
100 */
101 static const int TIXML2_MAJOR_VERSION = 7;
102 static const int TIXML2_MINOR_VERSION = 1;
103 static const int TIXML2_PATCH_VERSION = 0;
104 
105 #define TINYXML2_MAJOR_VERSION 7
106 #define TINYXML2_MINOR_VERSION 1
107 #define TINYXML2_PATCH_VERSION 0
108 
109 // A fixed element depth limit is problematic. There needs to be a
110 // limit to avoid a stack overflow. However, that limit varies per
111 // system, and the capacity of the stack. On the other hand, it's a trivial
112 // attack that can result from ill, malicious, or even correctly formed XML,
113 // so there needs to be a limit in place.
114 static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
115 
116 namespace tinyxml2
117 {
118 class XMLDocument;
119 class XMLElement;
120 class XMLAttribute;
121 class XMLComment;
122 class XMLText;
123 class XMLDeclaration;
124 class XMLUnknown;
125 class XMLPrinter;
126 
127 /*
128  A class that wraps strings. Normally stores the start and end
129  pointers into the XML file itself, and will apply normalization
130  and entity translation if actually read. Can also store (and memory
131  manage) a traditional char[]
132 
133  Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
134 */
135 class TINYXML2_LIB StrPair
136 {
137 public:
138  enum {
139  NEEDS_ENTITY_PROCESSING = 0x01,
140  NEEDS_NEWLINE_NORMALIZATION = 0x02,
141  NEEDS_WHITESPACE_COLLAPSING = 0x04,
142 
143  TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
144  TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
145  ATTRIBUTE_NAME = 0,
146  ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
147  ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
148  COMMENT = NEEDS_NEWLINE_NORMALIZATION
149  };
150 
151  StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
152  ~StrPair();
153 
154  void Set( char* start, char* end, int flags ) {
155  TIXMLASSERT( start );
156  TIXMLASSERT( end );
157  Reset();
158  _start = start;
159  _end = end;
160  _flags = flags | NEEDS_FLUSH;
161  }
162 
163  const char* GetStr();
164 
165  bool Empty() const {
166  return _start == _end;
167  }
168 
169  void SetInternedStr( const char* str ) {
170  Reset();
171  _start = const_cast<char*>(str);
172  }
173 
174  void SetStr( const char* str, int flags=0 );
175 
176  char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
177  char* ParseName( char* in );
178 
179  void TransferTo( StrPair* other );
180  void Reset();
181 
182 private:
183  void CollapseWhitespace();
184 
185  enum {
186  NEEDS_FLUSH = 0x100,
187  NEEDS_DELETE = 0x200
188  };
189 
190  int _flags;
191  char* _start;
192  char* _end;
193 
194  StrPair( const StrPair& other ); // not supported
195  void operator=( const StrPair& other ); // not supported, use TransferTo()
196 };
197 
198 
199 /*
200  A dynamic array of Plain Old Data. Doesn't support constructors, etc.
201  Has a small initial memory pool, so that low or no usage will not
202  cause a call to new/delete
203 */
204 template <class T, int INITIAL_SIZE>
205 class DynArray
206 {
207 public:
208  DynArray() :
209  _mem( _pool ),
210  _allocated( INITIAL_SIZE ),
211  _size( 0 )
212  {
213  }
214 
215  ~DynArray() {
216  if ( _mem != _pool ) {
217  delete [] _mem;
218  }
219  }
220 
221  void Clear() {
222  _size = 0;
223  }
224 
225  void Push( T t ) {
226  TIXMLASSERT( _size < INT_MAX );
227  EnsureCapacity( _size+1 );
228  _mem[_size] = t;
229  ++_size;
230  }
231 
232  T* PushArr( int count ) {
233  TIXMLASSERT( count >= 0 );
234  TIXMLASSERT( _size <= INT_MAX - count );
235  EnsureCapacity( _size+count );
236  T* ret = &_mem[_size];
237  _size += count;
238  return ret;
239  }
240 
241  T Pop() {
242  TIXMLASSERT( _size > 0 );
243  --_size;
244  return _mem[_size];
245  }
246 
247  void PopArr( int count ) {
248  TIXMLASSERT( _size >= count );
249  _size -= count;
250  }
251 
252  bool Empty() const {
253  return _size == 0;
254  }
255 
256  T& operator[](int i) {
257  TIXMLASSERT( i>= 0 && i < _size );
258  return _mem[i];
259  }
260 
261  const T& operator[](int i) const {
262  TIXMLASSERT( i>= 0 && i < _size );
263  return _mem[i];
264  }
265 
266  const T& PeekTop() const {
267  TIXMLASSERT( _size > 0 );
268  return _mem[ _size - 1];
269  }
270 
271  int Size() const {
272  TIXMLASSERT( _size >= 0 );
273  return _size;
274  }
275 
276  int Capacity() const {
277  TIXMLASSERT( _allocated >= INITIAL_SIZE );
278  return _allocated;
279  }
280 
281  void SwapRemove(int i) {
282  TIXMLASSERT(i >= 0 && i < _size);
283  TIXMLASSERT(_size > 0);
284  _mem[i] = _mem[_size - 1];
285  --_size;
286  }
287 
288  const T* Mem() const {
289  TIXMLASSERT( _mem );
290  return _mem;
291  }
292 
293  T* Mem() {
294  TIXMLASSERT( _mem );
295  return _mem;
296  }
297 
298 private:
299  DynArray( const DynArray& ); // not supported
300  void operator=( const DynArray& ); // not supported
301 
302  void EnsureCapacity( int cap ) {
303  TIXMLASSERT( cap > 0 );
304  if ( cap > _allocated ) {
305  TIXMLASSERT( cap <= INT_MAX / 2 );
306  const int newAllocated = cap * 2;
307  T* newMem = new T[newAllocated];
308  TIXMLASSERT( newAllocated >= _size );
309  memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
310  if ( _mem != _pool ) {
311  delete [] _mem;
312  }
313  _mem = newMem;
314  _allocated = newAllocated;
315  }
316  }
317 
318  T* _mem;
319  T _pool[INITIAL_SIZE];
320  int _allocated; // objects allocated
321  int _size; // number objects in use
322 };
323 
324 
325 /*
326  Parent virtual class of a pool for fast allocation
327  and deallocation of objects.
328 */
329 class MemPool
330 {
331 public:
332  MemPool() {}
333  virtual ~MemPool() {}
334 
335  virtual int ItemSize() const = 0;
336  virtual void* Alloc() = 0;
337  virtual void Free( void* ) = 0;
338  virtual void SetTracked() = 0;
339 };
340 
341 
342 /*
343  Template child class to create pools of the correct type.
344 */
345 template< int ITEM_SIZE >
346 class MemPoolT : public MemPool
347 {
348 public:
349  MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
350  ~MemPoolT() {
352  }
353 
354  void Clear() {
355  // Delete the blocks.
356  while( !_blockPtrs.Empty()) {
357  Block* lastBlock = _blockPtrs.Pop();
358  delete lastBlock;
359  }
360  _root = 0;
361  _currentAllocs = 0;
362  _nAllocs = 0;
363  _maxAllocs = 0;
364  _nUntracked = 0;
365  }
366 
367  virtual int ItemSize() const {
368  return ITEM_SIZE;
369  }
370  int CurrentAllocs() const {
371  return _currentAllocs;
372  }
373 
374  virtual void* Alloc() {
375  if ( !_root ) {
376  // Need a new block.
377  Block* block = new Block();
378  _blockPtrs.Push( block );
379 
380  Item* blockItems = block->items;
381  for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
382  blockItems[i].next = &(blockItems[i + 1]);
383  }
384  blockItems[ITEMS_PER_BLOCK - 1].next = 0;
385  _root = blockItems;
386  }
387  Item* const result = _root;
388  TIXMLASSERT( result != 0 );
389  _root = _root->next;
390 
391  ++_currentAllocs;
392  if ( _currentAllocs > _maxAllocs ) {
393  _maxAllocs = _currentAllocs;
394  }
395  ++_nAllocs;
396  ++_nUntracked;
397  return result;
398  }
399 
400  virtual void Free( void* mem ) {
401  if ( !mem ) {
402  return;
403  }
404  --_currentAllocs;
405  Item* item = static_cast<Item*>( mem );
406 #ifdef TINYXML2_DEBUG
407  memset( item, 0xfe, sizeof( *item ) );
408 #endif
409  item->next = _root;
410  _root = item;
411  }
412  void Trace( const char* name ) {
413  printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
414  name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
415  ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
416  }
417 
418  void SetTracked() {
419  --_nUntracked;
420  }
421 
422  int Untracked() const {
423  return _nUntracked;
424  }
425 
426  // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
427  // The test file is large, 170k.
428  // Release: VS2010 gcc(no opt)
429  // 1k: 4000
430  // 2k: 4000
431  // 4k: 3900 21000
432  // 16k: 5200
433  // 32k: 4300
434  // 64k: 4000 21000
435  // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
436  // in private part if ITEMS_PER_BLOCK is private
437  enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
438 
439 private:
440  MemPoolT( const MemPoolT& ); // not supported
441  void operator=( const MemPoolT& ); // not supported
442 
443  union Item {
444  Item* next;
445  char itemData[ITEM_SIZE];
446  };
447  struct Block {
448  Item items[ITEMS_PER_BLOCK];
449  };
450  DynArray< Block*, 10 > _blockPtrs;
451  Item* _root;
452 
453  int _currentAllocs;
454  int _nAllocs;
455  int _maxAllocs;
456  int _nUntracked;
457 };
458 
459 
460 
480 class TINYXML2_LIB XMLVisitor
481 {
482 public:
483  virtual ~XMLVisitor() {}
484 
486  virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
487  return true;
488  }
490  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
491  return true;
492  }
493 
495  virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
496  return true;
497  }
499  virtual bool VisitExit( const XMLElement& /*element*/ ) {
500  return true;
501  }
502 
504  virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
505  return true;
506  }
508  virtual bool Visit( const XMLText& /*text*/ ) {
509  return true;
510  }
512  virtual bool Visit( const XMLComment& /*comment*/ ) {
513  return true;
514  }
516  virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
517  return true;
518  }
519 };
520 
521 // WARNING: must match XMLDocument::_errorNames[]
522 enum XMLError {
523  XML_SUCCESS = 0,
524  XML_NO_ATTRIBUTE,
525  XML_WRONG_ATTRIBUTE_TYPE,
526  XML_ERROR_FILE_NOT_FOUND,
527  XML_ERROR_FILE_COULD_NOT_BE_OPENED,
528  XML_ERROR_FILE_READ_ERROR,
529  XML_ERROR_PARSING_ELEMENT,
530  XML_ERROR_PARSING_ATTRIBUTE,
531  XML_ERROR_PARSING_TEXT,
532  XML_ERROR_PARSING_CDATA,
533  XML_ERROR_PARSING_COMMENT,
534  XML_ERROR_PARSING_DECLARATION,
535  XML_ERROR_PARSING_UNKNOWN,
536  XML_ERROR_EMPTY_DOCUMENT,
537  XML_ERROR_MISMATCHED_ELEMENT,
538  XML_ERROR_PARSING,
539  XML_CAN_NOT_CONVERT_TEXT,
540  XML_NO_TEXT_NODE,
541  XML_ELEMENT_DEPTH_EXCEEDED,
542 
543  XML_ERROR_COUNT
544 };
545 
546 
547 /*
548  Utility functionality.
549 */
550 class TINYXML2_LIB XMLUtil
551 {
552 public:
553  static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
554  TIXMLASSERT( p );
555 
556  while( IsWhiteSpace(*p) ) {
557  if (curLineNumPtr && *p == '\n') {
558  ++(*curLineNumPtr);
559  }
560  ++p;
561  }
562  TIXMLASSERT( p );
563  return p;
564  }
565  static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
566  return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
567  }
568 
569  // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
570  // correct, but simple, and usually works.
571  static bool IsWhiteSpace( char p ) {
572  return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
573  }
574 
575  inline static bool IsNameStartChar( unsigned char ch ) {
576  if ( ch >= 128 ) {
577  // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
578  return true;
579  }
580  if ( isalpha( ch ) ) {
581  return true;
582  }
583  return ch == ':' || ch == '_';
584  }
585 
586  inline static bool IsNameChar( unsigned char ch ) {
587  return IsNameStartChar( ch )
588  || isdigit( ch )
589  || ch == '.'
590  || ch == '-';
591  }
592 
593  inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
594  if ( p == q ) {
595  return true;
596  }
597  TIXMLASSERT( p );
598  TIXMLASSERT( q );
599  TIXMLASSERT( nChar >= 0 );
600  return strncmp( p, q, nChar ) == 0;
601  }
602 
603  inline static bool IsUTF8Continuation( char p ) {
604  return ( p & 0x80 ) != 0;
605  }
606 
607  static const char* ReadBOM( const char* p, bool* hasBOM );
608  // p is the starting location,
609  // the UTF-8 value of the entity will be placed in value, and length filled in.
610  static const char* GetCharacterRef( const char* p, char* value, int* length );
611  static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
612 
613  // converts primitive types to strings
614  static void ToStr( int v, char* buffer, int bufferSize );
615  static void ToStr( unsigned v, char* buffer, int bufferSize );
616  static void ToStr( bool v, char* buffer, int bufferSize );
617  static void ToStr( float v, char* buffer, int bufferSize );
618  static void ToStr( double v, char* buffer, int bufferSize );
619  static void ToStr(int64_t v, char* buffer, int bufferSize);
620  static void ToStr(uint64_t v, char* buffer, int bufferSize);
621 
622  // converts strings to primitive types
623  static bool ToInt( const char* str, int* value );
624  static bool ToUnsigned( const char* str, unsigned* value );
625  static bool ToBool( const char* str, bool* value );
626  static bool ToFloat( const char* str, float* value );
627  static bool ToDouble( const char* str, double* value );
628  static bool ToInt64(const char* str, int64_t* value);
629  static bool ToUnsigned64(const char* str, uint64_t* value);
630  // Changes what is serialized for a boolean value.
631  // Default to "true" and "false". Shouldn't be changed
632  // unless you have a special testing or compatibility need.
633  // Be careful: static, global, & not thread safe.
634  // Be sure to set static const memory as parameters.
635  static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
636 
637 private:
638  static const char* writeBoolTrue;
639  static const char* writeBoolFalse;
640 };
641 
642 
668 class TINYXML2_LIB XMLNode
669 {
670  friend class XMLDocument;
671  friend class XMLElement;
672 public:
673 
675  const XMLDocument* GetDocument() const {
676  TIXMLASSERT( _document );
677  return _document;
678  }
681  TIXMLASSERT( _document );
682  return _document;
683  }
684 
686  virtual XMLElement* ToElement() {
687  return 0;
688  }
690  virtual XMLText* ToText() {
691  return 0;
692  }
694  virtual XMLComment* ToComment() {
695  return 0;
696  }
698  virtual XMLDocument* ToDocument() {
699  return 0;
700  }
703  return 0;
704  }
706  virtual XMLUnknown* ToUnknown() {
707  return 0;
708  }
709 
710  virtual const XMLElement* ToElement() const {
711  return 0;
712  }
713  virtual const XMLText* ToText() const {
714  return 0;
715  }
716  virtual const XMLComment* ToComment() const {
717  return 0;
718  }
719  virtual const XMLDocument* ToDocument() const {
720  return 0;
721  }
722  virtual const XMLDeclaration* ToDeclaration() const {
723  return 0;
724  }
725  virtual const XMLUnknown* ToUnknown() const {
726  return 0;
727  }
728 
738  const char* Value() const;
739 
743  void SetValue( const char* val, bool staticMem=false );
744 
746  int GetLineNum() const { return _parseLineNum; }
747 
749  const XMLNode* Parent() const {
750  return _parent;
751  }
752 
753  XMLNode* Parent() {
754  return _parent;
755  }
756 
758  bool NoChildren() const {
759  return !_firstChild;
760  }
761 
763  const XMLNode* FirstChild() const {
764  return _firstChild;
765  }
766 
767  XMLNode* FirstChild() {
768  return _firstChild;
769  }
770 
774  const XMLElement* FirstChildElement( const char* name = 0 ) const;
775 
776  XMLElement* FirstChildElement( const char* name = 0 ) {
777  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
778  }
779 
781  const XMLNode* LastChild() const {
782  return _lastChild;
783  }
784 
785  XMLNode* LastChild() {
786  return _lastChild;
787  }
788 
792  const XMLElement* LastChildElement( const char* name = 0 ) const;
793 
794  XMLElement* LastChildElement( const char* name = 0 ) {
795  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
796  }
797 
799  const XMLNode* PreviousSibling() const {
800  return _prev;
801  }
802 
803  XMLNode* PreviousSibling() {
804  return _prev;
805  }
806 
808  const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
809 
810  XMLElement* PreviousSiblingElement( const char* name = 0 ) {
811  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
812  }
813 
815  const XMLNode* NextSibling() const {
816  return _next;
817  }
818 
819  XMLNode* NextSibling() {
820  return _next;
821  }
822 
824  const XMLElement* NextSiblingElement( const char* name = 0 ) const;
825 
826  XMLElement* NextSiblingElement( const char* name = 0 ) {
827  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
828  }
829 
837  XMLNode* InsertEndChild( XMLNode* addThis );
838 
839  XMLNode* LinkEndChild( XMLNode* addThis ) {
840  return InsertEndChild( addThis );
841  }
849  XMLNode* InsertFirstChild( XMLNode* addThis );
858  XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
859 
863  void DeleteChildren();
864 
868  void DeleteChild( XMLNode* node );
869 
879  virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
880 
894  XMLNode* DeepClone( XMLDocument* target ) const;
895 
902  virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
903 
926  virtual bool Accept( XMLVisitor* visitor ) const = 0;
927 
933  void SetUserData(void* userData) { _userData = userData; }
934 
940  void* GetUserData() const { return _userData; }
941 
942 protected:
943  explicit XMLNode( XMLDocument* );
944  virtual ~XMLNode();
945 
946  virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
947 
948  XMLDocument* _document;
949  XMLNode* _parent;
950  mutable StrPair _value;
951  int _parseLineNum;
952 
953  XMLNode* _firstChild;
954  XMLNode* _lastChild;
955 
956  XMLNode* _prev;
957  XMLNode* _next;
958 
959  void* _userData;
960 
961 private:
962  MemPool* _memPool;
963  void Unlink( XMLNode* child );
964  static void DeleteNode( XMLNode* node );
965  void InsertChildPreamble( XMLNode* insertThis ) const;
966  const XMLElement* ToElementWithName( const char* name ) const;
967 
968  XMLNode( const XMLNode& ); // not supported
969  XMLNode& operator=( const XMLNode& ); // not supported
970 };
971 
972 
985 class TINYXML2_LIB XMLText : public XMLNode
986 {
987  friend class XMLDocument;
988 public:
989  virtual bool Accept( XMLVisitor* visitor ) const;
990 
991  virtual XMLText* ToText() {
992  return this;
993  }
994  virtual const XMLText* ToText() const {
995  return this;
996  }
997 
999  void SetCData( bool isCData ) {
1000  _isCData = isCData;
1001  }
1003  bool CData() const {
1004  return _isCData;
1005  }
1006 
1007  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1008  virtual bool ShallowEqual( const XMLNode* compare ) const;
1009 
1010 protected:
1011  explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
1012  virtual ~XMLText() {}
1013 
1014  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1015 
1016 private:
1017  bool _isCData;
1018 
1019  XMLText( const XMLText& ); // not supported
1020  XMLText& operator=( const XMLText& ); // not supported
1021 };
1022 
1023 
1025 class TINYXML2_LIB XMLComment : public XMLNode
1026 {
1027  friend class XMLDocument;
1028 public:
1029  virtual XMLComment* ToComment() {
1030  return this;
1031  }
1032  virtual const XMLComment* ToComment() const {
1033  return this;
1034  }
1035 
1036  virtual bool Accept( XMLVisitor* visitor ) const;
1037 
1038  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1039  virtual bool ShallowEqual( const XMLNode* compare ) const;
1040 
1041 protected:
1042  explicit XMLComment( XMLDocument* doc );
1043  virtual ~XMLComment();
1044 
1045  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
1046 
1047 private:
1048  XMLComment( const XMLComment& ); // not supported
1049  XMLComment& operator=( const XMLComment& ); // not supported
1050 };
1051 
1052 
1064 class TINYXML2_LIB XMLDeclaration : public XMLNode
1065 {
1066  friend class XMLDocument;
1067 public:
1069  return this;
1070  }
1071  virtual const XMLDeclaration* ToDeclaration() const {
1072  return this;
1073  }
1074 
1075  virtual bool Accept( XMLVisitor* visitor ) const;
1076 
1077  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1078  virtual bool ShallowEqual( const XMLNode* compare ) const;
1079 
1080 protected:
1081  explicit XMLDeclaration( XMLDocument* doc );
1082  virtual ~XMLDeclaration();
1083 
1084  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1085 
1086 private:
1087  XMLDeclaration( const XMLDeclaration& ); // not supported
1088  XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1089 };
1090 
1091 
1099 class TINYXML2_LIB XMLUnknown : public XMLNode
1100 {
1101  friend class XMLDocument;
1102 public:
1103  virtual XMLUnknown* ToUnknown() {
1104  return this;
1105  }
1106  virtual const XMLUnknown* ToUnknown() const {
1107  return this;
1108  }
1109 
1110  virtual bool Accept( XMLVisitor* visitor ) const;
1111 
1112  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1113  virtual bool ShallowEqual( const XMLNode* compare ) const;
1114 
1115 protected:
1116  explicit XMLUnknown( XMLDocument* doc );
1117  virtual ~XMLUnknown();
1118 
1119  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1120 
1121 private:
1122  XMLUnknown( const XMLUnknown& ); // not supported
1123  XMLUnknown& operator=( const XMLUnknown& ); // not supported
1124 };
1125 
1126 
1127 
1134 class TINYXML2_LIB XMLAttribute
1135 {
1136  friend class XMLElement;
1137 public:
1139  const char* Name() const;
1140 
1142  const char* Value() const;
1143 
1145  int GetLineNum() const { return _parseLineNum; }
1146 
1148  const XMLAttribute* Next() const {
1149  return _next;
1150  }
1151 
1156  int IntValue() const {
1157  int i = 0;
1158  QueryIntValue(&i);
1159  return i;
1160  }
1161 
1162  int64_t Int64Value() const {
1163  int64_t i = 0;
1164  QueryInt64Value(&i);
1165  return i;
1166  }
1167 
1168  uint64_t Unsigned64Value() const {
1169  uint64_t i = 0;
1170  QueryUnsigned64Value(&i);
1171  return i;
1172  }
1173 
1175  unsigned UnsignedValue() const {
1176  unsigned i=0;
1177  QueryUnsignedValue( &i );
1178  return i;
1179  }
1181  bool BoolValue() const {
1182  bool b=false;
1183  QueryBoolValue( &b );
1184  return b;
1185  }
1187  double DoubleValue() const {
1188  double d=0;
1189  QueryDoubleValue( &d );
1190  return d;
1191  }
1193  float FloatValue() const {
1194  float f=0;
1195  QueryFloatValue( &f );
1196  return f;
1197  }
1198 
1203  XMLError QueryIntValue( int* value ) const;
1205  XMLError QueryUnsignedValue( unsigned int* value ) const;
1207  XMLError QueryInt64Value(int64_t* value) const;
1209  XMLError QueryUnsigned64Value(uint64_t* value) const;
1211  XMLError QueryBoolValue( bool* value ) const;
1213  XMLError QueryDoubleValue( double* value ) const;
1215  XMLError QueryFloatValue( float* value ) const;
1216 
1218  void SetAttribute( const char* value );
1220  void SetAttribute( int value );
1222  void SetAttribute( unsigned value );
1224  void SetAttribute(int64_t value);
1226  void SetAttribute(uint64_t value);
1228  void SetAttribute( bool value );
1230  void SetAttribute( double value );
1232  void SetAttribute( float value );
1233 
1234 private:
1235  enum { BUF_SIZE = 200 };
1236 
1237  XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
1238  virtual ~XMLAttribute() {}
1239 
1240  XMLAttribute( const XMLAttribute& ); // not supported
1241  void operator=( const XMLAttribute& ); // not supported
1242  void SetName( const char* name );
1243 
1244  char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
1245 
1246  mutable StrPair _name;
1247  mutable StrPair _value;
1248  int _parseLineNum;
1249  XMLAttribute* _next;
1250  MemPool* _memPool;
1251 };
1252 
1253 
1258 class TINYXML2_LIB XMLElement : public XMLNode
1259 {
1260  friend class XMLDocument;
1261 public:
1263  const char* Name() const {
1264  return Value();
1265  }
1267  void SetName( const char* str, bool staticMem=false ) {
1268  SetValue( str, staticMem );
1269  }
1270 
1271  virtual XMLElement* ToElement() {
1272  return this;
1273  }
1274  virtual const XMLElement* ToElement() const {
1275  return this;
1276  }
1277  virtual bool Accept( XMLVisitor* visitor ) const;
1278 
1302  const char* Attribute( const char* name, const char* value=0 ) const;
1303 
1310  int IntAttribute(const char* name, int defaultValue = 0) const;
1312  unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1314  int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1316  uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
1318  bool BoolAttribute(const char* name, bool defaultValue = false) const;
1320  double DoubleAttribute(const char* name, double defaultValue = 0) const;
1322  float FloatAttribute(const char* name, float defaultValue = 0) const;
1323 
1337  XMLError QueryIntAttribute( const char* name, int* value ) const {
1338  const XMLAttribute* a = FindAttribute( name );
1339  if ( !a ) {
1340  return XML_NO_ATTRIBUTE;
1341  }
1342  return a->QueryIntValue( value );
1343  }
1344 
1346  XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
1347  const XMLAttribute* a = FindAttribute( name );
1348  if ( !a ) {
1349  return XML_NO_ATTRIBUTE;
1350  }
1351  return a->QueryUnsignedValue( value );
1352  }
1353 
1355  XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1356  const XMLAttribute* a = FindAttribute(name);
1357  if (!a) {
1358  return XML_NO_ATTRIBUTE;
1359  }
1360  return a->QueryInt64Value(value);
1361  }
1362 
1364  XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const {
1365  const XMLAttribute* a = FindAttribute(name);
1366  if(!a) {
1367  return XML_NO_ATTRIBUTE;
1368  }
1369  return a->QueryUnsigned64Value(value);
1370  }
1371 
1373  XMLError QueryBoolAttribute( const char* name, bool* value ) const {
1374  const XMLAttribute* a = FindAttribute( name );
1375  if ( !a ) {
1376  return XML_NO_ATTRIBUTE;
1377  }
1378  return a->QueryBoolValue( value );
1379  }
1381  XMLError QueryDoubleAttribute( const char* name, double* value ) const {
1382  const XMLAttribute* a = FindAttribute( name );
1383  if ( !a ) {
1384  return XML_NO_ATTRIBUTE;
1385  }
1386  return a->QueryDoubleValue( value );
1387  }
1389  XMLError QueryFloatAttribute( const char* name, float* value ) const {
1390  const XMLAttribute* a = FindAttribute( name );
1391  if ( !a ) {
1392  return XML_NO_ATTRIBUTE;
1393  }
1394  return a->QueryFloatValue( value );
1395  }
1396 
1398  XMLError QueryStringAttribute(const char* name, const char** value) const {
1399  const XMLAttribute* a = FindAttribute(name);
1400  if (!a) {
1401  return XML_NO_ATTRIBUTE;
1402  }
1403  *value = a->Value();
1404  return XML_SUCCESS;
1405  }
1406 
1407 
1408 
1426  XMLError QueryAttribute( const char* name, int* value ) const {
1427  return QueryIntAttribute( name, value );
1428  }
1429 
1430  XMLError QueryAttribute( const char* name, unsigned int* value ) const {
1431  return QueryUnsignedAttribute( name, value );
1432  }
1433 
1434  XMLError QueryAttribute(const char* name, int64_t* value) const {
1435  return QueryInt64Attribute(name, value);
1436  }
1437 
1438  XMLError QueryAttribute(const char* name, uint64_t* value) const {
1439  return QueryUnsigned64Attribute(name, value);
1440  }
1441 
1442  XMLError QueryAttribute( const char* name, bool* value ) const {
1443  return QueryBoolAttribute( name, value );
1444  }
1445 
1446  XMLError QueryAttribute( const char* name, double* value ) const {
1447  return QueryDoubleAttribute( name, value );
1448  }
1449 
1450  XMLError QueryAttribute( const char* name, float* value ) const {
1451  return QueryFloatAttribute( name, value );
1452  }
1453 
1455  void SetAttribute( const char* name, const char* value ) {
1456  XMLAttribute* a = FindOrCreateAttribute( name );
1457  a->SetAttribute( value );
1458  }
1460  void SetAttribute( const char* name, int value ) {
1461  XMLAttribute* a = FindOrCreateAttribute( name );
1462  a->SetAttribute( value );
1463  }
1465  void SetAttribute( const char* name, unsigned value ) {
1466  XMLAttribute* a = FindOrCreateAttribute( name );
1467  a->SetAttribute( value );
1468  }
1469 
1471  void SetAttribute(const char* name, int64_t value) {
1472  XMLAttribute* a = FindOrCreateAttribute(name);
1473  a->SetAttribute(value);
1474  }
1475 
1477  void SetAttribute(const char* name, uint64_t value) {
1478  XMLAttribute* a = FindOrCreateAttribute(name);
1479  a->SetAttribute(value);
1480  }
1481 
1483  void SetAttribute( const char* name, bool value ) {
1484  XMLAttribute* a = FindOrCreateAttribute( name );
1485  a->SetAttribute( value );
1486  }
1488  void SetAttribute( const char* name, double value ) {
1489  XMLAttribute* a = FindOrCreateAttribute( name );
1490  a->SetAttribute( value );
1491  }
1493  void SetAttribute( const char* name, float value ) {
1494  XMLAttribute* a = FindOrCreateAttribute( name );
1495  a->SetAttribute( value );
1496  }
1497 
1501  void DeleteAttribute( const char* name );
1502 
1504  const XMLAttribute* FirstAttribute() const {
1505  return _rootAttribute;
1506  }
1508  const XMLAttribute* FindAttribute( const char* name ) const;
1509 
1538  const char* GetText() const;
1539 
1574  void SetText( const char* inText );
1576  void SetText( int value );
1578  void SetText( unsigned value );
1580  void SetText(int64_t value);
1582  void SetText(uint64_t value);
1584  void SetText( bool value );
1586  void SetText( double value );
1588  void SetText( float value );
1589 
1616  XMLError QueryIntText( int* ival ) const;
1618  XMLError QueryUnsignedText( unsigned* uval ) const;
1620  XMLError QueryInt64Text(int64_t* uval) const;
1622  XMLError QueryUnsigned64Text(uint64_t* uval) const;
1624  XMLError QueryBoolText( bool* bval ) const;
1626  XMLError QueryDoubleText( double* dval ) const;
1628  XMLError QueryFloatText( float* fval ) const;
1629 
1630  int IntText(int defaultValue = 0) const;
1631 
1633  unsigned UnsignedText(unsigned defaultValue = 0) const;
1635  int64_t Int64Text(int64_t defaultValue = 0) const;
1637  uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
1639  bool BoolText(bool defaultValue = false) const;
1641  double DoubleText(double defaultValue = 0) const;
1643  float FloatText(float defaultValue = 0) const;
1644 
1645  // internal:
1646  enum ElementClosingType {
1647  OPEN, // <foo>
1648  CLOSED, // <foo/>
1649  CLOSING // </foo>
1650  };
1651  ElementClosingType ClosingType() const {
1652  return _closingType;
1653  }
1654  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1655  virtual bool ShallowEqual( const XMLNode* compare ) const;
1656 
1657 protected:
1658  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1659 
1660 private:
1661  XMLElement( XMLDocument* doc );
1662  virtual ~XMLElement();
1663  XMLElement( const XMLElement& ); // not supported
1664  void operator=( const XMLElement& ); // not supported
1665 
1666  XMLAttribute* FindOrCreateAttribute( const char* name );
1667  char* ParseAttributes( char* p, int* curLineNumPtr );
1668  static void DeleteAttribute( XMLAttribute* attribute );
1669  XMLAttribute* CreateAttribute();
1670 
1671  enum { BUF_SIZE = 200 };
1672  ElementClosingType _closingType;
1673  // The attribute list is ordered; there is no 'lastAttribute'
1674  // because the list needs to be scanned for dupes before adding
1675  // a new attribute.
1676  XMLAttribute* _rootAttribute;
1677 };
1678 
1679 
1680 enum Whitespace {
1681  PRESERVE_WHITESPACE,
1682  COLLAPSE_WHITESPACE
1683 };
1684 
1685 
1691 class TINYXML2_LIB XMLDocument : public XMLNode
1692 {
1693  friend class XMLElement;
1694  // Gives access to SetError and Push/PopDepth, but over-access for everything else.
1695  // Wishing C++ had "internal" scope.
1696  friend class XMLNode;
1697  friend class XMLText;
1698  friend class XMLComment;
1699  friend class XMLDeclaration;
1700  friend class XMLUnknown;
1701 public:
1703  XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1704  ~XMLDocument();
1705 
1707  TIXMLASSERT( this == _document );
1708  return this;
1709  }
1710  virtual const XMLDocument* ToDocument() const {
1711  TIXMLASSERT( this == _document );
1712  return this;
1713  }
1714 
1725  XMLError Parse( const char* xml, size_t nBytes=static_cast<size_t>(-1) );
1726 
1732  XMLError LoadFile( const char* filename );
1733 
1745  XMLError LoadFile( FILE* );
1746 
1752  XMLError SaveFile( const char* filename, bool compact = false );
1753 
1761  XMLError SaveFile( FILE* fp, bool compact = false );
1762 
1763  bool ProcessEntities() const {
1764  return _processEntities;
1765  }
1766  Whitespace WhitespaceMode() const {
1767  return _whitespaceMode;
1768  }
1769 
1773  bool HasBOM() const {
1774  return _writeBOM;
1775  }
1778  void SetBOM( bool useBOM ) {
1779  _writeBOM = useBOM;
1780  }
1781 
1786  return FirstChildElement();
1787  }
1788  const XMLElement* RootElement() const {
1789  return FirstChildElement();
1790  }
1791 
1806  void Print( XMLPrinter* streamer=0 ) const;
1807  virtual bool Accept( XMLVisitor* visitor ) const;
1808 
1814  XMLElement* NewElement( const char* name );
1820  XMLComment* NewComment( const char* comment );
1826  XMLText* NewText( const char* text );
1838  XMLDeclaration* NewDeclaration( const char* text=0 );
1844  XMLUnknown* NewUnknown( const char* text );
1845 
1850  void DeleteNode( XMLNode* node );
1851 
1852  void ClearError() {
1853  SetError(XML_SUCCESS, 0, 0);
1854  }
1855 
1857  bool Error() const {
1858  return _errorID != XML_SUCCESS;
1859  }
1861  XMLError ErrorID() const {
1862  return _errorID;
1863  }
1864  const char* ErrorName() const;
1865  static const char* ErrorIDToName(XMLError errorID);
1866 
1870  const char* ErrorStr() const;
1871 
1873  void PrintError() const;
1874 
1876  int ErrorLineNum() const
1877  {
1878  return _errorLineNum;
1879  }
1880 
1882  void Clear();
1883 
1891  void DeepCopy(XMLDocument* target) const;
1892 
1893  // internal
1894  char* Identify( char* p, XMLNode** node );
1895 
1896  // internal
1897  void MarkInUse(XMLNode*);
1898 
1899  virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
1900  return 0;
1901  }
1902  virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
1903  return false;
1904  }
1905 
1906 private:
1907  XMLDocument( const XMLDocument& ); // not supported
1908  void operator=( const XMLDocument& ); // not supported
1909 
1910  bool _writeBOM;
1911  bool _processEntities;
1912  XMLError _errorID;
1913  Whitespace _whitespaceMode;
1914  mutable StrPair _errorStr;
1915  int _errorLineNum;
1916  char* _charBuffer;
1917  int _parseCurLineNum;
1918  int _parsingDepth;
1919  // Memory tracking does add some overhead.
1920  // However, the code assumes that you don't
1921  // have a bunch of unlinked nodes around.
1922  // Therefore it takes less memory to track
1923  // in the document vs. a linked list in the XMLNode,
1924  // and the performance is the same.
1925  DynArray<XMLNode*, 10> _unlinked;
1926 
1927  MemPoolT< sizeof(XMLElement) > _elementPool;
1928  MemPoolT< sizeof(XMLAttribute) > _attributePool;
1929  MemPoolT< sizeof(XMLText) > _textPool;
1930  MemPoolT< sizeof(XMLComment) > _commentPool;
1931 
1932  static const char* _errorNames[XML_ERROR_COUNT];
1933 
1934  void Parse();
1935 
1936  void SetError( XMLError error, int lineNum, const char* format, ... );
1937 
1938  // Something of an obvious security hole, once it was discovered.
1939  // Either an ill-formed XML or an excessively deep one can overflow
1940  // the stack. Track stack depth, and error out if needed.
1941  class DepthTracker {
1942  public:
1943  explicit DepthTracker(XMLDocument * document) {
1944  this->_document = document;
1945  document->PushDepth();
1946  }
1947  ~DepthTracker() {
1948  _document->PopDepth();
1949  }
1950  private:
1951  XMLDocument * _document;
1952  };
1953  void PushDepth();
1954  void PopDepth();
1955 
1956  template<class NodeType, int PoolElementSize>
1957  NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
1958 };
1959 
1960 template<class NodeType, int PoolElementSize>
1961 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
1962 {
1963  TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
1964  TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
1965  NodeType* returnNode = new (pool.Alloc()) NodeType( this );
1966  TIXMLASSERT( returnNode );
1967  returnNode->_memPool = &pool;
1968 
1969  _unlinked.Push(returnNode);
1970  return returnNode;
1971 }
1972 
2028 class TINYXML2_LIB XMLHandle
2029 {
2030 public:
2032  explicit XMLHandle( XMLNode* node ) : _node( node ) {
2033  }
2035  explicit XMLHandle( XMLNode& node ) : _node( &node ) {
2036  }
2038  XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
2039  }
2041  XMLHandle& operator=( const XMLHandle& ref ) {
2042  _node = ref._node;
2043  return *this;
2044  }
2045 
2048  return XMLHandle( _node ? _node->FirstChild() : 0 );
2049  }
2051  XMLHandle FirstChildElement( const char* name = 0 ) {
2052  return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
2053  }
2056  return XMLHandle( _node ? _node->LastChild() : 0 );
2057  }
2059  XMLHandle LastChildElement( const char* name = 0 ) {
2060  return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
2061  }
2064  return XMLHandle( _node ? _node->PreviousSibling() : 0 );
2065  }
2067  XMLHandle PreviousSiblingElement( const char* name = 0 ) {
2068  return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2069  }
2072  return XMLHandle( _node ? _node->NextSibling() : 0 );
2073  }
2075  XMLHandle NextSiblingElement( const char* name = 0 ) {
2076  return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2077  }
2078 
2081  return _node;
2082  }
2085  return ( _node ? _node->ToElement() : 0 );
2086  }
2089  return ( _node ? _node->ToText() : 0 );
2090  }
2093  return ( _node ? _node->ToUnknown() : 0 );
2094  }
2097  return ( _node ? _node->ToDeclaration() : 0 );
2098  }
2099 
2100 private:
2101  XMLNode* _node;
2102 };
2103 
2104 
2109 class TINYXML2_LIB XMLConstHandle
2110 {
2111 public:
2112  explicit XMLConstHandle( const XMLNode* node ) : _node( node ) {
2113  }
2114  explicit XMLConstHandle( const XMLNode& node ) : _node( &node ) {
2115  }
2116  XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
2117  }
2118 
2119  XMLConstHandle& operator=( const XMLConstHandle& ref ) {
2120  _node = ref._node;
2121  return *this;
2122  }
2123 
2124  const XMLConstHandle FirstChild() const {
2125  return XMLConstHandle( _node ? _node->FirstChild() : 0 );
2126  }
2127  const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
2128  return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
2129  }
2130  const XMLConstHandle LastChild() const {
2131  return XMLConstHandle( _node ? _node->LastChild() : 0 );
2132  }
2133  const XMLConstHandle LastChildElement( const char* name = 0 ) const {
2134  return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
2135  }
2136  const XMLConstHandle PreviousSibling() const {
2137  return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
2138  }
2139  const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
2140  return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2141  }
2142  const XMLConstHandle NextSibling() const {
2143  return XMLConstHandle( _node ? _node->NextSibling() : 0 );
2144  }
2145  const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
2146  return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2147  }
2148 
2149 
2150  const XMLNode* ToNode() const {
2151  return _node;
2152  }
2153  const XMLElement* ToElement() const {
2154  return ( _node ? _node->ToElement() : 0 );
2155  }
2156  const XMLText* ToText() const {
2157  return ( _node ? _node->ToText() : 0 );
2158  }
2159  const XMLUnknown* ToUnknown() const {
2160  return ( _node ? _node->ToUnknown() : 0 );
2161  }
2162  const XMLDeclaration* ToDeclaration() const {
2163  return ( _node ? _node->ToDeclaration() : 0 );
2164  }
2165 
2166 private:
2167  const XMLNode* _node;
2168 };
2169 
2170 
2213 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2214 {
2215 public:
2222  XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2223  virtual ~XMLPrinter() {}
2224 
2226  void PushHeader( bool writeBOM, bool writeDeclaration );
2230  void OpenElement( const char* name, bool compactMode=false );
2232  void PushAttribute( const char* name, const char* value );
2233  void PushAttribute( const char* name, int value );
2234  void PushAttribute( const char* name, unsigned value );
2235  void PushAttribute( const char* name, int64_t value );
2236  void PushAttribute( const char* name, uint64_t value );
2237  void PushAttribute( const char* name, bool value );
2238  void PushAttribute( const char* name, double value );
2240  virtual void CloseElement( bool compactMode=false );
2241 
2243  void PushText( const char* text, bool cdata=false );
2245  void PushText( int value );
2247  void PushText( unsigned value );
2249  void PushText( int64_t value );
2251  void PushText( uint64_t value );
2253  void PushText( bool value );
2255  void PushText( float value );
2257  void PushText( double value );
2258 
2260  void PushComment( const char* comment );
2261 
2262  void PushDeclaration( const char* value );
2263  void PushUnknown( const char* value );
2264 
2265  virtual bool VisitEnter( const XMLDocument& /*doc*/ );
2266  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
2267  return true;
2268  }
2269 
2270  virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
2271  virtual bool VisitExit( const XMLElement& element );
2272 
2273  virtual bool Visit( const XMLText& text );
2274  virtual bool Visit( const XMLComment& comment );
2275  virtual bool Visit( const XMLDeclaration& declaration );
2276  virtual bool Visit( const XMLUnknown& unknown );
2277 
2282  const char* CStr() const {
2283  return _buffer.Mem();
2284  }
2290  int CStrSize() const {
2291  return _buffer.Size();
2292  }
2297  void ClearBuffer( bool resetToFirstElement = true ) {
2298  _buffer.Clear();
2299  _buffer.Push(0);
2300  _firstElement = resetToFirstElement;
2301  }
2302 
2303 protected:
2304  virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2305 
2309  virtual void PrintSpace( int depth );
2310  void Print( const char* format, ... );
2311  void Write( const char* data, size_t size );
2312  inline void Write( const char* data ) { Write( data, strlen( data ) ); }
2313  void Putc( char ch );
2314 
2315  void SealElementIfJustOpened();
2316  bool _elementJustOpened;
2317  DynArray< const char*, 10 > _stack;
2318 
2319 private:
2320  void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2321 
2322  bool _firstElement;
2323  FILE* _fp;
2324  int _depth;
2325  int _textDepth;
2326  bool _processEntities;
2327  bool _compactMode;
2328 
2329  enum {
2330  ENTITY_RANGE = 64,
2331  BUF_SIZE = 200
2332  };
2333  bool _entityFlag[ENTITY_RANGE];
2334  bool _restrictedEntityFlag[ENTITY_RANGE];
2335 
2336  DynArray< char, 20 > _buffer;
2337 
2338  // Prohibit cloning, intentionally not implemented
2339  XMLPrinter( const XMLPrinter& );
2340  XMLPrinter& operator=( const XMLPrinter& );
2341 };
2342 
2343 
2344 } // tinyxml2
2345 
2346 #if defined(_MSC_VER)
2347 # pragma warning(pop)
2348 #endif
2349 
2350 #endif // TINYXML2_INCLUDED
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1271
Definition: tinyxml2.h:550
bool BoolValue() const
Query as a boolean. See IntValue()
Definition: tinyxml2.h:1181
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1471
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1857
XMLError QueryIntValue(int *value) const
Definition: tinyxml2.cpp:1412
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1346
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:698
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:2032
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1457
Definition: tinyxml2.h:346
Definition: tinyxml2.h:2213
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1465
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:694
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition: tinyxml2.h:746
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1430
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:495
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:1003
Definition: tinyxml2.h:2109
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1103
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:508
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:763
virtual bool ShallowEqual(const XMLNode *) const
Definition: tinyxml2.h:1902
Definition: tinyxml2.h:1258
double DoubleValue() const
Query as a double. See IntValue()
Definition: tinyxml2.h:1187
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:490
const char * Value() const
The value of the attribute.
Definition: tinyxml2.cpp:1373
void SetAttribute(const char *value)
Set the attribute to a string value.
Definition: tinyxml2.cpp:1475
Definition: tinyxml2.cpp:119
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1389
Definition: tinyxml2.h:205
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:991
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:512
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:2055
virtual XMLNode * ShallowClone(XMLDocument *) const
Definition: tinyxml2.h:1899
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1455
Definition: tinyxml2.h:1691
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition: tinyxml2.h:2051
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition: tinyxml2.h:2041
void SetBOM(bool useBOM)
Definition: tinyxml2.h:1778
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1466
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1355
XMLError ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1861
XMLElement * RootElement()
Definition: tinyxml2.h:1785
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2075
Definition: tinyxml2.h:1099
Definition: tinyxml2.h:2028
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:749
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1148
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1381
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1267
Definition: tinyxml2.h:668
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition: tinyxml2.h:1488
int IntValue() const
Definition: tinyxml2.h:1156
Definition: tinyxml2.h:135
void ClearBuffer(bool resetToFirstElement=true)
Definition: tinyxml2.h:2297
XMLError QueryUnsigned64Attribute(const char *name, uint64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1364
void * GetUserData() const
Definition: tinyxml2.h:940
Definition: tinyxml2.h:1134
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition: tinyxml2.h:2059
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:2266
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:2035
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:999
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:680
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:675
Definition: tinyxml2.h:329
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1068
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:706
int ErrorLineNum() const
Return the line where the error occurred, or zero if unknown.
Definition: tinyxml2.h:1876
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:499
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:516
Definition: tinyxml2.h:985
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition: tinyxml2.h:799
Definition: tinyxml2.h:1064
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1483
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition: tinyxml2.h:1493
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1398
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1337
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2080
Definition: tinyxml2.h:480
void SetUserData(void *userData)
Definition: tinyxml2.h:933
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:2071
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1175
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1421
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:690
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file. ...
Definition: tinyxml2.h:1145
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1460
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1373
bool HasBOM() const
Definition: tinyxml2.h:1773
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2088
XMLError QueryUnsigned64Value(uint64_t *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1439
void SetAttribute(const char *name, uint64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1477
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:781
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:2063
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2096
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:758
int CStrSize() const
Definition: tinyxml2.h:2290
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1504
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2092
XMLError QueryAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1426
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:2047
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2084
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:2067
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:504
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:486
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1448
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:1706
Definition: tinyxml2.h:1025
float FloatValue() const
Query as a float. See IntValue()
Definition: tinyxml2.h:1193
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:702
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:686
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1029
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:815
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:2038
const char * CStr() const
Definition: tinyxml2.h:2282
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1263