Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
tinyxml2.h2384 linesDownload Raw Back to include
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
458/**
459	Implements the interface to the "Visitor pattern" (see the Accept() method.)
460	If you call the Accept() method, it requires being passed a XMLVisitor
461	class to handle callbacks. For nodes that contain other nodes (Document, Element)
462	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
463	are simply called with Visit().
464
465	If you return 'true' from a Visit method, recursive parsing will continue. If you return
466	false, <b>no children of this node or its siblings</b> will be visited.
467
468	All flavors of Visit methods have a default implementation that returns 'true' (continue
469	visiting). You need to only override methods that are interesting to you.
470
471	Generally Accept() is called on the XMLDocument, although all nodes support visiting.
472
473	You should never change the document from a callback.
474
475	@sa XMLNode::Accept()
476*/
477class TINYXML2_LIB XMLVisitor
478{
479public:
480    virtual ~XMLVisitor() {}
481
482    /// Visit a document.
483    virtual bool VisitEnter( const XMLDocument& /*doc*/ )			{
484        return true;
485    }
486    /// Visit a document.
487    virtual bool VisitExit( const XMLDocument& /*doc*/ )			{
488        return true;
489    }
490
491    /// Visit an element.
492    virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )	{
493        return true;
494    }
495    /// Visit an element.
496    virtual bool VisitExit( const XMLElement& /*element*/ )			{
497        return true;
498    }
499
500    /// Visit a declaration.
501    virtual bool Visit( const XMLDeclaration& /*declaration*/ )		{
502        return true;
503    }
504    /// Visit a text node.
505    virtual bool Visit( const XMLText& /*text*/ )					{
506        return true;
507    }
508    /// Visit a comment node.
509    virtual bool Visit( const XMLComment& /*comment*/ )				{
510        return true;
511    }
512    /// Visit an unknown node.
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
645/** XMLNode is a base class for every object that is in the
646	XML Document Object Model (DOM), except XMLAttributes.
647	Nodes have siblings, a parent, and children which can
648	be navigated. A node is always in a XMLDocument.
649	The type of a XMLNode can be queried, and it can
650	be cast to its more defined type.
651
652	A XMLDocument allocates memory for all its Nodes.
653	When the XMLDocument gets deleted, all its Nodes
654	will also be deleted.
655
656	@verbatim
657	A Document can contain:	Element	(container or leaf)
658							Comment (leaf)
659							Unknown (leaf)
660							Declaration( leaf )
661
662	An Element can contain:	Element (container or leaf)
663							Text	(leaf)
664							Attributes (not on tree)
665							Comment (leaf)
666							Unknown (leaf)
667
668	@endverbatim
669*/
670class TINYXML2_LIB XMLNode
671{
672    friend class XMLDocument;
673    friend class XMLElement;
674public:
675
676    /// Get the XMLDocument that owns this XMLNode.
677    const XMLDocument* GetDocument() const	{
678        TIXMLASSERT( _document );
679        return _document;
680    }
681    /// Get the XMLDocument that owns this XMLNode.
682    XMLDocument* GetDocument()				{
683        TIXMLASSERT( _document );
684        return _document;
685    }
686
687    /// Safely cast to an Element, or null.
688    virtual XMLElement*		ToElement()		{
689        return 0;
690    }
691    /// Safely cast to Text, or null.
692    virtual XMLText*		ToText()		{
693        return 0;
694    }
695    /// Safely cast to a Comment, or null.
696    virtual XMLComment*		ToComment()		{
697        return 0;
698    }
699    /// Safely cast to a Document, or null.
700    virtual XMLDocument*	ToDocument()	{
701        return 0;
702    }
703    /// Safely cast to a Declaration, or null.
704    virtual XMLDeclaration*	ToDeclaration()	{
705        return 0;
706    }
707    /// Safely cast to an Unknown, or null.
708    virtual XMLUnknown*		ToUnknown()		{
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
737    /** The meaning of 'value' changes for the specific type.
738    	@verbatim
739    	Document:	empty (NULL is returned, not an empty string)
740    	Element:	name of the element
741    	Comment:	the comment text
742    	Unknown:	the tag contents
743    	Text:		the text string
744    	@endverbatim
745    */
746    const char* Value() const;
747
748    /** Set the Value of an XML node.
749    	@sa Value()
750    */
751    void SetValue( const char* val, bool staticMem=false );
752
753    /// Gets the line number the node is in, if the document was parsed from a file.
754    int GetLineNum() const { return _parseLineNum; }
755
756    /// Get the parent of this node on the DOM.
757    const XMLNode*	Parent() const			{
758        return _parent;
759    }
760
761    XMLNode* Parent()						{
762        return _parent;
763    }
764
765    /// Returns true if this node has no children.
766    bool NoChildren() const					{
767        return !_firstChild;
768    }
769
770    /// Get the first child node, or null if none exists.
771    const XMLNode*  FirstChild() const		{
772        return _firstChild;
773    }
774
775    XMLNode*		FirstChild()			{
776        return _firstChild;
777    }
778
779    /** Get the first child element, or optionally the first child
780        element with the specified name.
781    */
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
788    /// Get the last child node, or null if none exists.
789    const XMLNode*	LastChild() const						{
790        return _lastChild;
791    }
792
793    XMLNode*		LastChild()								{
794        return _lastChild;
795    }
796
797    /** Get the last child element or optionally the last child
798        element with the specified name.
799    */
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
806    /// Get the previous (left) sibling node of this node.
807    const XMLNode*	PreviousSibling() const					{
808        return _prev;
809    }
810
811    XMLNode*	PreviousSibling()							{
812        return _prev;
813    }
814
815    /// Get the previous (left) sibling element of this node, with an optionally supplied name.
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
822    /// Get the next (right) sibling node of this node.
823    const XMLNode*	NextSibling() const						{
824        return _next;
825    }
826
827    XMLNode*	NextSibling()								{
828        return _next;
829    }
830
831    /// Get the next (right) sibling element of this node, with an optionally supplied name.
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
838    /**
839    	Add a child node as the last (right) child.
840		If the child node is already part of the document,
841		it is moved from its old location to the new location.
842		Returns the addThis argument or 0 if the node does not
843		belong to the same document.
844    */
845    XMLNode* InsertEndChild( XMLNode* addThis );
846
847    XMLNode* LinkEndChild( XMLNode* addThis )	{
848        return InsertEndChild( addThis );
849    }
850    /**
851    	Add a child node as the first (left) child.
852		If the child node is already part of the document,
853		it is moved from its old location to the new location.
854		Returns the addThis argument or 0 if the node does not
855		belong to the same document.
856    */
857    XMLNode* InsertFirstChild( XMLNode* addThis );
858    /**
859    	Add a node after the specified child node.
860		If the child node is already part of the document,
861		it is moved from its old location to the new location.
862		Returns the addThis argument or 0 if the afterThis node
863		is not a child of this node, or if the node does not
864		belong to the same document.
865    */
866    XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
867
868    /**
869    	Delete all the children of this node.
870    */
871    void DeleteChildren();
872
873    /**
874    	Delete a child of this node.
875    */
876    void DeleteChild( XMLNode* node );
877
878    /**
879    	Make a copy of this node, but not its children.
880    	You may pass in a Document pointer that will be
881    	the owner of the new Node. If the 'document' is
882    	null, then the node returned will be allocated
883    	from the current Document. (this->GetDocument())
884
885    	Note: if called on a XMLDocument, this will return null.
886    */
887    virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
888
889	/**
890		Make a copy of this node and all its children.
891
892		If the 'target' is null, then the nodes will
893		be allocated in the current document. If 'target'
894        is specified, the memory will be allocated in the
895        specified XMLDocument.
896
897		NOTE: This is probably not the correct tool to
898		copy a document, since XMLDocuments can have multiple
899		top level XMLNodes. You probably want to use
900        XMLDocument::DeepCopy()
901	*/
902	XMLNode* DeepClone( XMLDocument* target ) const;
903
904    /**
905    	Test if 2 nodes are the same, but don't test children.
906    	The 2 nodes do not need to be in the same Document.
907
908    	Note: if called on a XMLDocument, this will return false.
909    */
910    virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
911
912    /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
913    	XML tree will be conditionally visited and the host will be called back
914    	via the XMLVisitor interface.
915
916    	This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
917    	the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
918    	interface versus any other.)
919
920    	The interface has been based on ideas from:
921
922    	- http://www.saxproject.org/
923    	- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
924
925    	Which are both good references for "visiting".
926
927    	An example of using Accept():
928    	@verbatim
929    	XMLPrinter printer;
930    	tinyxmlDoc.Accept( &printer );
931    	const char* xmlcstr = printer.CStr();
932    	@endverbatim
933    */
934    virtual bool Accept( XMLVisitor* visitor ) const = 0;
935
936	/**
937		Set user data into the XMLNode. TinyXML-2 in
938		no way processes or interprets user data.
939		It is initially 0.
940	*/
941	void SetUserData(void* userData)	{ _userData = userData; }
942
943	/**
944		Get user data set into the XMLNode. TinyXML-2 in
945		no way processes or interprets user data.
946		It is initially 0.
947	*/
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
981/** XML text.
982
983	Note that a text node can have child element nodes, for example:
984	@verbatim
985	<root>This is <b>bold</b></root>
986	@endverbatim
987
988	A text node can have 2 ways to output the next. "normal" output
989	and CDATA. It will default to the mode it was parsed from the XML file and
990	you generally want to leave it alone, but you can change the output mode with
991	SetCData() and query it with CData().
992*/
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
1006    /// Declare whether this should be CDATA or standard text.
1007    void SetCData( bool isCData )			{
1008        _isCData = isCData;
1009    }
1010    /// Returns true if this is a CDATA text element.
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
1032/** An XML Comment. */
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
1061/** In correct XML the declaration is the first entry in the file.
1062	@verbatim
1063		<?xml version="1.0" standalone="yes"?>
1064	@endverbatim
1065
1066	TinyXML-2 will happily read or write files without a declaration,
1067	however.
1068
1069	The text of the declaration isn't interpreted. It is parsed
1070	and written as a string.
1071*/
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
1100/** Any tag that TinyXML-2 doesn't recognize is saved as an
1101	unknown. It is a tag of text, but should not be modified.
1102	It will be written back to the XML, unchanged, when the file
1103	is saved.
1104
1105	DTD tags get thrown into XMLUnknowns.
1106*/
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
1136/** An attribute is a name-value pair. Elements have an arbitrary
1137	number of attributes, each with a unique name.
1138
1139	@note The attributes are not XMLNodes. You may only query the
1140	Next() attribute in a list.
1141*/
1142class TINYXML2_LIB XMLAttribute
1143{
1144    friend class XMLElement;
1145public:
1146    /// The name of the attribute.
1147    const char* Name() const;
1148
1149    /// The value of the attribute.
1150    const char* Value() const;
1151
1152    /// Gets the line number the attribute is in, if the document was parsed from a file.
1153    int GetLineNum() const { return _parseLineNum; }
1154
1155    /// The next attribute in the list.
1156    const XMLAttribute* Next() const {
1157        return _next;
1158    }
1159
1160    /** IntValue interprets the attribute as an integer, and returns the value.
1161        If the value isn't an integer, 0 will be returned. There is no error checking;
1162    	use QueryIntValue() if you need error checking.
1163    */
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
1182    /// Query as an unsigned integer. See IntValue()
1183    unsigned UnsignedValue() const			{
1184        unsigned i=0;
1185        QueryUnsignedValue( &i );
1186        return i;
1187    }
1188    /// Query as a boolean. See IntValue()
1189    bool	 BoolValue() const				{
1190        bool b=false;
1191        QueryBoolValue( &b );
1192        return b;
1193    }
1194    /// Query as a double. See IntValue()
1195    double 	 DoubleValue() const			{
1196        double d=0;
1197        QueryDoubleValue( &d );
1198        return d;
1199    }
1200    /// Query as a float. See IntValue()

Showing the first 1,200 of 2384 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai