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

            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           80 :   XMLError QueryIntAttribute(const char* name, int* value) const {
    1196           80 :     const XMLAttribute* a = FindAttribute(name);
    1197           80 :     if (!a) {
    1198              :       return XML_NO_ATTRIBUTE;
    1199              :     }
    1200           80 :     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           68 :   XMLError QueryDoubleAttribute(const char* name, double* value) const {
    1240           68 :     const XMLAttribute* a = FindAttribute(name);
    1241           68 :     if (!a) {
    1242              :       return XML_NO_ATTRIBUTE;
    1243              :     }
    1244           64 :     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 2.0-1