TinyXML-2  6.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 -DDEBUG 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 DEBUG
58 # define 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(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 = 6;
102 static const int TIXML2_MINOR_VERSION = 0;
103 static const int TIXML2_PATCH_VERSION = 0;
104 
105 namespace tinyxml2
106 {
107 class XMLDocument;
108 class XMLElement;
109 class XMLAttribute;
110 class XMLComment;
111 class XMLText;
112 class XMLDeclaration;
113 class XMLUnknown;
114 class XMLPrinter;
115 
116 /*
117  A class that wraps strings. Normally stores the start and end
118  pointers into the XML file itself, and will apply normalization
119  and entity translation if actually read. Can also store (and memory
120  manage) a traditional char[]
121 */
122 class StrPair
123 {
124 public:
125  enum {
126  NEEDS_ENTITY_PROCESSING = 0x01,
127  NEEDS_NEWLINE_NORMALIZATION = 0x02,
128  NEEDS_WHITESPACE_COLLAPSING = 0x04,
129 
130  TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
131  TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
132  ATTRIBUTE_NAME = 0,
133  ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
134  ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
135  COMMENT = NEEDS_NEWLINE_NORMALIZATION
136  };
137 
138  StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
139  ~StrPair();
140 
141  void Set( char* start, char* end, int flags ) {
142  TIXMLASSERT( start );
143  TIXMLASSERT( end );
144  Reset();
145  _start = start;
146  _end = end;
147  _flags = flags | NEEDS_FLUSH;
148  }
149 
150  const char* GetStr();
151 
152  bool Empty() const {
153  return _start == _end;
154  }
155 
156  void SetInternedStr( const char* str ) {
157  Reset();
158  _start = const_cast<char*>(str);
159  }
160 
161  void SetStr( const char* str, int flags=0 );
162 
163  char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
164  char* ParseName( char* in );
165 
166  void TransferTo( StrPair* other );
167  void Reset();
168 
169 private:
170  void CollapseWhitespace();
171 
172  enum {
173  NEEDS_FLUSH = 0x100,
174  NEEDS_DELETE = 0x200
175  };
176 
177  int _flags;
178  char* _start;
179  char* _end;
180 
181  StrPair( const StrPair& other ); // not supported
182  void operator=( StrPair& other ); // not supported, use TransferTo()
183 };
184 
185 
186 /*
187  A dynamic array of Plain Old Data. Doesn't support constructors, etc.
188  Has a small initial memory pool, so that low or no usage will not
189  cause a call to new/delete
190 */
191 template <class T, int INITIAL_SIZE>
192 class DynArray
193 {
194 public:
195  DynArray() :
196  _mem( _pool ),
197  _allocated( INITIAL_SIZE ),
198  _size( 0 )
199  {
200  }
201 
202  ~DynArray() {
203  if ( _mem != _pool ) {
204  delete [] _mem;
205  }
206  }
207 
208  void Clear() {
209  _size = 0;
210  }
211 
212  void Push( T t ) {
213  TIXMLASSERT( _size < INT_MAX );
214  EnsureCapacity( _size+1 );
215  _mem[_size] = t;
216  ++_size;
217  }
218 
219  T* PushArr( int count ) {
220  TIXMLASSERT( count >= 0 );
221  TIXMLASSERT( _size <= INT_MAX - count );
222  EnsureCapacity( _size+count );
223  T* ret = &_mem[_size];
224  _size += count;
225  return ret;
226  }
227 
228  T Pop() {
229  TIXMLASSERT( _size > 0 );
230  --_size;
231  return _mem[_size];
232  }
233 
234  void PopArr( int count ) {
235  TIXMLASSERT( _size >= count );
236  _size -= count;
237  }
238 
239  bool Empty() const {
240  return _size == 0;
241  }
242 
243  T& operator[](int i) {
244  TIXMLASSERT( i>= 0 && i < _size );
245  return _mem[i];
246  }
247 
248  const T& operator[](int i) const {
249  TIXMLASSERT( i>= 0 && i < _size );
250  return _mem[i];
251  }
252 
253  const T& PeekTop() const {
254  TIXMLASSERT( _size > 0 );
255  return _mem[ _size - 1];
256  }
257 
258  int Size() const {
259  TIXMLASSERT( _size >= 0 );
260  return _size;
261  }
262 
263  int Capacity() const {
264  TIXMLASSERT( _allocated >= INITIAL_SIZE );
265  return _allocated;
266  }
267 
268  void SwapRemove(int i) {
269  TIXMLASSERT(i >= 0 && i < _size);
270  TIXMLASSERT(_size > 0);
271  _mem[i] = _mem[_size - 1];
272  --_size;
273  }
274 
275  const T* Mem() const {
276  TIXMLASSERT( _mem );
277  return _mem;
278  }
279 
280  T* Mem() {
281  TIXMLASSERT( _mem );
282  return _mem;
283  }
284 
285 private:
286  DynArray( const DynArray& ); // not supported
287  void operator=( const DynArray& ); // not supported
288 
289  void EnsureCapacity( int cap ) {
290  TIXMLASSERT( cap > 0 );
291  if ( cap > _allocated ) {
292  TIXMLASSERT( cap <= INT_MAX / 2 );
293  int newAllocated = cap * 2;
294  T* newMem = new T[newAllocated];
295  TIXMLASSERT( newAllocated >= _size );
296  memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
297  if ( _mem != _pool ) {
298  delete [] _mem;
299  }
300  _mem = newMem;
301  _allocated = newAllocated;
302  }
303  }
304 
305  T* _mem;
306  T _pool[INITIAL_SIZE];
307  int _allocated; // objects allocated
308  int _size; // number objects in use
309 };
310 
311 
312 /*
313  Parent virtual class of a pool for fast allocation
314  and deallocation of objects.
315 */
316 class MemPool
317 {
318 public:
319  MemPool() {}
320  virtual ~MemPool() {}
321 
322  virtual int ItemSize() const = 0;
323  virtual void* Alloc() = 0;
324  virtual void Free( void* ) = 0;
325  virtual void SetTracked() = 0;
326  virtual void Clear() = 0;
327 };
328 
329 
330 /*
331  Template child class to create pools of the correct type.
332 */
333 template< int ITEM_SIZE >
334 class MemPoolT : public MemPool
335 {
336 public:
337  MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
338  ~MemPoolT() {
339  Clear();
340  }
341 
342  void Clear() {
343  // Delete the blocks.
344  while( !_blockPtrs.Empty()) {
345  Block* lastBlock = _blockPtrs.Pop();
346  delete lastBlock;
347  }
348  _root = 0;
349  _currentAllocs = 0;
350  _nAllocs = 0;
351  _maxAllocs = 0;
352  _nUntracked = 0;
353  }
354 
355  virtual int ItemSize() const {
356  return ITEM_SIZE;
357  }
358  int CurrentAllocs() const {
359  return _currentAllocs;
360  }
361 
362  virtual void* Alloc() {
363  if ( !_root ) {
364  // Need a new block.
365  Block* block = new Block();
366  _blockPtrs.Push( block );
367 
368  Item* blockItems = block->items;
369  for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
370  blockItems[i].next = &(blockItems[i + 1]);
371  }
372  blockItems[ITEMS_PER_BLOCK - 1].next = 0;
373  _root = blockItems;
374  }
375  Item* const result = _root;
376  TIXMLASSERT( result != 0 );
377  _root = _root->next;
378 
379  ++_currentAllocs;
380  if ( _currentAllocs > _maxAllocs ) {
381  _maxAllocs = _currentAllocs;
382  }
383  ++_nAllocs;
384  ++_nUntracked;
385  return result;
386  }
387 
388  virtual void Free( void* mem ) {
389  if ( !mem ) {
390  return;
391  }
392  --_currentAllocs;
393  Item* item = static_cast<Item*>( mem );
394 #ifdef DEBUG
395  memset( item, 0xfe, sizeof( *item ) );
396 #endif
397  item->next = _root;
398  _root = item;
399  }
400  void Trace( const char* name ) {
401  printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
402  name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
403  ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
404  }
405 
406  void SetTracked() {
407  --_nUntracked;
408  }
409 
410  int Untracked() const {
411  return _nUntracked;
412  }
413 
414  // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
415  // The test file is large, 170k.
416  // Release: VS2010 gcc(no opt)
417  // 1k: 4000
418  // 2k: 4000
419  // 4k: 3900 21000
420  // 16k: 5200
421  // 32k: 4300
422  // 64k: 4000 21000
423  // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
424  // in private part if ITEMS_PER_BLOCK is private
425  enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
426 
427 private:
428  MemPoolT( const MemPoolT& ); // not supported
429  void operator=( const MemPoolT& ); // not supported
430 
431  union Item {
432  Item* next;
433  char itemData[ITEM_SIZE];
434  };
435  struct Block {
436  Item items[ITEMS_PER_BLOCK];
437  };
438  DynArray< Block*, 10 > _blockPtrs;
439  Item* _root;
440 
441  int _currentAllocs;
442  int _nAllocs;
443  int _maxAllocs;
444  int _nUntracked;
445 };
446 
447 
448 
468 class TINYXML2_LIB XMLVisitor
469 {
470 public:
471  virtual ~XMLVisitor() {}
472 
474  virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
475  return true;
476  }
478  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
479  return true;
480  }
481 
483  virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
484  return true;
485  }
487  virtual bool VisitExit( const XMLElement& /*element*/ ) {
488  return true;
489  }
490 
492  virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
493  return true;
494  }
496  virtual bool Visit( const XMLText& /*text*/ ) {
497  return true;
498  }
500  virtual bool Visit( const XMLComment& /*comment*/ ) {
501  return true;
502  }
504  virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
505  return true;
506  }
507 };
508 
509 // WARNING: must match XMLDocument::_errorNames[]
510 enum XMLError {
511  XML_SUCCESS = 0,
512  XML_NO_ATTRIBUTE,
513  XML_WRONG_ATTRIBUTE_TYPE,
514  XML_ERROR_FILE_NOT_FOUND,
515  XML_ERROR_FILE_COULD_NOT_BE_OPENED,
516  XML_ERROR_FILE_READ_ERROR,
517  UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version
518  XML_ERROR_PARSING_ELEMENT,
519  XML_ERROR_PARSING_ATTRIBUTE,
520  UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version
521  XML_ERROR_PARSING_TEXT,
522  XML_ERROR_PARSING_CDATA,
523  XML_ERROR_PARSING_COMMENT,
524  XML_ERROR_PARSING_DECLARATION,
525  XML_ERROR_PARSING_UNKNOWN,
526  XML_ERROR_EMPTY_DOCUMENT,
527  XML_ERROR_MISMATCHED_ELEMENT,
528  XML_ERROR_PARSING,
529  XML_CAN_NOT_CONVERT_TEXT,
530  XML_NO_TEXT_NODE,
531 
532  XML_ERROR_COUNT
533 };
534 
535 
536 /*
537  Utility functionality.
538 */
539 class TINYXML2_LIB XMLUtil
540 {
541 public:
542  static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
543  TIXMLASSERT( p );
544 
545  while( IsWhiteSpace(*p) ) {
546  if (curLineNumPtr && *p == '\n') {
547  ++(*curLineNumPtr);
548  }
549  ++p;
550  }
551  TIXMLASSERT( p );
552  return p;
553  }
554  static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
555  return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
556  }
557 
558  // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
559  // correct, but simple, and usually works.
560  static bool IsWhiteSpace( char p ) {
561  return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
562  }
563 
564  inline static bool IsNameStartChar( unsigned char ch ) {
565  if ( ch >= 128 ) {
566  // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
567  return true;
568  }
569  if ( isalpha( ch ) ) {
570  return true;
571  }
572  return ch == ':' || ch == '_';
573  }
574 
575  inline static bool IsNameChar( unsigned char ch ) {
576  return IsNameStartChar( ch )
577  || isdigit( ch )
578  || ch == '.'
579  || ch == '-';
580  }
581 
582  inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
583  if ( p == q ) {
584  return true;
585  }
586  TIXMLASSERT( p );
587  TIXMLASSERT( q );
588  TIXMLASSERT( nChar >= 0 );
589  return strncmp( p, q, nChar ) == 0;
590  }
591 
592  inline static bool IsUTF8Continuation( char p ) {
593  return ( p & 0x80 ) != 0;
594  }
595 
596  static const char* ReadBOM( const char* p, bool* hasBOM );
597  // p is the starting location,
598  // the UTF-8 value of the entity will be placed in value, and length filled in.
599  static const char* GetCharacterRef( const char* p, char* value, int* length );
600  static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
601 
602  // converts primitive types to strings
603  static void ToStr( int v, char* buffer, int bufferSize );
604  static void ToStr( unsigned v, char* buffer, int bufferSize );
605  static void ToStr( bool v, char* buffer, int bufferSize );
606  static void ToStr( float v, char* buffer, int bufferSize );
607  static void ToStr( double v, char* buffer, int bufferSize );
608  static void ToStr(int64_t v, char* buffer, int bufferSize);
609 
610  // converts strings to primitive types
611  static bool ToInt( const char* str, int* value );
612  static bool ToUnsigned( const char* str, unsigned* value );
613  static bool ToBool( const char* str, bool* value );
614  static bool ToFloat( const char* str, float* value );
615  static bool ToDouble( const char* str, double* value );
616  static bool ToInt64(const char* str, int64_t* value);
617 
618  // Changes what is serialized for a boolean value.
619  // Default to "true" and "false". Shouldn't be changed
620  // unless you have a special testing or compatibility need.
621  // Be careful: static, global, & not thread safe.
622  // Be sure to set static const memory as parameters.
623  static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
624 
625 private:
626  static const char* writeBoolTrue;
627  static const char* writeBoolFalse;
628 };
629 
630 
656 class TINYXML2_LIB XMLNode
657 {
658  friend class XMLDocument;
659  friend class XMLElement;
660 public:
661 
663  const XMLDocument* GetDocument() const {
664  TIXMLASSERT( _document );
665  return _document;
666  }
669  TIXMLASSERT( _document );
670  return _document;
671  }
672 
674  virtual XMLElement* ToElement() {
675  return 0;
676  }
678  virtual XMLText* ToText() {
679  return 0;
680  }
682  virtual XMLComment* ToComment() {
683  return 0;
684  }
686  virtual XMLDocument* ToDocument() {
687  return 0;
688  }
691  return 0;
692  }
694  virtual XMLUnknown* ToUnknown() {
695  return 0;
696  }
697 
698  virtual const XMLElement* ToElement() const {
699  return 0;
700  }
701  virtual const XMLText* ToText() const {
702  return 0;
703  }
704  virtual const XMLComment* ToComment() const {
705  return 0;
706  }
707  virtual const XMLDocument* ToDocument() const {
708  return 0;
709  }
710  virtual const XMLDeclaration* ToDeclaration() const {
711  return 0;
712  }
713  virtual const XMLUnknown* ToUnknown() const {
714  return 0;
715  }
716 
726  const char* Value() const;
727 
731  void SetValue( const char* val, bool staticMem=false );
732 
734  int GetLineNum() const { return _parseLineNum; }
735 
737  const XMLNode* Parent() const {
738  return _parent;
739  }
740 
741  XMLNode* Parent() {
742  return _parent;
743  }
744 
746  bool NoChildren() const {
747  return !_firstChild;
748  }
749 
751  const XMLNode* FirstChild() const {
752  return _firstChild;
753  }
754 
755  XMLNode* FirstChild() {
756  return _firstChild;
757  }
758 
762  const XMLElement* FirstChildElement( const char* name = 0 ) const;
763 
764  XMLElement* FirstChildElement( const char* name = 0 ) {
765  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
766  }
767 
769  const XMLNode* LastChild() const {
770  return _lastChild;
771  }
772 
773  XMLNode* LastChild() {
774  return _lastChild;
775  }
776 
780  const XMLElement* LastChildElement( const char* name = 0 ) const;
781 
782  XMLElement* LastChildElement( const char* name = 0 ) {
783  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
784  }
785 
787  const XMLNode* PreviousSibling() const {
788  return _prev;
789  }
790 
791  XMLNode* PreviousSibling() {
792  return _prev;
793  }
794 
796  const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
797 
798  XMLElement* PreviousSiblingElement( const char* name = 0 ) {
799  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
800  }
801 
803  const XMLNode* NextSibling() const {
804  return _next;
805  }
806 
807  XMLNode* NextSibling() {
808  return _next;
809  }
810 
812  const XMLElement* NextSiblingElement( const char* name = 0 ) const;
813 
814  XMLElement* NextSiblingElement( const char* name = 0 ) {
815  return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
816  }
817 
825  XMLNode* InsertEndChild( XMLNode* addThis );
826 
827  XMLNode* LinkEndChild( XMLNode* addThis ) {
828  return InsertEndChild( addThis );
829  }
837  XMLNode* InsertFirstChild( XMLNode* addThis );
846  XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
847 
851  void DeleteChildren();
852 
856  void DeleteChild( XMLNode* node );
857 
867  virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
868 
882  XMLNode* DeepClone( XMLDocument* target ) const;
883 
890  virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
891 
914  virtual bool Accept( XMLVisitor* visitor ) const = 0;
915 
921  void SetUserData(void* userData) { _userData = userData; }
922 
928  void* GetUserData() const { return _userData; }
929 
930 protected:
931  XMLNode( XMLDocument* );
932  virtual ~XMLNode();
933 
934  virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
935 
936  XMLDocument* _document;
937  XMLNode* _parent;
938  mutable StrPair _value;
939  int _parseLineNum;
940 
941  XMLNode* _firstChild;
942  XMLNode* _lastChild;
943 
944  XMLNode* _prev;
945  XMLNode* _next;
946 
947  void* _userData;
948 
949 private:
950  MemPool* _memPool;
951  void Unlink( XMLNode* child );
952  static void DeleteNode( XMLNode* node );
953  void InsertChildPreamble( XMLNode* insertThis ) const;
954  const XMLElement* ToElementWithName( const char* name ) const;
955 
956  XMLNode( const XMLNode& ); // not supported
957  XMLNode& operator=( const XMLNode& ); // not supported
958 };
959 
960 
973 class TINYXML2_LIB XMLText : public XMLNode
974 {
975  friend class XMLDocument;
976 public:
977  virtual bool Accept( XMLVisitor* visitor ) const;
978 
979  virtual XMLText* ToText() {
980  return this;
981  }
982  virtual const XMLText* ToText() const {
983  return this;
984  }
985 
987  void SetCData( bool isCData ) {
988  _isCData = isCData;
989  }
991  bool CData() const {
992  return _isCData;
993  }
994 
995  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
996  virtual bool ShallowEqual( const XMLNode* compare ) const;
997 
998 protected:
999  XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
1000  virtual ~XMLText() {}
1001 
1002  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1003 
1004 private:
1005  bool _isCData;
1006 
1007  XMLText( const XMLText& ); // not supported
1008  XMLText& operator=( const XMLText& ); // not supported
1009 };
1010 
1011 
1013 class TINYXML2_LIB XMLComment : public XMLNode
1014 {
1015  friend class XMLDocument;
1016 public:
1017  virtual XMLComment* ToComment() {
1018  return this;
1019  }
1020  virtual const XMLComment* ToComment() const {
1021  return this;
1022  }
1023 
1024  virtual bool Accept( XMLVisitor* visitor ) const;
1025 
1026  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1027  virtual bool ShallowEqual( const XMLNode* compare ) const;
1028 
1029 protected:
1030  XMLComment( XMLDocument* doc );
1031  virtual ~XMLComment();
1032 
1033  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
1034 
1035 private:
1036  XMLComment( const XMLComment& ); // not supported
1037  XMLComment& operator=( const XMLComment& ); // not supported
1038 };
1039 
1040 
1052 class TINYXML2_LIB XMLDeclaration : public XMLNode
1053 {
1054  friend class XMLDocument;
1055 public:
1057  return this;
1058  }
1059  virtual const XMLDeclaration* ToDeclaration() const {
1060  return this;
1061  }
1062 
1063  virtual bool Accept( XMLVisitor* visitor ) const;
1064 
1065  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1066  virtual bool ShallowEqual( const XMLNode* compare ) const;
1067 
1068 protected:
1069  XMLDeclaration( XMLDocument* doc );
1070  virtual ~XMLDeclaration();
1071 
1072  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1073 
1074 private:
1075  XMLDeclaration( const XMLDeclaration& ); // not supported
1076  XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1077 };
1078 
1079 
1087 class TINYXML2_LIB XMLUnknown : public XMLNode
1088 {
1089  friend class XMLDocument;
1090 public:
1091  virtual XMLUnknown* ToUnknown() {
1092  return this;
1093  }
1094  virtual const XMLUnknown* ToUnknown() const {
1095  return this;
1096  }
1097 
1098  virtual bool Accept( XMLVisitor* visitor ) const;
1099 
1100  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1101  virtual bool ShallowEqual( const XMLNode* compare ) const;
1102 
1103 protected:
1104  XMLUnknown( XMLDocument* doc );
1105  virtual ~XMLUnknown();
1106 
1107  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1108 
1109 private:
1110  XMLUnknown( const XMLUnknown& ); // not supported
1111  XMLUnknown& operator=( const XMLUnknown& ); // not supported
1112 };
1113 
1114 
1115 
1122 class TINYXML2_LIB XMLAttribute
1123 {
1124  friend class XMLElement;
1125 public:
1127  const char* Name() const;
1128 
1130  const char* Value() const;
1131 
1133  int GetLineNum() const { return _parseLineNum; }
1134 
1136  const XMLAttribute* Next() const {
1137  return _next;
1138  }
1139 
1144  int IntValue() const {
1145  int i = 0;
1146  QueryIntValue(&i);
1147  return i;
1148  }
1149 
1150  int64_t Int64Value() const {
1151  int64_t i = 0;
1152  QueryInt64Value(&i);
1153  return i;
1154  }
1155 
1157  unsigned UnsignedValue() const {
1158  unsigned i=0;
1159  QueryUnsignedValue( &i );
1160  return i;
1161  }
1163  bool BoolValue() const {
1164  bool b=false;
1165  QueryBoolValue( &b );
1166  return b;
1167  }
1169  double DoubleValue() const {
1170  double d=0;
1171  QueryDoubleValue( &d );
1172  return d;
1173  }
1175  float FloatValue() const {
1176  float f=0;
1177  QueryFloatValue( &f );
1178  return f;
1179  }
1180 
1185  XMLError QueryIntValue( int* value ) const;
1187  XMLError QueryUnsignedValue( unsigned int* value ) const;
1189  XMLError QueryInt64Value(int64_t* value) const;
1191  XMLError QueryBoolValue( bool* value ) const;
1193  XMLError QueryDoubleValue( double* value ) const;
1195  XMLError QueryFloatValue( float* value ) const;
1196 
1198  void SetAttribute( const char* value );
1200  void SetAttribute( int value );
1202  void SetAttribute( unsigned value );
1204  void SetAttribute(int64_t value);
1206  void SetAttribute( bool value );
1208  void SetAttribute( double value );
1210  void SetAttribute( float value );
1211 
1212 private:
1213  enum { BUF_SIZE = 200 };
1214 
1215  XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
1216  virtual ~XMLAttribute() {}
1217 
1218  XMLAttribute( const XMLAttribute& ); // not supported
1219  void operator=( const XMLAttribute& ); // not supported
1220  void SetName( const char* name );
1221 
1222  char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
1223 
1224  mutable StrPair _name;
1225  mutable StrPair _value;
1226  int _parseLineNum;
1227  XMLAttribute* _next;
1228  MemPool* _memPool;
1229 };
1230 
1231 
1236 class TINYXML2_LIB XMLElement : public XMLNode
1237 {
1238  friend class XMLDocument;
1239 public:
1241  const char* Name() const {
1242  return Value();
1243  }
1245  void SetName( const char* str, bool staticMem=false ) {
1246  SetValue( str, staticMem );
1247  }
1248 
1249  virtual XMLElement* ToElement() {
1250  return this;
1251  }
1252  virtual const XMLElement* ToElement() const {
1253  return this;
1254  }
1255  virtual bool Accept( XMLVisitor* visitor ) const;
1256 
1280  const char* Attribute( const char* name, const char* value=0 ) const;
1281 
1288  int IntAttribute(const char* name, int defaultValue = 0) const;
1290  unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1292  int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1294  bool BoolAttribute(const char* name, bool defaultValue = false) const;
1296  double DoubleAttribute(const char* name, double defaultValue = 0) const;
1298  float FloatAttribute(const char* name, float defaultValue = 0) const;
1299 
1313  XMLError QueryIntAttribute( const char* name, int* value ) const {
1314  const XMLAttribute* a = FindAttribute( name );
1315  if ( !a ) {
1316  return XML_NO_ATTRIBUTE;
1317  }
1318  return a->QueryIntValue( value );
1319  }
1320 
1322  XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
1323  const XMLAttribute* a = FindAttribute( name );
1324  if ( !a ) {
1325  return XML_NO_ATTRIBUTE;
1326  }
1327  return a->QueryUnsignedValue( value );
1328  }
1329 
1331  XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1332  const XMLAttribute* a = FindAttribute(name);
1333  if (!a) {
1334  return XML_NO_ATTRIBUTE;
1335  }
1336  return a->QueryInt64Value(value);
1337  }
1338 
1340  XMLError QueryBoolAttribute( const char* name, bool* value ) const {
1341  const XMLAttribute* a = FindAttribute( name );
1342  if ( !a ) {
1343  return XML_NO_ATTRIBUTE;
1344  }
1345  return a->QueryBoolValue( value );
1346  }
1348  XMLError QueryDoubleAttribute( const char* name, double* value ) const {
1349  const XMLAttribute* a = FindAttribute( name );
1350  if ( !a ) {
1351  return XML_NO_ATTRIBUTE;
1352  }
1353  return a->QueryDoubleValue( value );
1354  }
1356  XMLError QueryFloatAttribute( const char* name, float* value ) const {
1357  const XMLAttribute* a = FindAttribute( name );
1358  if ( !a ) {
1359  return XML_NO_ATTRIBUTE;
1360  }
1361  return a->QueryFloatValue( value );
1362  }
1363 
1364 
1382  int QueryAttribute( const char* name, int* value ) const {
1383  return QueryIntAttribute( name, value );
1384  }
1385 
1386  int QueryAttribute( const char* name, unsigned int* value ) const {
1387  return QueryUnsignedAttribute( name, value );
1388  }
1389 
1390  int QueryAttribute(const char* name, int64_t* value) const {
1391  return QueryInt64Attribute(name, value);
1392  }
1393 
1394  int QueryAttribute( const char* name, bool* value ) const {
1395  return QueryBoolAttribute( name, value );
1396  }
1397 
1398  int QueryAttribute( const char* name, double* value ) const {
1399  return QueryDoubleAttribute( name, value );
1400  }
1401 
1402  int QueryAttribute( const char* name, float* value ) const {
1403  return QueryFloatAttribute( name, value );
1404  }
1405 
1407  void SetAttribute( const char* name, const char* value ) {
1408  XMLAttribute* a = FindOrCreateAttribute( name );
1409  a->SetAttribute( value );
1410  }
1412  void SetAttribute( const char* name, int value ) {
1413  XMLAttribute* a = FindOrCreateAttribute( name );
1414  a->SetAttribute( value );
1415  }
1417  void SetAttribute( const char* name, unsigned value ) {
1418  XMLAttribute* a = FindOrCreateAttribute( name );
1419  a->SetAttribute( value );
1420  }
1421 
1423  void SetAttribute(const char* name, int64_t value) {
1424  XMLAttribute* a = FindOrCreateAttribute(name);
1425  a->SetAttribute(value);
1426  }
1427 
1429  void SetAttribute( const char* name, bool value ) {
1430  XMLAttribute* a = FindOrCreateAttribute( name );
1431  a->SetAttribute( value );
1432  }
1434  void SetAttribute( const char* name, double value ) {
1435  XMLAttribute* a = FindOrCreateAttribute( name );
1436  a->SetAttribute( value );
1437  }
1439  void SetAttribute( const char* name, float value ) {
1440  XMLAttribute* a = FindOrCreateAttribute( name );
1441  a->SetAttribute( value );
1442  }
1443 
1447  void DeleteAttribute( const char* name );
1448 
1450  const XMLAttribute* FirstAttribute() const {
1451  return _rootAttribute;
1452  }
1454  const XMLAttribute* FindAttribute( const char* name ) const;
1455 
1484  const char* GetText() const;
1485 
1520  void SetText( const char* inText );
1522  void SetText( int value );
1524  void SetText( unsigned value );
1526  void SetText(int64_t value);
1528  void SetText( bool value );
1530  void SetText( double value );
1532  void SetText( float value );
1533 
1560  XMLError QueryIntText( int* ival ) const;
1562  XMLError QueryUnsignedText( unsigned* uval ) const;
1564  XMLError QueryInt64Text(int64_t* uval) const;
1566  XMLError QueryBoolText( bool* bval ) const;
1568  XMLError QueryDoubleText( double* dval ) const;
1570  XMLError QueryFloatText( float* fval ) const;
1571 
1572  int IntText(int defaultValue = 0) const;
1573 
1575  unsigned UnsignedText(unsigned defaultValue = 0) const;
1577  int64_t Int64Text(int64_t defaultValue = 0) const;
1579  bool BoolText(bool defaultValue = false) const;
1581  double DoubleText(double defaultValue = 0) const;
1583  float FloatText(float defaultValue = 0) const;
1584 
1585  // internal:
1586  enum ElementClosingType {
1587  OPEN, // <foo>
1588  CLOSED, // <foo/>
1589  CLOSING // </foo>
1590  };
1591  ElementClosingType ClosingType() const {
1592  return _closingType;
1593  }
1594  virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1595  virtual bool ShallowEqual( const XMLNode* compare ) const;
1596 
1597 protected:
1598  char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1599 
1600 private:
1601  XMLElement( XMLDocument* doc );
1602  virtual ~XMLElement();
1603  XMLElement( const XMLElement& ); // not supported
1604  void operator=( const XMLElement& ); // not supported
1605 
1606  XMLAttribute* FindAttribute( const char* name ) {
1607  return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
1608  }
1609  XMLAttribute* FindOrCreateAttribute( const char* name );
1610  //void LinkAttribute( XMLAttribute* attrib );
1611  char* ParseAttributes( char* p, int* curLineNumPtr );
1612  static void DeleteAttribute( XMLAttribute* attribute );
1613  XMLAttribute* CreateAttribute();
1614 
1615  enum { BUF_SIZE = 200 };
1616  ElementClosingType _closingType;
1617  // The attribute list is ordered; there is no 'lastAttribute'
1618  // because the list needs to be scanned for dupes before adding
1619  // a new attribute.
1620  XMLAttribute* _rootAttribute;
1621 };
1622 
1623 
1624 enum Whitespace {
1625  PRESERVE_WHITESPACE,
1626  COLLAPSE_WHITESPACE
1627 };
1628 
1629 
1635 class TINYXML2_LIB XMLDocument : public XMLNode
1636 {
1637  friend class XMLElement;
1638  // Gives access to SetError, but over-access for everything else.
1639  // Wishing C++ had "internal" scope.
1640  friend class XMLNode;
1641  friend class XMLText;
1642  friend class XMLComment;
1643  friend class XMLDeclaration;
1644  friend class XMLUnknown;
1645 public:
1647  XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1648  ~XMLDocument();
1649 
1651  TIXMLASSERT( this == _document );
1652  return this;
1653  }
1654  virtual const XMLDocument* ToDocument() const {
1655  TIXMLASSERT( this == _document );
1656  return this;
1657  }
1658 
1669  XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
1670 
1676  XMLError LoadFile( const char* filename );
1677 
1689  XMLError LoadFile( FILE* );
1690 
1696  XMLError SaveFile( const char* filename, bool compact = false );
1697 
1705  XMLError SaveFile( FILE* fp, bool compact = false );
1706 
1707  bool ProcessEntities() const {
1708  return _processEntities;
1709  }
1710  Whitespace WhitespaceMode() const {
1711  return _whitespaceMode;
1712  }
1713 
1717  bool HasBOM() const {
1718  return _writeBOM;
1719  }
1722  void SetBOM( bool useBOM ) {
1723  _writeBOM = useBOM;
1724  }
1725 
1730  return FirstChildElement();
1731  }
1732  const XMLElement* RootElement() const {
1733  return FirstChildElement();
1734  }
1735 
1750  void Print( XMLPrinter* streamer=0 ) const;
1751  virtual bool Accept( XMLVisitor* visitor ) const;
1752 
1758  XMLElement* NewElement( const char* name );
1764  XMLComment* NewComment( const char* comment );
1770  XMLText* NewText( const char* text );
1782  XMLDeclaration* NewDeclaration( const char* text=0 );
1788  XMLUnknown* NewUnknown( const char* text );
1789 
1794  void DeleteNode( XMLNode* node );
1795 
1796  void ClearError() {
1797  SetError(XML_SUCCESS, 0, 0);
1798  }
1799 
1801  bool Error() const {
1802  return _errorID != XML_SUCCESS;
1803  }
1805  XMLError ErrorID() const {
1806  return _errorID;
1807  }
1808  const char* ErrorName() const;
1809  static const char* ErrorIDToName(XMLError errorID);
1810 
1814  const char* ErrorStr() const;
1815 
1817  void PrintError() const;
1818 
1820  int ErrorLineNum() const
1821  {
1822  return _errorLineNum;
1823  }
1824 
1826  void Clear();
1827 
1835  void DeepCopy(XMLDocument* target) const;
1836 
1837  // internal
1838  char* Identify( char* p, XMLNode** node );
1839 
1840  // internal
1841  void MarkInUse(XMLNode*);
1842 
1843  virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
1844  return 0;
1845  }
1846  virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
1847  return false;
1848  }
1849 
1850 private:
1851  XMLDocument( const XMLDocument& ); // not supported
1852  void operator=( const XMLDocument& ); // not supported
1853 
1854  bool _writeBOM;
1855  bool _processEntities;
1856  XMLError _errorID;
1857  Whitespace _whitespaceMode;
1858  mutable StrPair _errorStr;
1859  int _errorLineNum;
1860  char* _charBuffer;
1861  int _parseCurLineNum;
1862  // Memory tracking does add some overhead.
1863  // However, the code assumes that you don't
1864  // have a bunch of unlinked nodes around.
1865  // Therefore it takes less memory to track
1866  // in the document vs. a linked list in the XMLNode,
1867  // and the performance is the same.
1868  DynArray<XMLNode*, 10> _unlinked;
1869 
1870  MemPoolT< sizeof(XMLElement) > _elementPool;
1871  MemPoolT< sizeof(XMLAttribute) > _attributePool;
1872  MemPoolT< sizeof(XMLText) > _textPool;
1873  MemPoolT< sizeof(XMLComment) > _commentPool;
1874 
1875  static const char* _errorNames[XML_ERROR_COUNT];
1876 
1877  void Parse();
1878 
1879  void SetError( XMLError error, int lineNum, const char* format, ... );
1880 
1881  template<class NodeType, int PoolElementSize>
1882  NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
1883 };
1884 
1885 template<class NodeType, int PoolElementSize>
1886 inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
1887 {
1888  TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
1889  TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
1890  NodeType* returnNode = new (pool.Alloc()) NodeType( this );
1891  TIXMLASSERT( returnNode );
1892  returnNode->_memPool = &pool;
1893 
1894  _unlinked.Push(returnNode);
1895  return returnNode;
1896 }
1897 
1953 class TINYXML2_LIB XMLHandle
1954 {
1955 public:
1957  XMLHandle( XMLNode* node ) : _node( node ) {
1958  }
1960  XMLHandle( XMLNode& node ) : _node( &node ) {
1961  }
1963  XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
1964  }
1966  XMLHandle& operator=( const XMLHandle& ref ) {
1967  _node = ref._node;
1968  return *this;
1969  }
1970 
1973  return XMLHandle( _node ? _node->FirstChild() : 0 );
1974  }
1976  XMLHandle FirstChildElement( const char* name = 0 ) {
1977  return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
1978  }
1981  return XMLHandle( _node ? _node->LastChild() : 0 );
1982  }
1984  XMLHandle LastChildElement( const char* name = 0 ) {
1985  return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
1986  }
1989  return XMLHandle( _node ? _node->PreviousSibling() : 0 );
1990  }
1992  XMLHandle PreviousSiblingElement( const char* name = 0 ) {
1993  return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
1994  }
1997  return XMLHandle( _node ? _node->NextSibling() : 0 );
1998  }
2000  XMLHandle NextSiblingElement( const char* name = 0 ) {
2001  return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2002  }
2003 
2006  return _node;
2007  }
2010  return ( _node ? _node->ToElement() : 0 );
2011  }
2014  return ( _node ? _node->ToText() : 0 );
2015  }
2018  return ( _node ? _node->ToUnknown() : 0 );
2019  }
2022  return ( _node ? _node->ToDeclaration() : 0 );
2023  }
2024 
2025 private:
2026  XMLNode* _node;
2027 };
2028 
2029 
2034 class TINYXML2_LIB XMLConstHandle
2035 {
2036 public:
2037  XMLConstHandle( const XMLNode* node ) : _node( node ) {
2038  }
2039  XMLConstHandle( const XMLNode& node ) : _node( &node ) {
2040  }
2041  XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
2042  }
2043 
2044  XMLConstHandle& operator=( const XMLConstHandle& ref ) {
2045  _node = ref._node;
2046  return *this;
2047  }
2048 
2049  const XMLConstHandle FirstChild() const {
2050  return XMLConstHandle( _node ? _node->FirstChild() : 0 );
2051  }
2052  const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
2053  return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
2054  }
2055  const XMLConstHandle LastChild() const {
2056  return XMLConstHandle( _node ? _node->LastChild() : 0 );
2057  }
2058  const XMLConstHandle LastChildElement( const char* name = 0 ) const {
2059  return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
2060  }
2061  const XMLConstHandle PreviousSibling() const {
2062  return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
2063  }
2064  const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
2065  return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2066  }
2067  const XMLConstHandle NextSibling() const {
2068  return XMLConstHandle( _node ? _node->NextSibling() : 0 );
2069  }
2070  const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
2071  return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2072  }
2073 
2074 
2075  const XMLNode* ToNode() const {
2076  return _node;
2077  }
2078  const XMLElement* ToElement() const {
2079  return ( _node ? _node->ToElement() : 0 );
2080  }
2081  const XMLText* ToText() const {
2082  return ( _node ? _node->ToText() : 0 );
2083  }
2084  const XMLUnknown* ToUnknown() const {
2085  return ( _node ? _node->ToUnknown() : 0 );
2086  }
2087  const XMLDeclaration* ToDeclaration() const {
2088  return ( _node ? _node->ToDeclaration() : 0 );
2089  }
2090 
2091 private:
2092  const XMLNode* _node;
2093 };
2094 
2095 
2138 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2139 {
2140 public:
2147  XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2148  virtual ~XMLPrinter() {}
2149 
2151  void PushHeader( bool writeBOM, bool writeDeclaration );
2155  void OpenElement( const char* name, bool compactMode=false );
2157  void PushAttribute( const char* name, const char* value );
2158  void PushAttribute( const char* name, int value );
2159  void PushAttribute( const char* name, unsigned value );
2160  void PushAttribute(const char* name, int64_t value);
2161  void PushAttribute( const char* name, bool value );
2162  void PushAttribute( const char* name, double value );
2164  virtual void CloseElement( bool compactMode=false );
2165 
2167  void PushText( const char* text, bool cdata=false );
2169  void PushText( int value );
2171  void PushText( unsigned value );
2173  void PushText(int64_t value);
2175  void PushText( bool value );
2177  void PushText( float value );
2179  void PushText( double value );
2180 
2182  void PushComment( const char* comment );
2183 
2184  void PushDeclaration( const char* value );
2185  void PushUnknown( const char* value );
2186 
2187  virtual bool VisitEnter( const XMLDocument& /*doc*/ );
2188  virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
2189  return true;
2190  }
2191 
2192  virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
2193  virtual bool VisitExit( const XMLElement& element );
2194 
2195  virtual bool Visit( const XMLText& text );
2196  virtual bool Visit( const XMLComment& comment );
2197  virtual bool Visit( const XMLDeclaration& declaration );
2198  virtual bool Visit( const XMLUnknown& unknown );
2199 
2204  const char* CStr() const {
2205  return _buffer.Mem();
2206  }
2212  int CStrSize() const {
2213  return _buffer.Size();
2214  }
2219  void ClearBuffer() {
2220  _buffer.Clear();
2221  _buffer.Push(0);
2222  _firstElement = true;
2223  }
2224 
2225 protected:
2226  virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2227 
2231  virtual void PrintSpace( int depth );
2232  void Print( const char* format, ... );
2233  void Write( const char* data, size_t size );
2234  inline void Write( const char* data ) { Write( data, strlen( data ) ); }
2235  void Putc( char ch );
2236 
2237  void SealElementIfJustOpened();
2238  bool _elementJustOpened;
2239  DynArray< const char*, 10 > _stack;
2240 
2241 private:
2242  void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2243 
2244  bool _firstElement;
2245  FILE* _fp;
2246  int _depth;
2247  int _textDepth;
2248  bool _processEntities;
2249  bool _compactMode;
2250 
2251  enum {
2252  ENTITY_RANGE = 64,
2253  BUF_SIZE = 200
2254  };
2255  bool _entityFlag[ENTITY_RANGE];
2256  bool _restrictedEntityFlag[ENTITY_RANGE];
2257 
2258  DynArray< char, 20 > _buffer;
2259 
2260  // Prohibit cloning, intentionally not implemented
2261  XMLPrinter( const XMLPrinter& );
2262  XMLPrinter& operator=( const XMLPrinter& );
2263 };
2264 
2265 
2266 } // tinyxml2
2267 
2268 #if defined(_MSC_VER)
2269 # pragma warning(pop)
2270 #endif
2271 
2272 #endif // TINYXML2_INCLUDED
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1331
XMLError QueryIntValue(int *value) const
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1340
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:478
virtual XMLNode * ShallowClone(XMLDocument *) const
Definition: tinyxml2.h:1843
virtual bool ShallowEqual(const XMLNode *) const
Definition: tinyxml2.h:1846
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition: tinyxml2.h:1976
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2013
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
const char * CStr() const
Definition: tinyxml2.h:2204
XMLError ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1805
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2009
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:674
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:678
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1322
int CStrSize() const
Definition: tinyxml2.h:2212
float FloatValue() const
Query as a float. See IntValue()
Definition: tinyxml2.h:1175
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:1650
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2017
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1241
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:1963
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:1972
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:987
void SetUserData(void *userData)
Definition: tinyxml2.h:921
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:803
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1157
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition: tinyxml2.h:1984
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:1980
Definition: tinyxml2.h:1953
Definition: tinyxml2.h:1052
XMLElement * RootElement()
Definition: tinyxml2.h:1729
int QueryAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1382
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:979
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:1960
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1245
void SetBOM(bool useBOM)
Definition: tinyxml2.h:1722
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:1957
void ClearBuffer()
Definition: tinyxml2.h:2219
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1017
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1249
bool HasBOM() const
Definition: tinyxml2.h:1717
Definition: tinyxml2.h:105
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1356
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2005
bool BoolValue() const
Query as a boolean. See IntValue()
Definition: tinyxml2.h:1163
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:751
Definition: tinyxml2.h:1013
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1056
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:492
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:504
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1417
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1348
Definition: tinyxml2.h:1236
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:1996
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file. ...
Definition: tinyxml2.h:1133
int IntValue() const
Definition: tinyxml2.h:1144
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1091
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:991
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:1988
Definition: tinyxml2.h:2034
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition: tinyxml2.h:1966
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:2188
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:483
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1801
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:474
Definition: tinyxml2.h:1087
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:686
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:769
Definition: tinyxml2.h:1122
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1429
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2021
void SetAttribute(const char *value)
Set the attribute to a string value.
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1407
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:487
Definition: tinyxml2.h:2138
Definition: tinyxml2.h:1635
void * GetUserData() const
Definition: tinyxml2.h:928
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1423
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition: tinyxml2.h:1434
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:737
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:500
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition: tinyxml2.h:787
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2000
Definition: tinyxml2.h:656
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1313
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition: tinyxml2.h:734
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:496
Definition: tinyxml2.h:973
Definition: tinyxml2.h:468
int ErrorLineNum() const
Return the line where the error occured, or zero if unknown.
Definition: tinyxml2.h:1820
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:668
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:694
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition: tinyxml2.h:1439
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1136
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:746
double DoubleValue() const
Query as a double. See IntValue()
Definition: tinyxml2.h:1169
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:690
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:663
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:1992
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1412
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1450
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:682