LCOV - code coverage report
Current view: top level - tarch/tinyxml2 - tinyxml2.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 13 14 92.9 %
Date: 2026-02-16 14:39:39 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             : Original code by Lee Thomason (www.grinninglizard.com)
       3             : 
       4             : This software is provided 'as-is', without any express or implied
       5             : warranty. In no event will the authors be held liable for any
       6             : damages arising from the use of this software.
       7             : 
       8             : Permission is granted to anyone to use this software for any
       9             : purpose, including commercial applications, and to alter it and
      10             : redistribute it freely, subject to the following restrictions:
      11             : 
      12             : 1. The origin of this software must not be misrepresented; you must
      13             : not claim that you wrote the original software. If you use this
      14             : software in a product, an acknowledgment in the product documentation
      15             : would be appreciated but is not required.
      16             : 
      17             : 2. Altered source versions must be plainly marked as such, and
      18             : must not be misrepresented as being the original software.
      19             : 
      20             : 3. This notice may not be removed or altered from any source
      21             : distribution.
      22             : */
      23             : 
      24             : #ifndef TINYXML2_INCLUDED
      25             : #define TINYXML2_INCLUDED
      26             : 
      27             : #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
      28             : #include <ctype.h>
      29             : #include <limits.h>
      30             : #include <stdio.h>
      31             : #include <stdlib.h>
      32             : #include <string.h>
      33             : #if defined(__PS3__)
      34             : #include <stddef.h>
      35             : #endif
      36             : #else
      37             : #include <cctype>
      38             : #include <climits>
      39             : #include <cstdio>
      40             : #include <cstdlib>
      41             : #include <cstring>
      42             : #endif
      43             : #include <stdint.h>
      44             : 
      45             : /*
      46             :         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             : #if !defined(TIXMLASSERT)
      79             : #if defined(TINYXML2_DEBUG)
      80             : #if defined(_MSC_VER)
      81             : #// "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
      82             : #define TIXMLASSERT(x)                                                                                                                                         \
      83             :   do {                                                                                                                                                         \
      84             :     if (!((void)0, (x))) {                                                                                                                                     \
      85             :       __debugbreak();                                                                                                                                          \
      86             :     }                                                                                                                                                          \
      87             :   } while (false)
      88             : #elif defined(ANDROID_NDK)
      89             : #include <android/log.h>
      90             : #define TIXMLASSERT(x)                                                                                                                                         \
      91             :   do {                                                                                                                                                         \
      92             :     if (!(x)) {                                                                                                                                                \
      93             :       __android_log_assert("assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__);                                                                  \
      94             :     }                                                                                                                                                          \
      95             :   } while (false)
      96             : #else
      97             : #include <assert.h>
      98             : #define TIXMLASSERT assert
      99             : #endif
     100             : #else
     101             : #define TIXMLASSERT(x)                                                                                                                                         \
     102             :   do {                                                                                                                                                         \
     103             :   } while (false)
     104             : #endif
     105             : #endif
     106             : 
     107             : /* Versioning, past 1.0.14:
     108             :         http://semver.org/
     109             : */
     110             : static const int TIXML2_MAJOR_VERSION = 10;
     111             : static const int TIXML2_MINOR_VERSION = 0;
     112             : static const int TIXML2_PATCH_VERSION = 0;
     113             : 
     114             : #define TINYXML2_MAJOR_VERSION 10
     115             : #define TINYXML2_MINOR_VERSION 0
     116             : #define TINYXML2_PATCH_VERSION 0
     117             : 
     118             : // A fixed element depth limit is problematic. There needs to be a
     119             : // limit to avoid a stack overflow. However, that limit varies per
     120             : // system, and the capacity of the stack. On the other hand, it's a trivial
     121             : // attack that can result from ill, malicious, or even correctly formed XML,
     122             : // so there needs to be a limit in place.
     123             : static const int TINYXML2_MAX_ELEMENT_DEPTH = 500;
     124             : 
     125             : namespace tinyxml2 {
     126             : class XMLDocument;
     127             : class XMLElement;
     128             : class XMLAttribute;
     129             : class XMLComment;
     130             : class XMLText;
     131             : class XMLDeclaration;
     132             : class XMLUnknown;
     133             : class XMLPrinter;
     134             : 
     135             : /*
     136             :         A class that wraps strings. Normally stores the start and end
     137             :         pointers into the XML file itself, and will apply normalization
     138             :         and entity translation if actually read. Can also store (and memory
     139             :         manage) a traditional char[]
     140             : 
     141             :     Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
     142             : */
     143             : class TINYXML2_LIB StrPair {
     144             : public:
     145             :   enum Mode {
     146             :     NEEDS_ENTITY_PROCESSING = 0x01,
     147             :     NEEDS_NEWLINE_NORMALIZATION = 0x02,
     148             :     NEEDS_WHITESPACE_COLLAPSING = 0x04,
     149             : 
     150             :     TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
     151             :     TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
     152             :     ATTRIBUTE_NAME = 0,
     153             :     ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
     154             :     ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
     155             :     COMMENT = NEEDS_NEWLINE_NORMALIZATION
     156             :   };
     157             : 
     158             :   StrPair() : _flags(0), _start(0), _end(0) {}
     159             :   ~StrPair();
     160             : 
     161             :   void Set(char* start, char* end, int flags) {
     162             :     TIXMLASSERT(start);
     163             :     TIXMLASSERT(end);
     164             :     Reset();
     165             :     _start = start;
     166             :     _end = end;
     167             :     _flags = flags | NEEDS_FLUSH;
     168             :   }
     169             : 
     170             :   const char* GetStr();
     171             : 
     172             :   bool Empty() const { return _start == _end; }
     173             : 
     174             :   void SetInternedStr(const char* str) {
     175             :     Reset();
     176             :     _start = const_cast<char*>(str);
     177             :   }
     178             : 
     179             :   void SetStr(const char* str, int flags = 0);
     180             : 
     181             :   char* ParseText(char* in, const char* endTag, int strFlags, int* curLineNumPtr);
     182             :   char* ParseName(char* in);
     183             : 
     184             :   void TransferTo(StrPair* other);
     185             :   void Reset();
     186             : 
     187             : private:
     188             :   void CollapseWhitespace();
     189             : 
     190             :   enum { NEEDS_FLUSH = 0x100, NEEDS_DELETE = 0x200 };
     191             : 
     192             :   int _flags;
     193             :   char* _start;
     194             :   char* _end;
     195             : 
     196             :   StrPair(const StrPair& other);        // not supported
     197             :   void operator=(const StrPair& other); // not supported, use TransferTo()
     198             : };
     199             : 
     200             : /*
     201             :         A dynamic array of Plain Old Data. Doesn't support constructors, etc.
     202             :         Has a small initial memory pool, so that low or no usage will not
     203             :         cause a call to new/delete
     204             : */
     205             : template <class T, int INITIAL_SIZE> class DynArray {
     206             : public:
     207             :   DynArray() : _mem(_pool), _allocated(INITIAL_SIZE), _size(0) {}
     208             : 
     209             :   ~DynArray() {
     210             :     if (_mem != _pool) {
     211             :       delete[] _mem;
     212             :     }
     213             :   }
     214             : 
     215             :   void Clear() { _size = 0; }
     216             : 
     217             :   void Push(T t) {
     218             :     TIXMLASSERT(_size < INT_MAX);
     219             :     EnsureCapacity(_size + 1);
     220             :     _mem[_size] = t;
     221             :     ++_size;
     222             :   }
     223             : 
     224             :   T* PushArr(int count) {
     225             :     TIXMLASSERT(count >= 0);
     226             :     TIXMLASSERT(_size <= INT_MAX - count);
     227             :     EnsureCapacity(_size + count);
     228             :     T* ret = &_mem[_size];
     229             :     _size += count;
     230             :     return ret;
     231             :   }
     232             : 
     233             :   T Pop() {
     234             :     TIXMLASSERT(_size > 0);
     235             :     --_size;
     236             :     return _mem[_size];
     237             :   }
     238             : 
     239             :   void PopArr(int count) {
     240             :     TIXMLASSERT(_size >= count);
     241             :     _size -= count;
     242             :   }
     243             : 
     244             :   bool Empty() const { return _size == 0; }
     245             : 
     246             :   T& operator[](int i) {
     247             :     TIXMLASSERT(i >= 0 && i < _size);
     248             :     return _mem[i];
     249             :   }
     250             : 
     251             :   const T& operator[](int i) const {
     252             :     TIXMLASSERT(i >= 0 && i < _size);
     253             :     return _mem[i];
     254             :   }
     255             : 
     256             :   const T& PeekTop() const {
     257             :     TIXMLASSERT(_size > 0);
     258             :     return _mem[_size - 1];
     259             :   }
     260             : 
     261             :   int Size() const {
     262             :     TIXMLASSERT(_size >= 0);
     263             :     return _size;
     264             :   }
     265             : 
     266             :   int Capacity() const {
     267             :     TIXMLASSERT(_allocated >= INITIAL_SIZE);
     268             :     return _allocated;
     269             :   }
     270             : 
     271             :   void SwapRemove(int i) {
     272             :     TIXMLASSERT(i >= 0 && i < _size);
     273             :     TIXMLASSERT(_size > 0);
     274             :     _mem[i] = _mem[_size - 1];
     275             :     --_size;
     276             :   }
     277             : 
     278             :   const T* Mem() const {
     279             :     TIXMLASSERT(_mem);
     280             :     return _mem;
     281             :   }
     282             : 
     283             :   T* Mem() {
     284             :     TIXMLASSERT(_mem);
     285             :     return _mem;
     286             :   }
     287             : 
     288             : private:
     289             :   DynArray(const DynArray&);       // not supported
     290             :   void operator=(const DynArray&); // not supported
     291             : 
     292             :   void EnsureCapacity(int cap) {
     293             :     TIXMLASSERT(cap > 0);
     294             :     if (cap > _allocated) {
     295             :       TIXMLASSERT(cap <= INT_MAX / 2);
     296             :       const int newAllocated = cap * 2;
     297             :       T* newMem = new T[static_cast<unsigned int>(newAllocated)];
     298             :       TIXMLASSERT(newAllocated >= _size);
     299             :       memcpy(newMem, _mem, sizeof(T) * static_cast<size_t>(_size)); // warning: not using constructors, only works for PODs
     300             :       if (_mem != _pool) {
     301             :         delete[] _mem;
     302             :       }
     303             :       _mem = newMem;
     304             :       _allocated = newAllocated;
     305             :     }
     306             :   }
     307             : 
     308             :   T* _mem;
     309             :   T _pool[static_cast<size_t>(INITIAL_SIZE)];
     310             :   int _allocated; // objects allocated
     311             :   int _size;      // number objects in use
     312             : };
     313             : 
     314             : /*
     315             :         Parent virtual class of a pool for fast allocation
     316             :         and deallocation of objects.
     317             : */
     318             : class MemPool {
     319             : public:
     320             :   MemPool() {}
     321             :   virtual ~MemPool() {}
     322             : 
     323             :   virtual int ItemSize() const = 0;
     324             :   virtual void* Alloc() = 0;
     325             :   virtual void Free(void*) = 0;
     326             :   virtual void SetTracked() = 0;
     327             : };
     328             : 
     329             : /*
     330             :         Template child class to create pools of the correct type.
     331             : */
     332             : template <int ITEM_SIZE> class MemPoolT : public MemPool {
     333             : public:
     334             :   MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
     335             :   ~MemPoolT() { MemPoolT<ITEM_SIZE>::Clear(); }
     336             : 
     337             :   void Clear() {
     338             :     // Delete the blocks.
     339             :     while (!_blockPtrs.Empty()) {
     340             :       Block* lastBlock = _blockPtrs.Pop();
     341             :       delete lastBlock;
     342             :     }
     343             :     _root = 0;
     344             :     _currentAllocs = 0;
     345             :     _nAllocs = 0;
     346             :     _maxAllocs = 0;
     347             :     _nUntracked = 0;
     348             :   }
     349             : 
     350             :   virtual int ItemSize() const override { return ITEM_SIZE; }
     351             :   int CurrentAllocs() const { return _currentAllocs; }
     352             : 
     353             :   virtual void* Alloc() override {
     354             :     if (!_root) {
     355             :       // Need a new block.
     356             :       Block* block = new Block;
     357             :       _blockPtrs.Push(block);
     358             : 
     359             :       Item* blockItems = block->items;
     360             :       for (int i = 0; i < ITEMS_PER_BLOCK - 1; ++i) {
     361             :         blockItems[i].next = &(blockItems[i + 1]);
     362             :       }
     363             :       blockItems[ITEMS_PER_BLOCK - 1].next = 0;
     364             :       _root = blockItems;
     365             :     }
     366             :     Item* const result = _root;
     367             :     TIXMLASSERT(result != 0);
     368             :     _root = _root->next;
     369             : 
     370             :     ++_currentAllocs;
     371             :     if (_currentAllocs > _maxAllocs) {
     372             :       _maxAllocs = _currentAllocs;
     373             :     }
     374             :     ++_nAllocs;
     375             :     ++_nUntracked;
     376             :     return result;
     377             :   }
     378             : 
     379             :   virtual void Free(void* mem) override {
     380             :     if (!mem) {
     381             :       return;
     382             :     }
     383             :     --_currentAllocs;
     384             :     Item* item = static_cast<Item*>(mem);
     385             : #ifdef TINYXML2_DEBUG
     386             :     memset(item, 0xfe, sizeof(*item));
     387             : #endif
     388             :     item->next = _root;
     389             :     _root = item;
     390             :   }
     391             :   void Trace(const char* name) {
     392             :     printf("Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, ITEM_SIZE,
     393             :            _nAllocs, _blockPtrs.Size());
     394             :   }
     395             : 
     396             :   void SetTracked() override { --_nUntracked; }
     397             : 
     398             :   int Untracked() const { return _nUntracked; }
     399             : 
     400             :   // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
     401             :   // The test file is large, 170k.
     402             :   // Release:           VS2010 gcc(no opt)
     403             :   //            1k:             4000
     404             :   //            2k:             4000
     405             :   //            4k:             3900    21000
     406             :   //            16k:    5200
     407             :   //            32k:    4300
     408             :   //            64k:    4000    21000
     409             :   // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
     410             :   // in private part if ITEMS_PER_BLOCK is private
     411             :   enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
     412             : 
     413             : private:
     414             :   MemPoolT(const MemPoolT&);       // not supported
     415             :   void operator=(const MemPoolT&); // not supported
     416             : 
     417             :   union Item {
     418             :     Item* next;
     419             :     char itemData[static_cast<size_t>(ITEM_SIZE)];
     420             :   };
     421             :   struct Block {
     422             :     Item items[ITEMS_PER_BLOCK];
     423             :   };
     424             :   DynArray<Block*, 10> _blockPtrs;
     425             :   Item* _root;
     426             : 
     427             :   int _currentAllocs;
     428             :   int _nAllocs;
     429             :   int _maxAllocs;
     430             :   int _nUntracked;
     431             : };
     432             : 
     433             : /**
     434             :         Implements the interface to the "Visitor pattern" (see the Accept() method.)
     435             :         If you call the Accept() method, it requires being passed a XMLVisitor
     436             :         class to handle callbacks. For nodes that contain other nodes (Document, Element)
     437             :         you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
     438             :         are simply called with Visit().
     439             : 
     440             :         If you return 'true' from a Visit method, recursive parsing will continue. If you return
     441             :         false, <b>no children of this node or its siblings</b> will be visited.
     442             : 
     443             :         All flavors of Visit methods have a default implementation that returns 'true' (continue
     444             :         visiting). You need to only override methods that are interesting to you.
     445             : 
     446             :         Generally Accept() is called on the XMLDocument, although all nodes support visiting.
     447             : 
     448             :         You should never change the document from a callback.
     449             : 
     450             :         @sa XMLNode::Accept()
     451             : */
     452             : class TINYXML2_LIB XMLVisitor {
     453             : public:
     454             :   virtual ~XMLVisitor() {}
     455             : 
     456             :   /// Visit a document.
     457             :   virtual bool VisitEnter(const XMLDocument& /*doc*/) { return true; }
     458             :   /// Visit a document.
     459             :   virtual bool VisitExit(const XMLDocument& /*doc*/) { return true; }
     460             : 
     461             :   /// Visit an element.
     462             :   virtual bool VisitEnter(const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/) { return true; }
     463             :   /// Visit an element.
     464             :   virtual bool VisitExit(const XMLElement& /*element*/) { return true; }
     465             : 
     466             :   /// Visit a declaration.
     467             :   virtual bool Visit(const XMLDeclaration& /*declaration*/) { return true; }
     468             :   /// Visit a text node.
     469             :   virtual bool Visit(const XMLText& /*text*/) { return true; }
     470             :   /// Visit a comment node.
     471             :   virtual bool Visit(const XMLComment& /*comment*/) { return true; }
     472             :   /// Visit an unknown node.
     473             :   virtual bool Visit(const XMLUnknown& /*unknown*/) { return true; }
     474             : };
     475             : 
     476             : // WARNING: must match XMLDocument::_errorNames[]
     477             : enum XMLError {
     478             :   XML_SUCCESS = 0,
     479             :   XML_NO_ATTRIBUTE,
     480             :   XML_WRONG_ATTRIBUTE_TYPE,
     481             :   XML_ERROR_FILE_NOT_FOUND,
     482             :   XML_ERROR_FILE_COULD_NOT_BE_OPENED,
     483             :   XML_ERROR_FILE_READ_ERROR,
     484             :   XML_ERROR_PARSING_ELEMENT,
     485             :   XML_ERROR_PARSING_ATTRIBUTE,
     486             :   XML_ERROR_PARSING_TEXT,
     487             :   XML_ERROR_PARSING_CDATA,
     488             :   XML_ERROR_PARSING_COMMENT,
     489             :   XML_ERROR_PARSING_DECLARATION,
     490             :   XML_ERROR_PARSING_UNKNOWN,
     491             :   XML_ERROR_EMPTY_DOCUMENT,
     492             :   XML_ERROR_MISMATCHED_ELEMENT,
     493             :   XML_ERROR_PARSING,
     494             :   XML_CAN_NOT_CONVERT_TEXT,
     495             :   XML_NO_TEXT_NODE,
     496             :   XML_ELEMENT_DEPTH_EXCEEDED,
     497             : 
     498             :   XML_ERROR_COUNT
     499             : };
     500             : 
     501             : /*
     502             :         Utility functionality.
     503             : */
     504             : class TINYXML2_LIB XMLUtil {
     505             : public:
     506             :   static const char* SkipWhiteSpace(const char* p, int* curLineNumPtr) {
     507             :     TIXMLASSERT(p);
     508             : 
     509             :     while (IsWhiteSpace(*p)) {
     510             :       if (curLineNumPtr && *p == '\n') {
     511             :         ++(*curLineNumPtr);
     512             :       }
     513             :       ++p;
     514             :     }
     515             :     TIXMLASSERT(p);
     516             :     return p;
     517             :   }
     518             :   static char* SkipWhiteSpace(char* const p, int* curLineNumPtr) { return const_cast<char*>(SkipWhiteSpace(const_cast<const char*>(p), curLineNumPtr)); }
     519             : 
     520             :   // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
     521             :   // correct, but simple, and usually works.
     522             :   static bool IsWhiteSpace(char p) { return !IsUTF8Continuation(p) && isspace(static_cast<unsigned char>(p)); }
     523             : 
     524             :   inline static bool IsNameStartChar(unsigned char ch) {
     525             :     if (ch >= 128) {
     526             :       // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
     527             :       return true;
     528             :     }
     529             :     if (isalpha(ch)) {
     530             :       return true;
     531             :     }
     532             :     return ch == ':' || ch == '_';
     533             :   }
     534             : 
     535             :   inline static bool IsNameChar(unsigned char ch) { return IsNameStartChar(ch) || isdigit(ch) || ch == '.' || ch == '-'; }
     536             : 
     537             :   inline static bool IsPrefixHex(const char* p) {
     538             :     p = SkipWhiteSpace(p, 0);
     539             :     return p && *p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X');
     540             :   }
     541             : 
     542             :   inline static bool StringEqual(const char* p, const char* q, int nChar = INT_MAX) {
     543             :     if (p == q) {
     544             :       return true;
     545             :     }
     546             :     TIXMLASSERT(p);
     547             :     TIXMLASSERT(q);
     548             :     TIXMLASSERT(nChar >= 0);
     549             :     return strncmp(p, q, static_cast<size_t>(nChar)) == 0;
     550             :   }
     551             : 
     552             :   inline static bool IsUTF8Continuation(const char p) { return (p & 0x80) != 0; }
     553             : 
     554             :   static const char* ReadBOM(const char* p, bool* hasBOM);
     555             :   // p is the starting location,
     556             :   // the UTF-8 value of the entity will be placed in value, and length filled in.
     557             :   static const char* GetCharacterRef(const char* p, char* value, int* length);
     558             :   static void ConvertUTF32ToUTF8(unsigned long input, char* output, int* length);
     559             : 
     560             :   // converts primitive types to strings
     561             :   static void ToStr(int v, char* buffer, int bufferSize);
     562             :   static void ToStr(unsigned v, char* buffer, int bufferSize);
     563             :   static void ToStr(bool v, char* buffer, int bufferSize);
     564             :   static void ToStr(float v, char* buffer, int bufferSize);
     565             :   static void ToStr(double v, char* buffer, int bufferSize);
     566             :   static void ToStr(int64_t v, char* buffer, int bufferSize);
     567             :   static void ToStr(uint64_t v, char* buffer, int bufferSize);
     568             : 
     569             :   // converts strings to primitive types
     570             :   static bool ToInt(const char* str, int* value);
     571             :   static bool ToUnsigned(const char* str, unsigned* value);
     572             :   static bool ToBool(const char* str, bool* value);
     573             :   static bool ToFloat(const char* str, float* value);
     574             :   static bool ToDouble(const char* str, double* value);
     575             :   static bool ToInt64(const char* str, int64_t* value);
     576             :   static bool ToUnsigned64(const char* str, uint64_t* value);
     577             :   // Changes what is serialized for a boolean value.
     578             :   // Default to "true" and "false". Shouldn't be changed
     579             :   // unless you have a special testing or compatibility need.
     580             :   // Be careful: static, global, & not thread safe.
     581             :   // Be sure to set static const memory as parameters.
     582             :   static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
     583             : 
     584             : private:
     585             :   static const char* writeBoolTrue;
     586             :   static const char* writeBoolFalse;
     587             : };
     588             : 
     589             : /** XMLNode is a base class for every object that is in the
     590             :         XML Document Object Model (DOM), except XMLAttributes.
     591             :         Nodes have siblings, a parent, and children which can
     592             :         be navigated. A node is always in a XMLDocument.
     593             :         The type of a XMLNode can be queried, and it can
     594             :         be cast to its more defined type.
     595             : 
     596             :         A XMLDocument allocates memory for all its Nodes.
     597             :         When the XMLDocument gets deleted, all its Nodes
     598             :         will also be deleted.
     599             : 
     600             :         @verbatim
     601             :         A Document can contain: Element (container or leaf)
     602             :                                                         Comment (leaf)
     603             :                                                         Unknown (leaf)
     604             :                                                         Declaration( leaf )
     605             : 
     606             :         An Element can contain: Element (container or leaf)
     607             :                                                         Text    (leaf)
     608             :                                                         Attributes (not on tree)
     609             :                                                         Comment (leaf)
     610             :                                                         Unknown (leaf)
     611             : 
     612             :         @endverbatim
     613             : */
     614             : class TINYXML2_LIB XMLNode {
     615             :   friend class XMLDocument;
     616             :   friend class XMLElement;
     617             : 
     618             : public:
     619             :   /// Get the XMLDocument that owns this XMLNode.
     620             :   const XMLDocument* GetDocument() const {
     621             :     TIXMLASSERT(_document);
     622             :     return _document;
     623             :   }
     624             :   /// Get the XMLDocument that owns this XMLNode.
     625          20 :   XMLDocument* GetDocument() {
     626          20 :     TIXMLASSERT(_document);
     627          20 :     return _document;
     628             :   }
     629             : 
     630             :   /// Safely cast to an Element, or null.
     631             :   virtual XMLElement* ToElement() { return 0; }
     632             :   /// Safely cast to Text, or null.
     633             :   virtual XMLText* ToText() { return 0; }
     634             :   /// Safely cast to a Comment, or null.
     635             :   virtual XMLComment* ToComment() { return 0; }
     636             :   /// Safely cast to a Document, or null.
     637             :   virtual XMLDocument* ToDocument() { return 0; }
     638             :   /// Safely cast to a Declaration, or null.
     639             :   virtual XMLDeclaration* ToDeclaration() { return 0; }
     640             :   /// Safely cast to an Unknown, or null.
     641             :   virtual XMLUnknown* ToUnknown() { return 0; }
     642             : 
     643             :   virtual const XMLElement* ToElement() const { return 0; }
     644             :   virtual const XMLText* ToText() const { return 0; }
     645             :   virtual const XMLComment* ToComment() const { return 0; }
     646             :   virtual const XMLDocument* ToDocument() const { return 0; }
     647             :   virtual const XMLDeclaration* ToDeclaration() const { return 0; }
     648             :   virtual const XMLUnknown* ToUnknown() const { return 0; }
     649             : 
     650             :   // ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
     651             : 
     652             :   int ChildElementCount(const char* value) const;
     653             : 
     654             :   int ChildElementCount() const;
     655             : 
     656             :   /** The meaning of 'value' changes for the specific type.
     657             :       @verbatim
     658             :       Document: empty (NULL is returned, not an empty string)
     659             :       Element:  name of the element
     660             :       Comment:  the comment text
     661             :       Unknown:  the tag contents
     662             :       Text:             the text string
     663             :       @endverbatim
     664             :   */
     665             :   const char* Value() const;
     666             : 
     667             :   /** Set the Value of an XML node.
     668             :       @sa Value()
     669             :   */
     670             :   void SetValue(const char* val, bool staticMem = false);
     671             : 
     672             :   /// Gets the line number the node is in, if the document was parsed from a file.
     673             :   int GetLineNum() const { return _parseLineNum; }
     674             : 
     675             :   /// Get the parent of this node on the DOM.
     676             :   const XMLNode* Parent() const { return _parent; }
     677             : 
     678             :   XMLNode* Parent() { return _parent; }
     679             : 
     680             :   /// Returns true if this node has no children.
     681             :   bool NoChildren() const { return !_firstChild; }
     682             : 
     683             :   /// Get the first child node, or null if none exists.
     684             :   const XMLNode* FirstChild() const { return _firstChild; }
     685             : 
     686             :   XMLNode* FirstChild() { return _firstChild; }
     687             : 
     688             :   /** Get the first child element, or optionally the first child
     689             :       element with the specified name.
     690             :   */
     691             :   const XMLElement* FirstChildElement(const char* name = 0) const;
     692             : 
     693          68 :   XMLElement* FirstChildElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement(name)); }
     694             : 
     695             :   /// Get the last child node, or null if none exists.
     696             :   const XMLNode* LastChild() const { return _lastChild; }
     697             : 
     698             :   XMLNode* LastChild() { return _lastChild; }
     699             : 
     700             :   /** Get the last child element or optionally the last child
     701             :       element with the specified name.
     702             :   */
     703             :   const XMLElement* LastChildElement(const char* name = 0) const;
     704             : 
     705             :   XMLElement* LastChildElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name)); }
     706             : 
     707             :   /// Get the previous (left) sibling node of this node.
     708             :   const XMLNode* PreviousSibling() const { return _prev; }
     709             : 
     710             :   XMLNode* PreviousSibling() { return _prev; }
     711             : 
     712             :   /// Get the previous (left) sibling element of this node, with an optionally supplied name.
     713             :   const XMLElement* PreviousSiblingElement(const char* name = 0) const;
     714             : 
     715             :   XMLElement* PreviousSiblingElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement(name)); }
     716             : 
     717             :   /// Get the next (right) sibling node of this node.
     718             :   const XMLNode* NextSibling() const { return _next; }
     719             : 
     720             :   XMLNode* NextSibling() { return _next; }
     721             : 
     722             :   /// Get the next (right) sibling element of this node, with an optionally supplied name.
     723             :   const XMLElement* NextSiblingElement(const char* name = 0) const;
     724             : 
     725          44 :   XMLElement* NextSiblingElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement(name)); }
     726             : 
     727             :   /**
     728             :       Add a child node as the last (right) child.
     729             :               If the child node is already part of the document,
     730             :               it is moved from its old location to the new location.
     731             :               Returns the addThis argument or 0 if the node does not
     732             :               belong to the same document.
     733             :   */
     734             :   XMLNode* InsertEndChild(XMLNode* addThis);
     735             : 
     736             :   XMLNode* LinkEndChild(XMLNode* addThis) { return InsertEndChild(addThis); }
     737             :   /**
     738             :       Add a child node as the first (left) child.
     739             :               If the child node is already part of the document,
     740             :               it is moved from its old location to the new location.
     741             :               Returns the addThis argument or 0 if the node does not
     742             :               belong to the same document.
     743             :   */
     744             :   XMLNode* InsertFirstChild(XMLNode* addThis);
     745             :   /**
     746             :       Add a node after the specified child node.
     747             :               If the child node is already part of the document,
     748             :               it is moved from its old location to the new location.
     749             :               Returns the addThis argument or 0 if the afterThis node
     750             :               is not a child of this node, or if the node does not
     751             :               belong to the same document.
     752             :   */
     753             :   XMLNode* InsertAfterChild(XMLNode* afterThis, XMLNode* addThis);
     754             : 
     755             :   /**
     756             :       Delete all the children of this node.
     757             :   */
     758             :   void DeleteChildren();
     759             : 
     760             :   /**
     761             :       Delete a child of this node.
     762             :   */
     763             :   void DeleteChild(XMLNode* node);
     764             : 
     765             :   /**
     766             :       Make a copy of this node, but not its children.
     767             :       You may pass in a Document pointer that will be
     768             :       the owner of the new Node. If the 'document' is
     769             :       null, then the node returned will be allocated
     770             :       from the current Document. (this->GetDocument())
     771             : 
     772             :       Note: if called on a XMLDocument, this will return null.
     773             :   */
     774             :   virtual XMLNode* ShallowClone(XMLDocument* document) const = 0;
     775             : 
     776             :   /**
     777             :           Make a copy of this node and all its children.
     778             : 
     779             :           If the 'target' is null, then the nodes will
     780             :           be allocated in the current document. If 'target'
     781             :   is specified, the memory will be allocated is the
     782             :   specified XMLDocument.
     783             : 
     784             :           NOTE: This is probably not the correct tool to
     785             :           copy a document, since XMLDocuments can have multiple
     786             :           top level XMLNodes. You probably want to use
     787             :   XMLDocument::DeepCopy()
     788             :   */
     789             :   XMLNode* DeepClone(XMLDocument* target) const;
     790             : 
     791             :   /**
     792             :       Test if 2 nodes are the same, but don't test children.
     793             :       The 2 nodes do not need to be in the same Document.
     794             : 
     795             :       Note: if called on a XMLDocument, this will return false.
     796             :   */
     797             :   virtual bool ShallowEqual(const XMLNode* compare) const = 0;
     798             : 
     799             :   /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
     800             :       XML tree will be conditionally visited and the host will be called back
     801             :       via the XMLVisitor interface.
     802             : 
     803             :       This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
     804             :       the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
     805             :       interface versus any other.)
     806             : 
     807             :       The interface has been based on ideas from:
     808             : 
     809             :       - http://www.saxproject.org/
     810             :       - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
     811             : 
     812             :       Which are both good references for "visiting".
     813             : 
     814             :       An example of using Accept():
     815             :       @verbatim
     816             :       XMLPrinter printer;
     817             :       tinyxmlDoc.Accept( &printer );
     818             :       const char* xmlcstr = printer.CStr();
     819             :       @endverbatim
     820             :   */
     821             :   virtual bool Accept(XMLVisitor* visitor) const = 0;
     822             : 
     823             :   /**
     824             :           Set user data into the XMLNode. TinyXML-2 in
     825             :           no way processes or interprets user data.
     826             :           It is initially 0.
     827             :   */
     828             :   void SetUserData(void* userData) { _userData = userData; }
     829             : 
     830             :   /**
     831             :           Get user data set into the XMLNode. TinyXML-2 in
     832             :           no way processes or interprets user data.
     833             :           It is initially 0.
     834             :   */
     835             :   void* GetUserData() const { return _userData; }
     836             : 
     837             : protected:
     838             :   explicit XMLNode(XMLDocument*);
     839             :   virtual ~XMLNode();
     840             : 
     841             :   virtual char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr);
     842             : 
     843             :   XMLDocument* _document;
     844             :   XMLNode* _parent;
     845             :   mutable StrPair _value;
     846             :   int _parseLineNum;
     847             : 
     848             :   XMLNode* _firstChild;
     849             :   XMLNode* _lastChild;
     850             : 
     851             :   XMLNode* _prev;
     852             :   XMLNode* _next;
     853             : 
     854             :   void* _userData;
     855             : 
     856             : private:
     857             :   MemPool* _memPool;
     858             :   void Unlink(XMLNode* child);
     859             :   static void DeleteNode(XMLNode* node);
     860             :   void InsertChildPreamble(XMLNode* insertThis) const;
     861             :   const XMLElement* ToElementWithName(const char* name) const;
     862             : 
     863             :   XMLNode(const XMLNode&);            // not supported
     864             :   XMLNode& operator=(const XMLNode&); // not supported
     865             : };
     866             : 
     867             : /** XML text.
     868             : 
     869             :         Note that a text node can have child element nodes, for example:
     870             :         @verbatim
     871             :         <root>This is <b>bold</b></root>
     872             :         @endverbatim
     873             : 
     874             :         A text node can have 2 ways to output the next. "normal" output
     875             :         and CDATA. It will default to the mode it was parsed from the XML file and
     876             :         you generally want to leave it alone, but you can change the output mode with
     877             :         SetCData() and query it with CData().
     878             : */
     879             : class TINYXML2_LIB XMLText : public XMLNode {
     880             :   friend class XMLDocument;
     881             : 
     882             : public:
     883             :   virtual bool Accept(XMLVisitor* visitor) const override;
     884             : 
     885             :   virtual XMLText* ToText() override { return this; }
     886             :   virtual const XMLText* ToText() const override { return this; }
     887             : 
     888             :   /// Declare whether this should be CDATA or standard text.
     889             :   void SetCData(bool isCData) { _isCData = isCData; }
     890             :   /// Returns true if this is a CDATA text element.
     891             :   bool CData() const { return _isCData; }
     892             : 
     893             :   virtual XMLNode* ShallowClone(XMLDocument* document) const override;
     894             :   virtual bool ShallowEqual(const XMLNode* compare) const override;
     895             : 
     896             : protected:
     897             :   explicit XMLText(XMLDocument* doc) : XMLNode(doc), _isCData(false) {}
     898             :   virtual ~XMLText() {}
     899             : 
     900             :   char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
     901             : 
     902             : private:
     903             :   bool _isCData;
     904             : 
     905             :   XMLText(const XMLText&);            // not supported
     906             :   XMLText& operator=(const XMLText&); // not supported
     907             : };
     908             : 
     909             : /** An XML Comment. */
     910             : class TINYXML2_LIB XMLComment : public XMLNode {
     911             :   friend class XMLDocument;
     912             : 
     913             : public:
     914             :   virtual XMLComment* ToComment() override { return this; }
     915             :   virtual const XMLComment* ToComment() const override { return this; }
     916             : 
     917             :   virtual bool Accept(XMLVisitor* visitor) const override;
     918             : 
     919             :   virtual XMLNode* ShallowClone(XMLDocument* document) const override;
     920             :   virtual bool ShallowEqual(const XMLNode* compare) const override;
     921             : 
     922             : protected:
     923             :   explicit XMLComment(XMLDocument* doc);
     924             :   virtual ~XMLComment();
     925             : 
     926             :   char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
     927             : 
     928             : private:
     929             :   XMLComment(const XMLComment&);            // not supported
     930             :   XMLComment& operator=(const XMLComment&); // not supported
     931             : };
     932             : 
     933             : /** In correct XML the declaration is the first entry in the file.
     934             :         @verbatim
     935             :                 <?xml version="1.0" standalone="yes"?>
     936             :         @endverbatim
     937             : 
     938             :         TinyXML-2 will happily read or write files without a declaration,
     939             :         however.
     940             : 
     941             :         The text of the declaration isn't interpreted. It is parsed
     942             :         and written as a string.
     943             : */
     944             : class TINYXML2_LIB XMLDeclaration : public XMLNode {
     945             :   friend class XMLDocument;
     946             : 
     947             : public:
     948             :   virtual XMLDeclaration* ToDeclaration() override { return this; }
     949             :   virtual const XMLDeclaration* ToDeclaration() const override { return this; }
     950             : 
     951             :   virtual bool Accept(XMLVisitor* visitor) const override;
     952             : 
     953             :   virtual XMLNode* ShallowClone(XMLDocument* document) const override;
     954             :   virtual bool ShallowEqual(const XMLNode* compare) const override;
     955             : 
     956             : protected:
     957             :   explicit XMLDeclaration(XMLDocument* doc);
     958             :   virtual ~XMLDeclaration();
     959             : 
     960             :   char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
     961             : 
     962             : private:
     963             :   XMLDeclaration(const XMLDeclaration&);            // not supported
     964             :   XMLDeclaration& operator=(const XMLDeclaration&); // not supported
     965             : };
     966             : 
     967             : /** Any tag that TinyXML-2 doesn't recognize is saved as an
     968             :         unknown. It is a tag of text, but should not be modified.
     969             :         It will be written back to the XML, unchanged, when the file
     970             :         is saved.
     971             : 
     972             :         DTD tags get thrown into XMLUnknowns.
     973             : */
     974             : class TINYXML2_LIB XMLUnknown : public XMLNode {
     975             :   friend class XMLDocument;
     976             : 
     977             : public:
     978             :   virtual XMLUnknown* ToUnknown() override { return this; }
     979             :   virtual const XMLUnknown* ToUnknown() const override { return this; }
     980             : 
     981             :   virtual bool Accept(XMLVisitor* visitor) const override;
     982             : 
     983             :   virtual XMLNode* ShallowClone(XMLDocument* document) const override;
     984             :   virtual bool ShallowEqual(const XMLNode* compare) const override;
     985             : 
     986             : protected:
     987             :   explicit XMLUnknown(XMLDocument* doc);
     988             :   virtual ~XMLUnknown();
     989             : 
     990             :   char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
     991             : 
     992             : private:
     993             :   XMLUnknown(const XMLUnknown&);            // not supported
     994             :   XMLUnknown& operator=(const XMLUnknown&); // not supported
     995             : };
     996             : 
     997             : /** An attribute is a name-value pair. Elements have an arbitrary
     998             :         number of attributes, each with a unique name.
     999             : 
    1000             :         @note The attributes are not XMLNodes. You may only query the
    1001             :         Next() attribute in a list.
    1002             : */
    1003             : class TINYXML2_LIB XMLAttribute {
    1004             :   friend class XMLElement;
    1005             : 
    1006             : public:
    1007             :   /// The name of the attribute.
    1008             :   const char* Name() const;
    1009             : 
    1010             :   /// The value of the attribute.
    1011             :   const char* Value() const;
    1012             : 
    1013             :   /// Gets the line number the attribute is in, if the document was parsed from a file.
    1014             :   int GetLineNum() const { return _parseLineNum; }
    1015             : 
    1016             :   /// The next attribute in the list.
    1017             :   const XMLAttribute* Next() const { return _next; }
    1018             : 
    1019             :   /** IntValue interprets the attribute as an integer, and returns the value.
    1020             :       If the value isn't an integer, 0 will be returned. There is no error checking;
    1021             :       use QueryIntValue() if you need error checking.
    1022             :   */
    1023             :   int IntValue() const {
    1024             :     int i = 0;
    1025             :     QueryIntValue(&i);
    1026             :     return i;
    1027             :   }
    1028             : 
    1029             :   int64_t Int64Value() const {
    1030             :     int64_t i = 0;
    1031             :     QueryInt64Value(&i);
    1032             :     return i;
    1033             :   }
    1034             : 
    1035             :   uint64_t Unsigned64Value() const {
    1036             :     uint64_t i = 0;
    1037             :     QueryUnsigned64Value(&i);
    1038             :     return i;
    1039             :   }
    1040             : 
    1041             :   /// Query as an unsigned integer. See IntValue()
    1042             :   unsigned UnsignedValue() const {
    1043             :     unsigned i = 0;
    1044             :     QueryUnsignedValue(&i);
    1045             :     return i;
    1046             :   }
    1047             :   /// Query as a boolean. See IntValue()
    1048             :   bool BoolValue() const {
    1049             :     bool b = false;
    1050             :     QueryBoolValue(&b);
    1051             :     return b;
    1052             :   }
    1053             :   /// Query as a double. See IntValue()
    1054             :   double DoubleValue() const {
    1055             :     double d = 0;
    1056             :     QueryDoubleValue(&d);
    1057             :     return d;
    1058             :   }
    1059             :   /// Query as a float. See IntValue()
    1060             :   float FloatValue() const {
    1061             :     float f = 0;
    1062             :     QueryFloatValue(&f);
    1063             :     return f;
    1064             :   }
    1065             : 
    1066             :   /** QueryIntValue interprets the attribute as an integer, and returns the value
    1067             :       in the provided parameter. The function will return XML_SUCCESS on success,
    1068             :       and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
    1069             :   */
    1070             :   XMLError QueryIntValue(int* value) const;
    1071             :   /// See QueryIntValue
    1072             :   XMLError QueryUnsignedValue(unsigned int* value) const;
    1073             :   /// See QueryIntValue
    1074             :   XMLError QueryInt64Value(int64_t* value) const;
    1075             :   /// See QueryIntValue
    1076             :   XMLError QueryUnsigned64Value(uint64_t* value) const;
    1077             :   /// See QueryIntValue
    1078             :   XMLError QueryBoolValue(bool* value) const;
    1079             :   /// See QueryIntValue
    1080             :   XMLError QueryDoubleValue(double* value) const;
    1081             :   /// See QueryIntValue
    1082             :   XMLError QueryFloatValue(float* value) const;
    1083             : 
    1084             :   /// Set the attribute to a string value.
    1085             :   void SetAttribute(const char* value);
    1086             :   /// Set the attribute to value.
    1087             :   void SetAttribute(int value);
    1088             :   /// Set the attribute to value.
    1089             :   void SetAttribute(unsigned value);
    1090             :   /// Set the attribute to value.
    1091             :   void SetAttribute(int64_t value);
    1092             :   /// Set the attribute to value.
    1093             :   void SetAttribute(uint64_t value);
    1094             :   /// Set the attribute to value.
    1095             :   void SetAttribute(bool value);
    1096             :   /// Set the attribute to value.
    1097             :   void SetAttribute(double value);
    1098             :   /// Set the attribute to value.
    1099             :   void SetAttribute(float value);
    1100             : 
    1101             : private:
    1102             :   enum { BUF_SIZE = 200 };
    1103             : 
    1104             :   XMLAttribute() : _name(), _value(), _parseLineNum(0), _next(0), _memPool(0) {}
    1105             :   virtual ~XMLAttribute() {}
    1106             : 
    1107             :   XMLAttribute(const XMLAttribute&);   // not supported
    1108             :   void operator=(const XMLAttribute&); // not supported
    1109             :   void SetName(const char* name);
    1110             : 
    1111             :   char* ParseDeep(char* p, bool processEntities, int* curLineNumPtr);
    1112             : 
    1113             :   mutable StrPair _name;
    1114             :   mutable StrPair _value;
    1115             :   int _parseLineNum;
    1116             :   XMLAttribute* _next;
    1117             :   MemPool* _memPool;
    1118             : };
    1119             : 
    1120             : /** The element is a container class. It has a value, the element name,
    1121             :         and can contain other elements, text, comments, and unknowns.
    1122             :         Elements also contain an arbitrary number of attributes.
    1123             : */
    1124             : class TINYXML2_LIB XMLElement : public XMLNode {
    1125             :   friend class XMLDocument;
    1126             : 
    1127             : public:
    1128             :   /// Get the name of an element (which is the Value() of the node.)
    1129           0 :   const char* Name() const { return Value(); }
    1130             :   /// Set the name of the element.
    1131             :   void SetName(const char* str, bool staticMem = false) { SetValue(str, staticMem); }
    1132             : 
    1133             :   virtual XMLElement* ToElement() override { return this; }
    1134             :   virtual const XMLElement* ToElement() const override { return this; }
    1135             :   virtual bool Accept(XMLVisitor* visitor) const override;
    1136             : 
    1137             :   /** Given an attribute name, Attribute() returns the value
    1138             :       for the attribute of that name, or null if none
    1139             :       exists. For example:
    1140             : 
    1141             :       @verbatim
    1142             :       const char* value = ele->Attribute( "foo" );
    1143             :       @endverbatim
    1144             : 
    1145             :       The 'value' parameter is normally null. However, if specified,
    1146             :       the attribute will only be returned if the 'name' and 'value'
    1147             :       match. This allow you to write code:
    1148             : 
    1149             :       @verbatim
    1150             :       if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
    1151             :       @endverbatim
    1152             : 
    1153             :       rather than:
    1154             :       @verbatim
    1155             :       if ( ele->Attribute( "foo" ) ) {
    1156             :               if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
    1157             :       }
    1158             :       @endverbatim
    1159             :   */
    1160             :   const char* Attribute(const char* name, const char* value = 0) const;
    1161             : 
    1162             :   /** Given an attribute name, IntAttribute() returns the value
    1163             :       of the attribute interpreted as an integer. The default
    1164             :       value will be returned if the attribute isn't present,
    1165             :       or if there is an error. (For a method with error
    1166             :       checking, see QueryIntAttribute()).
    1167             :   */
    1168             :   int IntAttribute(const char* name, int defaultValue = 0) const;
    1169             :   /// See IntAttribute()
    1170             :   unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
    1171             :   /// See IntAttribute()
    1172             :   int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
    1173             :   /// See IntAttribute()
    1174             :   uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
    1175             :   /// See IntAttribute()
    1176             :   bool BoolAttribute(const char* name, bool defaultValue = false) const;
    1177             :   /// See IntAttribute()
    1178             :   double DoubleAttribute(const char* name, double defaultValue = 0) const;
    1179             :   /// See IntAttribute()
    1180             :   float FloatAttribute(const char* name, float defaultValue = 0) const;
    1181             : 
    1182             :   /** Given an attribute name, QueryIntAttribute() returns
    1183             :       XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
    1184             :       can't be performed, or XML_NO_ATTRIBUTE if the attribute
    1185             :       doesn't exist. If successful, the result of the conversion
    1186             :       will be written to 'value'. If not successful, nothing will
    1187             :       be written to 'value'. This allows you to provide default
    1188             :       value:
    1189             : 
    1190             :       @verbatim
    1191             :       int value = 10;
    1192             :       QueryIntAttribute( "foo", &value );         // if "foo" isn't found, value will still be 10
    1193             :       @endverbatim
    1194             :   */
    1195          56 :   XMLError QueryIntAttribute(const char* name, int* value) const {
    1196          56 :     const XMLAttribute* a = FindAttribute(name);
    1197          56 :     if (!a) {
    1198             :       return XML_NO_ATTRIBUTE;
    1199             :     }
    1200          56 :     return a->QueryIntValue(value);
    1201             :   }
    1202             : 
    1203             :   /// See QueryIntAttribute()
    1204             :   XMLError QueryUnsignedAttribute(const char* name, unsigned int* value) const {
    1205             :     const XMLAttribute* a = FindAttribute(name);
    1206             :     if (!a) {
    1207             :       return XML_NO_ATTRIBUTE;
    1208             :     }
    1209             :     return a->QueryUnsignedValue(value);
    1210             :   }
    1211             : 
    1212             :   /// See QueryIntAttribute()
    1213             :   XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
    1214             :     const XMLAttribute* a = FindAttribute(name);
    1215             :     if (!a) {
    1216             :       return XML_NO_ATTRIBUTE;
    1217             :     }
    1218             :     return a->QueryInt64Value(value);
    1219             :   }
    1220             : 
    1221             :   /// See QueryIntAttribute()
    1222             :   XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const {
    1223             :     const XMLAttribute* a = FindAttribute(name);
    1224             :     if (!a) {
    1225             :       return XML_NO_ATTRIBUTE;
    1226             :     }
    1227             :     return a->QueryUnsigned64Value(value);
    1228             :   }
    1229             : 
    1230             :   /// See QueryIntAttribute()
    1231             :   XMLError QueryBoolAttribute(const char* name, bool* value) const {
    1232             :     const XMLAttribute* a = FindAttribute(name);
    1233             :     if (!a) {
    1234             :       return XML_NO_ATTRIBUTE;
    1235             :     }
    1236             :     return a->QueryBoolValue(value);
    1237             :   }
    1238             :   /// See QueryIntAttribute()
    1239          36 :   XMLError QueryDoubleAttribute(const char* name, double* value) const {
    1240          36 :     const XMLAttribute* a = FindAttribute(name);
    1241          36 :     if (!a) {
    1242             :       return XML_NO_ATTRIBUTE;
    1243             :     }
    1244          36 :     return a->QueryDoubleValue(value);
    1245             :   }
    1246             :   /// See QueryIntAttribute()
    1247             :   XMLError QueryFloatAttribute(const char* name, float* value) const {
    1248             :     const XMLAttribute* a = FindAttribute(name);
    1249             :     if (!a) {
    1250             :       return XML_NO_ATTRIBUTE;
    1251             :     }
    1252             :     return a->QueryFloatValue(value);
    1253             :   }
    1254             : 
    1255             :   /// See QueryIntAttribute()
    1256             :   XMLError QueryStringAttribute(const char* name, const char** value) const {
    1257             :     const XMLAttribute* a = FindAttribute(name);
    1258             :     if (!a) {
    1259             :       return XML_NO_ATTRIBUTE;
    1260             :     }
    1261             :     *value = a->Value();
    1262             :     return XML_SUCCESS;
    1263             :   }
    1264             : 
    1265             :   /** Given an attribute name, QueryAttribute() returns
    1266             :       XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
    1267             :       can't be performed, or XML_NO_ATTRIBUTE if the attribute
    1268             :       doesn't exist. It is overloaded for the primitive types,
    1269             :               and is a generally more convenient replacement of
    1270             :               QueryIntAttribute() and related functions.
    1271             : 
    1272             :               If successful, the result of the conversion
    1273             :       will be written to 'value'. If not successful, nothing will
    1274             :       be written to 'value'. This allows you to provide default
    1275             :       value:
    1276             : 
    1277             :       @verbatim
    1278             :       int value = 10;
    1279             :       QueryAttribute( "foo", &value );            // if "foo" isn't found, value will still be 10
    1280             :       @endverbatim
    1281             :   */
    1282             :   XMLError QueryAttribute(const char* name, int* value) const { return QueryIntAttribute(name, value); }
    1283             : 
    1284             :   XMLError QueryAttribute(const char* name, unsigned int* value) const { return QueryUnsignedAttribute(name, value); }
    1285             : 
    1286             :   XMLError QueryAttribute(const char* name, int64_t* value) const { return QueryInt64Attribute(name, value); }
    1287             : 
    1288             :   XMLError QueryAttribute(const char* name, uint64_t* value) const { return QueryUnsigned64Attribute(name, value); }
    1289             : 
    1290             :   XMLError QueryAttribute(const char* name, bool* value) const { return QueryBoolAttribute(name, value); }
    1291             : 
    1292             :   XMLError QueryAttribute(const char* name, double* value) const { return QueryDoubleAttribute(name, value); }
    1293             : 
    1294             :   XMLError QueryAttribute(const char* name, float* value) const { return QueryFloatAttribute(name, value); }
    1295             : 
    1296             :   XMLError QueryAttribute(const char* name, const char** value) const { return QueryStringAttribute(name, value); }
    1297             : 
    1298             :   /// Sets the named attribute to value.
    1299             :   void SetAttribute(const char* name, const char* value) {
    1300             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1301             :     a->SetAttribute(value);
    1302             :   }
    1303             :   /// Sets the named attribute to value.
    1304             :   void SetAttribute(const char* name, int value) {
    1305             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1306             :     a->SetAttribute(value);
    1307             :   }
    1308             :   /// Sets the named attribute to value.
    1309             :   void SetAttribute(const char* name, unsigned value) {
    1310             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1311             :     a->SetAttribute(value);
    1312             :   }
    1313             : 
    1314             :   /// Sets the named attribute to value.
    1315             :   void SetAttribute(const char* name, int64_t value) {
    1316             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1317             :     a->SetAttribute(value);
    1318             :   }
    1319             : 
    1320             :   /// Sets the named attribute to value.
    1321             :   void SetAttribute(const char* name, uint64_t value) {
    1322             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1323             :     a->SetAttribute(value);
    1324             :   }
    1325             : 
    1326             :   /// Sets the named attribute to value.
    1327             :   void SetAttribute(const char* name, bool value) {
    1328             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1329             :     a->SetAttribute(value);
    1330             :   }
    1331             :   /// Sets the named attribute to value.
    1332             :   void SetAttribute(const char* name, double value) {
    1333             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1334             :     a->SetAttribute(value);
    1335             :   }
    1336             :   /// Sets the named attribute to value.
    1337             :   void SetAttribute(const char* name, float value) {
    1338             :     XMLAttribute* a = FindOrCreateAttribute(name);
    1339             :     a->SetAttribute(value);
    1340             :   }
    1341             : 
    1342             :   /**
    1343             :       Delete an attribute.
    1344             :   */
    1345             :   void DeleteAttribute(const char* name);
    1346             : 
    1347             :   /// Return the first attribute in the list.
    1348             :   const XMLAttribute* FirstAttribute() const { return _rootAttribute; }
    1349             :   /// Query a specific attribute in the list.
    1350             :   const XMLAttribute* FindAttribute(const char* name) const;
    1351             : 
    1352             :   /** Convenience function for easy access to the text inside an element. Although easy
    1353             :       and concise, GetText() is limited compared to getting the XMLText child
    1354             :       and accessing it directly.
    1355             : 
    1356             :       If the first child of 'this' is a XMLText, the GetText()
    1357             :       returns the character string of the Text node, else null is returned.
    1358             : 
    1359             :       This is a convenient method for getting the text of simple contained text:
    1360             :       @verbatim
    1361             :       <foo>This is text</foo>
    1362             :               const char* str = fooElement->GetText();
    1363             :       @endverbatim
    1364             : 
    1365             :       'str' will be a pointer to "This is text".
    1366             : 
    1367             :       Note that this function can be misleading. If the element foo was created from
    1368             :       this XML:
    1369             :       @verbatim
    1370             :               <foo><b>This is text</b></foo>
    1371             :       @endverbatim
    1372             : 
    1373             :       then the value of str would be null. The first child node isn't a text node, it is
    1374             :       another element. From this XML:
    1375             :       @verbatim
    1376             :               <foo>This is <b>text</b></foo>
    1377             :       @endverbatim
    1378             :       GetText() will return "This is ".
    1379             :   */
    1380             :   const char* GetText() const;
    1381             : 
    1382             :   /** Convenience function for easy access to the text inside an element. Although easy
    1383             :       and concise, SetText() is limited compared to creating an XMLText child
    1384             :       and mutating it directly.
    1385             : 
    1386             :       If the first child of 'this' is a XMLText, SetText() sets its value to
    1387             :               the given string, otherwise it will create a first child that is an XMLText.
    1388             : 
    1389             :       This is a convenient method for setting the text of simple contained text:
    1390             :       @verbatim
    1391             :       <foo>This is text</foo>
    1392             :               fooElement->SetText( "Hullaballoo!" );
    1393             :       <foo>Hullaballoo!</foo>
    1394             :               @endverbatim
    1395             : 
    1396             :       Note that this function can be misleading. If the element foo was created from
    1397             :       this XML:
    1398             :       @verbatim
    1399             :               <foo><b>This is text</b></foo>
    1400             :       @endverbatim
    1401             : 
    1402             :       then it will not change "This is text", but rather prefix it with a text element:
    1403             :       @verbatim
    1404             :               <foo>Hullaballoo!<b>This is text</b></foo>
    1405             :       @endverbatim
    1406             : 
    1407             :               For this XML:
    1408             :       @verbatim
    1409             :               <foo />
    1410             :       @endverbatim
    1411             :       SetText() will generate
    1412             :       @verbatim
    1413             :               <foo>Hullaballoo!</foo>
    1414             :       @endverbatim
    1415             :   */
    1416             :   void SetText(const char* inText);
    1417             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1418             :   void SetText(int value);
    1419             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1420             :   void SetText(unsigned value);
    1421             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1422             :   void SetText(int64_t value);
    1423             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1424             :   void SetText(uint64_t value);
    1425             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1426             :   void SetText(bool value);
    1427             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1428             :   void SetText(double value);
    1429             :   /// Convenience method for setting text inside an element. See SetText() for important limitations.
    1430             :   void SetText(float value);
    1431             : 
    1432             :   /**
    1433             :       Convenience method to query the value of a child text node. This is probably best
    1434             :       shown by example. Given you have a document is this form:
    1435             :       @verbatim
    1436             :               <point>
    1437             :                       <x>1</x>
    1438             :                       <y>1.4</y>
    1439             :               </point>
    1440             :       @endverbatim
    1441             : 
    1442             :       The QueryIntText() and similar functions provide a safe and easier way to get to the
    1443             :       "value" of x and y.
    1444             : 
    1445             :       @verbatim
    1446             :               int x = 0;
    1447             :               float y = 0;      // types of x and y are contrived for example
    1448             :               const XMLElement* xElement = pointElement->FirstChildElement( "x" );
    1449             :               const XMLElement* yElement = pointElement->FirstChildElement( "y" );
    1450             :               xElement->QueryIntText( &x );
    1451             :               yElement->QueryFloatText( &y );
    1452             :       @endverbatim
    1453             : 
    1454             :       @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
    1455             :                        to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
    1456             : 
    1457             :   */
    1458             :   XMLError QueryIntText(int* ival) const;
    1459             :   /// See QueryIntText()
    1460             :   XMLError QueryUnsignedText(unsigned* uval) const;
    1461             :   /// See QueryIntText()
    1462             :   XMLError QueryInt64Text(int64_t* uval) const;
    1463             :   /// See QueryIntText()
    1464             :   XMLError QueryUnsigned64Text(uint64_t* uval) const;
    1465             :   /// See QueryIntText()
    1466             :   XMLError QueryBoolText(bool* bval) const;
    1467             :   /// See QueryIntText()
    1468             :   XMLError QueryDoubleText(double* dval) const;
    1469             :   /// See QueryIntText()
    1470             :   XMLError QueryFloatText(float* fval) const;
    1471             : 
    1472             :   int IntText(int defaultValue = 0) const;
    1473             : 
    1474             :   /// See QueryIntText()
    1475             :   unsigned UnsignedText(unsigned defaultValue = 0) const;
    1476             :   /// See QueryIntText()
    1477             :   int64_t Int64Text(int64_t defaultValue = 0) const;
    1478             :   /// See QueryIntText()
    1479             :   uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
    1480             :   /// See QueryIntText()
    1481             :   bool BoolText(bool defaultValue = false) const;
    1482             :   /// See QueryIntText()
    1483             :   double DoubleText(double defaultValue = 0) const;
    1484             :   /// See QueryIntText()
    1485             :   float FloatText(float defaultValue = 0) const;
    1486             : 
    1487             :   /**
    1488             :       Convenience method to create a new XMLElement and add it as last (right)
    1489             :       child of this node. Returns the created and inserted element.
    1490             :   */
    1491             :   XMLElement* InsertNewChildElement(const char* name);
    1492             :   /// See InsertNewChildElement()
    1493             :   XMLComment* InsertNewComment(const char* comment);
    1494             :   /// See InsertNewChildElement()
    1495             :   XMLText* InsertNewText(const char* text);
    1496             :   /// See InsertNewChildElement()
    1497             :   XMLDeclaration* InsertNewDeclaration(const char* text);
    1498             :   /// See InsertNewChildElement()
    1499             :   XMLUnknown* InsertNewUnknown(const char* text);
    1500             : 
    1501             :   // internal:
    1502             :   enum ElementClosingType {
    1503             :     OPEN,   // <foo>
    1504             :     CLOSED, // <foo/>
    1505             :     CLOSING // </foo>
    1506             :   };
    1507             :   ElementClosingType ClosingType() const { return _closingType; }
    1508             :   virtual XMLNode* ShallowClone(XMLDocument* document) const override;
    1509             :   virtual bool ShallowEqual(const XMLNode* compare) const override;
    1510             : 
    1511             : protected:
    1512             :   char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
    1513             : 
    1514             : private:
    1515             :   XMLElement(XMLDocument* doc);
    1516             :   virtual ~XMLElement();
    1517             :   XMLElement(const XMLElement&);     // not supported
    1518             :   void operator=(const XMLElement&); // not supported
    1519             : 
    1520             :   XMLAttribute* FindOrCreateAttribute(const char* name);
    1521             :   char* ParseAttributes(char* p, int* curLineNumPtr);
    1522             :   static void DeleteAttribute(XMLAttribute* attribute);
    1523             :   XMLAttribute* CreateAttribute();
    1524             : 
    1525             :   enum { BUF_SIZE = 200 };
    1526             :   ElementClosingType _closingType;
    1527             :   // The attribute list is ordered; there is no 'lastAttribute'
    1528             :   // because the list needs to be scanned for dupes before adding
    1529             :   // a new attribute.
    1530             :   XMLAttribute* _rootAttribute;
    1531             : };
    1532             : 
    1533             : enum Whitespace { PRESERVE_WHITESPACE, COLLAPSE_WHITESPACE, PEDANTIC_WHITESPACE };
    1534             : 
    1535             : /** A Document binds together all the functionality.
    1536             :         It can be saved, loaded, and printed to the screen.
    1537             :         All Nodes are connected and allocated to a Document.
    1538             :         If the Document is deleted, all its Nodes are also deleted.
    1539             : */
    1540             : class TINYXML2_LIB XMLDocument : public XMLNode {
    1541             :   friend class XMLElement;
    1542             :   // Gives access to SetError and Push/PopDepth, but over-access for everything else.
    1543             :   // Wishing C++ had "internal" scope.
    1544             :   friend class XMLNode;
    1545             :   friend class XMLText;
    1546             :   friend class XMLComment;
    1547             :   friend class XMLDeclaration;
    1548             :   friend class XMLUnknown;
    1549             : 
    1550             : public:
    1551             :   /// constructor
    1552             :   XMLDocument(bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE);
    1553             :   ~XMLDocument();
    1554             : 
    1555             :   virtual XMLDocument* ToDocument() override {
    1556             :     TIXMLASSERT(this == _document);
    1557             :     return this;
    1558             :   }
    1559             :   virtual const XMLDocument* ToDocument() const override {
    1560             :     TIXMLASSERT(this == _document);
    1561             :     return this;
    1562             :   }
    1563             : 
    1564             :   /**
    1565             :       Parse an XML file from a character string.
    1566             :       Returns XML_SUCCESS (0) on success, or
    1567             :       an errorID.
    1568             : 
    1569             :       You may optionally pass in the 'nBytes', which is
    1570             :       the number of bytes which will be parsed. If not
    1571             :       specified, TinyXML-2 will assume 'xml' points to a
    1572             :       null terminated string.
    1573             :   */
    1574             :   XMLError Parse(const char* xml, size_t nBytes = static_cast<size_t>(-1));
    1575             : 
    1576             :   /**
    1577             :       Load an XML file from disk.
    1578             :       Returns XML_SUCCESS (0) on success, or
    1579             :       an errorID.
    1580             :   */
    1581             :   XMLError LoadFile(const char* filename);
    1582             : 
    1583             :   /**
    1584             :       Load an XML file from disk. You are responsible
    1585             :       for providing and closing the FILE*.
    1586             : 
    1587             :       NOTE: The file should be opened as binary ("rb")
    1588             :       not text in order for TinyXML-2 to correctly
    1589             :       do newline normalization.
    1590             : 
    1591             :       Returns XML_SUCCESS (0) on success, or
    1592             :       an errorID.
    1593             :   */
    1594             :   XMLError LoadFile(FILE*);
    1595             : 
    1596             :   /**
    1597             :       Save the XML file to disk.
    1598             :       Returns XML_SUCCESS (0) on success, or
    1599             :       an errorID.
    1600             :   */
    1601             :   XMLError SaveFile(const char* filename, bool compact = false);
    1602             : 
    1603             :   /**
    1604             :       Save the XML file to disk. You are responsible
    1605             :       for providing and closing the FILE*.
    1606             : 
    1607             :       Returns XML_SUCCESS (0) on success, or
    1608             :       an errorID.
    1609             :   */
    1610             :   XMLError SaveFile(FILE* fp, bool compact = false);
    1611             : 
    1612             :   bool ProcessEntities() const { return _processEntities; }
    1613             :   Whitespace WhitespaceMode() const { return _whitespaceMode; }
    1614             : 
    1615             :   /**
    1616             :       Returns true if this document has a leading Byte Order Mark of UTF8.
    1617             :   */
    1618             :   bool HasBOM() const { return _writeBOM; }
    1619             :   /** Sets whether to write the BOM when writing the file.
    1620             :    */
    1621             :   void SetBOM(bool useBOM) { _writeBOM = useBOM; }
    1622             : 
    1623             :   /** Return the root element of DOM. Equivalent to FirstChildElement().
    1624             :       To get the first node, use FirstChild().
    1625             :   */
    1626             :   XMLElement* RootElement() { return FirstChildElement(); }
    1627             :   const XMLElement* RootElement() const { return FirstChildElement(); }
    1628             : 
    1629             :   /** Print the Document. If the Printer is not provided, it will
    1630             :       print to stdout. If you provide Printer, this can print to a file:
    1631             :       @verbatim
    1632             :       XMLPrinter printer( fp );
    1633             :       doc.Print( &printer );
    1634             :       @endverbatim
    1635             : 
    1636             :       Or you can use a printer to print to memory:
    1637             :       @verbatim
    1638             :       XMLPrinter printer;
    1639             :       doc.Print( &printer );
    1640             :       // printer.CStr() has a const char* to the XML
    1641             :       @endverbatim
    1642             :   */
    1643             :   void Print(XMLPrinter* streamer = 0) const;
    1644             :   virtual bool Accept(XMLVisitor* visitor) const override;
    1645             : 
    1646             :   /**
    1647             :       Create a new Element associated with
    1648             :       this Document. The memory for the Element
    1649             :       is managed by the Document.
    1650             :   */
    1651             :   XMLElement* NewElement(const char* name);
    1652             :   /**
    1653             :       Create a new Comment associated with
    1654             :       this Document. The memory for the Comment
    1655             :       is managed by the Document.
    1656             :   */
    1657             :   XMLComment* NewComment(const char* comment);
    1658             :   /**
    1659             :       Create a new Text associated with
    1660             :       this Document. The memory for the Text
    1661             :       is managed by the Document.
    1662             :   */
    1663             :   XMLText* NewText(const char* text);
    1664             :   /**
    1665             :       Create a new Declaration associated with
    1666             :       this Document. The memory for the object
    1667             :       is managed by the Document.
    1668             : 
    1669             :       If the 'text' param is null, the standard
    1670             :       declaration is used.:
    1671             :       @verbatim
    1672             :               <?xml version="1.0" encoding="UTF-8"?>
    1673             :       @endverbatim
    1674             :   */
    1675             :   XMLDeclaration* NewDeclaration(const char* text = 0);
    1676             :   /**
    1677             :       Create a new Unknown associated with
    1678             :       this Document. The memory for the object
    1679             :       is managed by the Document.
    1680             :   */
    1681             :   XMLUnknown* NewUnknown(const char* text);
    1682             : 
    1683             :   /**
    1684             :       Delete a node associated with this document.
    1685             :       It will be unlinked from the DOM.
    1686             :   */
    1687             :   void DeleteNode(XMLNode* node);
    1688             : 
    1689             :   /// Clears the error flags.
    1690             :   void ClearError();
    1691             : 
    1692             :   /// Return true if there was an error parsing the document.
    1693             :   bool Error() const { return _errorID != XML_SUCCESS; }
    1694             :   /// Return the errorID.
    1695             :   XMLError ErrorID() const { return _errorID; }
    1696             :   const char* ErrorName() const;
    1697             :   static const char* ErrorIDToName(XMLError errorID);
    1698             : 
    1699             :   /** Returns a "long form" error description. A hopefully helpful
    1700             :       diagnostic with location, line number, and/or additional info.
    1701             :   */
    1702             :   const char* ErrorStr() const;
    1703             : 
    1704             :   /// A (trivial) utility function that prints the ErrorStr() to stdout.
    1705             :   void PrintError() const;
    1706             : 
    1707             :   /// Return the line where the error occurred, or zero if unknown.
    1708             :   int ErrorLineNum() const { return _errorLineNum; }
    1709             : 
    1710             :   /// Clear the document, resetting it to the initial state.
    1711             :   void Clear();
    1712             : 
    1713             :   /**
    1714             :           Copies this document to a target document.
    1715             :           The target will be completely cleared before the copy.
    1716             :           If you want to copy a sub-tree, see XMLNode::DeepClone().
    1717             : 
    1718             :           NOTE: that the 'target' must be non-null.
    1719             :   */
    1720             :   void DeepCopy(XMLDocument* target) const;
    1721             : 
    1722             :   // internal
    1723             :   char* Identify(char* p, XMLNode** node, bool first);
    1724             : 
    1725             :   // internal
    1726             :   void MarkInUse(const XMLNode* const);
    1727             : 
    1728             :   virtual XMLNode* ShallowClone(XMLDocument* /*document*/) const override { return 0; }
    1729             :   virtual bool ShallowEqual(const XMLNode* /*compare*/) const override { return false; }
    1730             : 
    1731             : private:
    1732             :   XMLDocument(const XMLDocument&);    // not supported
    1733             :   void operator=(const XMLDocument&); // not supported
    1734             : 
    1735             :   bool _writeBOM;
    1736             :   bool _processEntities;
    1737             :   XMLError _errorID;
    1738             :   Whitespace _whitespaceMode;
    1739             :   mutable StrPair _errorStr;
    1740             :   int _errorLineNum;
    1741             :   char* _charBuffer;
    1742             :   int _parseCurLineNum;
    1743             :   int _parsingDepth;
    1744             :   // Memory tracking does add some overhead.
    1745             :   // However, the code assumes that you don't
    1746             :   // have a bunch of unlinked nodes around.
    1747             :   // Therefore it takes less memory to track
    1748             :   // in the document vs. a linked list in the XMLNode,
    1749             :   // and the performance is the same.
    1750             :   DynArray<XMLNode*, 10> _unlinked;
    1751             : 
    1752             :   MemPoolT<sizeof(XMLElement)> _elementPool;
    1753             :   MemPoolT<sizeof(XMLAttribute)> _attributePool;
    1754             :   MemPoolT<sizeof(XMLText)> _textPool;
    1755             :   MemPoolT<sizeof(XMLComment)> _commentPool;
    1756             : 
    1757             :   static const char* _errorNames[XML_ERROR_COUNT];
    1758             : 
    1759             :   void Parse();
    1760             : 
    1761             :   void SetError(XMLError error, int lineNum, const char* format, ...);
    1762             : 
    1763             :   // Something of an obvious security hole, once it was discovered.
    1764             :   // Either an ill-formed XML or an excessively deep one can overflow
    1765             :   // the stack. Track stack depth, and error out if needed.
    1766             :   class DepthTracker {
    1767             :   public:
    1768             :     explicit DepthTracker(XMLDocument* document) {
    1769             :       this->_document = document;
    1770             :       document->PushDepth();
    1771             :     }
    1772             :     ~DepthTracker() { _document->PopDepth(); }
    1773             : 
    1774             :   private:
    1775             :     XMLDocument* _document;
    1776             :   };
    1777             :   void PushDepth();
    1778             :   void PopDepth();
    1779             : 
    1780             :   template <class NodeType, int PoolElementSize> NodeType* CreateUnlinkedNode(MemPoolT<PoolElementSize>& pool);
    1781             : };
    1782             : 
    1783             : template <class NodeType, int PoolElementSize> inline NodeType* XMLDocument::CreateUnlinkedNode(MemPoolT<PoolElementSize>& pool) {
    1784             :   TIXMLASSERT(sizeof(NodeType) == PoolElementSize);
    1785             :   TIXMLASSERT(sizeof(NodeType) == pool.ItemSize());
    1786             :   NodeType* returnNode = new (pool.Alloc()) NodeType(this);
    1787             :   TIXMLASSERT(returnNode);
    1788             :   returnNode->_memPool = &pool;
    1789             : 
    1790             :   _unlinked.Push(returnNode);
    1791             :   return returnNode;
    1792             : }
    1793             : 
    1794             : /**
    1795             :         A XMLHandle is a class that wraps a node pointer with null checks; this is
    1796             :         an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
    1797             :         DOM structure. It is a separate utility class.
    1798             : 
    1799             :         Take an example:
    1800             :         @verbatim
    1801             :         <Document>
    1802             :                 <Element attributeA = "valueA">
    1803             :                         <Child attributeB = "value1" />
    1804             :                         <Child attributeB = "value2" />
    1805             :                 </Element>
    1806             :         </Document>
    1807             :         @endverbatim
    1808             : 
    1809             :         Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
    1810             :         easy to write a *lot* of code that looks like:
    1811             : 
    1812             :         @verbatim
    1813             :         XMLElement* root = document.FirstChildElement( "Document" );
    1814             :         if ( root )
    1815             :         {
    1816             :                 XMLElement* element = root->FirstChildElement( "Element" );
    1817             :                 if ( element )
    1818             :                 {
    1819             :                         XMLElement* child = element->FirstChildElement( "Child" );
    1820             :                         if ( child )
    1821             :                         {
    1822             :                                 XMLElement* child2 = child->NextSiblingElement( "Child" );
    1823             :                                 if ( child2 )
    1824             :                                 {
    1825             :                                         // Finally do something useful.
    1826             :         @endverbatim
    1827             : 
    1828             :         And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
    1829             :         of such code. A XMLHandle checks for null pointers so it is perfectly safe
    1830             :         and correct to use:
    1831             : 
    1832             :         @verbatim
    1833             :         XMLHandle docHandle( &document );
    1834             :         XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
    1835             :         if ( child2 )
    1836             :         {
    1837             :                 // do something useful
    1838             :         @endverbatim
    1839             : 
    1840             :         Which is MUCH more concise and useful.
    1841             : 
    1842             :         It is also safe to copy handles - internally they are nothing more than node pointers.
    1843             :         @verbatim
    1844             :         XMLHandle handleCopy = handle;
    1845             :         @endverbatim
    1846             : 
    1847             :         See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
    1848             : */
    1849             : class TINYXML2_LIB XMLHandle {
    1850             : public:
    1851             :   /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
    1852             :   explicit XMLHandle(XMLNode* node) : _node(node) {}
    1853             :   /// Create a handle from a node.
    1854             :   explicit XMLHandle(XMLNode& node) : _node(&node) {}
    1855             :   /// Copy constructor
    1856             :   XMLHandle(const XMLHandle& ref) : _node(ref._node) {}
    1857             :   /// Assignment
    1858             :   XMLHandle& operator=(const XMLHandle& ref) {
    1859             :     _node = ref._node;
    1860             :     return *this;
    1861             :   }
    1862             : 
    1863             :   /// Get the first child of this handle.
    1864             :   XMLHandle FirstChild() { return XMLHandle(_node ? _node->FirstChild() : 0); }
    1865             :   /// Get the first child element of this handle.
    1866             :   XMLHandle FirstChildElement(const char* name = 0) { return XMLHandle(_node ? _node->FirstChildElement(name) : 0); }
    1867             :   /// Get the last child of this handle.
    1868             :   XMLHandle LastChild() { return XMLHandle(_node ? _node->LastChild() : 0); }
    1869             :   /// Get the last child element of this handle.
    1870             :   XMLHandle LastChildElement(const char* name = 0) { return XMLHandle(_node ? _node->LastChildElement(name) : 0); }
    1871             :   /// Get the previous sibling of this handle.
    1872             :   XMLHandle PreviousSibling() { return XMLHandle(_node ? _node->PreviousSibling() : 0); }
    1873             :   /// Get the previous sibling element of this handle.
    1874             :   XMLHandle PreviousSiblingElement(const char* name = 0) { return XMLHandle(_node ? _node->PreviousSiblingElement(name) : 0); }
    1875             :   /// Get the next sibling of this handle.
    1876             :   XMLHandle NextSibling() { return XMLHandle(_node ? _node->NextSibling() : 0); }
    1877             :   /// Get the next sibling element of this handle.
    1878             :   XMLHandle NextSiblingElement(const char* name = 0) { return XMLHandle(_node ? _node->NextSiblingElement(name) : 0); }
    1879             : 
    1880             :   /// Safe cast to XMLNode. This can return null.
    1881             :   XMLNode* ToNode() { return _node; }
    1882             :   /// Safe cast to XMLElement. This can return null.
    1883             :   XMLElement* ToElement() { return (_node ? _node->ToElement() : 0); }
    1884             :   /// Safe cast to XMLText. This can return null.
    1885             :   XMLText* ToText() { return (_node ? _node->ToText() : 0); }
    1886             :   /// Safe cast to XMLUnknown. This can return null.
    1887             :   XMLUnknown* ToUnknown() { return (_node ? _node->ToUnknown() : 0); }
    1888             :   /// Safe cast to XMLDeclaration. This can return null.
    1889             :   XMLDeclaration* ToDeclaration() { return (_node ? _node->ToDeclaration() : 0); }
    1890             : 
    1891             : private:
    1892             :   XMLNode* _node;
    1893             : };
    1894             : 
    1895             : /**
    1896             :         A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
    1897             :         same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
    1898             : */
    1899             : class TINYXML2_LIB XMLConstHandle {
    1900             : public:
    1901             :   explicit XMLConstHandle(const XMLNode* node) : _node(node) {}
    1902             :   explicit XMLConstHandle(const XMLNode& node) : _node(&node) {}
    1903             :   XMLConstHandle(const XMLConstHandle& ref) : _node(ref._node) {}
    1904             : 
    1905             :   XMLConstHandle& operator=(const XMLConstHandle& ref) {
    1906             :     _node = ref._node;
    1907             :     return *this;
    1908             :   }
    1909             : 
    1910             :   const XMLConstHandle FirstChild() const { return XMLConstHandle(_node ? _node->FirstChild() : 0); }
    1911             :   const XMLConstHandle FirstChildElement(const char* name = 0) const { return XMLConstHandle(_node ? _node->FirstChildElement(name) : 0); }
    1912             :   const XMLConstHandle LastChild() const { return XMLConstHandle(_node ? _node->LastChild() : 0); }
    1913             :   const XMLConstHandle LastChildElement(const char* name = 0) const { return XMLConstHandle(_node ? _node->LastChildElement(name) : 0); }
    1914             :   const XMLConstHandle PreviousSibling() const { return XMLConstHandle(_node ? _node->PreviousSibling() : 0); }
    1915             :   const XMLConstHandle PreviousSiblingElement(const char* name = 0) const { return XMLConstHandle(_node ? _node->PreviousSiblingElement(name) : 0); }
    1916             :   const XMLConstHandle NextSibling() const { return XMLConstHandle(_node ? _node->NextSibling() : 0); }
    1917             :   const XMLConstHandle NextSiblingElement(const char* name = 0) const { return XMLConstHandle(_node ? _node->NextSiblingElement(name) : 0); }
    1918             : 
    1919             :   const XMLNode* ToNode() const { return _node; }
    1920             :   const XMLElement* ToElement() const { return (_node ? _node->ToElement() : 0); }
    1921             :   const XMLText* ToText() const { return (_node ? _node->ToText() : 0); }
    1922             :   const XMLUnknown* ToUnknown() const { return (_node ? _node->ToUnknown() : 0); }
    1923             :   const XMLDeclaration* ToDeclaration() const { return (_node ? _node->ToDeclaration() : 0); }
    1924             : 
    1925             : private:
    1926             :   const XMLNode* _node;
    1927             : };
    1928             : 
    1929             : /**
    1930             :         Printing functionality. The XMLPrinter gives you more
    1931             :         options than the XMLDocument::Print() method.
    1932             : 
    1933             :         It can:
    1934             :         -# Print to memory.
    1935             :         -# Print to a file you provide.
    1936             :         -# Print XML without a XMLDocument.
    1937             : 
    1938             :         Print to Memory
    1939             : 
    1940             :         @verbatim
    1941             :         XMLPrinter printer;
    1942             :         doc.Print( &printer );
    1943             :         SomeFunction( printer.CStr() );
    1944             :         @endverbatim
    1945             : 
    1946             :         Print to a File
    1947             : 
    1948             :         You provide the file pointer.
    1949             :         @verbatim
    1950             :         XMLPrinter printer( fp );
    1951             :         doc.Print( &printer );
    1952             :         @endverbatim
    1953             : 
    1954             :         Print without a XMLDocument
    1955             : 
    1956             :         When loading, an XML parser is very useful. However, sometimes
    1957             :         when saving, it just gets in the way. The code is often set up
    1958             :         for streaming, and constructing the DOM is just overhead.
    1959             : 
    1960             :         The Printer supports the streaming case. The following code
    1961             :         prints out a trivially simple XML file without ever creating
    1962             :         an XML document.
    1963             : 
    1964             :         @verbatim
    1965             :         XMLPrinter printer( fp );
    1966             :         printer.OpenElement( "foo" );
    1967             :         printer.PushAttribute( "foo", "bar" );
    1968             :         printer.CloseElement();
    1969             :         @endverbatim
    1970             : */
    1971             : class TINYXML2_LIB XMLPrinter : public XMLVisitor {
    1972             : public:
    1973             :   /** Construct the printer. If the FILE* is specified,
    1974             :       this will print to the FILE. Else it will print
    1975             :       to memory, and the result is available in CStr().
    1976             :       If 'compact' is set to true, then output is created
    1977             :       with only required whitespace and newlines.
    1978             :   */
    1979             :   XMLPrinter(FILE* file = 0, bool compact = false, int depth = 0);
    1980             :   virtual ~XMLPrinter() {}
    1981             : 
    1982             :   /** If streaming, write the BOM and declaration. */
    1983             :   void PushHeader(bool writeBOM, bool writeDeclaration);
    1984             :   /** If streaming, start writing an element.
    1985             :       The element must be closed with CloseElement()
    1986             :   */
    1987             :   void OpenElement(const char* name, bool compactMode = false);
    1988             :   /// If streaming, add an attribute to an open element.
    1989             :   void PushAttribute(const char* name, const char* value);
    1990             :   void PushAttribute(const char* name, int value);
    1991             :   void PushAttribute(const char* name, unsigned value);
    1992             :   void PushAttribute(const char* name, int64_t value);
    1993             :   void PushAttribute(const char* name, uint64_t value);
    1994             :   void PushAttribute(const char* name, bool value);
    1995             :   void PushAttribute(const char* name, double value);
    1996             :   /// If streaming, close the Element.
    1997             :   virtual void CloseElement(bool compactMode = false);
    1998             : 
    1999             :   /// Add a text node.
    2000             :   void PushText(const char* text, bool cdata = false);
    2001             :   /// Add a text node from an integer.
    2002             :   void PushText(int value);
    2003             :   /// Add a text node from an unsigned.
    2004             :   void PushText(unsigned value);
    2005             :   /// Add a text node from a signed 64bit integer.
    2006             :   void PushText(int64_t value);
    2007             :   /// Add a text node from an unsigned 64bit integer.
    2008             :   void PushText(uint64_t value);
    2009             :   /// Add a text node from a bool.
    2010             :   void PushText(bool value);
    2011             :   /// Add a text node from a float.
    2012             :   void PushText(float value);
    2013             :   /// Add a text node from a double.
    2014             :   void PushText(double value);
    2015             : 
    2016             :   /// Add a comment
    2017             :   void PushComment(const char* comment);
    2018             : 
    2019             :   void PushDeclaration(const char* value);
    2020             :   void PushUnknown(const char* value);
    2021             : 
    2022             :   virtual bool VisitEnter(const XMLDocument& /*doc*/) override;
    2023             :   virtual bool VisitExit(const XMLDocument& /*doc*/) override { return true; }
    2024             : 
    2025             :   virtual bool VisitEnter(const XMLElement& element, const XMLAttribute* attribute) override;
    2026             :   virtual bool VisitExit(const XMLElement& element) override;
    2027             : 
    2028             :   virtual bool Visit(const XMLText& text) override;
    2029             :   virtual bool Visit(const XMLComment& comment) override;
    2030             :   virtual bool Visit(const XMLDeclaration& declaration) override;
    2031             :   virtual bool Visit(const XMLUnknown& unknown) override;
    2032             : 
    2033             :   /**
    2034             :       If in print to memory mode, return a pointer to
    2035             :       the XML file in memory.
    2036             :   */
    2037             :   const char* CStr() const { return _buffer.Mem(); }
    2038             :   /**
    2039             :       If in print to memory mode, return the size
    2040             :       of the XML file in memory. (Note the size returned
    2041             :       includes the terminating null.)
    2042             :   */
    2043             :   int CStrSize() const { return _buffer.Size(); }
    2044             :   /**
    2045             :       If in print to memory mode, reset the buffer to the
    2046             :       beginning.
    2047             :   */
    2048             :   void ClearBuffer(bool resetToFirstElement = true) {
    2049             :     _buffer.Clear();
    2050             :     _buffer.Push(0);
    2051             :     _firstElement = resetToFirstElement;
    2052             :   }
    2053             : 
    2054             : protected:
    2055             :   virtual bool CompactMode(const XMLElement&) { return _compactMode; }
    2056             : 
    2057             :   /** Prints out the space before an element. You may override to change
    2058             :       the space and tabs used. A PrintSpace() override should call Print().
    2059             :   */
    2060             :   virtual void PrintSpace(int depth);
    2061             :   virtual void Print(const char* format, ...);
    2062             :   virtual void Write(const char* data, size_t size);
    2063             :   virtual void Putc(char ch);
    2064             : 
    2065             :   inline void Write(const char* data) { Write(data, strlen(data)); }
    2066             : 
    2067             :   void SealElementIfJustOpened();
    2068             :   bool _elementJustOpened;
    2069             :   DynArray<const char*, 10> _stack;
    2070             : 
    2071             : private:
    2072             :   /**
    2073             :      Prepares to write a new node. This includes sealing an element that was
    2074             :      just opened, and writing any whitespace necessary if not in compact mode.
    2075             :    */
    2076             :   void PrepareForNewNode(bool compactMode);
    2077             :   void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities.
    2078             : 
    2079             :   bool _firstElement;
    2080             :   FILE* _fp;
    2081             :   int _depth;
    2082             :   int _textDepth;
    2083             :   bool _processEntities;
    2084             :   bool _compactMode;
    2085             : 
    2086             :   enum { ENTITY_RANGE = 64, BUF_SIZE = 200 };
    2087             :   bool _entityFlag[ENTITY_RANGE];
    2088             :   bool _restrictedEntityFlag[ENTITY_RANGE];
    2089             : 
    2090             :   DynArray<char, 20> _buffer;
    2091             : 
    2092             :   // Prohibit cloning, intentionally not implemented
    2093             :   XMLPrinter(const XMLPrinter&);
    2094             :   XMLPrinter& operator=(const XMLPrinter&);
    2095             : };
    2096             : 
    2097             : } // namespace tinyxml2
    2098             : 
    2099             : #if defined(_MSC_VER)
    2100             : #pragma warning(pop)
    2101             : #endif
    2102             : 
    2103             : #endif // TINYXML2_INCLUDED

Generated by: LCOV version 1.14