MaMiCo 1.2
Loading...
Searching...
No Matches
tinyxml2.h
1/*
2Original code by Lee Thomason (www.grinninglizard.com)
3
4This software is provided 'as-is', without any express or implied
5warranty. In no event will the authors be held liable for any
6damages arising from the use of this software.
7
8Permission is granted to anyone to use this software for any
9purpose, including commercial applications, and to alter it and
10redistribute it freely, subject to the following restrictions:
11
121. The origin of this software must not be misrepresented; you must
13not claim that you wrote the original software. If you use this
14software in a product, an acknowledgment in the product documentation
15would be appreciated but is not required.
16
172. Altered source versions must be plainly marked as such, and
18must not be misrepresented as being the original software.
19
203. This notice may not be removed or altered from any source
21distribution.
22*/
23
24#ifndef TINYXML2_INCLUDED
25#define TINYXML2_INCLUDED
26
27#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
28#include <ctype.h>
29#include <limits.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#if defined(__PS3__)
34#include <stddef.h>
35#endif
36#else
37#include <cctype>
38#include <climits>
39#include <cstdio>
40#include <cstdlib>
41#include <cstring>
42#endif
43#include <stdint.h>
44
45/*
46 gcc:
47 g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
48
49 Formatting, Artistic Style:
50 AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
51*/
52
53#if defined(_DEBUG) || defined(__DEBUG__)
54#ifndef TINYXML2_DEBUG
55#define TINYXML2_DEBUG
56#endif
57#endif
58
59#ifdef _MSC_VER
60#pragma warning(push)
61#pragma warning(disable : 4251)
62#endif
63
64#ifdef _MSC_VER
65#ifdef TINYXML2_EXPORT
66#define TINYXML2_LIB __declspec(dllexport)
67#elif defined(TINYXML2_IMPORT)
68#define TINYXML2_LIB __declspec(dllimport)
69#else
70#define TINYXML2_LIB
71#endif
72#elif __GNUC__ >= 4
73#define TINYXML2_LIB __attribute__((visibility("default")))
74#else
75#define TINYXML2_LIB
76#endif
77
78#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*/
110static const int TIXML2_MAJOR_VERSION = 10;
111static const int TIXML2_MINOR_VERSION = 0;
112static 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.
123static const int TINYXML2_MAX_ELEMENT_DEPTH = 500;
124
125namespace tinyxml2 {
126class XMLDocument;
127class XMLElement;
128class XMLAttribute;
129class XMLComment;
130class XMLText;
131class XMLDeclaration;
132class XMLUnknown;
133class 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*/
143class TINYXML2_LIB StrPair {
144public:
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
187private:
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*/
205template <class T, int INITIAL_SIZE> class DynArray {
206public:
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
288private:
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*/
318class MemPool {
319public:
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*/
332template <int ITEM_SIZE> class MemPoolT : public MemPool {
333public:
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
413private:
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
452class TINYXML2_LIB XMLVisitor {
453public:
454 virtual ~XMLVisitor() {}
455
457 virtual bool VisitEnter(const XMLDocument& /*doc*/) { return true; }
459 virtual bool VisitExit(const XMLDocument& /*doc*/) { return true; }
460
462 virtual bool VisitEnter(const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/) { return true; }
464 virtual bool VisitExit(const XMLElement& /*element*/) { return true; }
465
467 virtual bool Visit(const XMLDeclaration& /*declaration*/) { return true; }
469 virtual bool Visit(const XMLText& /*text*/) { return true; }
471 virtual bool Visit(const XMLComment& /*comment*/) { return true; }
473 virtual bool Visit(const XMLUnknown& /*unknown*/) { return true; }
474};
475
476// WARNING: must match XMLDocument::_errorNames[]
477enum 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*/
504class TINYXML2_LIB XMLUtil {
505public:
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
584private:
585 static const char* writeBoolTrue;
586 static const char* writeBoolFalse;
587};
588
614class TINYXML2_LIB XMLNode {
615 friend class XMLDocument;
616 friend class XMLElement;
617
618public:
620 const XMLDocument* GetDocument() const {
621 TIXMLASSERT(_document);
622 return _document;
623 }
624
625 XMLDocument* GetDocument() {
626 TIXMLASSERT(_document);
627 return _document;
628 }
629
631 virtual XMLElement* ToElement() { return 0; }
633 virtual XMLText* ToText() { return 0; }
635 virtual XMLComment* ToComment() { return 0; }
637 virtual XMLDocument* ToDocument() { return 0; }
639 virtual XMLDeclaration* ToDeclaration() { return 0; }
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
665 const char* Value() const;
666
670 void SetValue(const char* val, bool staticMem = false);
671
673 int GetLineNum() const { return _parseLineNum; }
674
676 const XMLNode* Parent() const { return _parent; }
677
678 XMLNode* Parent() { return _parent; }
679
681 bool NoChildren() const { return !_firstChild; }
682
684 const XMLNode* FirstChild() const { return _firstChild; }
685
686 XMLNode* FirstChild() { return _firstChild; }
687
691 const XMLElement* FirstChildElement(const char* name = 0) const;
692
693 XMLElement* FirstChildElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement(name)); }
694
696 const XMLNode* LastChild() const { return _lastChild; }
697
698 XMLNode* LastChild() { return _lastChild; }
699
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
708 const XMLNode* PreviousSibling() const { return _prev; }
709
710 XMLNode* PreviousSibling() { return _prev; }
711
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
718 const XMLNode* NextSibling() const { return _next; }
719
720 XMLNode* NextSibling() { return _next; }
721
723 const XMLElement* NextSiblingElement(const char* name = 0) const;
724
725 XMLElement* NextSiblingElement(const char* name = 0) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement(name)); }
726
734 XMLNode* InsertEndChild(XMLNode* addThis);
735
736 XMLNode* LinkEndChild(XMLNode* addThis) { return InsertEndChild(addThis); }
744 XMLNode* InsertFirstChild(XMLNode* addThis);
753 XMLNode* InsertAfterChild(XMLNode* afterThis, XMLNode* addThis);
754
759
763 void DeleteChild(XMLNode* node);
764
774 virtual XMLNode* ShallowClone(XMLDocument* document) const = 0;
775
789 XMLNode* DeepClone(XMLDocument* target) const;
790
797 virtual bool ShallowEqual(const XMLNode* compare) const = 0;
798
821 virtual bool Accept(XMLVisitor* visitor) const = 0;
822
828 void SetUserData(void* userData) { _userData = userData; }
829
835 void* GetUserData() const { return _userData; }
836
837protected:
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
856private:
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
879class TINYXML2_LIB XMLText : public XMLNode {
880 friend class XMLDocument;
881
882public:
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
889 void SetCData(bool isCData) { _isCData = isCData; }
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
896protected:
897 explicit XMLText(XMLDocument* doc) : XMLNode(doc), _isCData(false) {}
898 virtual ~XMLText() {}
899
900 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
901
902private:
903 bool _isCData;
904
905 XMLText(const XMLText&); // not supported
906 XMLText& operator=(const XMLText&); // not supported
907};
908
910class TINYXML2_LIB XMLComment : public XMLNode {
911 friend class XMLDocument;
912
913public:
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
922protected:
923 explicit XMLComment(XMLDocument* doc);
924 virtual ~XMLComment();
925
926 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
927
928private:
929 XMLComment(const XMLComment&); // not supported
930 XMLComment& operator=(const XMLComment&); // not supported
931};
932
944class TINYXML2_LIB XMLDeclaration : public XMLNode {
945 friend class XMLDocument;
946
947public:
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
956protected:
957 explicit XMLDeclaration(XMLDocument* doc);
958 virtual ~XMLDeclaration();
959
960 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
961
962private:
963 XMLDeclaration(const XMLDeclaration&); // not supported
964 XMLDeclaration& operator=(const XMLDeclaration&); // not supported
965};
966
974class TINYXML2_LIB XMLUnknown : public XMLNode {
975 friend class XMLDocument;
976
977public:
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
986protected:
987 explicit XMLUnknown(XMLDocument* doc);
988 virtual ~XMLUnknown();
989
990 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
991
992private:
993 XMLUnknown(const XMLUnknown&); // not supported
994 XMLUnknown& operator=(const XMLUnknown&); // not supported
995};
996
1003class TINYXML2_LIB XMLAttribute {
1004 friend class XMLElement;
1005
1006public:
1008 const char* Name() const;
1009
1011 const char* Value() const;
1012
1014 int GetLineNum() const { return _parseLineNum; }
1015
1017 const XMLAttribute* Next() const { return _next; }
1018
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
1042 unsigned UnsignedValue() const {
1043 unsigned i = 0;
1045 return i;
1046 }
1047
1048 bool BoolValue() const {
1049 bool b = false;
1050 QueryBoolValue(&b);
1051 return b;
1052 }
1053
1054 double DoubleValue() const {
1055 double d = 0;
1056 QueryDoubleValue(&d);
1057 return d;
1058 }
1059
1060 float FloatValue() const {
1061 float f = 0;
1062 QueryFloatValue(&f);
1063 return f;
1064 }
1065
1070 XMLError QueryIntValue(int* value) const;
1072 XMLError QueryUnsignedValue(unsigned int* value) const;
1074 XMLError QueryInt64Value(int64_t* value) const;
1076 XMLError QueryUnsigned64Value(uint64_t* value) const;
1078 XMLError QueryBoolValue(bool* value) const;
1080 XMLError QueryDoubleValue(double* value) const;
1082 XMLError QueryFloatValue(float* value) const;
1083
1085 void SetAttribute(const char* value);
1087 void SetAttribute(int value);
1089 void SetAttribute(unsigned value);
1091 void SetAttribute(int64_t value);
1093 void SetAttribute(uint64_t value);
1095 void SetAttribute(bool value);
1097 void SetAttribute(double value);
1099 void SetAttribute(float value);
1100
1101private:
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
1124class TINYXML2_LIB XMLElement : public XMLNode {
1125 friend class XMLDocument;
1126
1127public:
1129 const char* Name() const { return Value(); }
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
1160 const char* Attribute(const char* name, const char* value = 0) const;
1161
1168 int IntAttribute(const char* name, int defaultValue = 0) const;
1170 unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1172 int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1174 uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
1176 bool BoolAttribute(const char* name, bool defaultValue = false) const;
1178 double DoubleAttribute(const char* name, double defaultValue = 0) const;
1180 float FloatAttribute(const char* name, float defaultValue = 0) const;
1181
1195 XMLError QueryIntAttribute(const char* name, int* value) const {
1196 const XMLAttribute* a = FindAttribute(name);
1197 if (!a) {
1198 return XML_NO_ATTRIBUTE;
1199 }
1200 return a->QueryIntValue(value);
1201 }
1202
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
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
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
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
1239 XMLError QueryDoubleAttribute(const char* name, double* value) const {
1240 const XMLAttribute* a = FindAttribute(name);
1241 if (!a) {
1242 return XML_NO_ATTRIBUTE;
1243 }
1244 return a->QueryDoubleValue(value);
1245 }
1246
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
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
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
1299 void SetAttribute(const char* name, const char* value) {
1300 XMLAttribute* a = FindOrCreateAttribute(name);
1301 a->SetAttribute(value);
1302 }
1303
1304 void SetAttribute(const char* name, int value) {
1305 XMLAttribute* a = FindOrCreateAttribute(name);
1306 a->SetAttribute(value);
1307 }
1308
1309 void SetAttribute(const char* name, unsigned value) {
1310 XMLAttribute* a = FindOrCreateAttribute(name);
1311 a->SetAttribute(value);
1312 }
1313
1315 void SetAttribute(const char* name, int64_t value) {
1316 XMLAttribute* a = FindOrCreateAttribute(name);
1317 a->SetAttribute(value);
1318 }
1319
1321 void SetAttribute(const char* name, uint64_t value) {
1322 XMLAttribute* a = FindOrCreateAttribute(name);
1323 a->SetAttribute(value);
1324 }
1325
1327 void SetAttribute(const char* name, bool value) {
1328 XMLAttribute* a = FindOrCreateAttribute(name);
1329 a->SetAttribute(value);
1330 }
1331
1332 void SetAttribute(const char* name, double value) {
1333 XMLAttribute* a = FindOrCreateAttribute(name);
1334 a->SetAttribute(value);
1335 }
1336
1337 void SetAttribute(const char* name, float value) {
1338 XMLAttribute* a = FindOrCreateAttribute(name);
1339 a->SetAttribute(value);
1340 }
1341
1345 void DeleteAttribute(const char* name);
1346
1348 const XMLAttribute* FirstAttribute() const { return _rootAttribute; }
1350 const XMLAttribute* FindAttribute(const char* name) const;
1351
1380 const char* GetText() const;
1381
1416 void SetText(const char* inText);
1418 void SetText(int value);
1420 void SetText(unsigned value);
1422 void SetText(int64_t value);
1424 void SetText(uint64_t value);
1426 void SetText(bool value);
1428 void SetText(double value);
1430 void SetText(float value);
1431
1458 XMLError QueryIntText(int* ival) const;
1460 XMLError QueryUnsignedText(unsigned* uval) const;
1462 XMLError QueryInt64Text(int64_t* uval) const;
1464 XMLError QueryUnsigned64Text(uint64_t* uval) const;
1466 XMLError QueryBoolText(bool* bval) const;
1468 XMLError QueryDoubleText(double* dval) const;
1470 XMLError QueryFloatText(float* fval) const;
1471
1472 int IntText(int defaultValue = 0) const;
1473
1475 unsigned UnsignedText(unsigned defaultValue = 0) const;
1477 int64_t Int64Text(int64_t defaultValue = 0) const;
1479 uint64_t Unsigned64Text(uint64_t defaultValue = 0) const;
1481 bool BoolText(bool defaultValue = false) const;
1483 double DoubleText(double defaultValue = 0) const;
1485 float FloatText(float defaultValue = 0) const;
1486
1491 XMLElement* InsertNewChildElement(const char* name);
1493 XMLComment* InsertNewComment(const char* comment);
1495 XMLText* InsertNewText(const char* text);
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
1511protected:
1512 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) override;
1513
1514private:
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
1533enum Whitespace { PRESERVE_WHITESPACE, COLLAPSE_WHITESPACE, PEDANTIC_WHITESPACE };
1534
1540class 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
1550public:
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
1574 XMLError Parse(const char* xml, size_t nBytes = static_cast<size_t>(-1));
1575
1581 XMLError LoadFile(const char* filename);
1582
1594 XMLError LoadFile(FILE*);
1595
1601 XMLError SaveFile(const char* filename, bool compact = false);
1602
1610 XMLError SaveFile(FILE* fp, bool compact = false);
1611
1612 bool ProcessEntities() const { return _processEntities; }
1613 Whitespace WhitespaceMode() const { return _whitespaceMode; }
1614
1618 bool HasBOM() const { return _writeBOM; }
1621 void SetBOM(bool useBOM) { _writeBOM = useBOM; }
1622
1626 XMLElement* RootElement() { return FirstChildElement(); }
1627 const XMLElement* RootElement() const { return FirstChildElement(); }
1628
1643 void Print(XMLPrinter* streamer = 0) const;
1644 virtual bool Accept(XMLVisitor* visitor) const override;
1645
1651 XMLElement* NewElement(const char* name);
1657 XMLComment* NewComment(const char* comment);
1663 XMLText* NewText(const char* text);
1675 XMLDeclaration* NewDeclaration(const char* text = 0);
1681 XMLUnknown* NewUnknown(const char* text);
1682
1687 void DeleteNode(XMLNode* node);
1688
1691
1693 bool Error() const { return _errorID != XML_SUCCESS; }
1695 XMLError ErrorID() const { return _errorID; }
1696 const char* ErrorName() const;
1697 static const char* ErrorIDToName(XMLError errorID);
1698
1702 const char* ErrorStr() const;
1703
1705 void PrintError() const;
1706
1708 int ErrorLineNum() const { return _errorLineNum; }
1709
1711 void Clear();
1712
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
1731private:
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
1783template <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
1849class TINYXML2_LIB XMLHandle {
1850public:
1852 explicit XMLHandle(XMLNode* node) : _node(node) {}
1854 explicit XMLHandle(XMLNode& node) : _node(&node) {}
1856 XMLHandle(const XMLHandle& ref) : _node(ref._node) {}
1859 _node = ref._node;
1860 return *this;
1861 }
1862
1864 XMLHandle FirstChild() { return XMLHandle(_node ? _node->FirstChild() : 0); }
1866 XMLHandle FirstChildElement(const char* name = 0) { return XMLHandle(_node ? _node->FirstChildElement(name) : 0); }
1868 XMLHandle LastChild() { return XMLHandle(_node ? _node->LastChild() : 0); }
1870 XMLHandle LastChildElement(const char* name = 0) { return XMLHandle(_node ? _node->LastChildElement(name) : 0); }
1872 XMLHandle PreviousSibling() { return XMLHandle(_node ? _node->PreviousSibling() : 0); }
1874 XMLHandle PreviousSiblingElement(const char* name = 0) { return XMLHandle(_node ? _node->PreviousSiblingElement(name) : 0); }
1876 XMLHandle NextSibling() { return XMLHandle(_node ? _node->NextSibling() : 0); }
1878 XMLHandle NextSiblingElement(const char* name = 0) { return XMLHandle(_node ? _node->NextSiblingElement(name) : 0); }
1879
1881 XMLNode* ToNode() { return _node; }
1883 XMLElement* ToElement() { return (_node ? _node->ToElement() : 0); }
1885 XMLText* ToText() { return (_node ? _node->ToText() : 0); }
1887 XMLUnknown* ToUnknown() { return (_node ? _node->ToUnknown() : 0); }
1889 XMLDeclaration* ToDeclaration() { return (_node ? _node->ToDeclaration() : 0); }
1890
1891private:
1892 XMLNode* _node;
1893};
1894
1899class TINYXML2_LIB XMLConstHandle {
1900public:
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
1925private:
1926 const XMLNode* _node;
1927};
1928
1971class TINYXML2_LIB XMLPrinter : public XMLVisitor {
1972public:
1979 XMLPrinter(FILE* file = 0, bool compact = false, int depth = 0);
1980 virtual ~XMLPrinter() {}
1981
1983 void PushHeader(bool writeBOM, bool writeDeclaration);
1987 void OpenElement(const char* name, bool compactMode = false);
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);
1997 virtual void CloseElement(bool compactMode = false);
1998
2000 void PushText(const char* text, bool cdata = false);
2002 void PushText(int value);
2004 void PushText(unsigned value);
2006 void PushText(int64_t value);
2008 void PushText(uint64_t value);
2010 void PushText(bool value);
2012 void PushText(float value);
2014 void PushText(double value);
2015
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
2037 const char* CStr() const { return _buffer.Mem(); }
2043 int CStrSize() const { return _buffer.Size(); }
2048 void ClearBuffer(bool resetToFirstElement = true) {
2049 _buffer.Clear();
2050 _buffer.Push(0);
2051 _firstElement = resetToFirstElement;
2052 }
2053
2054protected:
2055 virtual bool CompactMode(const XMLElement&) { return _compactMode; }
2056
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;
2070
2071private:
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
Definition tinyxml2.h:205
Definition tinyxml2.h:332
Definition tinyxml2.h:318
Definition tinyxml2.h:143
Definition tinyxml2.h:1003
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file.
Definition tinyxml2.h:1014
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition tinyxml2.h:1042
void SetAttribute(uint64_t value)
Set the attribute to value.
float FloatValue() const
Query as a float. See IntValue()
Definition tinyxml2.h:1060
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
void SetAttribute(const char *value)
Set the attribute to a string value.
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
double DoubleValue() const
Query as a double. See IntValue()
Definition tinyxml2.h:1054
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
const char * Name() const
The name of the attribute.
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
XMLError QueryIntValue(int *value) const
void SetAttribute(int64_t value)
Set the attribute to value.
bool BoolValue() const
Query as a boolean. See IntValue()
Definition tinyxml2.h:1048
void SetAttribute(double value)
Set the attribute to value.
const XMLAttribute * Next() const
The next attribute in the list.
Definition tinyxml2.h:1017
const char * Value() const
The value of the attribute.
void SetAttribute(bool value)
Set the attribute to value.
void SetAttribute(int value)
Set the attribute to value.
int IntValue() const
Definition tinyxml2.h:1023
void SetAttribute(unsigned value)
Set the attribute to value.
void SetAttribute(float value)
Set the attribute to value.
XMLError QueryUnsigned64Value(uint64_t *value) const
See QueryIntValue.
Definition tinyxml2.h:910
virtual bool Accept(XMLVisitor *visitor) const override
virtual XMLNode * ShallowClone(XMLDocument *document) const override
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLComment * ToComment() override
Safely cast to a Comment, or null.
Definition tinyxml2.h:914
Definition tinyxml2.h:944
virtual XMLNode * ShallowClone(XMLDocument *document) const override
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLDeclaration * ToDeclaration() override
Safely cast to a Declaration, or null.
Definition tinyxml2.h:948
virtual bool Accept(XMLVisitor *visitor) const override
Definition tinyxml2.h:1540
virtual XMLNode * ShallowClone(XMLDocument *) const override
Definition tinyxml2.h:1728
XMLElement * RootElement()
Definition tinyxml2.h:1626
void SetBOM(bool useBOM)
Definition tinyxml2.h:1621
void PrintError() const
A (trivial) utility function that prints the ErrorStr() to stdout.
virtual XMLDocument * ToDocument() override
Safely cast to a Document, or null.
Definition tinyxml2.h:1555
XMLError LoadFile(const char *filename)
bool HasBOM() const
Definition tinyxml2.h:1618
bool Error() const
Return true if there was an error parsing the document.
Definition tinyxml2.h:1693
XMLComment * NewComment(const char *comment)
XMLElement * NewElement(const char *name)
void ClearError()
Clears the error flags.
XMLUnknown * NewUnknown(const char *text)
int ErrorLineNum() const
Return the line where the error occurred, or zero if unknown.
Definition tinyxml2.h:1708
XMLDocument(bool processEntities=true, Whitespace whitespaceMode=PRESERVE_WHITESPACE)
constructor
XMLError LoadFile(FILE *)
void Clear()
Clear the document, resetting it to the initial state.
XMLError SaveFile(const char *filename, bool compact=false)
virtual bool Accept(XMLVisitor *visitor) const override
void Print(XMLPrinter *streamer=0) const
XMLError SaveFile(FILE *fp, bool compact=false)
void DeleteNode(XMLNode *node)
virtual bool ShallowEqual(const XMLNode *) const override
Definition tinyxml2.h:1729
XMLText * NewText(const char *text)
XMLDeclaration * NewDeclaration(const char *text=0)
const char * ErrorStr() const
XMLError Parse(const char *xml, size_t nBytes=static_cast< size_t >(-1))
void DeepCopy(XMLDocument *target) const
XMLError ErrorID() const
Return the errorID.
Definition tinyxml2.h:1695
Definition tinyxml2.h:1124
const char * GetText() const
double DoubleAttribute(const char *name, double defaultValue=0) const
See IntAttribute()
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition tinyxml2.h:1299
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
XMLError QueryUnsigned64Attribute(const char *name, uint64_t *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1222
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1231
XMLError QueryUnsignedText(unsigned *uval) const
See QueryIntText()
const XMLAttribute * FindAttribute(const char *name) const
Query a specific attribute in the list.
void SetText(const char *inText)
uint64_t Unsigned64Attribute(const char *name, uint64_t defaultValue=0) const
See IntAttribute()
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition tinyxml2.h:1332
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1204
XMLError QueryBoolText(bool *bval) const
See QueryIntText()
float FloatText(float defaultValue=0) const
See QueryIntText()
const char * Attribute(const char *name, const char *value=0) const
unsigned UnsignedText(unsigned defaultValue=0) const
See QueryIntText()
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition tinyxml2.h:1348
void SetText(float value)
Convenience method for setting text inside an element. See SetText() for important limitations.
bool BoolAttribute(const char *name, bool defaultValue=false) const
See IntAttribute()
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition tinyxml2.h:1337
XMLError QueryAttribute(const char *name, int *value) const
Definition tinyxml2.h:1282
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1239
int64_t Int64Attribute(const char *name, int64_t defaultValue=0) const
See IntAttribute()
void SetText(double value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryDoubleText(double *dval) const
See QueryIntText()
bool BoolText(bool defaultValue=false) const
See QueryIntText()
virtual XMLNode * ShallowClone(XMLDocument *document) const override
void SetText(uint64_t value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(int64_t value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(unsigned value)
Convenience method for setting text inside an element. See SetText() for important limitations.
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1213
XMLDeclaration * InsertNewDeclaration(const char *text)
See InsertNewChildElement()
double DoubleText(double defaultValue=0) const
See QueryIntText()
virtual XMLElement * ToElement() override
Safely cast to an Element, or null.
Definition tinyxml2.h:1133
XMLError QueryIntAttribute(const char *name, int *value) const
Definition tinyxml2.h:1195
XMLError QueryIntText(int *ival) const
int IntAttribute(const char *name, int defaultValue=0) const
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition tinyxml2.h:1131
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition tinyxml2.h:1327
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
virtual bool ShallowEqual(const XMLNode *compare) const override
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition tinyxml2.h:1304
XMLComment * InsertNewComment(const char *comment)
See InsertNewChildElement()
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition tinyxml2.h:1315
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
const char * Name() const
Get the name of an element (which is the Value() of the node.)
Definition tinyxml2.h:1129
XMLElement * InsertNewChildElement(const char *name)
XMLError QueryUnsigned64Text(uint64_t *uval) const
See QueryIntText()
XMLText * InsertNewText(const char *text)
See InsertNewChildElement()
virtual bool Accept(XMLVisitor *visitor) const override
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition tinyxml2.h:1247
void SetAttribute(const char *name, uint64_t value)
Sets the named attribute to value.
Definition tinyxml2.h:1321
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition tinyxml2.h:1256
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition tinyxml2.h:1309
void SetText(bool value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void SetText(int value)
Convenience method for setting text inside an element. See SetText() for important limitations.
void DeleteAttribute(const char *name)
uint64_t Unsigned64Text(uint64_t defaultValue=0) const
See QueryIntText()
XMLError QueryFloatText(float *fval) const
See QueryIntText()
XMLUnknown * InsertNewUnknown(const char *text)
See InsertNewChildElement()
unsigned UnsignedAttribute(const char *name, unsigned defaultValue=0) const
See IntAttribute()
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition tinyxml2.h:1872
XMLHandle LastChildElement(const char *name=0)
Get the last child element of this handle.
Definition tinyxml2.h:1870
XMLHandle FirstChild()
Get the first child of this handle.
Definition tinyxml2.h:1864
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition tinyxml2.h:1881
XMLHandle FirstChildElement(const char *name=0)
Get the first child element of this handle.
Definition tinyxml2.h:1866
XMLHandle PreviousSiblingElement(const char *name=0)
Get the previous sibling element of this handle.
Definition tinyxml2.h:1874
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition tinyxml2.h:1889
XMLHandle(XMLNode *node)
Create a handle from any node (at any depth of the tree.) This can be a null pointer.
Definition tinyxml2.h:1852
XMLHandle LastChild()
Get the last child of this handle.
Definition tinyxml2.h:1868
XMLHandle & operator=(const XMLHandle &ref)
Assignment.
Definition tinyxml2.h:1858
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition tinyxml2.h:1854
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition tinyxml2.h:1876
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition tinyxml2.h:1883
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition tinyxml2.h:1885
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition tinyxml2.h:1887
XMLHandle NextSiblingElement(const char *name=0)
Get the next sibling element of this handle.
Definition tinyxml2.h:1878
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition tinyxml2.h:1856
Definition tinyxml2.h:614
void SetUserData(void *userData)
Definition tinyxml2.h:828
const char * Value() const
void SetValue(const char *val, bool staticMem=false)
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition tinyxml2.h:633
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition tinyxml2.h:639
const XMLElement * NextSiblingElement(const char *name=0) const
Get the next (right) sibling element of this node, with an optionally supplied name.
void * GetUserData() const
Definition tinyxml2.h:835
const XMLElement * FirstChildElement(const char *name=0) const
void DeleteChild(XMLNode *node)
XMLNode * DeepClone(XMLDocument *target) const
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition tinyxml2.h:625
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition tinyxml2.h:676
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition tinyxml2.h:635
const XMLElement * LastChildElement(const char *name=0) const
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition tinyxml2.h:637
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition tinyxml2.h:696
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition tinyxml2.h:620
virtual bool ShallowEqual(const XMLNode *compare) const =0
virtual bool Accept(XMLVisitor *visitor) const =0
virtual XMLNode * ShallowClone(XMLDocument *document) const =0
XMLNode * InsertAfterChild(XMLNode *afterThis, XMLNode *addThis)
const XMLNode * PreviousSibling() const
Get the previous (left) sibling node of this node.
Definition tinyxml2.h:708
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition tinyxml2.h:631
const XMLElement * PreviousSiblingElement(const char *name=0) const
Get the previous (left) sibling element of this node, with an optionally supplied name.
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition tinyxml2.h:673
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition tinyxml2.h:641
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition tinyxml2.h:684
bool NoChildren() const
Returns true if this node has no children.
Definition tinyxml2.h:681
XMLNode * InsertFirstChild(XMLNode *addThis)
XMLNode * InsertEndChild(XMLNode *addThis)
const XMLNode * NextSibling() const
Get the next (right) sibling node of this node.
Definition tinyxml2.h:718
Definition tinyxml2.h:1971
virtual void PrintSpace(int depth)
void PushHeader(bool writeBOM, bool writeDeclaration)
void PushText(const char *text, bool cdata=false)
Add a text node.
void PushText(float value)
Add a text node from a float.
void OpenElement(const char *name, bool compactMode=false)
virtual bool VisitExit(const XMLDocument &) override
Visit a document.
Definition tinyxml2.h:2023
virtual bool Visit(const XMLUnknown &unknown) override
Visit an unknown node.
int CStrSize() const
Definition tinyxml2.h:2043
void PushText(int value)
Add a text node from an integer.
void PushText(bool value)
Add a text node from a bool.
virtual bool VisitEnter(const XMLElement &element, const XMLAttribute *attribute) override
Visit an element.
void PushText(uint64_t value)
Add a text node from an unsigned 64bit integer.
virtual bool Visit(const XMLDeclaration &declaration) override
Visit a declaration.
void PushText(unsigned value)
Add a text node from an unsigned.
void ClearBuffer(bool resetToFirstElement=true)
Definition tinyxml2.h:2048
virtual bool VisitEnter(const XMLDocument &) override
Visit a document.
virtual bool Visit(const XMLComment &comment) override
Visit a comment node.
void PrepareForNewNode(bool compactMode)
void PushText(int64_t value)
Add a text node from a signed 64bit integer.
virtual bool VisitExit(const XMLElement &element) override
Visit an element.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
XMLPrinter(FILE *file=0, bool compact=false, int depth=0)
void PushText(double value)
Add a text node from a double.
const char * CStr() const
Definition tinyxml2.h:2037
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
virtual bool Visit(const XMLText &text) override
Visit a text node.
void PushComment(const char *comment)
Add a comment.
Definition tinyxml2.h:879
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLText * ToText() override
Safely cast to Text, or null.
Definition tinyxml2.h:885
virtual XMLNode * ShallowClone(XMLDocument *document) const override
virtual bool Accept(XMLVisitor *visitor) const override
bool CData() const
Returns true if this is a CDATA text element.
Definition tinyxml2.h:891
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition tinyxml2.h:889
Definition tinyxml2.h:974
virtual bool ShallowEqual(const XMLNode *compare) const override
virtual XMLNode * ShallowClone(XMLDocument *document) const override
virtual XMLUnknown * ToUnknown() override
Safely cast to an Unknown, or null.
Definition tinyxml2.h:978
virtual bool Accept(XMLVisitor *visitor) const override
Definition tinyxml2.h:504
Definition tinyxml2.h:452
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition tinyxml2.h:473
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition tinyxml2.h:459
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition tinyxml2.h:464
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition tinyxml2.h:457
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition tinyxml2.h:471
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition tinyxml2.h:467
virtual bool Visit(const XMLText &)
Visit a text node.
Definition tinyxml2.h:469
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition tinyxml2.h:462
Definition tinyxml2.h:421
Definition tinyxml2.h:417