Update instructions in containers.rst
[gromacs.git] / src / external / tinyxml2 / tinyxml2.h
bloba4769c868cf6582a06d51fb47a03c1d5ded24ccd
1 /*
2 Original code by Lee Thomason (www.grinninglizard.com)
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any
6 damages arising from the use of this software.
8 Permission is granted to anyone to use this software for any
9 purpose, including commercial applications, and to alter it and
10 redistribute it freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must
13 not claim that you wrote the original software. If you use this
14 software in a product, an acknowledgment in the product documentation
15 would be appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and
18 must not be misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source
21 distribution.
24 #ifndef TINYXML2_INCLUDED
25 #define TINYXML2_INCLUDED
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 # include <stdarg.h>
34 #else
35 # include <cctype>
36 # include <climits>
37 # include <cstdio>
38 # include <cstdlib>
39 # include <cstring>
40 # include <cstdarg>
41 #endif
44 TODO: intern strings instead of allocation.
47 gcc:
48 g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
50 Formatting, Artistic Style:
51 AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
54 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
55 # ifndef DEBUG
56 # define DEBUG
57 # endif
58 #endif
60 #ifdef _MSC_VER
61 # pragma warning(push)
62 # pragma warning(disable: 4251)
63 #endif
65 #ifdef _WIN32
66 # ifdef TINYXML2_EXPORT
67 # define TINYXML2_LIB __declspec(dllexport)
68 # elif defined(TINYXML2_IMPORT)
69 # define TINYXML2_LIB __declspec(dllimport)
70 # else
71 # define TINYXML2_LIB
72 # endif
73 #else
74 # define TINYXML2_LIB
75 #endif
78 #if defined(DEBUG)
79 # if defined(_MSC_VER)
80 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
81 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
82 # elif defined (ANDROID_NDK)
83 # include <android/log.h>
84 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
85 # else
86 # include <assert.h>
87 # define TIXMLASSERT assert
88 # endif
89 # else
90 # define TIXMLASSERT( x ) {}
91 #endif
94 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
95 // Microsoft visual studio, version 2005 and higher.
96 /*int _snprintf_s(
97 char *buffer,
98 size_t sizeOfBuffer,
99 size_t count,
100 const char *format [,
101 argument] ...
102 );*/
103 inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
105 va_list va;
106 va_start( va, format );
107 int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
108 va_end( va );
109 return result;
111 #define TIXML_SSCANF sscanf_s
112 #elif defined WINCE
113 #define TIXML_SNPRINTF _snprintf
114 #define TIXML_SSCANF sscanf
115 #else
116 // GCC version 3 and higher
117 //#warning( "Using sn* functions." )
118 #define TIXML_SNPRINTF snprintf
119 #define TIXML_SSCANF sscanf
120 #endif
122 /* Versioning, past 1.0.14:
123 http://semver.org/
125 static const int TIXML2_MAJOR_VERSION = 3;
126 static const int TIXML2_MINOR_VERSION = 0;
127 static const int TIXML2_PATCH_VERSION = 0;
129 namespace tinyxml2
131 class XMLDocument;
132 class XMLElement;
133 class XMLAttribute;
134 class XMLComment;
135 class XMLText;
136 class XMLDeclaration;
137 class XMLUnknown;
138 class XMLPrinter;
141 A class that wraps strings. Normally stores the start and end
142 pointers into the XML file itself, and will apply normalization
143 and entity translation if actually read. Can also store (and memory
144 manage) a traditional char[]
146 class StrPair
148 public:
149 enum {
150 NEEDS_ENTITY_PROCESSING = 0x01,
151 NEEDS_NEWLINE_NORMALIZATION = 0x02,
152 COLLAPSE_WHITESPACE = 0x04,
154 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
155 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
156 ATTRIBUTE_NAME = 0,
157 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
158 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
159 COMMENT = NEEDS_NEWLINE_NORMALIZATION
162 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
163 ~StrPair();
165 void Set( char* start, char* end, int flags ) {
166 Reset();
167 _start = start;
168 _end = end;
169 _flags = flags | NEEDS_FLUSH;
172 const char* GetStr();
174 bool Empty() const {
175 return _start == _end;
178 void SetInternedStr( const char* str ) {
179 Reset();
180 _start = const_cast<char*>(str);
183 void SetStr( const char* str, int flags=0 );
185 char* ParseText( char* in, const char* endTag, int strFlags );
186 char* ParseName( char* in );
188 void TransferTo( StrPair* other );
190 private:
191 void Reset();
192 void CollapseWhitespace();
194 enum {
195 NEEDS_FLUSH = 0x100,
196 NEEDS_DELETE = 0x200
199 // After parsing, if *_end != 0, it can be set to zero.
200 int _flags;
201 char* _start;
202 char* _end;
204 StrPair( const StrPair& other ); // not supported
205 void operator=( StrPair& other ); // not supported, use TransferTo()
210 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
211 Has a small initial memory pool, so that low or no usage will not
212 cause a call to new/delete
214 template <class T, int INIT>
215 class DynArray
217 public:
218 DynArray() {
219 _mem = _pool;
220 _allocated = INIT;
221 _size = 0;
224 ~DynArray() {
225 if ( _mem != _pool ) {
226 delete [] _mem;
230 void Clear() {
231 _size = 0;
234 void Push( T t ) {
235 TIXMLASSERT( _size < INT_MAX );
236 EnsureCapacity( _size+1 );
237 _mem[_size++] = t;
240 T* PushArr( int count ) {
241 TIXMLASSERT( count >= 0 );
242 TIXMLASSERT( _size <= INT_MAX - count );
243 EnsureCapacity( _size+count );
244 T* ret = &_mem[_size];
245 _size += count;
246 return ret;
249 T Pop() {
250 TIXMLASSERT( _size > 0 );
251 return _mem[--_size];
254 void PopArr( int count ) {
255 TIXMLASSERT( _size >= count );
256 _size -= count;
259 bool Empty() const {
260 return _size == 0;
263 T& operator[](int i) {
264 TIXMLASSERT( i>= 0 && i < _size );
265 return _mem[i];
268 const T& operator[](int i) const {
269 TIXMLASSERT( i>= 0 && i < _size );
270 return _mem[i];
273 const T& PeekTop() const {
274 TIXMLASSERT( _size > 0 );
275 return _mem[ _size - 1];
278 int Size() const {
279 TIXMLASSERT( _size >= 0 );
280 return _size;
283 int Capacity() const {
284 return _allocated;
287 const T* Mem() const {
288 return _mem;
291 T* Mem() {
292 return _mem;
295 private:
296 DynArray( const DynArray& ); // not supported
297 void operator=( const DynArray& ); // not supported
299 void EnsureCapacity( int cap ) {
300 TIXMLASSERT( cap > 0 );
301 if ( cap > _allocated ) {
302 TIXMLASSERT( cap <= INT_MAX / 2 );
303 int newAllocated = cap * 2;
304 T* newMem = new T[newAllocated];
305 memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
306 if ( _mem != _pool ) {
307 delete [] _mem;
309 _mem = newMem;
310 _allocated = newAllocated;
314 T* _mem;
315 T _pool[INIT];
316 int _allocated; // objects allocated
317 int _size; // number objects in use
322 Parent virtual class of a pool for fast allocation
323 and deallocation of objects.
325 class MemPool
327 public:
328 MemPool() {}
329 virtual ~MemPool() {}
331 virtual int ItemSize() const = 0;
332 virtual void* Alloc() = 0;
333 virtual void Free( void* ) = 0;
334 virtual void SetTracked() = 0;
335 virtual void Clear() = 0;
340 Template child class to create pools of the correct type.
342 template< int SIZE >
343 class MemPoolT : public MemPool
345 public:
346 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
347 ~MemPoolT() {
348 Clear();
351 void Clear() {
352 // Delete the blocks.
353 while( !_blockPtrs.Empty()) {
354 Block* b = _blockPtrs.Pop();
355 delete b;
357 _root = 0;
358 _currentAllocs = 0;
359 _nAllocs = 0;
360 _maxAllocs = 0;
361 _nUntracked = 0;
364 virtual int ItemSize() const {
365 return SIZE;
367 int CurrentAllocs() const {
368 return _currentAllocs;
371 virtual void* Alloc() {
372 if ( !_root ) {
373 // Need a new block.
374 Block* block = new Block();
375 _blockPtrs.Push( block );
377 for( int i=0; i<COUNT-1; ++i ) {
378 block->chunk[i].next = &block->chunk[i+1];
380 block->chunk[COUNT-1].next = 0;
381 _root = block->chunk;
383 void* result = _root;
384 _root = _root->next;
386 ++_currentAllocs;
387 if ( _currentAllocs > _maxAllocs ) {
388 _maxAllocs = _currentAllocs;
390 _nAllocs++;
391 _nUntracked++;
392 return result;
395 virtual void Free( void* mem ) {
396 if ( !mem ) {
397 return;
399 --_currentAllocs;
400 Chunk* chunk = static_cast<Chunk*>( mem );
401 #ifdef DEBUG
402 memset( chunk, 0xfe, sizeof(Chunk) );
403 #endif
404 chunk->next = _root;
405 _root = chunk;
407 void Trace( const char* name ) {
408 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
409 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
412 void SetTracked() {
413 _nUntracked--;
416 int Untracked() const {
417 return _nUntracked;
420 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
421 // The test file is large, 170k.
422 // Release: VS2010 gcc(no opt)
423 // 1k: 4000
424 // 2k: 4000
425 // 4k: 3900 21000
426 // 16k: 5200
427 // 32k: 4300
428 // 64k: 4000 21000
429 enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
431 private:
432 MemPoolT( const MemPoolT& ); // not supported
433 void operator=( const MemPoolT& ); // not supported
435 union Chunk {
436 Chunk* next;
437 char mem[SIZE];
439 struct Block {
440 Chunk chunk[COUNT];
442 DynArray< Block*, 10 > _blockPtrs;
443 Chunk* _root;
445 int _currentAllocs;
446 int _nAllocs;
447 int _maxAllocs;
448 int _nUntracked;
454 Implements the interface to the "Visitor pattern" (see the Accept() method.)
455 If you call the Accept() method, it requires being passed a XMLVisitor
456 class to handle callbacks. For nodes that contain other nodes (Document, Element)
457 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
458 are simply called with Visit().
460 If you return 'true' from a Visit method, recursive parsing will continue. If you return
461 false, <b>no children of this node or its siblings</b> will be visited.
463 All flavors of Visit methods have a default implementation that returns 'true' (continue
464 visiting). You need to only override methods that are interesting to you.
466 Generally Accept() is called on the XMLDocument, although all nodes support visiting.
468 You should never change the document from a callback.
470 @sa XMLNode::Accept()
472 class TINYXML2_LIB XMLVisitor
474 public:
475 virtual ~XMLVisitor() {}
477 /// Visit a document.
478 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
479 return true;
481 /// Visit a document.
482 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
483 return true;
486 /// Visit an element.
487 virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
488 return true;
490 /// Visit an element.
491 virtual bool VisitExit( const XMLElement& /*element*/ ) {
492 return true;
495 /// Visit a declaration.
496 virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
497 return true;
499 /// Visit a text node.
500 virtual bool Visit( const XMLText& /*text*/ ) {
501 return true;
503 /// Visit a comment node.
504 virtual bool Visit( const XMLComment& /*comment*/ ) {
505 return true;
507 /// Visit an unknown node.
508 virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
509 return true;
513 // WARNING: must match XMLDocument::_errorNames[]
514 enum XMLError {
515 XML_SUCCESS = 0,
516 XML_NO_ERROR = 0,
517 XML_NO_ATTRIBUTE,
518 XML_WRONG_ATTRIBUTE_TYPE,
519 XML_ERROR_FILE_NOT_FOUND,
520 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
521 XML_ERROR_FILE_READ_ERROR,
522 XML_ERROR_ELEMENT_MISMATCH,
523 XML_ERROR_PARSING_ELEMENT,
524 XML_ERROR_PARSING_ATTRIBUTE,
525 XML_ERROR_IDENTIFYING_TAG,
526 XML_ERROR_PARSING_TEXT,
527 XML_ERROR_PARSING_CDATA,
528 XML_ERROR_PARSING_COMMENT,
529 XML_ERROR_PARSING_DECLARATION,
530 XML_ERROR_PARSING_UNKNOWN,
531 XML_ERROR_EMPTY_DOCUMENT,
532 XML_ERROR_MISMATCHED_ELEMENT,
533 XML_ERROR_PARSING,
534 XML_CAN_NOT_CONVERT_TEXT,
535 XML_NO_TEXT_NODE,
537 XML_ERROR_COUNT
542 Utility functionality.
544 class XMLUtil
546 public:
547 static const char* SkipWhiteSpace( const char* p ) {
548 TIXMLASSERT( p );
549 while( IsWhiteSpace(*p) ) {
550 ++p;
552 TIXMLASSERT( p );
553 return p;
555 static char* SkipWhiteSpace( char* p ) {
556 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
559 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
560 // correct, but simple, and usually works.
561 static bool IsWhiteSpace( char p ) {
562 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
565 inline static bool IsNameStartChar( unsigned char ch ) {
566 if ( ch >= 128 ) {
567 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
568 return true;
570 if ( isalpha( ch ) ) {
571 return true;
573 return ch == ':' || ch == '_';
576 inline static bool IsNameChar( unsigned char ch ) {
577 return IsNameStartChar( ch )
578 || isdigit( ch )
579 || ch == '.'
580 || ch == '-';
583 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
584 if ( p == q ) {
585 return true;
587 int n = 0;
588 while( *p && *q && *p == *q && n<nChar ) {
589 ++p;
590 ++q;
591 ++n;
593 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
594 return true;
596 return false;
599 inline static bool IsUTF8Continuation( const char p ) {
600 return ( p & 0x80 ) != 0;
603 static const char* ReadBOM( const char* p, bool* hasBOM );
604 // p is the starting location,
605 // the UTF-8 value of the entity will be placed in value, and length filled in.
606 static const char* GetCharacterRef( const char* p, char* value, int* length );
607 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
609 // converts primitive types to strings
610 static void ToStr( int v, char* buffer, int bufferSize );
611 static void ToStr( unsigned v, char* buffer, int bufferSize );
612 static void ToStr( bool v, char* buffer, int bufferSize );
613 static void ToStr( float v, char* buffer, int bufferSize );
614 static void ToStr( double v, char* buffer, int bufferSize );
616 // converts strings to primitive types
617 static bool ToInt( const char* str, int* value );
618 static bool ToUnsigned( const char* str, unsigned* value );
619 static bool ToBool( const char* str, bool* value );
620 static bool ToFloat( const char* str, float* value );
621 static bool ToDouble( const char* str, double* value );
625 /** XMLNode is a base class for every object that is in the
626 XML Document Object Model (DOM), except XMLAttributes.
627 Nodes have siblings, a parent, and children which can
628 be navigated. A node is always in a XMLDocument.
629 The type of a XMLNode can be queried, and it can
630 be cast to its more defined type.
632 A XMLDocument allocates memory for all its Nodes.
633 When the XMLDocument gets deleted, all its Nodes
634 will also be deleted.
636 @verbatim
637 A Document can contain: Element (container or leaf)
638 Comment (leaf)
639 Unknown (leaf)
640 Declaration( leaf )
642 An Element can contain: Element (container or leaf)
643 Text (leaf)
644 Attributes (not on tree)
645 Comment (leaf)
646 Unknown (leaf)
648 @endverbatim
650 class TINYXML2_LIB XMLNode
652 friend class XMLDocument;
653 friend class XMLElement;
654 public:
656 /// Get the XMLDocument that owns this XMLNode.
657 const XMLDocument* GetDocument() const {
658 return _document;
660 /// Get the XMLDocument that owns this XMLNode.
661 XMLDocument* GetDocument() {
662 return _document;
665 /// Safely cast to an Element, or null.
666 virtual XMLElement* ToElement() {
667 return 0;
669 /// Safely cast to Text, or null.
670 virtual XMLText* ToText() {
671 return 0;
673 /// Safely cast to a Comment, or null.
674 virtual XMLComment* ToComment() {
675 return 0;
677 /// Safely cast to a Document, or null.
678 virtual XMLDocument* ToDocument() {
679 return 0;
681 /// Safely cast to a Declaration, or null.
682 virtual XMLDeclaration* ToDeclaration() {
683 return 0;
685 /// Safely cast to an Unknown, or null.
686 virtual XMLUnknown* ToUnknown() {
687 return 0;
690 virtual const XMLElement* ToElement() const {
691 return 0;
693 virtual const XMLText* ToText() const {
694 return 0;
696 virtual const XMLComment* ToComment() const {
697 return 0;
699 virtual const XMLDocument* ToDocument() const {
700 return 0;
702 virtual const XMLDeclaration* ToDeclaration() const {
703 return 0;
705 virtual const XMLUnknown* ToUnknown() const {
706 return 0;
709 /** The meaning of 'value' changes for the specific type.
710 @verbatim
711 Document: empty
712 Element: name of the element
713 Comment: the comment text
714 Unknown: the tag contents
715 Text: the text string
716 @endverbatim
718 const char* Value() const;
720 /** Set the Value of an XML node.
721 @sa Value()
723 void SetValue( const char* val, bool staticMem=false );
725 /// Get the parent of this node on the DOM.
726 const XMLNode* Parent() const {
727 return _parent;
730 XMLNode* Parent() {
731 return _parent;
734 /// Returns true if this node has no children.
735 bool NoChildren() const {
736 return !_firstChild;
739 /// Get the first child node, or null if none exists.
740 const XMLNode* FirstChild() const {
741 return _firstChild;
744 XMLNode* FirstChild() {
745 return _firstChild;
748 /** Get the first child element, or optionally the first child
749 element with the specified name.
751 const XMLElement* FirstChildElement( const char* value=0 ) const;
753 XMLElement* FirstChildElement( const char* value=0 ) {
754 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value ));
757 /// Get the last child node, or null if none exists.
758 const XMLNode* LastChild() const {
759 return _lastChild;
762 XMLNode* LastChild() {
763 return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() );
766 /** Get the last child element or optionally the last child
767 element with the specified name.
769 const XMLElement* LastChildElement( const char* value=0 ) const;
771 XMLElement* LastChildElement( const char* value=0 ) {
772 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) );
775 /// Get the previous (left) sibling node of this node.
776 const XMLNode* PreviousSibling() const {
777 return _prev;
780 XMLNode* PreviousSibling() {
781 return _prev;
784 /// Get the previous (left) sibling element of this node, with an optionally supplied name.
785 const XMLElement* PreviousSiblingElement( const char* value=0 ) const ;
787 XMLElement* PreviousSiblingElement( const char* value=0 ) {
788 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) );
791 /// Get the next (right) sibling node of this node.
792 const XMLNode* NextSibling() const {
793 return _next;
796 XMLNode* NextSibling() {
797 return _next;
800 /// Get the next (right) sibling element of this node, with an optionally supplied name.
801 const XMLElement* NextSiblingElement( const char* value=0 ) const;
803 XMLElement* NextSiblingElement( const char* value=0 ) {
804 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) );
808 Add a child node as the last (right) child.
809 If the child node is already part of the document,
810 it is moved from its old location to the new location.
811 Returns the addThis argument or 0 if the node does not
812 belong to the same document.
814 XMLNode* InsertEndChild( XMLNode* addThis );
816 XMLNode* LinkEndChild( XMLNode* addThis ) {
817 return InsertEndChild( addThis );
820 Add a child node as the first (left) child.
821 If the child node is already part of the document,
822 it is moved from its old location to the new location.
823 Returns the addThis argument or 0 if the node does not
824 belong to the same document.
826 XMLNode* InsertFirstChild( XMLNode* addThis );
828 Add a node after the specified child node.
829 If the child node is already part of the document,
830 it is moved from its old location to the new location.
831 Returns the addThis argument or 0 if the afterThis node
832 is not a child of this node, or if the node does not
833 belong to the same document.
835 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
838 Delete all the children of this node.
840 void DeleteChildren();
843 Delete a child of this node.
845 void DeleteChild( XMLNode* node );
848 Make a copy of this node, but not its children.
849 You may pass in a Document pointer that will be
850 the owner of the new Node. If the 'document' is
851 null, then the node returned will be allocated
852 from the current Document. (this->GetDocument())
854 Note: if called on a XMLDocument, this will return null.
856 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
859 Test if 2 nodes are the same, but don't test children.
860 The 2 nodes do not need to be in the same Document.
862 Note: if called on a XMLDocument, this will return false.
864 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
866 /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
867 XML tree will be conditionally visited and the host will be called back
868 via the XMLVisitor interface.
870 This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
871 the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
872 interface versus any other.)
874 The interface has been based on ideas from:
876 - http://www.saxproject.org/
877 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
879 Which are both good references for "visiting".
881 An example of using Accept():
882 @verbatim
883 XMLPrinter printer;
884 tinyxmlDoc.Accept( &printer );
885 const char* xmlcstr = printer.CStr();
886 @endverbatim
888 virtual bool Accept( XMLVisitor* visitor ) const = 0;
890 // internal
891 virtual char* ParseDeep( char*, StrPair* );
893 protected:
894 XMLNode( XMLDocument* );
895 virtual ~XMLNode();
897 XMLDocument* _document;
898 XMLNode* _parent;
899 mutable StrPair _value;
901 XMLNode* _firstChild;
902 XMLNode* _lastChild;
904 XMLNode* _prev;
905 XMLNode* _next;
907 private:
908 MemPool* _memPool;
909 void Unlink( XMLNode* child );
910 static void DeleteNode( XMLNode* node );
911 void InsertChildPreamble( XMLNode* insertThis ) const;
913 XMLNode( const XMLNode& ); // not supported
914 XMLNode& operator=( const XMLNode& ); // not supported
918 /** XML text.
920 Note that a text node can have child element nodes, for example:
921 @verbatim
922 <root>This is <b>bold</b></root>
923 @endverbatim
925 A text node can have 2 ways to output the next. "normal" output
926 and CDATA. It will default to the mode it was parsed from the XML file and
927 you generally want to leave it alone, but you can change the output mode with
928 SetCData() and query it with CData().
930 class TINYXML2_LIB XMLText : public XMLNode
932 friend class XMLBase;
933 friend class XMLDocument;
934 public:
935 virtual bool Accept( XMLVisitor* visitor ) const;
937 virtual XMLText* ToText() {
938 return this;
940 virtual const XMLText* ToText() const {
941 return this;
944 /// Declare whether this should be CDATA or standard text.
945 void SetCData( bool isCData ) {
946 _isCData = isCData;
948 /// Returns true if this is a CDATA text element.
949 bool CData() const {
950 return _isCData;
953 char* ParseDeep( char*, StrPair* endTag );
954 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
955 virtual bool ShallowEqual( const XMLNode* compare ) const;
957 protected:
958 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
959 virtual ~XMLText() {}
961 private:
962 bool _isCData;
964 XMLText( const XMLText& ); // not supported
965 XMLText& operator=( const XMLText& ); // not supported
969 /** An XML Comment. */
970 class TINYXML2_LIB XMLComment : public XMLNode
972 friend class XMLDocument;
973 public:
974 virtual XMLComment* ToComment() {
975 return this;
977 virtual const XMLComment* ToComment() const {
978 return this;
981 virtual bool Accept( XMLVisitor* visitor ) const;
983 char* ParseDeep( char*, StrPair* endTag );
984 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
985 virtual bool ShallowEqual( const XMLNode* compare ) const;
987 protected:
988 XMLComment( XMLDocument* doc );
989 virtual ~XMLComment();
991 private:
992 XMLComment( const XMLComment& ); // not supported
993 XMLComment& operator=( const XMLComment& ); // not supported
997 /** In correct XML the declaration is the first entry in the file.
998 @verbatim
999 <?xml version="1.0" standalone="yes"?>
1000 @endverbatim
1002 TinyXML-2 will happily read or write files without a declaration,
1003 however.
1005 The text of the declaration isn't interpreted. It is parsed
1006 and written as a string.
1008 class TINYXML2_LIB XMLDeclaration : public XMLNode
1010 friend class XMLDocument;
1011 public:
1012 virtual XMLDeclaration* ToDeclaration() {
1013 return this;
1015 virtual const XMLDeclaration* ToDeclaration() const {
1016 return this;
1019 virtual bool Accept( XMLVisitor* visitor ) const;
1021 char* ParseDeep( char*, StrPair* endTag );
1022 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1023 virtual bool ShallowEqual( const XMLNode* compare ) const;
1025 protected:
1026 XMLDeclaration( XMLDocument* doc );
1027 virtual ~XMLDeclaration();
1029 private:
1030 XMLDeclaration( const XMLDeclaration& ); // not supported
1031 XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
1035 /** Any tag that TinyXML-2 doesn't recognize is saved as an
1036 unknown. It is a tag of text, but should not be modified.
1037 It will be written back to the XML, unchanged, when the file
1038 is saved.
1040 DTD tags get thrown into XMLUnknowns.
1042 class TINYXML2_LIB XMLUnknown : public XMLNode
1044 friend class XMLDocument;
1045 public:
1046 virtual XMLUnknown* ToUnknown() {
1047 return this;
1049 virtual const XMLUnknown* ToUnknown() const {
1050 return this;
1053 virtual bool Accept( XMLVisitor* visitor ) const;
1055 char* ParseDeep( char*, StrPair* endTag );
1056 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1057 virtual bool ShallowEqual( const XMLNode* compare ) const;
1059 protected:
1060 XMLUnknown( XMLDocument* doc );
1061 virtual ~XMLUnknown();
1063 private:
1064 XMLUnknown( const XMLUnknown& ); // not supported
1065 XMLUnknown& operator=( const XMLUnknown& ); // not supported
1070 /** An attribute is a name-value pair. Elements have an arbitrary
1071 number of attributes, each with a unique name.
1073 @note The attributes are not XMLNodes. You may only query the
1074 Next() attribute in a list.
1076 class TINYXML2_LIB XMLAttribute
1078 friend class XMLElement;
1079 public:
1080 /// The name of the attribute.
1081 const char* Name() const;
1083 /// The value of the attribute.
1084 const char* Value() const;
1086 /// The next attribute in the list.
1087 const XMLAttribute* Next() const {
1088 return _next;
1091 /** IntValue interprets the attribute as an integer, and returns the value.
1092 If the value isn't an integer, 0 will be returned. There is no error checking;
1093 use QueryIntValue() if you need error checking.
1095 int IntValue() const {
1096 int i=0;
1097 QueryIntValue( &i );
1098 return i;
1100 /// Query as an unsigned integer. See IntValue()
1101 unsigned UnsignedValue() const {
1102 unsigned i=0;
1103 QueryUnsignedValue( &i );
1104 return i;
1106 /// Query as a boolean. See IntValue()
1107 bool BoolValue() const {
1108 bool b=false;
1109 QueryBoolValue( &b );
1110 return b;
1112 /// Query as a double. See IntValue()
1113 double DoubleValue() const {
1114 double d=0;
1115 QueryDoubleValue( &d );
1116 return d;
1118 /// Query as a float. See IntValue()
1119 float FloatValue() const {
1120 float f=0;
1121 QueryFloatValue( &f );
1122 return f;
1125 /** QueryIntValue interprets the attribute as an integer, and returns the value
1126 in the provided parameter. The function will return XML_NO_ERROR on success,
1127 and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
1129 XMLError QueryIntValue( int* value ) const;
1130 /// See QueryIntValue
1131 XMLError QueryUnsignedValue( unsigned int* value ) const;
1132 /// See QueryIntValue
1133 XMLError QueryBoolValue( bool* value ) const;
1134 /// See QueryIntValue
1135 XMLError QueryDoubleValue( double* value ) const;
1136 /// See QueryIntValue
1137 XMLError QueryFloatValue( float* value ) const;
1139 /// Set the attribute to a string value.
1140 void SetAttribute( const char* value );
1141 /// Set the attribute to value.
1142 void SetAttribute( int value );
1143 /// Set the attribute to value.
1144 void SetAttribute( unsigned value );
1145 /// Set the attribute to value.
1146 void SetAttribute( bool value );
1147 /// Set the attribute to value.
1148 void SetAttribute( double value );
1149 /// Set the attribute to value.
1150 void SetAttribute( float value );
1152 private:
1153 enum { BUF_SIZE = 200 };
1155 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
1156 virtual ~XMLAttribute() {}
1158 XMLAttribute( const XMLAttribute& ); // not supported
1159 void operator=( const XMLAttribute& ); // not supported
1160 void SetName( const char* name );
1162 char* ParseDeep( char* p, bool processEntities );
1164 mutable StrPair _name;
1165 mutable StrPair _value;
1166 XMLAttribute* _next;
1167 MemPool* _memPool;
1171 /** The element is a container class. It has a value, the element name,
1172 and can contain other elements, text, comments, and unknowns.
1173 Elements also contain an arbitrary number of attributes.
1175 class TINYXML2_LIB XMLElement : public XMLNode
1177 friend class XMLBase;
1178 friend class XMLDocument;
1179 public:
1180 /// Get the name of an element (which is the Value() of the node.)
1181 const char* Name() const {
1182 return Value();
1184 /// Set the name of the element.
1185 void SetName( const char* str, bool staticMem=false ) {
1186 SetValue( str, staticMem );
1189 virtual XMLElement* ToElement() {
1190 return this;
1192 virtual const XMLElement* ToElement() const {
1193 return this;
1195 virtual bool Accept( XMLVisitor* visitor ) const;
1197 /** Given an attribute name, Attribute() returns the value
1198 for the attribute of that name, or null if none
1199 exists. For example:
1201 @verbatim
1202 const char* value = ele->Attribute( "foo" );
1203 @endverbatim
1205 The 'value' parameter is normally null. However, if specified,
1206 the attribute will only be returned if the 'name' and 'value'
1207 match. This allow you to write code:
1209 @verbatim
1210 if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
1211 @endverbatim
1213 rather than:
1214 @verbatim
1215 if ( ele->Attribute( "foo" ) ) {
1216 if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
1218 @endverbatim
1220 const char* Attribute( const char* name, const char* value=0 ) const;
1222 /** Given an attribute name, IntAttribute() returns the value
1223 of the attribute interpreted as an integer. 0 will be
1224 returned if there is an error. For a method with error
1225 checking, see QueryIntAttribute()
1227 int IntAttribute( const char* name ) const {
1228 int i=0;
1229 QueryIntAttribute( name, &i );
1230 return i;
1232 /// See IntAttribute()
1233 unsigned UnsignedAttribute( const char* name ) const {
1234 unsigned i=0;
1235 QueryUnsignedAttribute( name, &i );
1236 return i;
1238 /// See IntAttribute()
1239 bool BoolAttribute( const char* name ) const {
1240 bool b=false;
1241 QueryBoolAttribute( name, &b );
1242 return b;
1244 /// See IntAttribute()
1245 double DoubleAttribute( const char* name ) const {
1246 double d=0;
1247 QueryDoubleAttribute( name, &d );
1248 return d;
1250 /// See IntAttribute()
1251 float FloatAttribute( const char* name ) const {
1252 float f=0;
1253 QueryFloatAttribute( name, &f );
1254 return f;
1257 /** Given an attribute name, QueryIntAttribute() returns
1258 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1259 can't be performed, or XML_NO_ATTRIBUTE if the attribute
1260 doesn't exist. If successful, the result of the conversion
1261 will be written to 'value'. If not successful, nothing will
1262 be written to 'value'. This allows you to provide default
1263 value:
1265 @verbatim
1266 int value = 10;
1267 QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
1268 @endverbatim
1270 XMLError QueryIntAttribute( const char* name, int* value ) const {
1271 const XMLAttribute* a = FindAttribute( name );
1272 if ( !a ) {
1273 return XML_NO_ATTRIBUTE;
1275 return a->QueryIntValue( value );
1277 /// See QueryIntAttribute()
1278 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
1279 const XMLAttribute* a = FindAttribute( name );
1280 if ( !a ) {
1281 return XML_NO_ATTRIBUTE;
1283 return a->QueryUnsignedValue( value );
1285 /// See QueryIntAttribute()
1286 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
1287 const XMLAttribute* a = FindAttribute( name );
1288 if ( !a ) {
1289 return XML_NO_ATTRIBUTE;
1291 return a->QueryBoolValue( value );
1293 /// See QueryIntAttribute()
1294 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
1295 const XMLAttribute* a = FindAttribute( name );
1296 if ( !a ) {
1297 return XML_NO_ATTRIBUTE;
1299 return a->QueryDoubleValue( value );
1301 /// See QueryIntAttribute()
1302 XMLError QueryFloatAttribute( const char* name, float* value ) const {
1303 const XMLAttribute* a = FindAttribute( name );
1304 if ( !a ) {
1305 return XML_NO_ATTRIBUTE;
1307 return a->QueryFloatValue( value );
1311 /** Given an attribute name, QueryAttribute() returns
1312 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1313 can't be performed, or XML_NO_ATTRIBUTE if the attribute
1314 doesn't exist. It is overloaded for the primitive types,
1315 and is a generally more convenient replacement of
1316 QueryIntAttribute() and related functions.
1318 If successful, the result of the conversion
1319 will be written to 'value'. If not successful, nothing will
1320 be written to 'value'. This allows you to provide default
1321 value:
1323 @verbatim
1324 int value = 10;
1325 QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
1326 @endverbatim
1328 int QueryAttribute( const char* name, int* value ) const {
1329 return QueryIntAttribute( name, value );
1332 int QueryAttribute( const char* name, unsigned int* value ) const {
1333 return QueryUnsignedAttribute( name, value );
1336 int QueryAttribute( const char* name, bool* value ) const {
1337 return QueryBoolAttribute( name, value );
1340 int QueryAttribute( const char* name, double* value ) const {
1341 return QueryDoubleAttribute( name, value );
1344 int QueryAttribute( const char* name, float* value ) const {
1345 return QueryFloatAttribute( name, value );
1348 /// Sets the named attribute to value.
1349 void SetAttribute( const char* name, const char* value ) {
1350 XMLAttribute* a = FindOrCreateAttribute( name );
1351 a->SetAttribute( value );
1353 /// Sets the named attribute to value.
1354 void SetAttribute( const char* name, int value ) {
1355 XMLAttribute* a = FindOrCreateAttribute( name );
1356 a->SetAttribute( value );
1358 /// Sets the named attribute to value.
1359 void SetAttribute( const char* name, unsigned value ) {
1360 XMLAttribute* a = FindOrCreateAttribute( name );
1361 a->SetAttribute( value );
1363 /// Sets the named attribute to value.
1364 void SetAttribute( const char* name, bool value ) {
1365 XMLAttribute* a = FindOrCreateAttribute( name );
1366 a->SetAttribute( value );
1368 /// Sets the named attribute to value.
1369 void SetAttribute( const char* name, double value ) {
1370 XMLAttribute* a = FindOrCreateAttribute( name );
1371 a->SetAttribute( value );
1373 /// Sets the named attribute to value.
1374 void SetAttribute( const char* name, float value ) {
1375 XMLAttribute* a = FindOrCreateAttribute( name );
1376 a->SetAttribute( value );
1380 Delete an attribute.
1382 void DeleteAttribute( const char* name );
1384 /// Return the first attribute in the list.
1385 const XMLAttribute* FirstAttribute() const {
1386 return _rootAttribute;
1388 /// Query a specific attribute in the list.
1389 const XMLAttribute* FindAttribute( const char* name ) const;
1391 /** Convenience function for easy access to the text inside an element. Although easy
1392 and concise, GetText() is limited compared to getting the XMLText child
1393 and accessing it directly.
1395 If the first child of 'this' is a XMLText, the GetText()
1396 returns the character string of the Text node, else null is returned.
1398 This is a convenient method for getting the text of simple contained text:
1399 @verbatim
1400 <foo>This is text</foo>
1401 const char* str = fooElement->GetText();
1402 @endverbatim
1404 'str' will be a pointer to "This is text".
1406 Note that this function can be misleading. If the element foo was created from
1407 this XML:
1408 @verbatim
1409 <foo><b>This is text</b></foo>
1410 @endverbatim
1412 then the value of str would be null. The first child node isn't a text node, it is
1413 another element. From this XML:
1414 @verbatim
1415 <foo>This is <b>text</b></foo>
1416 @endverbatim
1417 GetText() will return "This is ".
1419 const char* GetText() const;
1421 /** Convenience function for easy access to the text inside an element. Although easy
1422 and concise, SetText() is limited compared to creating an XMLText child
1423 and mutating it directly.
1425 If the first child of 'this' is a XMLText, SetText() sets its value to
1426 the given string, otherwise it will create a first child that is an XMLText.
1428 This is a convenient method for setting the text of simple contained text:
1429 @verbatim
1430 <foo>This is text</foo>
1431 fooElement->SetText( "Hullaballoo!" );
1432 <foo>Hullaballoo!</foo>
1433 @endverbatim
1435 Note that this function can be misleading. If the element foo was created from
1436 this XML:
1437 @verbatim
1438 <foo><b>This is text</b></foo>
1439 @endverbatim
1441 then it will not change "This is text", but rather prefix it with a text element:
1442 @verbatim
1443 <foo>Hullaballoo!<b>This is text</b></foo>
1444 @endverbatim
1446 For this XML:
1447 @verbatim
1448 <foo />
1449 @endverbatim
1450 SetText() will generate
1451 @verbatim
1452 <foo>Hullaballoo!</foo>
1453 @endverbatim
1455 void SetText( const char* inText );
1456 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1457 void SetText( int value );
1458 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1459 void SetText( unsigned value );
1460 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1461 void SetText( bool value );
1462 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1463 void SetText( double value );
1464 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1465 void SetText( float value );
1468 Convenience method to query the value of a child text node. This is probably best
1469 shown by example. Given you have a document is this form:
1470 @verbatim
1471 <point>
1472 <x>1</x>
1473 <y>1.4</y>
1474 </point>
1475 @endverbatim
1477 The QueryIntText() and similar functions provide a safe and easier way to get to the
1478 "value" of x and y.
1480 @verbatim
1481 int x = 0;
1482 float y = 0; // types of x and y are contrived for example
1483 const XMLElement* xElement = pointElement->FirstChildElement( "x" );
1484 const XMLElement* yElement = pointElement->FirstChildElement( "y" );
1485 xElement->QueryIntText( &x );
1486 yElement->QueryFloatText( &y );
1487 @endverbatim
1489 @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
1490 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
1493 XMLError QueryIntText( int* ival ) const;
1494 /// See QueryIntText()
1495 XMLError QueryUnsignedText( unsigned* uval ) const;
1496 /// See QueryIntText()
1497 XMLError QueryBoolText( bool* bval ) const;
1498 /// See QueryIntText()
1499 XMLError QueryDoubleText( double* dval ) const;
1500 /// See QueryIntText()
1501 XMLError QueryFloatText( float* fval ) const;
1503 // internal:
1504 enum {
1505 OPEN, // <foo>
1506 CLOSED, // <foo/>
1507 CLOSING // </foo>
1509 int ClosingType() const {
1510 return _closingType;
1512 char* ParseDeep( char* p, StrPair* endTag );
1513 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
1514 virtual bool ShallowEqual( const XMLNode* compare ) const;
1516 private:
1517 XMLElement( XMLDocument* doc );
1518 virtual ~XMLElement();
1519 XMLElement( const XMLElement& ); // not supported
1520 void operator=( const XMLElement& ); // not supported
1522 XMLAttribute* FindAttribute( const char* name ) {
1523 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
1525 XMLAttribute* FindOrCreateAttribute( const char* name );
1526 //void LinkAttribute( XMLAttribute* attrib );
1527 char* ParseAttributes( char* p );
1528 static void DeleteAttribute( XMLAttribute* attribute );
1530 enum { BUF_SIZE = 200 };
1531 int _closingType;
1532 // The attribute list is ordered; there is no 'lastAttribute'
1533 // because the list needs to be scanned for dupes before adding
1534 // a new attribute.
1535 XMLAttribute* _rootAttribute;
1539 enum Whitespace {
1540 PRESERVE_WHITESPACE,
1541 COLLAPSE_WHITESPACE
1545 /** A Document binds together all the functionality.
1546 It can be saved, loaded, and printed to the screen.
1547 All Nodes are connected and allocated to a Document.
1548 If the Document is deleted, all its Nodes are also deleted.
1550 class TINYXML2_LIB XMLDocument : public XMLNode
1552 friend class XMLElement;
1553 public:
1554 /// constructor
1555 XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
1556 ~XMLDocument();
1558 virtual XMLDocument* ToDocument() {
1559 return this;
1561 virtual const XMLDocument* ToDocument() const {
1562 return this;
1566 Parse an XML file from a character string.
1567 Returns XML_NO_ERROR (0) on success, or
1568 an errorID.
1570 You may optionally pass in the 'nBytes', which is
1571 the number of bytes which will be parsed. If not
1572 specified, TinyXML-2 will assume 'xml' points to a
1573 null terminated string.
1575 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
1578 Load an XML file from disk.
1579 Returns XML_NO_ERROR (0) on success, or
1580 an errorID.
1582 XMLError LoadFile( const char* filename );
1585 Load an XML file from disk. You are responsible
1586 for providing and closing the FILE*.
1588 NOTE: The file should be opened as binary ("rb")
1589 not text in order for TinyXML-2 to correctly
1590 do newline normalization.
1592 Returns XML_NO_ERROR (0) on success, or
1593 an errorID.
1595 XMLError LoadFile( FILE* );
1598 Save the XML file to disk.
1599 Returns XML_NO_ERROR (0) on success, or
1600 an errorID.
1602 XMLError SaveFile( const char* filename, bool compact = false );
1605 Save the XML file to disk. You are responsible
1606 for providing and closing the FILE*.
1608 Returns XML_NO_ERROR (0) on success, or
1609 an errorID.
1611 XMLError SaveFile( FILE* fp, bool compact = false );
1613 bool ProcessEntities() const {
1614 return _processEntities;
1616 Whitespace WhitespaceMode() const {
1617 return _whitespace;
1621 Returns true if this document has a leading Byte Order Mark of UTF8.
1623 bool HasBOM() const {
1624 return _writeBOM;
1626 /** Sets whether to write the BOM when writing the file.
1628 void SetBOM( bool useBOM ) {
1629 _writeBOM = useBOM;
1632 /** Return the root element of DOM. Equivalent to FirstChildElement().
1633 To get the first node, use FirstChild().
1635 XMLElement* RootElement() {
1636 return FirstChildElement();
1638 const XMLElement* RootElement() const {
1639 return FirstChildElement();
1642 /** Print the Document. If the Printer is not provided, it will
1643 print to stdout. If you provide Printer, this can print to a file:
1644 @verbatim
1645 XMLPrinter printer( fp );
1646 doc.Print( &printer );
1647 @endverbatim
1649 Or you can use a printer to print to memory:
1650 @verbatim
1651 XMLPrinter printer;
1652 doc.Print( &printer );
1653 // printer.CStr() has a const char* to the XML
1654 @endverbatim
1656 void Print( XMLPrinter* streamer=0 ) const;
1657 virtual bool Accept( XMLVisitor* visitor ) const;
1660 Create a new Element associated with
1661 this Document. The memory for the Element
1662 is managed by the Document.
1664 XMLElement* NewElement( const char* name );
1666 Create a new Comment associated with
1667 this Document. The memory for the Comment
1668 is managed by the Document.
1670 XMLComment* NewComment( const char* comment );
1672 Create a new Text associated with
1673 this Document. The memory for the Text
1674 is managed by the Document.
1676 XMLText* NewText( const char* text );
1678 Create a new Declaration associated with
1679 this Document. The memory for the object
1680 is managed by the Document.
1682 If the 'text' param is null, the standard
1683 declaration is used.:
1684 @verbatim
1685 <?xml version="1.0" encoding="UTF-8"?>
1686 @endverbatim
1688 XMLDeclaration* NewDeclaration( const char* text=0 );
1690 Create a new Unknown associated with
1691 this Document. The memory for the object
1692 is managed by the Document.
1694 XMLUnknown* NewUnknown( const char* text );
1697 Delete a node associated with this document.
1698 It will be unlinked from the DOM.
1700 void DeleteNode( XMLNode* node );
1702 void SetError( XMLError error, const char* str1, const char* str2 );
1704 /// Return true if there was an error parsing the document.
1705 bool Error() const {
1706 return _errorID != XML_NO_ERROR;
1708 /// Return the errorID.
1709 XMLError ErrorID() const {
1710 return _errorID;
1712 const char* ErrorName() const;
1714 /// Return a possibly helpful diagnostic location or string.
1715 const char* GetErrorStr1() const {
1716 return _errorStr1;
1718 /// Return a possibly helpful secondary diagnostic location or string.
1719 const char* GetErrorStr2() const {
1720 return _errorStr2;
1722 /// If there is an error, print it to stdout.
1723 void PrintError() const;
1725 /// Clear the document, resetting it to the initial state.
1726 void Clear();
1728 // internal
1729 char* Identify( char* p, XMLNode** node );
1731 virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
1732 return 0;
1734 virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
1735 return false;
1738 private:
1739 XMLDocument( const XMLDocument& ); // not supported
1740 void operator=( const XMLDocument& ); // not supported
1742 bool _writeBOM;
1743 bool _processEntities;
1744 XMLError _errorID;
1745 Whitespace _whitespace;
1746 const char* _errorStr1;
1747 const char* _errorStr2;
1748 char* _charBuffer;
1750 MemPoolT< sizeof(XMLElement) > _elementPool;
1751 MemPoolT< sizeof(XMLAttribute) > _attributePool;
1752 MemPoolT< sizeof(XMLText) > _textPool;
1753 MemPoolT< sizeof(XMLComment) > _commentPool;
1755 static const char* _errorNames[XML_ERROR_COUNT];
1757 void Parse();
1762 A XMLHandle is a class that wraps a node pointer with null checks; this is
1763 an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
1764 DOM structure. It is a separate utility class.
1766 Take an example:
1767 @verbatim
1768 <Document>
1769 <Element attributeA = "valueA">
1770 <Child attributeB = "value1" />
1771 <Child attributeB = "value2" />
1772 </Element>
1773 </Document>
1774 @endverbatim
1776 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1777 easy to write a *lot* of code that looks like:
1779 @verbatim
1780 XMLElement* root = document.FirstChildElement( "Document" );
1781 if ( root )
1783 XMLElement* element = root->FirstChildElement( "Element" );
1784 if ( element )
1786 XMLElement* child = element->FirstChildElement( "Child" );
1787 if ( child )
1789 XMLElement* child2 = child->NextSiblingElement( "Child" );
1790 if ( child2 )
1792 // Finally do something useful.
1793 @endverbatim
1795 And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
1796 of such code. A XMLHandle checks for null pointers so it is perfectly safe
1797 and correct to use:
1799 @verbatim
1800 XMLHandle docHandle( &document );
1801 XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
1802 if ( child2 )
1804 // do something useful
1805 @endverbatim
1807 Which is MUCH more concise and useful.
1809 It is also safe to copy handles - internally they are nothing more than node pointers.
1810 @verbatim
1811 XMLHandle handleCopy = handle;
1812 @endverbatim
1814 See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
1816 class TINYXML2_LIB XMLHandle
1818 public:
1819 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1820 XMLHandle( XMLNode* node ) {
1821 _node = node;
1823 /// Create a handle from a node.
1824 XMLHandle( XMLNode& node ) {
1825 _node = &node;
1827 /// Copy constructor
1828 XMLHandle( const XMLHandle& ref ) {
1829 _node = ref._node;
1831 /// Assignment
1832 XMLHandle& operator=( const XMLHandle& ref ) {
1833 _node = ref._node;
1834 return *this;
1837 /// Get the first child of this handle.
1838 XMLHandle FirstChild() {
1839 return XMLHandle( _node ? _node->FirstChild() : 0 );
1841 /// Get the first child element of this handle.
1842 XMLHandle FirstChildElement( const char* value=0 ) {
1843 return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 );
1845 /// Get the last child of this handle.
1846 XMLHandle LastChild() {
1847 return XMLHandle( _node ? _node->LastChild() : 0 );
1849 /// Get the last child element of this handle.
1850 XMLHandle LastChildElement( const char* _value=0 ) {
1851 return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 );
1853 /// Get the previous sibling of this handle.
1854 XMLHandle PreviousSibling() {
1855 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
1857 /// Get the previous sibling element of this handle.
1858 XMLHandle PreviousSiblingElement( const char* _value=0 ) {
1859 return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
1861 /// Get the next sibling of this handle.
1862 XMLHandle NextSibling() {
1863 return XMLHandle( _node ? _node->NextSibling() : 0 );
1865 /// Get the next sibling element of this handle.
1866 XMLHandle NextSiblingElement( const char* _value=0 ) {
1867 return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
1870 /// Safe cast to XMLNode. This can return null.
1871 XMLNode* ToNode() {
1872 return _node;
1874 /// Safe cast to XMLElement. This can return null.
1875 XMLElement* ToElement() {
1876 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
1878 /// Safe cast to XMLText. This can return null.
1879 XMLText* ToText() {
1880 return ( ( _node == 0 ) ? 0 : _node->ToText() );
1882 /// Safe cast to XMLUnknown. This can return null.
1883 XMLUnknown* ToUnknown() {
1884 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
1886 /// Safe cast to XMLDeclaration. This can return null.
1887 XMLDeclaration* ToDeclaration() {
1888 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
1891 private:
1892 XMLNode* _node;
1897 A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
1898 same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
1900 class TINYXML2_LIB XMLConstHandle
1902 public:
1903 XMLConstHandle( const XMLNode* node ) {
1904 _node = node;
1906 XMLConstHandle( const XMLNode& node ) {
1907 _node = &node;
1909 XMLConstHandle( const XMLConstHandle& ref ) {
1910 _node = ref._node;
1913 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
1914 _node = ref._node;
1915 return *this;
1918 const XMLConstHandle FirstChild() const {
1919 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
1921 const XMLConstHandle FirstChildElement( const char* value=0 ) const {
1922 return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 );
1924 const XMLConstHandle LastChild() const {
1925 return XMLConstHandle( _node ? _node->LastChild() : 0 );
1927 const XMLConstHandle LastChildElement( const char* _value=0 ) const {
1928 return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 );
1930 const XMLConstHandle PreviousSibling() const {
1931 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
1933 const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const {
1934 return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );
1936 const XMLConstHandle NextSibling() const {
1937 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
1939 const XMLConstHandle NextSiblingElement( const char* _value=0 ) const {
1940 return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 );
1944 const XMLNode* ToNode() const {
1945 return _node;
1947 const XMLElement* ToElement() const {
1948 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
1950 const XMLText* ToText() const {
1951 return ( ( _node == 0 ) ? 0 : _node->ToText() );
1953 const XMLUnknown* ToUnknown() const {
1954 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
1956 const XMLDeclaration* ToDeclaration() const {
1957 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
1960 private:
1961 const XMLNode* _node;
1966 Printing functionality. The XMLPrinter gives you more
1967 options than the XMLDocument::Print() method.
1969 It can:
1970 -# Print to memory.
1971 -# Print to a file you provide.
1972 -# Print XML without a XMLDocument.
1974 Print to Memory
1976 @verbatim
1977 XMLPrinter printer;
1978 doc.Print( &printer );
1979 SomeFunction( printer.CStr() );
1980 @endverbatim
1982 Print to a File
1984 You provide the file pointer.
1985 @verbatim
1986 XMLPrinter printer( fp );
1987 doc.Print( &printer );
1988 @endverbatim
1990 Print without a XMLDocument
1992 When loading, an XML parser is very useful. However, sometimes
1993 when saving, it just gets in the way. The code is often set up
1994 for streaming, and constructing the DOM is just overhead.
1996 The Printer supports the streaming case. The following code
1997 prints out a trivially simple XML file without ever creating
1998 an XML document.
2000 @verbatim
2001 XMLPrinter printer( fp );
2002 printer.OpenElement( "foo" );
2003 printer.PushAttribute( "foo", "bar" );
2004 printer.CloseElement();
2005 @endverbatim
2007 class TINYXML2_LIB XMLPrinter : public XMLVisitor
2009 public:
2010 /** Construct the printer. If the FILE* is specified,
2011 this will print to the FILE. Else it will print
2012 to memory, and the result is available in CStr().
2013 If 'compact' is set to true, then output is created
2014 with only required whitespace and newlines.
2016 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
2017 virtual ~XMLPrinter() {}
2019 /** If streaming, write the BOM and declaration. */
2020 void PushHeader( bool writeBOM, bool writeDeclaration );
2021 /** If streaming, start writing an element.
2022 The element must be closed with CloseElement()
2024 void OpenElement( const char* name, bool compactMode=false );
2025 /// If streaming, add an attribute to an open element.
2026 void PushAttribute( const char* name, const char* value );
2027 void PushAttribute( const char* name, int value );
2028 void PushAttribute( const char* name, unsigned value );
2029 void PushAttribute( const char* name, bool value );
2030 void PushAttribute( const char* name, double value );
2031 /// If streaming, close the Element.
2032 virtual void CloseElement( bool compactMode=false );
2034 /// Add a text node.
2035 void PushText( const char* text, bool cdata=false );
2036 /// Add a text node from an integer.
2037 void PushText( int value );
2038 /// Add a text node from an unsigned.
2039 void PushText( unsigned value );
2040 /// Add a text node from a bool.
2041 void PushText( bool value );
2042 /// Add a text node from a float.
2043 void PushText( float value );
2044 /// Add a text node from a double.
2045 void PushText( double value );
2047 /// Add a comment
2048 void PushComment( const char* comment );
2050 void PushDeclaration( const char* value );
2051 void PushUnknown( const char* value );
2053 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
2054 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
2055 return true;
2058 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
2059 virtual bool VisitExit( const XMLElement& element );
2061 virtual bool Visit( const XMLText& text );
2062 virtual bool Visit( const XMLComment& comment );
2063 virtual bool Visit( const XMLDeclaration& declaration );
2064 virtual bool Visit( const XMLUnknown& unknown );
2067 If in print to memory mode, return a pointer to
2068 the XML file in memory.
2070 const char* CStr() const {
2071 return _buffer.Mem();
2074 If in print to memory mode, return the size
2075 of the XML file in memory. (Note the size returned
2076 includes the terminating null.)
2078 int CStrSize() const {
2079 return _buffer.Size();
2082 If in print to memory mode, reset the buffer to the
2083 beginning.
2085 void ClearBuffer() {
2086 _buffer.Clear();
2087 _buffer.Push(0);
2090 protected:
2091 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
2093 /** Prints out the space before an element. You may override to change
2094 the space and tabs used. A PrintSpace() override should call Print().
2096 virtual void PrintSpace( int depth );
2097 void Print( const char* format, ... );
2099 void SealElementIfJustOpened();
2100 bool _elementJustOpened;
2101 DynArray< const char*, 10 > _stack;
2103 private:
2104 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2106 bool _firstElement;
2107 FILE* _fp;
2108 int _depth;
2109 int _textDepth;
2110 bool _processEntities;
2111 bool _compactMode;
2113 enum {
2114 ENTITY_RANGE = 64,
2115 BUF_SIZE = 200
2117 bool _entityFlag[ENTITY_RANGE];
2118 bool _restrictedEntityFlag[ENTITY_RANGE];
2120 DynArray< char, 20 > _buffer;
2124 } // tinyxml2
2126 #if defined(_MSC_VER)
2127 # pragma warning(pop)
2128 #endif
2130 #endif // TINYXML2_INCLUDED