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