TinyXML-2 6.2.0
tinyxml2.h
1/*
2Original code by Lee Thomason (www.grinninglizard.com)
3
4This software is provided 'as-is', without any express or implied
5warranty. In no event will the authors be held liable for any
6damages arising from the use of this software.
7
8Permission is granted to anyone to use this software for any
9purpose, including commercial applications, and to alter it and
10redistribute it freely, subject to the following restrictions:
11
121. The origin of this software must not be misrepresented; you must
13not claim that you wrote the original software. If you use this
14software in a product, an acknowledgment in the product documentation
15would be appreciated but is not required.
16
172. Altered source versions must be plainly marked as such, and
18must not be misrepresented as being the original software.
19
203. This notice may not be removed or altered from any source
21distribution.
22*/
23
24#ifndef TINYXML2_INCLUDED
25#define TINYXML2_INCLUDED
26
27#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
28# include <ctype.h>
29# include <limits.h>
30# include <stdio.h>
31# include <stdlib.h>
32# include <string.h>
33# if defined(__PS3__)
34# include <stddef.h>
35# endif
36#else
37# include <cctype>
38# include <climits>
39# include <cstdio>
40# include <cstdlib>
41# include <cstring>
42#endif
43#include <stdint.h>
44
45/*
46 TODO: intern strings instead of allocation.
47*/
48/*
49 gcc:
50 g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
51
52 Formatting, Artistic Style:
53 AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
54*/
55
56#if defined( _DEBUG ) || defined (__DEBUG__)
57# ifndef TINYXML2_DEBUG
58# define TINYXML2_DEBUG
59# endif
60#endif
61
62#ifdef _MSC_VER
63# pragma warning(push)
64# pragma warning(disable: 4251)
65#endif
66
67#ifdef _WIN32
68# ifdef TINYXML2_EXPORT
69# define TINYXML2_LIB __declspec(dllexport)
70# elif defined(TINYXML2_IMPORT)
71# define TINYXML2_LIB __declspec(dllimport)
72# else
73# define TINYXML2_LIB
74# endif
75#elif __GNUC__ >= 4
76# define TINYXML2_LIB __attribute__((visibility("default")))
77#else
78# define TINYXML2_LIB
79#endif
80
81
82#if defined(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*/
101static const int TIXML2_MAJOR_VERSION = 6;
102static const int TIXML2_MINOR_VERSION = 2;
103static const int TIXML2_PATCH_VERSION = 0;
104
105#define TINYXML2_MAJOR_VERSION 6
106#define TINYXML2_MINOR_VERSION 2
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.
114static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
115
116namespace tinyxml2
117{
118class XMLDocument;
119class XMLElement;
120class XMLAttribute;
121class XMLComment;
122class XMLText;
123class XMLDeclaration;
124class XMLUnknown;
125class 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*/
133class StrPair
134{
135public:
136 enum {
137 NEEDS_ENTITY_PROCESSING = 0x01,
138 NEEDS_NEWLINE_NORMALIZATION = 0x02,
139 NEEDS_WHITESPACE_COLLAPSING = 0x04,
140
141 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
142 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
143 ATTRIBUTE_NAME = 0,
144 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
145 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
146 COMMENT = NEEDS_NEWLINE_NORMALIZATION
147 };
148
149 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
150 ~StrPair();
151
152 void Set( char* start, char* end, int flags ) {
153 TIXMLASSERT( start );
154 TIXMLASSERT( end );
155 Reset();
156 _start = start;
157 _end = end;
158 _flags = flags | NEEDS_FLUSH;
159 }
160
161 const char* GetStr();
162
163 bool Empty() const {
164 return _start == _end;
165 }
166
167 void SetInternedStr( const char* str ) {
168 Reset();
169 _start = const_cast<char*>(str);
170 }
171
172 void SetStr( const char* str, int flags=0 );
173
174 char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
175 char* ParseName( char* in );
176
177 void TransferTo( StrPair* other );
178 void Reset();
179
180private:
181 void CollapseWhitespace();
182
183 enum {
184 NEEDS_FLUSH = 0x100,
185 NEEDS_DELETE = 0x200
186 };
187
188 int _flags;
189 char* _start;
190 char* _end;
191
192 StrPair( const StrPair& other ); // not supported
193 void operator=( StrPair& other ); // not supported, use TransferTo()
194};
195
196
197/*
198 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
199 Has a small initial memory pool, so that low or no usage will not
200 cause a call to new/delete
201*/
202template <class T, int INITIAL_SIZE>
203class DynArray
204{
205public:
206 DynArray() :
207 _mem( _pool ),
208 _allocated( INITIAL_SIZE ),
209 _size( 0 )
210 {
211 }
212
213 ~DynArray() {
214 if ( _mem != _pool ) {
215 delete [] _mem;
216 }
217 }
218
219 void Clear() {
220 _size = 0;
221 }
222
223 void Push( T t ) {
224 TIXMLASSERT( _size < INT_MAX );
225 EnsureCapacity( _size+1 );
226 _mem[_size] = t;
227 ++_size;
228 }
229
230 T* PushArr( int count ) {
231 TIXMLASSERT( count >= 0 );
232 TIXMLASSERT( _size <= INT_MAX - count );
233 EnsureCapacity( _size+count );
234 T* ret = &_mem[_size];
235 _size += count;
236 return ret;
237 }
238
239 T Pop() {
240 TIXMLASSERT( _size > 0 );
241 --_size;
242 return _mem[_size];
243 }
244
245 void PopArr( int count ) {
246 TIXMLASSERT( _size >= count );
247 _size -= count;
248 }
249
250 bool Empty() const {
251 return _size == 0;
252 }
253
254 T& operator[](int i) {
255 TIXMLASSERT( i>= 0 && i < _size );
256 return _mem[i];
257 }
258
259 const T& operator[](int i) const {
260 TIXMLASSERT( i>= 0 && i < _size );
261 return _mem[i];
262 }
263
264 const T& PeekTop() const {
265 TIXMLASSERT( _size > 0 );
266 return _mem[ _size - 1];
267 }
268
269 int Size() const {
270 TIXMLASSERT( _size >= 0 );
271 return _size;
272 }
273
274 int Capacity() const {
275 TIXMLASSERT( _allocated >= INITIAL_SIZE );
276 return _allocated;
277 }
278
279 void SwapRemove(int i) {
280 TIXMLASSERT(i >= 0 && i < _size);
281 TIXMLASSERT(_size > 0);
282 _mem[i] = _mem[_size - 1];
283 --_size;
284 }
285
286 const T* Mem() const {
287 TIXMLASSERT( _mem );
288 return _mem;
289 }
290
291 T* Mem() {
292 TIXMLASSERT( _mem );
293 return _mem;
294 }
295
296private:
297 DynArray( const DynArray& ); // not supported
298 void operator=( const DynArray& ); // not supported
299
300 void EnsureCapacity( int cap ) {
301 TIXMLASSERT( cap > 0 );
302 if ( cap > _allocated ) {
303 TIXMLASSERT( cap <= INT_MAX / 2 );
304 int newAllocated = cap * 2;
305 T* newMem = new T[newAllocated];
306 TIXMLASSERT( newAllocated >= _size );
307 memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
308 if ( _mem != _pool ) {
309 delete [] _mem;
310 }
311 _mem = newMem;
312 _allocated = newAllocated;
313 }
314 }
315
316 T* _mem;
317 T _pool[INITIAL_SIZE];
318 int _allocated; // objects allocated
319 int _size; // number objects in use
320};
321
322
323/*
324 Parent virtual class of a pool for fast allocation
325 and deallocation of objects.
326*/
327class MemPool
328{
329public:
330 MemPool() {}
331 virtual ~MemPool() {}
332
333 virtual int ItemSize() const = 0;
334 virtual void* Alloc() = 0;
335 virtual void Free( void* ) = 0;
336 virtual void SetTracked() = 0;
337 virtual void Clear() = 0;
338};
339
340
341/*
342 Template child class to create pools of the correct type.
343*/
344template< int ITEM_SIZE >
345class MemPoolT : public MemPool
346{
347public:
348 MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
349 ~MemPoolT() {
350 Clear();
351 }
352
353 void Clear() {
354 // Delete the blocks.
355 while( !_blockPtrs.Empty()) {
356 Block* lastBlock = _blockPtrs.Pop();
357 delete lastBlock;
358 }
359 _root = 0;
360 _currentAllocs = 0;
361 _nAllocs = 0;
362 _maxAllocs = 0;
363 _nUntracked = 0;
364 }
365
366 virtual int ItemSize() const {
367 return ITEM_SIZE;
368 }
369 int CurrentAllocs() const {
370 return _currentAllocs;
371 }
372
373 virtual void* Alloc() {
374 if ( !_root ) {
375 // Need a new block.
376 Block* block = new Block();
377 _blockPtrs.Push( block );
378
379 Item* blockItems = block->items;
380 for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
381 blockItems[i].next = &(blockItems[i + 1]);
382 }
383 blockItems[ITEMS_PER_BLOCK - 1].next = 0;
384 _root = blockItems;
385 }
386 Item* const result = _root;
387 TIXMLASSERT( result != 0 );
388 _root = _root->next;
389
390 ++_currentAllocs;
391 if ( _currentAllocs > _maxAllocs ) {
392 _maxAllocs = _currentAllocs;
393 }
394 ++_nAllocs;
395 ++_nUntracked;
396 return result;
397 }
398
399 virtual void Free( void* mem ) {
400 if ( !mem ) {
401 return;
402 }
403 --_currentAllocs;
404 Item* item = static_cast<Item*>( mem );
405#ifdef TINYXML2_DEBUG
406 memset( item, 0xfe, sizeof( *item ) );
407#endif
408 item->next = _root;
409 _root = item;
410 }
411 void Trace( const char* name ) {
412 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
413 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
414 ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
415 }
416
417 void SetTracked() {
418 --_nUntracked;
419 }
420
421 int Untracked() const {
422 return _nUntracked;
423 }
424
425 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
426 // The test file is large, 170k.
427 // Release: VS2010 gcc(no opt)
428 // 1k: 4000
429 // 2k: 4000
430 // 4k: 3900 21000
431 // 16k: 5200
432 // 32k: 4300
433 // 64k: 4000 21000
434 // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
435 // in private part if ITEMS_PER_BLOCK is private
436 enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
437
438private:
439 MemPoolT( const MemPoolT& ); // not supported
440 void operator=( const MemPoolT& ); // not supported
441
442 union Item {
443 Item* next;
444 char itemData[ITEM_SIZE];
445 };
446 struct Block {
447 Item items[ITEMS_PER_BLOCK];
448 };
449 DynArray< Block*, 10 > _blockPtrs;
450 Item* _root;
451
452 int _currentAllocs;
453 int _nAllocs;
454 int _maxAllocs;
455 int _nUntracked;
456};
457
458
459
479class TINYXML2_LIB XMLVisitor
480{
481public:
482 virtual ~XMLVisitor() {}
483
485 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
486 return true;
487 }
489 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
490 return true;
491 }
492
494 virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
495 return true;
496 }
498 virtual bool VisitExit( const XMLElement& /*element*/ ) {
499 return true;
500 }
501
503 virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
504 return true;
505 }
507 virtual bool Visit( const XMLText& /*text*/ ) {
508 return true;
509 }
511 virtual bool Visit( const XMLComment& /*comment*/ ) {
512 return true;
513 }
515 virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
516 return true;
517 }
518};
519
520// WARNING: must match XMLDocument::_errorNames[]
521enum XMLError {
522 XML_SUCCESS = 0,
523 XML_NO_ATTRIBUTE,
524 XML_WRONG_ATTRIBUTE_TYPE,
525 XML_ERROR_FILE_NOT_FOUND,
526 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
527 XML_ERROR_FILE_READ_ERROR,
528 UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version
529 XML_ERROR_PARSING_ELEMENT,
530 XML_ERROR_PARSING_ATTRIBUTE,
531 UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version
532 XML_ERROR_PARSING_TEXT,
533 XML_ERROR_PARSING_CDATA,
534 XML_ERROR_PARSING_COMMENT,
535 XML_ERROR_PARSING_DECLARATION,
536 XML_ERROR_PARSING_UNKNOWN,
537 XML_ERROR_EMPTY_DOCUMENT,
538 XML_ERROR_MISMATCHED_ELEMENT,
539 XML_ERROR_PARSING,
540 XML_CAN_NOT_CONVERT_TEXT,
541 XML_NO_TEXT_NODE,
542 XML_ELEMENT_DEPTH_EXCEEDED,
543
544 XML_ERROR_COUNT
545};
546
547
548/*
549 Utility functionality.
550*/
551class TINYXML2_LIB XMLUtil
552{
553public:
554 static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
555 TIXMLASSERT( p );
556
557 while( IsWhiteSpace(*p) ) {
558 if (curLineNumPtr && *p == '\n') {
559 ++(*curLineNumPtr);
560 }
561 ++p;
562 }
563 TIXMLASSERT( p );
564 return p;
565 }
566 static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
567 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
568 }
569
570 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
571 // correct, but simple, and usually works.
572 static bool IsWhiteSpace( char p ) {
573 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
574 }
575
576 inline static bool IsNameStartChar( unsigned char ch ) {
577 if ( ch >= 128 ) {
578 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
579 return true;
580 }
581 if ( isalpha( ch ) ) {
582 return true;
583 }
584 return ch == ':' || ch == '_';
585 }
586
587 inline static bool IsNameChar( unsigned char ch ) {
588 return IsNameStartChar( ch )
589 || isdigit( ch )
590 || ch == '.'
591 || ch == '-';
592 }
593
594 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
595 if ( p == q ) {
596 return true;
597 }
598 TIXMLASSERT( p );
599 TIXMLASSERT( q );
600 TIXMLASSERT( nChar >= 0 );
601 return strncmp( p, q, nChar ) == 0;
602 }
603
604 inline static bool IsUTF8Continuation( char p ) {
605 return ( p & 0x80 ) != 0;
606 }
607
608 static const char* ReadBOM( const char* p, bool* hasBOM );
609 // p is the starting location,
610 // the UTF-8 value of the entity will be placed in value, and length filled in.
611 static const char* GetCharacterRef( const char* p, char* value, int* length );
612 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
613
614 // converts primitive types to strings
615 static void ToStr( int v, char* buffer, int bufferSize );
616 static void ToStr( unsigned v, char* buffer, int bufferSize );
617 static void ToStr( bool v, char* buffer, int bufferSize );
618 static void ToStr( float v, char* buffer, int bufferSize );
619 static void ToStr( double v, char* buffer, int bufferSize );
620 static void ToStr(int64_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
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
637private:
638 static const char* writeBoolTrue;
639 static const char* writeBoolFalse;
640};
641
642
668class TINYXML2_LIB XMLNode
669{
670 friend class XMLDocument;
671 friend class XMLElement;
672public:
673
675 const XMLDocument* GetDocument() const {
676 TIXMLASSERT( _document );
677 return _document;
678 }
681 TIXMLASSERT( _document );
682 return _document;
683 }
684
687 return 0;
688 }
690 virtual XMLText* ToText() {
691 return 0;
692 }
695 return 0;
696 }
699 return 0;
700 }
703 return 0;
704 }
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
838
839 XMLNode* LinkEndChild( XMLNode* addThis ) {
840 return InsertEndChild( addThis );
841 }
858 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
859
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
942protected:
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
961private:
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
985class TINYXML2_LIB XMLText : public XMLNode
986{
987 friend class XMLDocument;
988public:
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
1010protected:
1011 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
1012 virtual ~XMLText() {}
1013
1014 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1015
1016private:
1017 bool _isCData;
1018
1019 XMLText( const XMLText& ); // not supported
1020 XMLText& operator=( const XMLText& ); // not supported
1021};
1022
1023
1025class TINYXML2_LIB XMLComment : public XMLNode
1026{
1027 friend class XMLDocument;
1028public:
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
1041protected:
1042 XMLComment( XMLDocument* doc );
1043 virtual ~XMLComment();
1044
1045 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
1046
1047private:
1048 XMLComment( const XMLComment& ); // not supported
1049 XMLComment& operator=( const XMLComment& ); // not supported
1050};
1051
1052
1064class TINYXML2_LIB XMLDeclaration : public XMLNode
1065{
1066 friend class XMLDocument;
1067public:
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
1080protected:
1082 virtual ~XMLDeclaration();
1083
1084 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1085
1086private:
1087 XMLDeclaration( const XMLDeclaration& ); // not supported
1088 XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1089};
1090
1091
1099class TINYXML2_LIB XMLUnknown : public XMLNode
1100{
1101 friend class XMLDocument;
1102public:
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
1115protected:
1116 XMLUnknown( XMLDocument* doc );
1117 virtual ~XMLUnknown();
1118
1119 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1120
1121private:
1122 XMLUnknown( const XMLUnknown& ); // not supported
1123 XMLUnknown& operator=( const XMLUnknown& ); // not supported
1124};
1125
1126
1127
1134class TINYXML2_LIB XMLAttribute
1135{
1136 friend class XMLElement;
1137public:
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
1169 unsigned UnsignedValue() const {
1170 unsigned i=0;
1171 QueryUnsignedValue( &i );
1172 return i;
1173 }
1175 bool BoolValue() const {
1176 bool b=false;
1177 QueryBoolValue( &b );
1178 return b;
1179 }
1181 double DoubleValue() const {
1182 double d=0;
1183 QueryDoubleValue( &d );
1184 return d;
1185 }
1187 float FloatValue() const {
1188 float f=0;
1189 QueryFloatValue( &f );
1190 return f;
1191 }
1192
1197 XMLError QueryIntValue( int* value ) const;
1199 XMLError QueryUnsignedValue( unsigned int* value ) const;
1201 XMLError QueryInt64Value(int64_t* value) const;
1203 XMLError QueryBoolValue( bool* value ) const;
1205 XMLError QueryDoubleValue( double* value ) const;
1207 XMLError QueryFloatValue( float* value ) const;
1208
1210 void SetAttribute( const char* value );
1212 void SetAttribute( int value );
1214 void SetAttribute( unsigned value );
1216 void SetAttribute(int64_t value);
1218 void SetAttribute( bool value );
1220 void SetAttribute( double value );
1222 void SetAttribute( float value );
1223
1224private:
1225 enum { BUF_SIZE = 200 };
1226
1227 XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
1228 virtual ~XMLAttribute() {}
1229
1230 XMLAttribute( const XMLAttribute& ); // not supported
1231 void operator=( const XMLAttribute& ); // not supported
1232 void SetName( const char* name );
1233
1234 char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
1235
1236 mutable StrPair _name;
1237 mutable StrPair _value;
1238 int _parseLineNum;
1239 XMLAttribute* _next;
1240 MemPool* _memPool;
1241};
1242
1243
1248class TINYXML2_LIB XMLElement : public XMLNode
1249{
1250 friend class XMLDocument;
1251public:
1253 const char* Name() const {
1254 return Value();
1255 }
1257 void SetName( const char* str, bool staticMem=false ) {
1258 SetValue( str, staticMem );
1259 }
1260
1262 return this;
1263 }
1264 virtual const XMLElement* ToElement() const {
1265 return this;
1266 }
1267 virtual bool Accept( XMLVisitor* visitor ) const;
1268
1292 const char* Attribute( const char* name, const char* value=0 ) const;
1293
1300 int IntAttribute(const char* name, int defaultValue = 0) const;
1302 unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1304 int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1306 bool BoolAttribute(const char* name, bool defaultValue = false) const;
1308 double DoubleAttribute(const char* name, double defaultValue = 0) const;
1310 float FloatAttribute(const char* name, float defaultValue = 0) const;
1311
1325 XMLError QueryIntAttribute( const char* name, int* value ) const {
1326 const XMLAttribute* a = FindAttribute( name );
1327 if ( !a ) {
1328 return XML_NO_ATTRIBUTE;
1329 }
1330 return a->QueryIntValue( value );
1331 }
1332
1334 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
1335 const XMLAttribute* a = FindAttribute( name );
1336 if ( !a ) {
1337 return XML_NO_ATTRIBUTE;
1338 }
1339 return a->QueryUnsignedValue( value );
1340 }
1341
1343 XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1344 const XMLAttribute* a = FindAttribute(name);
1345 if (!a) {
1346 return XML_NO_ATTRIBUTE;
1347 }
1348 return a->QueryInt64Value(value);
1349 }
1350
1352 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
1353 const XMLAttribute* a = FindAttribute( name );
1354 if ( !a ) {
1355 return XML_NO_ATTRIBUTE;
1356 }
1357 return a->QueryBoolValue( value );
1358 }
1360 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
1361 const XMLAttribute* a = FindAttribute( name );
1362 if ( !a ) {
1363 return XML_NO_ATTRIBUTE;
1364 }
1365 return a->QueryDoubleValue( value );
1366 }
1368 XMLError QueryFloatAttribute( const char* name, float* value ) const {
1369 const XMLAttribute* a = FindAttribute( name );
1370 if ( !a ) {
1371 return XML_NO_ATTRIBUTE;
1372 }
1373 return a->QueryFloatValue( value );
1374 }
1375
1377 XMLError QueryStringAttribute(const char* name, const char** value) const {
1378 const XMLAttribute* a = FindAttribute(name);
1379 if (!a) {
1380 return XML_NO_ATTRIBUTE;
1381 }
1382 *value = a->Value();
1383 return XML_SUCCESS;
1384 }
1385
1386
1387
1405 int QueryAttribute( const char* name, int* value ) const {
1406 return QueryIntAttribute( name, value );
1407 }
1408
1409 int QueryAttribute( const char* name, unsigned int* value ) const {
1410 return QueryUnsignedAttribute( name, value );
1411 }
1412
1413 int QueryAttribute(const char* name, int64_t* value) const {
1414 return QueryInt64Attribute(name, value);
1415 }
1416
1417 int QueryAttribute( const char* name, bool* value ) const {
1418 return QueryBoolAttribute( name, value );
1419 }
1420
1421 int QueryAttribute( const char* name, double* value ) const {
1422 return QueryDoubleAttribute( name, value );
1423 }
1424
1425 int QueryAttribute( const char* name, float* value ) const {
1426 return QueryFloatAttribute( name, value );
1427 }
1428
1430 void SetAttribute( const char* name, const char* value ) {
1431 XMLAttribute* a = FindOrCreateAttribute( name );
1432 a->SetAttribute( value );
1433 }
1435 void SetAttribute( const char* name, int value ) {
1436 XMLAttribute* a = FindOrCreateAttribute( name );
1437 a->SetAttribute( value );
1438 }
1440 void SetAttribute( const char* name, unsigned value ) {
1441 XMLAttribute* a = FindOrCreateAttribute( name );
1442 a->SetAttribute( value );
1443 }
1444
1446 void SetAttribute(const char* name, int64_t value) {
1447 XMLAttribute* a = FindOrCreateAttribute(name);
1448 a->SetAttribute(value);
1449 }
1450
1452 void SetAttribute( const char* name, bool value ) {
1453 XMLAttribute* a = FindOrCreateAttribute( name );
1454 a->SetAttribute( value );
1455 }
1457 void SetAttribute( const char* name, double value ) {
1458 XMLAttribute* a = FindOrCreateAttribute( name );
1459 a->SetAttribute( value );
1460 }
1462 void SetAttribute( const char* name, float value ) {
1463 XMLAttribute* a = FindOrCreateAttribute( name );
1464 a->SetAttribute( value );
1465 }
1466
1470 void DeleteAttribute( const char* name );
1471
1474 return _rootAttribute;
1475 }
1477 const XMLAttribute* FindAttribute( const char* name ) const;
1478
1507 const char* GetText() const;
1508
1543 void SetText( const char* inText );
1545 void SetText( int value );
1547 void SetText( unsigned value );
1549 void SetText(int64_t value);
1551 void SetText( bool value );
1553 void SetText( double value );
1555 void SetText( float value );
1556
1583 XMLError QueryIntText( int* ival ) const;
1585 XMLError QueryUnsignedText( unsigned* uval ) const;
1587 XMLError QueryInt64Text(int64_t* uval) const;
1589 XMLError QueryBoolText( bool* bval ) const;
1591 XMLError QueryDoubleText( double* dval ) const;
1593 XMLError QueryFloatText( float* fval ) const;
1594
1595 int IntText(int defaultValue = 0) const;
1596
1598 unsigned UnsignedText(unsigned defaultValue = 0) const;
1600 int64_t Int64Text(int64_t defaultValue = 0) const;
1602 bool BoolText(bool defaultValue = false) const;
1604 double DoubleText(double defaultValue = 0) const;
1606 float FloatText(float defaultValue = 0) const;
1607
1608 // internal:
1609 enum ElementClosingType {
1610 OPEN, // <foo>
1611 CLOSED, // <foo/>
1612 CLOSING // </foo>
1613 };
1614 ElementClosingType ClosingType() const {
1615 return _closingType;
1616 }
1617 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1618 virtual bool ShallowEqual( const XMLNode* compare ) const;
1619
1620protected:
1621 char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
1622
1623private:
1624 XMLElement( XMLDocument* doc );
1625 virtual ~XMLElement();
1626 XMLElement( const XMLElement& ); // not supported
1627 void operator=( const XMLElement& ); // not supported
1628
1629 XMLAttribute* FindAttribute( const char* name ) {
1630 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
1631 }
1632 XMLAttribute* FindOrCreateAttribute( const char* name );
1633 //void LinkAttribute( XMLAttribute* attrib );
1634 char* ParseAttributes( char* p, int* curLineNumPtr );
1635 static void DeleteAttribute( XMLAttribute* attribute );
1636 XMLAttribute* CreateAttribute();
1637
1638 enum { BUF_SIZE = 200 };
1639 ElementClosingType _closingType;
1640 // The attribute list is ordered; there is no 'lastAttribute'
1641 // because the list needs to be scanned for dupes before adding
1642 // a new attribute.
1643 XMLAttribute* _rootAttribute;
1644};
1645
1646
1647enum Whitespace {
1648 PRESERVE_WHITESPACE,
1649 COLLAPSE_WHITESPACE
1650};
1651
1652
1658class TINYXML2_LIB XMLDocument : public XMLNode
1659{
1660 friend class XMLElement;
1661 // Gives access to SetError and Push/PopDepth, but over-access for everything else.
1662 // Wishing C++ had "internal" scope.
1663 friend class XMLNode;
1664 friend class XMLText;
1665 friend class XMLComment;
1666 friend class XMLDeclaration;
1667 friend class XMLUnknown;
1668public:
1670 XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1671 ~XMLDocument();
1672
1674 TIXMLASSERT( this == _document );
1675 return this;
1676 }
1677 virtual const XMLDocument* ToDocument() const {
1678 TIXMLASSERT( this == _document );
1679 return this;
1680 }
1681
1692 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
1693
1699 XMLError LoadFile( const char* filename );
1700
1712 XMLError LoadFile( FILE* );
1713
1719 XMLError SaveFile( const char* filename, bool compact = false );
1720
1728 XMLError SaveFile( FILE* fp, bool compact = false );
1729
1730 bool ProcessEntities() const {
1731 return _processEntities;
1732 }
1733 Whitespace WhitespaceMode() const {
1734 return _whitespaceMode;
1735 }
1736
1740 bool HasBOM() const {
1741 return _writeBOM;
1742 }
1745 void SetBOM( bool useBOM ) {
1746 _writeBOM = useBOM;
1747 }
1748
1753 return FirstChildElement();
1754 }
1755 const XMLElement* RootElement() const {
1756 return FirstChildElement();
1757 }
1758
1773 void Print( XMLPrinter* streamer=0 ) const;
1774 virtual bool Accept( XMLVisitor* visitor ) const;
1775
1781 XMLElement* NewElement( const char* name );
1787 XMLComment* NewComment( const char* comment );
1793 XMLText* NewText( const char* text );
1805 XMLDeclaration* NewDeclaration( const char* text=0 );
1811 XMLUnknown* NewUnknown( const char* text );
1812
1817 void DeleteNode( XMLNode* node );
1818
1819 void ClearError() {
1820 SetError(XML_SUCCESS, 0, 0);
1821 }
1822
1824 bool Error() const {
1825 return _errorID != XML_SUCCESS;
1826 }
1828 XMLError ErrorID() const {
1829 return _errorID;
1830 }
1831 const char* ErrorName() const;
1832 static const char* ErrorIDToName(XMLError errorID);
1833
1837 const char* ErrorStr() const;
1838
1840 void PrintError() const;
1841
1843 int ErrorLineNum() const
1844 {
1845 return _errorLineNum;
1846 }
1847
1849 void Clear();
1850
1858 void DeepCopy(XMLDocument* target) const;
1859
1860 // internal
1861 char* Identify( char* p, XMLNode** node );
1862
1863 // internal
1864 void MarkInUse(XMLNode*);
1865
1866 virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
1867 return 0;
1868 }
1869 virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
1870 return false;
1871 }
1872
1873private:
1874 XMLDocument( const XMLDocument& ); // not supported
1875 void operator=( const XMLDocument& ); // not supported
1876
1877 bool _writeBOM;
1878 bool _processEntities;
1879 XMLError _errorID;
1880 Whitespace _whitespaceMode;
1881 mutable StrPair _errorStr;
1882 int _errorLineNum;
1883 char* _charBuffer;
1884 int _parseCurLineNum;
1885 int _parsingDepth;
1886 // Memory tracking does add some overhead.
1887 // However, the code assumes that you don't
1888 // have a bunch of unlinked nodes around.
1889 // Therefore it takes less memory to track
1890 // in the document vs. a linked list in the XMLNode,
1891 // and the performance is the same.
1892 DynArray<XMLNode*, 10> _unlinked;
1893
1894 MemPoolT< sizeof(XMLElement) > _elementPool;
1895 MemPoolT< sizeof(XMLAttribute) > _attributePool;
1896 MemPoolT< sizeof(XMLText) > _textPool;
1897 MemPoolT< sizeof(XMLComment) > _commentPool;
1898
1899 static const char* _errorNames[XML_ERROR_COUNT];
1900
1901 void Parse();
1902
1903 void SetError( XMLError error, int lineNum, const char* format, ... );
1904
1905 // Something of an obvious security hole, once it was discovered.
1906 // Either an ill-formed XML or an excessively deep one can overflow
1907 // the stack. Track stack depth, and error out if needed.
1908 class DepthTracker {
1909 public:
1910 DepthTracker(XMLDocument * document) {
1911 this->_document = document;
1912 document->PushDepth();
1913 }
1914 ~DepthTracker() {
1915 _document->PopDepth();
1916 }
1917 private:
1918 XMLDocument * _document;
1919 };
1920 void PushDepth();
1921 void PopDepth();
1922
1923 template<class NodeType, int PoolElementSize>
1924 NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
1925};
1926
1927template<class NodeType, int PoolElementSize>
1928inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
1929{
1930 TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
1931 TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
1932 NodeType* returnNode = new (pool.Alloc()) NodeType( this );
1933 TIXMLASSERT( returnNode );
1934 returnNode->_memPool = &pool;
1935
1936 _unlinked.Push(returnNode);
1937 return returnNode;
1938}
1939
1995class TINYXML2_LIB XMLHandle
1996{
1997public:
1999 XMLHandle( XMLNode* node ) : _node( node ) {
2000 }
2002 XMLHandle( XMLNode& node ) : _node( &node ) {
2003 }
2005 XMLHandle( const XMLHandle& ref ) : _node( ref._node ) {
2006 }
2009 _node = ref._node;
2010 return *this;
2011 }
2012
2015 return XMLHandle( _node ? _node->FirstChild() : 0 );
2016 }
2018 XMLHandle FirstChildElement( const char* name = 0 ) {
2019 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
2020 }
2023 return XMLHandle( _node ? _node->LastChild() : 0 );
2024 }
2026 XMLHandle LastChildElement( const char* name = 0 ) {
2027 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
2028 }
2031 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
2032 }
2034 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
2035 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2036 }
2039 return XMLHandle( _node ? _node->NextSibling() : 0 );
2040 }
2042 XMLHandle NextSiblingElement( const char* name = 0 ) {
2043 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2044 }
2045
2048 return _node;
2049 }
2052 return ( _node ? _node->ToElement() : 0 );
2053 }
2056 return ( _node ? _node->ToText() : 0 );
2057 }
2060 return ( _node ? _node->ToUnknown() : 0 );
2061 }
2064 return ( _node ? _node->ToDeclaration() : 0 );
2065 }
2066
2067private:
2068 XMLNode* _node;
2069};
2070
2071
2076class TINYXML2_LIB XMLConstHandle
2077{
2078public:
2079 XMLConstHandle( const XMLNode* node ) : _node( node ) {
2080 }
2081 XMLConstHandle( const XMLNode& node ) : _node( &node ) {
2082 }
2083 XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) {
2084 }
2085
2086 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
2087 _node = ref._node;
2088 return *this;
2089 }
2090
2091 const XMLConstHandle FirstChild() const {
2092 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
2093 }
2094 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
2095 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
2096 }
2097 const XMLConstHandle LastChild() const {
2098 return XMLConstHandle( _node ? _node->LastChild() : 0 );
2099 }
2100 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
2101 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
2102 }
2103 const XMLConstHandle PreviousSibling() const {
2104 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
2105 }
2106 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
2107 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
2108 }
2109 const XMLConstHandle NextSibling() const {
2110 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
2111 }
2112 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
2113 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
2114 }
2115
2116
2117 const XMLNode* ToNode() const {
2118 return _node;
2119 }
2120 const XMLElement* ToElement() const {
2121 return ( _node ? _node->ToElement() : 0 );
2122 }
2123 const XMLText* ToText() const {
2124 return ( _node ? _node->ToText() : 0 );
2125 }
2126 const XMLUnknown* ToUnknown() const {
2127 return ( _node ? _node->ToUnknown() : 0 );
2128 }
2129 const XMLDeclaration* ToDeclaration() const {
2130 return ( _node ? _node->ToDeclaration() : 0 );
2131 }
2132
2133private:
2134 const XMLNode* _node;
2135};
2136
2137
2180class TINYXML2_LIB XMLPrinter : public XMLVisitor
2181{
2182public:
2189 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2190 virtual ~XMLPrinter() {}
2191
2193 void PushHeader( bool writeBOM, bool writeDeclaration );
2197 void OpenElement( const char* name, bool compactMode=false );
2199 void PushAttribute( const char* name, const char* value );
2200 void PushAttribute( const char* name, int value );
2201 void PushAttribute( const char* name, unsigned value );
2202 void PushAttribute(const char* name, int64_t value);
2203 void PushAttribute( const char* name, bool value );
2204 void PushAttribute( const char* name, double value );
2206 virtual void CloseElement( bool compactMode=false );
2207
2209 void PushText( const char* text, bool cdata=false );
2211 void PushText( int value );
2213 void PushText( unsigned value );
2215 void PushText(int64_t value);
2217 void PushText( bool value );
2219 void PushText( float value );
2221 void PushText( double value );
2222
2224 void PushComment( const char* comment );
2225
2226 void PushDeclaration( const char* value );
2227 void PushUnknown( const char* value );
2228
2229 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
2230 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
2231 return true;
2232 }
2233
2234 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
2235 virtual bool VisitExit( const XMLElement& element );
2236
2237 virtual bool Visit( const XMLText& text );
2238 virtual bool Visit( const XMLComment& comment );
2239 virtual bool Visit( const XMLDeclaration& declaration );
2240 virtual bool Visit( const XMLUnknown& unknown );
2241
2246 const char* CStr() const {
2247 return _buffer.Mem();
2248 }
2254 int CStrSize() const {
2255 return _buffer.Size();
2256 }
2262 _buffer.Clear();
2263 _buffer.Push(0);
2264 _firstElement = true;
2265 }
2266
2267protected:
2268 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2269
2273 virtual void PrintSpace( int depth );
2274 void Print( const char* format, ... );
2275 void Write( const char* data, size_t size );
2276 inline void Write( const char* data ) { Write( data, strlen( data ) ); }
2277 void Putc( char ch );
2278
2279 void SealElementIfJustOpened();
2280 bool _elementJustOpened;
2281 DynArray< const char*, 10 > _stack;
2282
2283private:
2284 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2285
2286 bool _firstElement;
2287 FILE* _fp;
2288 int _depth;
2289 int _textDepth;
2290 bool _processEntities;
2291 bool _compactMode;
2292
2293 enum {
2294 ENTITY_RANGE = 64,
2295 BUF_SIZE = 200
2296 };
2297 bool _entityFlag[ENTITY_RANGE];
2298 bool _restrictedEntityFlag[ENTITY_RANGE];
2299
2300 DynArray< char, 20 > _buffer;
2301
2302 // Prohibit cloning, intentionally not implemented
2303 XMLPrinter( const XMLPrinter& );
2304 XMLPrinter& operator=( const XMLPrinter& );
2305};
2306
2307
2308} // tinyxml2
2309
2310#if defined(_MSC_VER)
2311# pragma warning(pop)
2312#endif
2313
2314#endif // TINYXML2_INCLUDED
Definition: tinyxml2.h:1135
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file.
Definition: tinyxml2.h:1145
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1169
float FloatValue() const
Query as a float. See IntValue()
Definition: tinyxml2.h:1187
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
void SetAttribute(const char *value)
Set the attribute to a string value.
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
double DoubleValue() const
Query as a double. See IntValue()
Definition: tinyxml2.h:1181
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
const char * Name() const
The name of the attribute.
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
XMLError QueryIntValue(int *value) const
void SetAttribute(int64_t value)
Set the attribute to value.
bool BoolValue() const
Query as a boolean. See IntValue()
Definition: tinyxml2.h:1175
void SetAttribute(double value)
Set the attribute to value.
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1148
const char * Value() const
The value of the attribute.
void SetAttribute(bool value)
Set the attribute to value.
void SetAttribute(int value)
Set the attribute to value.
int IntValue() const
Definition: tinyxml2.h:1156
void SetAttribute(unsigned value)
Set the attribute to value.
void SetAttribute(float value)
Set the attribute to value.
Definition: tinyxml2.h:1026
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1029
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLNode * ShallowClone(XMLDocument *document) const
Definition: tinyxml2.h:2077
Definition: tinyxml2.h:1065
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1068
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLNode * ShallowClone(XMLDocument *document) const
Definition: tinyxml2.h:1659
XMLElement * RootElement()
Definition: tinyxml2.h:1752
void SetBOM(bool useBOM)
Definition: tinyxml2.h:1745
XMLError Parse(const char *xml, size_t nBytes=(size_t)(-1))
void PrintError() const
A (trivial) utility function that prints the ErrorStr() to stdout.
XMLError LoadFile(const char *filename)
bool HasBOM() const
Definition: tinyxml2.h:1740
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1824
XMLComment * NewComment(const char *comment)
XMLElement * NewElement(const char *name)
XMLUnknown * NewUnknown(const char *text)
int ErrorLineNum() const
Return the line where the error occured, or zero if unknown.
Definition: tinyxml2.h:1843
XMLDocument(bool processEntities=true, Whitespace whitespaceMode=PRESERVE_WHITESPACE)
constructor
XMLError LoadFile(FILE *)
void Clear()
Clear the document, resetting it to the initial state.
virtual bool ShallowEqual(const XMLNode *) const
Definition: tinyxml2.h:1869
XMLError SaveFile(const char *filename, bool compact=false)
void Print(XMLPrinter *streamer=0) const
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:1673
XMLError SaveFile(FILE *fp, bool compact=false)
virtual bool Accept(XMLVisitor *visitor) const
void DeleteNode(XMLNode *node)
XMLText * NewText(const char *text)
XMLDeclaration * NewDeclaration(const char *text=0)
const char * ErrorStr() const
virtual XMLNode * ShallowClone(XMLDocument *) const
Definition: tinyxml2.h:1866
void DeepCopy(XMLDocument *target) const
XMLError ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1828
Definition: tinyxml2.h:1249
int QueryAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1405
const char * GetText() const
double DoubleAttribute(const char *name, double defaultValue=0) const
See IntAttribute()
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1430
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1352
XMLError QueryUnsignedText(unsigned *uval) const
See QueryIntText()
const XMLAttribute * FindAttribute(const char *name) const
Query a specific attribute in the list.
virtual XMLNode * ShallowClone(XMLDocument *document) const
void SetText(const char *inText)
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition: tinyxml2.h:1457
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1334
virtual bool Accept(XMLVisitor *visitor) const
XMLError QueryBoolText(bool *bval) const
See QueryIntText()
float FloatText(float defaultValue=0) const
See QueryIntText()
const char * Attribute(const char *name, const char *value=0) const
unsigned UnsignedText(unsigned defaultValue=0) const
See QueryIntText()
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1473
void SetText(float value)
Convenience method for setting text inside an element. See SetText() for important limitations.
bool BoolAttribute(const char *name, bool defaultValue=false) const
See IntAttribute()
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition: tinyxml2.h:1462
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1360
int64_t Int64Attribute(const char *name, int64_t defaultValue=0) const
See IntAttribute()
void SetText(double value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryDoubleText(double *dval) const
See QueryIntText()
bool BoolText(bool defaultValue=false) const
See QueryIntText()
void SetText(int64_t value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(unsigned value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1343
double DoubleText(double defaultValue=0) const
See QueryIntText()
XMLError QueryIntAttribute(const char *name, int *value) const
Definition: tinyxml2.h:1325
XMLError QueryIntText(int *ival) const
int IntAttribute(const char *name, int defaultValue=0) const
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1257
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1452
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1435
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1446
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1261
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition: tinyxml2.h:1253
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1368
virtual bool ShallowEqual(const XMLNode *compare) const
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1377
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1440
void SetText(bool value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(int value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void DeleteAttribute(const char *name)
XMLError QueryFloatText(float *fval) const
See QueryIntText()
unsigned UnsignedAttribute(const char *name, unsigned defaultValue=0) const
See IntAttribute()
Definition: tinyxml2.h:1996
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:2030
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition: tinyxml2.h:2026
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:2014
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2047
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition: tinyxml2.h:2018
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:2034
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2063
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:1999
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:2022
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition: tinyxml2.h:2008
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:2002
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:2038
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2051
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2055
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2059
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2042
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:2005
Definition: tinyxml2.h:669
void SetUserData(void *userData)
Definition: tinyxml2.h:933
const char * Value() const
void SetValue(const char *val, bool staticMem=false)
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:690
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:702
const XMLElement * NextSiblingElement(const char *name=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
void * GetUserData() const
Definition: tinyxml2.h:940
const XMLElement * FirstChildElement(const char *name=0) const
void DeleteChild(XMLNode *node)
XMLNode * DeepClone(XMLDocument *target) const
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:680
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:749
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:694
const XMLElement * LastChildElement(const char *name=0) const
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:698
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:781
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:675
virtual bool ShallowEqual(const XMLNode *compare) const =0
virtual bool Accept(XMLVisitor *visitor) const =0
virtual XMLNode * ShallowClone(XMLDocument *document) const =0
XMLNode * InsertAfterChild(XMLNode *afterThis, XMLNode *addThis)
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition: tinyxml2.h:799
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:686
const XMLElement * PreviousSiblingElement(const char *name=0) const
Get the previous (left) sibling element of this node, with an optionally supplied name.
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition: tinyxml2.h:746
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:706
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:763
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:758
XMLNode * InsertFirstChild(XMLNode *addThis)
XMLNode * InsertEndChild(XMLNode *addThis)
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition: tinyxml2.h:815
Definition: tinyxml2.h:2181
virtual void PrintSpace(int depth)
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:2230
void PushHeader(bool writeBOM, bool writeDeclaration)
void PushText(const char *text, bool cdata=false)
Add a text node.
void PushText(float value)
Add a text node from a float.
void OpenElement(const char *name, bool compactMode=false)
void ClearBuffer()
Definition: tinyxml2.h:2261
virtual bool Visit(const XMLText &text)
Visit a text node.
virtual bool VisitEnter(const XMLElement &element, const XMLAttribute *attribute)
Visit an element.
int CStrSize() const
Definition: tinyxml2.h:2254
void PushText(int value)
Add a text node from an integer.
virtual bool Visit(const XMLComment &comment)
Visit a comment node.
void PushText(bool value)
Add a text node from a bool.
void PushText(unsigned value)
Add a text node from an unsigned.
void PushText(int64_t value)
Add a text node from an unsigned.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
virtual bool Visit(const XMLDeclaration &declaration)
Visit a declaration.
virtual bool Visit(const XMLUnknown &unknown)
Visit an unknown node.
XMLPrinter(FILE *file=0, bool compact=false, int depth=0)
void PushText(double value)
Add a text node from a double.
const char * CStr() const
Definition: tinyxml2.h:2246
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
virtual bool VisitExit(const XMLElement &element)
Visit an element.
void PushComment(const char *comment)
Add a comment.
Definition: tinyxml2.h:986
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:991
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:1003
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:999
virtual bool ShallowEqual(const XMLNode *compare) const
virtual XMLNode * ShallowClone(XMLDocument *document) const
Definition: tinyxml2.h:1100
virtual bool ShallowEqual(const XMLNode *compare) const
virtual bool Accept(XMLVisitor *visitor) const
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1103
virtual XMLNode * ShallowClone(XMLDocument *document) const
Definition: tinyxml2.h:480
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:515
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:489
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:498
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:485
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:511
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:503
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:507
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:494