blob: 8136d82bd271b7b50edcffa934d1a6907d3fdc52 [file] [log] [blame]
Lee Thomason50f97b22012-02-11 16:33:40 -08001#ifndef TINYXML_INCLUDED
U-Lama\Leee13c3e62011-12-28 14:36:55 -08002#define TINYXML2_INCLUDED
3
Lee Thomason2c85a712012-01-31 08:24:24 -08004/*
5 TODO
Lee Thomason50adb4c2012-02-13 15:07:09 -08006 X const and non-const versions of API
Lee Thomason455c9d42012-02-06 09:14:14 -08007 X memory pool the class construction
Lee Thomason50adb4c2012-02-13 15:07:09 -08008 X attribute accessors
9 X node navigation
Lee Thomason2c85a712012-01-31 08:24:24 -080010 - handles
Lee Thomason50adb4c2012-02-13 15:07:09 -080011 X visit pattern - change streamer?
12 X make constructors protected
13 X hide copy constructor
14 X hide = operator
Lee Thomason56bdd022012-02-09 18:16:58 -080015 X UTF8 support: isAlpha, etc.
U-Stream\Leeae25a442012-02-17 17:48:16 -080016 X string buffer for sets. (Grr.)
Lee Thomason1ff38e02012-02-14 18:18:16 -080017 - MS BOM
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080018 X print to memory buffer
Lee Thomason50adb4c2012-02-13 15:07:09 -080019 - tests from xml1
Lee Thomason1ff38e02012-02-14 18:18:16 -080020 - xml1 tests especially UTF-8
Lee Thomason50adb4c2012-02-13 15:07:09 -080021 - perf test: xml1
22 - perf test: xenowar
U-Stream\Leeae25a442012-02-17 17:48:16 -080023 - test: load(char*)
24 - test: load(FILE*)
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080025 - rename declaration
26 - rename streamer
Lee Thomason2c85a712012-01-31 08:24:24 -080027*/
28
U-Lama\Lee4cee6112011-12-31 14:58:18 -080029#include <limits.h>
Lee Thomasonce0763e2012-01-11 15:43:54 -080030#include <ctype.h>
31#include <stdio.h>
Lee Thomason2c85a712012-01-31 08:24:24 -080032#include <memory.h>
U-Lama\Lee4cee6112011-12-31 14:58:18 -080033
34#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
35 #ifndef DEBUG
36 #define DEBUG
37 #endif
38#endif
39
40
41#if defined(DEBUG)
42 #if defined(_MSC_VER)
43 #define TIXMLASSERT( x ) if ( !(x)) { _asm { int 3 } } //if ( !(x)) WinDebugBreak()
44 #elif defined (ANDROID_NDK)
45 #include <android/log.h>
46 #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
47 #else
48 #include <assert.h>
49 #define TIXMLASSERT assert
50 #endif
51#else
52 #define TIXMLASSERT( x ) {}
53#endif
54
U-Lama\Leee13c3e62011-12-28 14:36:55 -080055
Lee Thomason1a1d4a72012-02-15 09:09:25 -080056// Deprecated library function hell. Compilers want to use the
57// new safe versions. This probably doesn't fully address the problem,
58// but it gets closer. There are too many compilers for me to fully
59// test. If you get compilation troubles, undefine TIXML_SAFE
60
61#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
62 // Microsoft visual studio, version 2005 and higher.
63 #define TIXML_SNPRINTF _snprintf_s
64 #define TIXML_SSCANF sscanf_s
65#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
66 // Microsoft visual studio, version 6 and higher.
67 //#pragma message( "Using _sn* functions." )
68 #define TIXML_SNPRINTF _snprintf
69 #define TIXML_SSCANF sscanf
70#elif defined(__GNUC__) && (__GNUC__ >= 3 )
U-Stream\Leeae25a442012-02-17 17:48:16 -080071 // GCC version 3 and higher
Lee Thomason1a1d4a72012-02-15 09:09:25 -080072 //#warning( "Using sn* functions." )
73 #define TIXML_SNPRINTF snprintf
74 #define TIXML_SSCANF sscanf
75#else
76 #define TIXML_SNPRINTF snprintf
77 #define TIXML_SSCANF sscanf
78#endif
Lee Thomason1ff38e02012-02-14 18:18:16 -080079
80
U-Lama\Leee13c3e62011-12-28 14:36:55 -080081namespace tinyxml2
82{
Lee Thomasonce0763e2012-01-11 15:43:54 -080083class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -080084class XMLElement;
85class XMLAttribute;
86class XMLComment;
87class XMLNode;
Lee Thomason5492a1c2012-01-23 15:32:10 -080088class XMLText;
Lee Thomason50f97b22012-02-11 16:33:40 -080089class XMLDeclaration;
90class XMLUnknown;
U-Lama\Leee13c3e62011-12-28 14:36:55 -080091
Lee Thomason5cae8972012-01-24 18:03:07 -080092class XMLStreamer;
93
U-Stream\Leeae25a442012-02-17 17:48:16 -080094/*
95 A class that wraps strings. Normally stores the start and end
96 pointers into the XML file itself, and will apply normalization
97 and entity transalion if actually read. Can also store (and memory
98 manage) a traditional char[]
99*/
Lee Thomason39ede242012-01-20 11:27:56 -0800100class StrPair
101{
Lee Thomasond34f52c2012-01-20 12:55:24 -0800102public:
Lee Thomason39ede242012-01-20 11:27:56 -0800103 enum {
Lee Thomasone4422302012-01-20 17:59:50 -0800104 NEEDS_ENTITY_PROCESSING = 0x01,
Lee Thomason18d68bd2012-01-26 18:17:26 -0800105 NEEDS_NEWLINE_NORMALIZATION = 0x02,
106
107 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
108 ATTRIBUTE_NAME = 0,
109 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
110 COMMENT = NEEDS_NEWLINE_NORMALIZATION,
Lee Thomason39ede242012-01-20 11:27:56 -0800111 };
112
113 StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800114 ~StrPair();
115
Lee Thomasone4422302012-01-20 17:59:50 -0800116 void Set( char* start, char* end, int flags ) {
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800117 Reset();
Lee Thomason39ede242012-01-20 11:27:56 -0800118 this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
119 }
120 const char* GetStr();
Lee Thomasone4422302012-01-20 17:59:50 -0800121 bool Empty() const { return start == end; }
Lee Thomason39ede242012-01-20 11:27:56 -0800122
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800123 void SetInternedStr( const char* str ) { Reset(); this->start = (char*) str; }
124 void SetStr( const char* str, int flags=0 );
125
Lee Thomason56bdd022012-02-09 18:16:58 -0800126 char* ParseText( char* in, const char* endTag, int strFlags );
127 char* ParseName( char* in );
128
Lee Thomason2c85a712012-01-31 08:24:24 -0800129
Lee Thomason39ede242012-01-20 11:27:56 -0800130private:
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800131 void Reset();
132
Lee Thomasone4422302012-01-20 17:59:50 -0800133 enum {
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800134 NEEDS_FLUSH = 0x100,
135 NEEDS_DELETE = 0x200
Lee Thomasone4422302012-01-20 17:59:50 -0800136 };
137
Lee Thomason39ede242012-01-20 11:27:56 -0800138 // After parsing, if *end != 0, it can be set to zero.
139 int flags;
Lee Thomasone4422302012-01-20 17:59:50 -0800140 char* start;
Lee Thomason39ede242012-01-20 11:27:56 -0800141 char* end;
142};
143
U-Lama\Lee560bd472011-12-28 19:42:49 -0800144
U-Stream\Leeae25a442012-02-17 17:48:16 -0800145/*
146 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
147 Has a small initial memory pool, so that low or no usage will not
148 cause a call to new/delete
149*/
Lee Thomason2c85a712012-01-31 08:24:24 -0800150template <class T, int INIT>
151class DynArray
152{
153public:
154 DynArray< T, INIT >()
155 {
156 mem = pool;
157 allocated = INIT;
158 size = 0;
159 }
160 ~DynArray()
161 {
162 if ( mem != pool ) {
163 delete mem;
164 }
165 }
166 void Push( T t )
167 {
168 EnsureCapacity( size+1 );
169 mem[size++] = t;
170 }
171
172 T* PushArr( int count )
173 {
174 EnsureCapacity( size+count );
175 T* ret = &mem[size];
176 size += count;
177 return ret;
178 }
179 T Pop() {
180 return mem[--size];
181 }
182 void PopArr( int count )
183 {
184 TIXMLASSERT( size >= count );
185 size -= count;
186 }
187
U-Stream\Leeae25a442012-02-17 17:48:16 -0800188 bool Empty() const { return size == 0; }
189 T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
190 const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
191 int Size() const { return size; }
192 int Capacity() const { return allocated; }
193 const T* Mem() const { return mem; }
194 T* Mem() { return mem; }
Lee Thomason2c85a712012-01-31 08:24:24 -0800195
196
197private:
198 void EnsureCapacity( int cap ) {
199 if ( cap > allocated ) {
200 int newAllocated = cap * 2;
201 T* newMem = new T[newAllocated];
202 memcpy( newMem, mem, sizeof(T)*size ); // warning: not using constructors, only works for PODs
203 if ( mem != pool ) delete [] mem;
204 mem = newMem;
205 allocated = newAllocated;
206 }
207 }
208
209 T* mem;
210 T pool[INIT];
211 int allocated; // objects allocated
212 int size; // number objects in use
213};
214
Lee Thomason50adb4c2012-02-13 15:07:09 -0800215
U-Stream\Leeae25a442012-02-17 17:48:16 -0800216/*
217 Parent virtual class a a pool for fast allocation
218 and deallocation of objects.
219*/
Lee Thomasond1983222012-02-06 08:41:24 -0800220class MemPool
221{
222public:
223 MemPool() {}
224 virtual ~MemPool() {}
225
226 virtual int ItemSize() const = 0;
227 virtual void* Alloc() = 0;
228 virtual void Free( void* ) = 0;
229};
230
Lee Thomason50adb4c2012-02-13 15:07:09 -0800231
U-Stream\Leeae25a442012-02-17 17:48:16 -0800232/*
233 Template child class to create pools of the correct type.
234*/
Lee Thomasond1983222012-02-06 08:41:24 -0800235template< int SIZE >
236class MemPoolT : public MemPool
237{
238public:
Lee Thomason455c9d42012-02-06 09:14:14 -0800239 MemPoolT() : root(0), currentAllocs(0), nAllocs(0), maxAllocs(0) {}
Lee Thomasond1983222012-02-06 08:41:24 -0800240 ~MemPoolT() {
241 // Delete the blocks.
242 for( int i=0; i<blockPtrs.Size(); ++i ) {
243 delete blockPtrs[i];
244 }
245 }
246
247 virtual int ItemSize() const { return SIZE; }
Lee Thomason455c9d42012-02-06 09:14:14 -0800248 int CurrentAllocs() const { return currentAllocs; }
Lee Thomasond1983222012-02-06 08:41:24 -0800249
250 virtual void* Alloc() {
251 if ( !root ) {
252 // Need a new block.
253 Block* block = new Block();
254 blockPtrs.Push( block );
255
256 for( int i=0; i<COUNT-1; ++i ) {
257 block->chunk[i].next = &block->chunk[i+1];
258 }
259 block->chunk[COUNT-1].next = 0;
260 root = block->chunk;
261 }
262 void* result = root;
263 root = root->next;
Lee Thomason455c9d42012-02-06 09:14:14 -0800264
265 ++currentAllocs;
266 if ( currentAllocs > maxAllocs ) maxAllocs = currentAllocs;
267 nAllocs++;
Lee Thomasond1983222012-02-06 08:41:24 -0800268 return result;
269 }
270 virtual void Free( void* mem ) {
271 if ( !mem ) return;
Lee Thomason455c9d42012-02-06 09:14:14 -0800272 --currentAllocs;
Lee Thomasond1983222012-02-06 08:41:24 -0800273 Chunk* chunk = (Chunk*)mem;
274 memset( chunk, 0xfe, sizeof(Chunk) );
275 chunk->next = root;
276 root = chunk;
277 }
Lee Thomason455c9d42012-02-06 09:14:14 -0800278 void Trace( const char* name ) {
Lee Thomason43f59302012-02-06 18:18:11 -0800279 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
280 name, maxAllocs, maxAllocs*SIZE/1024, currentAllocs, SIZE, nAllocs, blockPtrs.Size() );
Lee Thomason455c9d42012-02-06 09:14:14 -0800281 }
Lee Thomasond1983222012-02-06 08:41:24 -0800282
283private:
284 enum { COUNT = 1024/SIZE };
285 union Chunk {
286 Chunk* next;
287 char mem[SIZE];
288 };
289 struct Block {
290 Chunk chunk[COUNT];
291 };
292 DynArray< Block*, 10 > blockPtrs;
293 Chunk* root;
Lee Thomason455c9d42012-02-06 09:14:14 -0800294
295 int currentAllocs;
296 int nAllocs;
297 int maxAllocs;
Lee Thomasond1983222012-02-06 08:41:24 -0800298};
299
Lee Thomason2c85a712012-01-31 08:24:24 -0800300
Lee Thomason56bdd022012-02-09 18:16:58 -0800301
302/**
303 Implements the interface to the "Visitor pattern" (see the Accept() method.)
304 If you call the Accept() method, it requires being passed a XMLVisitor
305 class to handle callbacks. For nodes that contain other nodes (Document, Element)
306 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
307 are simply called with Visit().
308
309 If you return 'true' from a Visit method, recursive parsing will continue. If you return
310 false, <b>no children of this node or its sibilings</b> will be Visited.
311
312 All flavors of Visit methods have a default implementation that returns 'true' (continue
313 visiting). You need to only override methods that are interesting to you.
314
315 Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
316
317 You should never change the document from a callback.
318
319 @sa XMLNode::Accept()
320*/
321class XMLVisitor
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800322{
323public:
Lee Thomason56bdd022012-02-09 18:16:58 -0800324 virtual ~XMLVisitor() {}
Lee Thomasond1983222012-02-06 08:41:24 -0800325
Lee Thomason56bdd022012-02-09 18:16:58 -0800326 /// Visit a document.
327 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { return true; }
328 /// Visit a document.
329 virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
330
331 /// Visit an element.
332 virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { return true; }
333 /// Visit an element.
334 virtual bool VisitExit( const XMLElement& /*element*/ ) { return true; }
335
336 /// Visit a declaration
Lee Thomason50f97b22012-02-11 16:33:40 -0800337 virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { return true; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800338 /// Visit a text node
339 virtual bool Visit( const XMLText& /*text*/ ) { return true; }
340 /// Visit a comment node
341 virtual bool Visit( const XMLComment& /*comment*/ ) { return true; }
342 /// Visit an unknown node
Lee Thomason50f97b22012-02-11 16:33:40 -0800343 virtual bool Visit( const XMLUnknown& /*unknown*/ ) { return true; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800344};
345
346
U-Stream\Leeae25a442012-02-17 17:48:16 -0800347/*
348 Utility functionality.
349*/
Lee Thomason56bdd022012-02-09 18:16:58 -0800350class XMLUtil
351{
Lee Thomasond1983222012-02-06 08:41:24 -0800352public:
Lee Thomason56bdd022012-02-09 18:16:58 -0800353 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
354 // correct, but simple, and usually works.
U-Stream\Leeae25a442012-02-17 17:48:16 -0800355 static const char* SkipWhiteSpace( const char* p ) { while( !IsUTF8Continuation(*p) && isspace( *p ) ) { ++p; } return p; }
356 static char* SkipWhiteSpace( char* p ) { while( !IsUTF8Continuation(*p) && isspace( *p ) ) { ++p; } return p; }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800357
358 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
359 int n = 0;
Lee Thomasond34f52c2012-01-20 12:55:24 -0800360 if ( p == q ) {
361 return true;
362 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800363 while( *p && *q && *p == *q && n<nChar ) {
364 ++p; ++q; ++n;
365 }
366 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
367 return true;
368 }
369 return false;
370 }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800371 inline static int IsUTF8Continuation( unsigned char p ) { return p & 0x80; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800372 inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte < 128 ) ? isalnum( anyByte ) : 1; }
373 inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte < 128 ) ? isalpha( anyByte ) : 1; }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800374
375 static const char* ReadBOM( const char* p, bool* hasBOM );
376 // p is the starting location,
377 // the UTF-8 value of the entity will be placed in value, and length filled in.
Lee Thomasond6277762012-02-22 16:00:12 -0800378 static const char* GetCharacterRef( const char* p, char* value, int* length );
379 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800380};
381
Lee Thomason5cae8972012-01-24 18:03:07 -0800382
Lee Thomasond1983222012-02-06 08:41:24 -0800383class XMLNode
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800384{
385 friend class XMLDocument;
386 friend class XMLElement;
387public:
Lee Thomason751da522012-02-10 08:50:51 -0800388 const XMLDocument* GetDocument() const { return document; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800389 XMLDocument* GetDocument() { return document; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800390
Lee Thomason56bdd022012-02-09 18:16:58 -0800391 virtual XMLElement* ToElement() { return 0; }
392 virtual XMLText* ToText() { return 0; }
393 virtual XMLComment* ToComment() { return 0; }
394 virtual XMLDocument* ToDocument() { return 0; }
Lee Thomason50f97b22012-02-11 16:33:40 -0800395 virtual XMLDeclaration* ToDeclaration() { return 0; }
396 virtual XMLUnknown* ToUnknown() { return 0; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800397
Lee Thomason50f97b22012-02-11 16:33:40 -0800398 virtual const XMLElement* ToElement() const { return 0; }
399 virtual const XMLText* ToText() const { return 0; }
400 virtual const XMLComment* ToComment() const { return 0; }
401 virtual const XMLDocument* ToDocument() const { return 0; }
402 virtual const XMLDeclaration* ToDeclaration() const { return 0; }
403 virtual const XMLUnknown* ToUnknown() const { return 0; }
Lee Thomason751da522012-02-10 08:50:51 -0800404
Lee Thomason2c85a712012-01-31 08:24:24 -0800405 const char* Value() const { return value.GetStr(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800406 void SetValue( const char* val, bool staticMem=false );
Lee Thomason2c85a712012-01-31 08:24:24 -0800407
Lee Thomason751da522012-02-10 08:50:51 -0800408 const XMLNode* Parent() const { return parent; }
409 XMLNode* Parent() { return parent; }
410
Lee Thomason50f97b22012-02-11 16:33:40 -0800411 /// Returns true if this node has no children.
412 bool NoChildren() const { return !firstChild; }
Lee Thomason751da522012-02-10 08:50:51 -0800413
Lee Thomason56bdd022012-02-09 18:16:58 -0800414 const XMLNode* FirstChild() const { return firstChild; }
415 XMLNode* FirstChild() { return firstChild; }
416 const XMLElement* FirstChildElement( const char* value=0 ) const;
417 XMLElement* FirstChildElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value )); }
Lee Thomason3f57d272012-01-11 15:30:03 -0800418
Lee Thomason56bdd022012-02-09 18:16:58 -0800419 const XMLNode* LastChild() const { return lastChild; }
420 XMLNode* LastChild() { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800421
Lee Thomason56bdd022012-02-09 18:16:58 -0800422 const XMLElement* LastChildElement( const char* value=0 ) const;
423 XMLElement* LastChildElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) ); }
424
425 const XMLNode* PreviousSibling() const { return prev; }
426 XMLNode* PreviousSibling() { return prev; }
427
428 const XMLNode* PreviousSiblingElement( const char* value=0 ) const ;
429 XMLNode* PreviousSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) ); }
430
431 const XMLNode* NextSibling() const { return next; }
432 XMLNode* NextSibling() { return next; }
433
434 const XMLNode* NextSiblingElement( const char* value=0 ) const;
435 XMLNode* NextSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) ); }
436
Lee Thomason1ff38e02012-02-14 18:18:16 -0800437 /**
438
439 Tests: Programmatic DOM
440 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800441 XMLNode* InsertEndChild( XMLNode* addThis );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800442 /**
443
444 Tests: Programmatic DOM
445 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800446 XMLNode* InsertFirstChild( XMLNode* addThis );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800447 /**
448
449 Tests: Programmatic DOM
450 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800451 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
452
U-Stream\Leeae25a442012-02-17 17:48:16 -0800453 /**
454 Tests: All (used by destructor)
455 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800456 void ClearChildren();
U-Stream\Leeae25a442012-02-17 17:48:16 -0800457
458 /**
459 Tests: Progammatic DOM
460 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800461 void DeleteChild( XMLNode* node );
462
463 virtual bool Accept( XMLVisitor* visitor ) const = 0;
Lee Thomason56bdd022012-02-09 18:16:58 -0800464
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800465 virtual char* ParseDeep( char*, StrPair* );
Lee Thomason3f57d272012-01-11 15:30:03 -0800466
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800467protected:
468 XMLNode( XMLDocument* );
Lee Thomasond1983222012-02-06 08:41:24 -0800469 virtual ~XMLNode();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800470 XMLNode( const XMLNode& ); // not supported
471 void operator=( const XMLNode& ); // not supported
Lee Thomasond1983222012-02-06 08:41:24 -0800472
Lee Thomason3f57d272012-01-11 15:30:03 -0800473 XMLDocument* document;
474 XMLNode* parent;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800475 mutable StrPair value;
Lee Thomason3f57d272012-01-11 15:30:03 -0800476
477 XMLNode* firstChild;
478 XMLNode* lastChild;
479
480 XMLNode* prev;
481 XMLNode* next;
482
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800483private:
Lee Thomasond1983222012-02-06 08:41:24 -0800484 MemPool* memPool;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800485 void Unlink( XMLNode* child );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800486};
487
488
Lee Thomason5492a1c2012-01-23 15:32:10 -0800489class XMLText : public XMLNode
490{
Lee Thomason2c85a712012-01-31 08:24:24 -0800491 friend class XMLBase;
492 friend class XMLDocument;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800493public:
Lee Thomason56bdd022012-02-09 18:16:58 -0800494 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800495
Lee Thomason751da522012-02-10 08:50:51 -0800496 virtual XMLText* ToText() { return this; }
497 virtual const XMLText* ToText() const { return this; }
Lee Thomason5492a1c2012-01-23 15:32:10 -0800498
Lee Thomason50f97b22012-02-11 16:33:40 -0800499 void SetCData( bool value ) { isCData = true; }
500 bool CData() const { return isCData; }
501
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800502 char* ParseDeep( char*, StrPair* endTag );
Lee Thomason5492a1c2012-01-23 15:32:10 -0800503
504protected:
Lee Thomason50f97b22012-02-11 16:33:40 -0800505 XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {}
506 virtual ~XMLText() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800507 XMLText( const XMLText& ); // not supported
508 void operator=( const XMLText& ); // not supported
Lee Thomason5492a1c2012-01-23 15:32:10 -0800509
510private:
Lee Thomason50f97b22012-02-11 16:33:40 -0800511 bool isCData;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800512};
513
514
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800515class XMLComment : public XMLNode
516{
Lee Thomason2c85a712012-01-31 08:24:24 -0800517 friend class XMLDocument;
Lee Thomason3f57d272012-01-11 15:30:03 -0800518public:
Lee Thomason751da522012-02-10 08:50:51 -0800519 virtual XMLComment* ToComment() { return this; }
520 virtual const XMLComment* ToComment() const { return this; }
Lee Thomasonce0763e2012-01-11 15:43:54 -0800521
Lee Thomason56bdd022012-02-09 18:16:58 -0800522 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800523
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800524 char* ParseDeep( char*, StrPair* endTag );
Lee Thomasonce0763e2012-01-11 15:43:54 -0800525
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800526protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800527 XMLComment( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800528 virtual ~XMLComment();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800529 XMLComment( const XMLComment& ); // not supported
530 void operator=( const XMLComment& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800531
Lee Thomason3f57d272012-01-11 15:30:03 -0800532private:
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800533};
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800534
535
Lee Thomason50f97b22012-02-11 16:33:40 -0800536class XMLDeclaration : public XMLNode
537{
538 friend class XMLDocument;
539public:
540 virtual XMLDeclaration* ToDeclaration() { return this; }
541 virtual const XMLDeclaration* ToDeclaration() const { return this; }
542
543 virtual bool Accept( XMLVisitor* visitor ) const;
544
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800545 char* ParseDeep( char*, StrPair* endTag );
Lee Thomason50f97b22012-02-11 16:33:40 -0800546
547protected:
548 XMLDeclaration( XMLDocument* doc );
549 virtual ~XMLDeclaration();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800550 XMLDeclaration( const XMLDeclaration& ); // not supported
551 void operator=( const XMLDeclaration& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800552};
553
554
555class XMLUnknown : public XMLNode
556{
557 friend class XMLDocument;
558public:
559 virtual XMLUnknown* ToUnknown() { return this; }
560 virtual const XMLUnknown* ToUnknown() const { return this; }
561
562 virtual bool Accept( XMLVisitor* visitor ) const;
563
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800564 char* ParseDeep( char*, StrPair* endTag );
Lee Thomason50f97b22012-02-11 16:33:40 -0800565
566protected:
567 XMLUnknown( XMLDocument* doc );
568 virtual ~XMLUnknown();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800569 XMLUnknown( const XMLUnknown& ); // not supported
570 void operator=( const XMLUnknown& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800571};
572
573
Lee Thomason1ff38e02012-02-14 18:18:16 -0800574enum {
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800575 XML_NO_ERROR = 0,
576
Lee Thomason1ff38e02012-02-14 18:18:16 -0800577 NO_ATTRIBUTE,
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800578 WRONG_ATTRIBUTE_TYPE,
579
580 ERROR_FILE_NOT_FOUND,
581 ERROR_ELEMENT_MISMATCH,
582 ERROR_PARSING_ELEMENT,
583 ERROR_PARSING_ATTRIBUTE,
584 ERROR_IDENTIFYING_TAG,
585 ERROR_PARSING_TEXT,
586 ERROR_PARSING_CDATA,
587 ERROR_PARSING_COMMENT,
588 ERROR_PARSING_DECLARATION,
Lee Thomasond6277762012-02-22 16:00:12 -0800589 ERROR_PARSING_UNKNOWN,
590 ERROR_EMPTY_DOCUMENT,
Lee Thomason (grinliz)784607f2012-02-24 16:23:40 -0800591 ERROR_MISMATCHED_ELEMENT,
592 ERROR_PARSING
Lee Thomason1ff38e02012-02-14 18:18:16 -0800593};
594
595
Lee Thomason56bdd022012-02-09 18:16:58 -0800596class XMLAttribute
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800597{
598 friend class XMLElement;
599public:
Lee Thomason751da522012-02-10 08:50:51 -0800600 const char* Name() const { return name.GetStr(); }
601 const char* Value() const { return value.GetStr(); }
602 const XMLAttribute* Next() const { return next; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800603
U-Stream\Leeae25a442012-02-17 17:48:16 -0800604 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( &i ); return i; }
605 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( &i ); return i; }
606 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( &b ); return b; }
607 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( &d ); return d; }
608 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( &f ); return f; }
609
Lee Thomason1ff38e02012-02-14 18:18:16 -0800610 int QueryIntAttribute( int* value ) const;
611 int QueryUnsignedAttribute( unsigned int* value ) const;
612 int QueryBoolAttribute( bool* value ) const;
613 int QueryDoubleAttribute( double* value ) const;
614 int QueryFloatAttribute( float* value ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800615
Lee Thomason1ff38e02012-02-14 18:18:16 -0800616 void SetAttribute( const char* value );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800617 void SetAttribute( int value );
618 void SetAttribute( unsigned value );
619 void SetAttribute( bool value );
620 void SetAttribute( double value );
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800621 void SetAttribute( float value );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800622
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800623private:
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800624 enum { BUF_SIZE = 200 };
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800625
Lee Thomasond1983222012-02-06 08:41:24 -0800626 XMLAttribute( XMLElement* element ) : next( 0 ) {}
627 virtual ~XMLAttribute() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800628 XMLAttribute( const XMLAttribute& ); // not supported
629 void operator=( const XMLAttribute& ); // not supported
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800630 void SetName( const char* name );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800631
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800632 char* ParseDeep( char* p );
633
Lee Thomason751da522012-02-10 08:50:51 -0800634 mutable StrPair name;
635 mutable StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800636 XMLAttribute* next;
Lee Thomason43f59302012-02-06 18:18:11 -0800637 MemPool* memPool;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800638};
639
640
641class XMLElement : public XMLNode
642{
Lee Thomason2c85a712012-01-31 08:24:24 -0800643 friend class XMLBase;
644 friend class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800645public:
Lee Thomason2c85a712012-01-31 08:24:24 -0800646 const char* Name() const { return Value(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800647 void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800648
Lee Thomason751da522012-02-10 08:50:51 -0800649 virtual XMLElement* ToElement() { return this; }
650 virtual const XMLElement* ToElement() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800651 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800652
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800653 const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); }
Lee Thomason751da522012-02-10 08:50:51 -0800654
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800655 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; }
656 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
657 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; }
658 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; }
659 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; }
660
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800661 int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); }
662 int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); }
663 int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); }
664 int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); }
665 int QueryFloatAttribute( const char* name, float* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryFloatAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800666
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800667 void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
668 void SetAttribute( const char* name, int value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
669 void SetAttribute( const char* name, unsigned value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
670 void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
671 void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800672
U-Stream\Leeae25a442012-02-17 17:48:16 -0800673 /**
674 Tests: Programmatic DOM
675 */
676 void DeleteAttribute( const char* name );
Lee Thomason751da522012-02-10 08:50:51 -0800677
678 const XMLAttribute* FirstAttribute() const { return rootAttribute; }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800679 const XMLAttribute* FindAttribute( const char* name ) const;
Lee Thomason751da522012-02-10 08:50:51 -0800680
Lee Thomason50f97b22012-02-11 16:33:40 -0800681 const char* GetText() const;
Lee Thomason751da522012-02-10 08:50:51 -0800682
Lee Thomason2c85a712012-01-31 08:24:24 -0800683 // internal:
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800684 enum {
685 OPEN, // <foo>
686 CLOSED, // <foo/>
687 CLOSING // </foo>
688 };
689 int ClosingType() const { return closingType; }
Lee Thomason (grinliz)7468f112012-02-24 08:56:50 -0800690 char* ParseDeep( char* p, StrPair* endTag );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800691
Lee Thomason50adb4c2012-02-13 15:07:09 -0800692private:
Lee Thomason2c85a712012-01-31 08:24:24 -0800693 XMLElement( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800694 virtual ~XMLElement();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800695 XMLElement( const XMLElement& ); // not supported
696 void operator=( const XMLElement& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800697
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800698 XMLAttribute* FindAttribute( const char* name );
699 XMLAttribute* FindOrCreateAttribute( const char* name );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800700 void LinkAttribute( XMLAttribute* attrib );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800701 char* ParseAttributes( char* p );
Lee Thomason67d61312012-01-24 16:01:51 -0800702
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800703 int closingType;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800704 XMLAttribute* rootAttribute;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800705};
706
707
Lee Thomason67d61312012-01-24 16:01:51 -0800708class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800709{
Lee Thomasond1983222012-02-06 08:41:24 -0800710 friend class XMLElement;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800711public:
Lee Thomason18d68bd2012-01-26 18:17:26 -0800712 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800713 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800714
Lee Thomason751da522012-02-10 08:50:51 -0800715 virtual XMLDocument* ToDocument() { return this; }
716 virtual const XMLDocument* ToDocument() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800717
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800718 int Parse( const char* xml );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800719 int LoadFile( const char* filename );
720 int LoadFile( FILE* );
721 void SaveFile( const char* filename );
722
723 bool HasBOM() const { return writeBOM; }
Lee Thomasond6277762012-02-22 16:00:12 -0800724 XMLElement* RootElement() { return FirstChildElement(); }
725 const XMLElement* RootElement() const { return FirstChildElement(); }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800726
Lee Thomason5cae8972012-01-24 18:03:07 -0800727 void Print( XMLStreamer* streamer=0 );
Lee Thomason56bdd022012-02-09 18:16:58 -0800728 virtual bool Accept( XMLVisitor* visitor ) const;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800729
Lee Thomason1ff38e02012-02-14 18:18:16 -0800730 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800731 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800732 */
Lee Thomason2c85a712012-01-31 08:24:24 -0800733 XMLElement* NewElement( const char* name );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800734 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800735 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800736 */
737 XMLComment* NewComment( const char* comment );
738 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800739 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800740 */
741 XMLText* NewText( const char* text );
Lee Thomason2c85a712012-01-31 08:24:24 -0800742
U-Stream\Leeae25a442012-02-17 17:48:16 -0800743 /**
744 Tests: Programmatic DOM
745 */
746 void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); }
747
Lee Thomason67d61312012-01-24 16:01:51 -0800748 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800749
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800750 bool Error() const { return errorID != XML_NO_ERROR; }
751 int ErrorID() const { return errorID; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800752 const char* GetErrorStr1() const { return errorStr1; }
753 const char* GetErrorStr2() const { return errorStr2; }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800754 void PrintError() const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800755
Lee Thomasond1983222012-02-06 08:41:24 -0800756 char* Identify( char* p, XMLNode** node );
Lee Thomason2c85a712012-01-31 08:24:24 -0800757
Lee Thomason3f57d272012-01-11 15:30:03 -0800758private:
Lee Thomason50adb4c2012-02-13 15:07:09 -0800759 XMLDocument( const XMLDocument& ); // not supported
760 void operator=( const XMLDocument& ); // not supported
Lee Thomason18d68bd2012-01-26 18:17:26 -0800761 void InitDocument();
762
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800763 bool writeBOM;
Lee Thomason7c913cd2012-01-26 18:32:34 -0800764 int errorID;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800765 const char* errorStr1;
766 const char* errorStr2;
767 char* charBuffer;
Lee Thomasond1983222012-02-06 08:41:24 -0800768
769 MemPoolT< sizeof(XMLElement) > elementPool;
770 MemPoolT< sizeof(XMLAttribute) > attributePool;
771 MemPoolT< sizeof(XMLText) > textPool;
772 MemPoolT< sizeof(XMLComment) > commentPool;
Lee Thomason5cae8972012-01-24 18:03:07 -0800773};
774
Lee Thomason7c913cd2012-01-26 18:32:34 -0800775
Lee Thomason751da522012-02-10 08:50:51 -0800776class XMLStreamer : public XMLVisitor
Lee Thomason5cae8972012-01-24 18:03:07 -0800777{
778public:
U-Stream\Leeae25a442012-02-17 17:48:16 -0800779 XMLStreamer( FILE* file=0 );
Lee Thomason5cae8972012-01-24 18:03:07 -0800780 ~XMLStreamer() {}
781
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800782 void PushHeader( bool writeBOM, bool writeDeclaration );
Lee Thomason56bdd022012-02-09 18:16:58 -0800783 void OpenElement( const char* name );
Lee Thomason5cae8972012-01-24 18:03:07 -0800784 void PushAttribute( const char* name, const char* value );
785 void CloseElement();
786
Lee Thomason50f97b22012-02-11 16:33:40 -0800787 void PushText( const char* text, bool cdata=false );
Lee Thomason5cae8972012-01-24 18:03:07 -0800788 void PushComment( const char* comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800789 void PushDeclaration( const char* value );
790 void PushUnknown( const char* value );
Lee Thomason5cae8972012-01-24 18:03:07 -0800791
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800792 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
Lee Thomason751da522012-02-10 08:50:51 -0800793 virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
794
795 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
796 virtual bool VisitExit( const XMLElement& element );
797
798 virtual bool Visit( const XMLText& text );
799 virtual bool Visit( const XMLComment& comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800800 virtual bool Visit( const XMLDeclaration& declaration );
801 virtual bool Visit( const XMLUnknown& unknown );
Lee Thomason751da522012-02-10 08:50:51 -0800802
U-Stream\Leeae25a442012-02-17 17:48:16 -0800803 const char* CStr() const { return buffer.Mem(); }
Lee Thomason751da522012-02-10 08:50:51 -0800804
Lee Thomason5cae8972012-01-24 18:03:07 -0800805private:
806 void SealElement();
807 void PrintSpace( int depth );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800808 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
U-Stream\Leeae25a442012-02-17 17:48:16 -0800809 void Print( const char* format, ... );
Lee Thomason5cae8972012-01-24 18:03:07 -0800810
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800811 bool elementJustOpened;
812 bool firstElement;
Lee Thomason5cae8972012-01-24 18:03:07 -0800813 FILE* fp;
814 int depth;
Lee Thomason56bdd022012-02-09 18:16:58 -0800815 int textDepth;
816
Lee Thomason857b8682012-01-25 17:50:25 -0800817 enum {
Lee Thomason951d8832012-01-26 08:47:06 -0800818 ENTITY_RANGE = 64
Lee Thomason857b8682012-01-25 17:50:25 -0800819 };
820 bool entityFlag[ENTITY_RANGE];
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800821 bool restrictedEntityFlag[ENTITY_RANGE];
Lee Thomason5cae8972012-01-24 18:03:07 -0800822
Lee Thomason2c85a712012-01-31 08:24:24 -0800823 DynArray< const char*, 10 > stack;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800824 DynArray< char, 20 > buffer, accumulator;
Lee Thomason5cae8972012-01-24 18:03:07 -0800825};
826
827
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800828}; // tinyxml2
829
U-Lama\Lee560bd472011-12-28 19:42:49 -0800830
831
U-Stream\Leeae25a442012-02-17 17:48:16 -0800832#endif // TINYXML2_INCLUDED