blob: 4792b0945de2f33db2502770156dca179be6eb2d [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 Thomason8a5dfee2012-01-18 17:43:40 -0800374};
375
Lee Thomason5cae8972012-01-24 18:03:07 -0800376
Lee Thomasond1983222012-02-06 08:41:24 -0800377class XMLNode
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800378{
379 friend class XMLDocument;
380 friend class XMLElement;
381public:
Lee Thomason751da522012-02-10 08:50:51 -0800382 const XMLDocument* GetDocument() const { return document; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800383 XMLDocument* GetDocument() { return document; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800384
Lee Thomason56bdd022012-02-09 18:16:58 -0800385 virtual XMLElement* ToElement() { return 0; }
386 virtual XMLText* ToText() { return 0; }
387 virtual XMLComment* ToComment() { return 0; }
388 virtual XMLDocument* ToDocument() { return 0; }
Lee Thomason50f97b22012-02-11 16:33:40 -0800389 virtual XMLDeclaration* ToDeclaration() { return 0; }
390 virtual XMLUnknown* ToUnknown() { return 0; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800391
Lee Thomason50f97b22012-02-11 16:33:40 -0800392 virtual const XMLElement* ToElement() const { return 0; }
393 virtual const XMLText* ToText() const { return 0; }
394 virtual const XMLComment* ToComment() const { return 0; }
395 virtual const XMLDocument* ToDocument() const { return 0; }
396 virtual const XMLDeclaration* ToDeclaration() const { return 0; }
397 virtual const XMLUnknown* ToUnknown() const { return 0; }
Lee Thomason751da522012-02-10 08:50:51 -0800398
Lee Thomason2c85a712012-01-31 08:24:24 -0800399 const char* Value() const { return value.GetStr(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800400 void SetValue( const char* val, bool staticMem=false );
Lee Thomason2c85a712012-01-31 08:24:24 -0800401
Lee Thomason751da522012-02-10 08:50:51 -0800402 const XMLNode* Parent() const { return parent; }
403 XMLNode* Parent() { return parent; }
404
Lee Thomason50f97b22012-02-11 16:33:40 -0800405 /// Returns true if this node has no children.
406 bool NoChildren() const { return !firstChild; }
Lee Thomason751da522012-02-10 08:50:51 -0800407
Lee Thomason56bdd022012-02-09 18:16:58 -0800408 const XMLNode* FirstChild() const { return firstChild; }
409 XMLNode* FirstChild() { return firstChild; }
410 const XMLElement* FirstChildElement( const char* value=0 ) const;
411 XMLElement* FirstChildElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value )); }
Lee Thomason3f57d272012-01-11 15:30:03 -0800412
Lee Thomason56bdd022012-02-09 18:16:58 -0800413 const XMLNode* LastChild() const { return lastChild; }
414 XMLNode* LastChild() { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800415
Lee Thomason56bdd022012-02-09 18:16:58 -0800416 const XMLElement* LastChildElement( const char* value=0 ) const;
417 XMLElement* LastChildElement( const char* value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) ); }
418
419 const XMLNode* PreviousSibling() const { return prev; }
420 XMLNode* PreviousSibling() { return prev; }
421
422 const XMLNode* PreviousSiblingElement( const char* value=0 ) const ;
423 XMLNode* PreviousSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) ); }
424
425 const XMLNode* NextSibling() const { return next; }
426 XMLNode* NextSibling() { return next; }
427
428 const XMLNode* NextSiblingElement( const char* value=0 ) const;
429 XMLNode* NextSiblingElement( const char* value=0 ) { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) ); }
430
Lee Thomason1ff38e02012-02-14 18:18:16 -0800431 /**
432
433 Tests: Programmatic DOM
434 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800435 XMLNode* InsertEndChild( XMLNode* addThis );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800436 /**
437
438 Tests: Programmatic DOM
439 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800440 XMLNode* InsertFirstChild( XMLNode* addThis );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800441 /**
442
443 Tests: Programmatic DOM
444 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800445 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
446
U-Stream\Leeae25a442012-02-17 17:48:16 -0800447 /**
448 Tests: All (used by destructor)
449 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800450 void ClearChildren();
U-Stream\Leeae25a442012-02-17 17:48:16 -0800451
452 /**
453 Tests: Progammatic DOM
454 */
Lee Thomason56bdd022012-02-09 18:16:58 -0800455 void DeleteChild( XMLNode* node );
456
457 virtual bool Accept( XMLVisitor* visitor ) const = 0;
Lee Thomason56bdd022012-02-09 18:16:58 -0800458
Lee Thomason67d61312012-01-24 16:01:51 -0800459 virtual char* ParseDeep( char* );
Lee Thomason67d61312012-01-24 16:01:51 -0800460 virtual bool IsClosingElement() const { return false; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800461
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800462protected:
463 XMLNode( XMLDocument* );
Lee Thomasond1983222012-02-06 08:41:24 -0800464 virtual ~XMLNode();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800465 XMLNode( const XMLNode& ); // not supported
466 void operator=( const XMLNode& ); // not supported
Lee Thomasond1983222012-02-06 08:41:24 -0800467
Lee Thomason3f57d272012-01-11 15:30:03 -0800468 XMLDocument* document;
469 XMLNode* parent;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800470 mutable StrPair value;
Lee Thomason3f57d272012-01-11 15:30:03 -0800471
472 XMLNode* firstChild;
473 XMLNode* lastChild;
474
475 XMLNode* prev;
476 XMLNode* next;
477
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800478private:
Lee Thomasond1983222012-02-06 08:41:24 -0800479 MemPool* memPool;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800480 void Unlink( XMLNode* child );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800481};
482
483
Lee Thomason5492a1c2012-01-23 15:32:10 -0800484class XMLText : public XMLNode
485{
Lee Thomason2c85a712012-01-31 08:24:24 -0800486 friend class XMLBase;
487 friend class XMLDocument;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800488public:
Lee Thomason56bdd022012-02-09 18:16:58 -0800489 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800490
Lee Thomason751da522012-02-10 08:50:51 -0800491 virtual XMLText* ToText() { return this; }
492 virtual const XMLText* ToText() const { return this; }
Lee Thomason5492a1c2012-01-23 15:32:10 -0800493
Lee Thomason50f97b22012-02-11 16:33:40 -0800494 void SetCData( bool value ) { isCData = true; }
495 bool CData() const { return isCData; }
496
Lee Thomason5492a1c2012-01-23 15:32:10 -0800497 char* ParseDeep( char* );
498
499protected:
Lee Thomason50f97b22012-02-11 16:33:40 -0800500 XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {}
501 virtual ~XMLText() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800502 XMLText( const XMLText& ); // not supported
503 void operator=( const XMLText& ); // not supported
Lee Thomason5492a1c2012-01-23 15:32:10 -0800504
505private:
Lee Thomason50f97b22012-02-11 16:33:40 -0800506 bool isCData;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800507};
508
509
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800510class XMLComment : public XMLNode
511{
Lee Thomason2c85a712012-01-31 08:24:24 -0800512 friend class XMLDocument;
Lee Thomason3f57d272012-01-11 15:30:03 -0800513public:
Lee Thomason751da522012-02-10 08:50:51 -0800514 virtual XMLComment* ToComment() { return this; }
515 virtual const XMLComment* ToComment() const { return this; }
Lee Thomasonce0763e2012-01-11 15:43:54 -0800516
Lee Thomason56bdd022012-02-09 18:16:58 -0800517 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800518
Lee Thomasonce0763e2012-01-11 15:43:54 -0800519 char* ParseDeep( char* );
520
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800521protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800522 XMLComment( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800523 virtual ~XMLComment();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800524 XMLComment( const XMLComment& ); // not supported
525 void operator=( const XMLComment& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800526
Lee Thomason3f57d272012-01-11 15:30:03 -0800527private:
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800528};
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800529
530
Lee Thomason50f97b22012-02-11 16:33:40 -0800531class XMLDeclaration : public XMLNode
532{
533 friend class XMLDocument;
534public:
535 virtual XMLDeclaration* ToDeclaration() { return this; }
536 virtual const XMLDeclaration* ToDeclaration() const { return this; }
537
538 virtual bool Accept( XMLVisitor* visitor ) const;
539
540 char* ParseDeep( char* );
541
542protected:
543 XMLDeclaration( XMLDocument* doc );
544 virtual ~XMLDeclaration();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800545 XMLDeclaration( const XMLDeclaration& ); // not supported
546 void operator=( const XMLDeclaration& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800547};
548
549
550class XMLUnknown : public XMLNode
551{
552 friend class XMLDocument;
553public:
554 virtual XMLUnknown* ToUnknown() { return this; }
555 virtual const XMLUnknown* ToUnknown() const { return this; }
556
557 virtual bool Accept( XMLVisitor* visitor ) const;
558
559 char* ParseDeep( char* );
560
561protected:
562 XMLUnknown( XMLDocument* doc );
563 virtual ~XMLUnknown();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800564 XMLUnknown( const XMLUnknown& ); // not supported
565 void operator=( const XMLUnknown& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800566};
567
568
Lee Thomason1ff38e02012-02-14 18:18:16 -0800569enum {
570 ATTRIBUTE_SUCCESS,
571 NO_ATTRIBUTE,
572 WRONG_ATTRIBUTE_TYPE
573};
574
575
Lee Thomason56bdd022012-02-09 18:16:58 -0800576class XMLAttribute
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800577{
578 friend class XMLElement;
579public:
Lee Thomason751da522012-02-10 08:50:51 -0800580 const char* Name() const { return name.GetStr(); }
581 const char* Value() const { return value.GetStr(); }
582 const XMLAttribute* Next() const { return next; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800583
U-Stream\Leeae25a442012-02-17 17:48:16 -0800584 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( &i ); return i; }
585 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( &i ); return i; }
586 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( &b ); return b; }
587 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( &d ); return d; }
588 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( &f ); return f; }
589
Lee Thomason1ff38e02012-02-14 18:18:16 -0800590 int QueryIntAttribute( int* value ) const;
591 int QueryUnsignedAttribute( unsigned int* value ) const;
592 int QueryBoolAttribute( bool* value ) const;
593 int QueryDoubleAttribute( double* value ) const;
594 int QueryFloatAttribute( float* value ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800595
Lee Thomason1ff38e02012-02-14 18:18:16 -0800596 void SetAttribute( const char* value );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800597 void SetAttribute( int value );
598 void SetAttribute( unsigned value );
599 void SetAttribute( bool value );
600 void SetAttribute( double value );
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800601 void SetAttribute( float value );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800602
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800603private:
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800604 enum { BUF_SIZE = 200 };
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800605
Lee Thomasond1983222012-02-06 08:41:24 -0800606 XMLAttribute( XMLElement* element ) : next( 0 ) {}
607 virtual ~XMLAttribute() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800608 XMLAttribute( const XMLAttribute& ); // not supported
609 void operator=( const XMLAttribute& ); // not supported
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800610 void SetName( const char* name );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800611
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800612 char* ParseDeep( char* p );
613
Lee Thomason751da522012-02-10 08:50:51 -0800614 mutable StrPair name;
615 mutable StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800616 XMLAttribute* next;
Lee Thomason43f59302012-02-06 18:18:11 -0800617 MemPool* memPool;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800618};
619
620
621class XMLElement : public XMLNode
622{
Lee Thomason2c85a712012-01-31 08:24:24 -0800623 friend class XMLBase;
624 friend class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800625public:
Lee Thomason2c85a712012-01-31 08:24:24 -0800626 const char* Name() const { return Value(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800627 void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800628
Lee Thomason751da522012-02-10 08:50:51 -0800629 virtual XMLElement* ToElement() { return this; }
630 virtual const XMLElement* ToElement() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800631 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800632
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800633 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 -0800634
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800635 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; }
636 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
637 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; }
638 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; }
639 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; }
640
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800641 int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); }
642 int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); }
643 int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); }
644 int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); }
645 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 -0800646
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800647 void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
648 void SetAttribute( const char* name, int value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
649 void SetAttribute( const char* name, unsigned value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
650 void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
651 void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800652
U-Stream\Leeae25a442012-02-17 17:48:16 -0800653 /**
654 Tests: Programmatic DOM
655 */
656 void DeleteAttribute( const char* name );
Lee Thomason751da522012-02-10 08:50:51 -0800657
658 const XMLAttribute* FirstAttribute() const { return rootAttribute; }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800659 const XMLAttribute* FindAttribute( const char* name ) const;
Lee Thomason751da522012-02-10 08:50:51 -0800660
Lee Thomason50f97b22012-02-11 16:33:40 -0800661 const char* GetText() const;
Lee Thomason751da522012-02-10 08:50:51 -0800662
Lee Thomason2c85a712012-01-31 08:24:24 -0800663 // internal:
664 virtual bool IsClosingElement() const { return closing; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800665 char* ParseDeep( char* p );
666
Lee Thomason50adb4c2012-02-13 15:07:09 -0800667private:
Lee Thomason2c85a712012-01-31 08:24:24 -0800668 XMLElement( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800669 virtual ~XMLElement();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800670 XMLElement( const XMLElement& ); // not supported
671 void operator=( const XMLElement& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800672
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800673 XMLAttribute* FindAttribute( const char* name );
674 XMLAttribute* FindOrCreateAttribute( const char* name );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800675 void LinkAttribute( XMLAttribute* attrib );
Lee Thomason67d61312012-01-24 16:01:51 -0800676 char* ParseAttributes( char* p, bool *closedElement );
677
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800678 bool closing;
679 XMLAttribute* rootAttribute;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800680};
681
682
Lee Thomason67d61312012-01-24 16:01:51 -0800683class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800684{
Lee Thomasond1983222012-02-06 08:41:24 -0800685 friend class XMLElement;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800686public:
Lee Thomason18d68bd2012-01-26 18:17:26 -0800687 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800688 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800689
Lee Thomason751da522012-02-10 08:50:51 -0800690 virtual XMLDocument* ToDocument() { return this; }
691 virtual const XMLDocument* ToDocument() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800692
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800693 int Parse( const char* xml );
694 int Load( const char* filename );
Lee Thomason7c913cd2012-01-26 18:32:34 -0800695 int Load( FILE* );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800696 void Save( const char* filename );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800697
Lee Thomason5cae8972012-01-24 18:03:07 -0800698 void Print( XMLStreamer* streamer=0 );
Lee Thomason56bdd022012-02-09 18:16:58 -0800699 virtual bool Accept( XMLVisitor* visitor ) const;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800700
Lee Thomason1ff38e02012-02-14 18:18:16 -0800701 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800702 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800703 */
Lee Thomason2c85a712012-01-31 08:24:24 -0800704 XMLElement* NewElement( const char* name );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800705 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800706 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800707 */
708 XMLComment* NewComment( const char* comment );
709 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800710 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800711 */
712 XMLText* NewText( const char* text );
Lee Thomason2c85a712012-01-31 08:24:24 -0800713
U-Stream\Leeae25a442012-02-17 17:48:16 -0800714 /**
715 Tests: Programmatic DOM
716 */
717 void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); }
718
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800719 enum {
Lee Thomason18d68bd2012-01-26 18:17:26 -0800720 NO_ERROR = 0,
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800721 ERROR_FILE_NOT_FOUND,
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800722 ERROR_ELEMENT_MISMATCH,
723 ERROR_PARSING_ELEMENT,
Lee Thomason50f97b22012-02-11 16:33:40 -0800724 ERROR_PARSING_ATTRIBUTE,
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800725 ERROR_IDENTIFYING_TAG,
726 ERROR_PARSING_TEXT,
727 ERROR_PARSING_CDATA,
728 ERROR_PARSING_COMMENT,
729 ERROR_PARSING_DECLARATION,
730 ERROR_PARSING_UNKNOWN
731
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800732 };
Lee Thomason67d61312012-01-24 16:01:51 -0800733 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800734
Lee Thomason7c913cd2012-01-26 18:32:34 -0800735 bool Error() const { return errorID != NO_ERROR; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800736 int GetErrorID() const { return errorID; }
737 const char* GetErrorStr1() const { return errorStr1; }
738 const char* GetErrorStr2() const { return errorStr2; }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800739 void PrintError() const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800740
Lee Thomasond1983222012-02-06 08:41:24 -0800741 char* Identify( char* p, XMLNode** node );
Lee Thomason2c85a712012-01-31 08:24:24 -0800742
Lee Thomason3f57d272012-01-11 15:30:03 -0800743private:
Lee Thomason50adb4c2012-02-13 15:07:09 -0800744 XMLDocument( const XMLDocument& ); // not supported
745 void operator=( const XMLDocument& ); // not supported
Lee Thomason18d68bd2012-01-26 18:17:26 -0800746 void InitDocument();
747
Lee Thomason7c913cd2012-01-26 18:32:34 -0800748 int errorID;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800749 const char* errorStr1;
750 const char* errorStr2;
751 char* charBuffer;
Lee Thomasond1983222012-02-06 08:41:24 -0800752
753 MemPoolT< sizeof(XMLElement) > elementPool;
754 MemPoolT< sizeof(XMLAttribute) > attributePool;
755 MemPoolT< sizeof(XMLText) > textPool;
756 MemPoolT< sizeof(XMLComment) > commentPool;
Lee Thomason5cae8972012-01-24 18:03:07 -0800757};
758
Lee Thomason7c913cd2012-01-26 18:32:34 -0800759
Lee Thomason751da522012-02-10 08:50:51 -0800760class XMLStreamer : public XMLVisitor
Lee Thomason5cae8972012-01-24 18:03:07 -0800761{
762public:
U-Stream\Leeae25a442012-02-17 17:48:16 -0800763 XMLStreamer( FILE* file=0 );
Lee Thomason5cae8972012-01-24 18:03:07 -0800764 ~XMLStreamer() {}
765
Lee Thomason56bdd022012-02-09 18:16:58 -0800766 void OpenElement( const char* name );
Lee Thomason5cae8972012-01-24 18:03:07 -0800767 void PushAttribute( const char* name, const char* value );
768 void CloseElement();
769
Lee Thomason50f97b22012-02-11 16:33:40 -0800770 void PushText( const char* text, bool cdata=false );
Lee Thomason5cae8972012-01-24 18:03:07 -0800771 void PushComment( const char* comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800772 void PushDeclaration( const char* value );
773 void PushUnknown( const char* value );
Lee Thomason5cae8972012-01-24 18:03:07 -0800774
Lee Thomason751da522012-02-10 08:50:51 -0800775 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { return true; }
776 virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
777
778 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
779 virtual bool VisitExit( const XMLElement& element );
780
781 virtual bool Visit( const XMLText& text );
782 virtual bool Visit( const XMLComment& comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800783 virtual bool Visit( const XMLDeclaration& declaration );
784 virtual bool Visit( const XMLUnknown& unknown );
Lee Thomason751da522012-02-10 08:50:51 -0800785
U-Stream\Leeae25a442012-02-17 17:48:16 -0800786 const char* CStr() const { return buffer.Mem(); }
Lee Thomason751da522012-02-10 08:50:51 -0800787
Lee Thomason5cae8972012-01-24 18:03:07 -0800788private:
789 void SealElement();
790 void PrintSpace( int depth );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800791 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
U-Stream\Leeae25a442012-02-17 17:48:16 -0800792 void Print( const char* format, ... );
Lee Thomason5cae8972012-01-24 18:03:07 -0800793
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800794 bool elementJustOpened;
795 bool firstElement;
Lee Thomason5cae8972012-01-24 18:03:07 -0800796 FILE* fp;
797 int depth;
Lee Thomason56bdd022012-02-09 18:16:58 -0800798 int textDepth;
799
Lee Thomason857b8682012-01-25 17:50:25 -0800800 enum {
Lee Thomason951d8832012-01-26 08:47:06 -0800801 ENTITY_RANGE = 64
Lee Thomason857b8682012-01-25 17:50:25 -0800802 };
803 bool entityFlag[ENTITY_RANGE];
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800804 bool restrictedEntityFlag[ENTITY_RANGE];
Lee Thomason5cae8972012-01-24 18:03:07 -0800805
Lee Thomason2c85a712012-01-31 08:24:24 -0800806 DynArray< const char*, 10 > stack;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800807 DynArray< char, 20 > buffer, accumulator;
Lee Thomason5cae8972012-01-24 18:03:07 -0800808};
809
810
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800811}; // tinyxml2
812
U-Lama\Lee560bd472011-12-28 19:42:49 -0800813
814
U-Stream\Leeae25a442012-02-17 17:48:16 -0800815#endif // TINYXML2_INCLUDED