blob: 2a6e3443100a4fb4907563d864edf7f0b1870dfe [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#ifndef TINYXML2_INCLUDED
2#define TINYXML2_INCLUDED
3
Lee Thomason2c85a712012-01-31 08:24:24 -08004/*
5 TODO
6 - const and non-const versions of API
Lee Thomason455c9d42012-02-06 09:14:14 -08007 X memory pool the class construction
Lee Thomason2c85a712012-01-31 08:24:24 -08008 - attribute accessors
9 - node navigation
10 - handles
11 - visit pattern - change streamer?
12 - make constructors protected
13 - hide copy constructor
14 - hide = operator
Lee Thomasond1983222012-02-06 08:41:24 -080015 - UTF8 support: isAlpha, etc.
Lee Thomason2c85a712012-01-31 08:24:24 -080016*/
17
U-Lama\Lee4cee6112011-12-31 14:58:18 -080018#include <limits.h>
Lee Thomasonce0763e2012-01-11 15:43:54 -080019#include <ctype.h>
20#include <stdio.h>
Lee Thomason2c85a712012-01-31 08:24:24 -080021#include <memory.h>
U-Lama\Lee4cee6112011-12-31 14:58:18 -080022
23#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
24 #ifndef DEBUG
25 #define DEBUG
26 #endif
27#endif
28
29
30#if defined(DEBUG)
31 #if defined(_MSC_VER)
32 #define TIXMLASSERT( x ) if ( !(x)) { _asm { int 3 } } //if ( !(x)) WinDebugBreak()
33 #elif defined (ANDROID_NDK)
34 #include <android/log.h>
35 #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
36 #else
37 #include <assert.h>
38 #define TIXMLASSERT assert
39 #endif
40#else
41 #define TIXMLASSERT( x ) {}
42#endif
43
U-Lama\Leee13c3e62011-12-28 14:36:55 -080044
45namespace tinyxml2
46{
Lee Thomasonce0763e2012-01-11 15:43:54 -080047class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -080048class XMLElement;
49class XMLAttribute;
50class XMLComment;
51class XMLNode;
Lee Thomason5492a1c2012-01-23 15:32:10 -080052class XMLText;
U-Lama\Leee13c3e62011-12-28 14:36:55 -080053
Lee Thomason5cae8972012-01-24 18:03:07 -080054class XMLStreamer;
55
Lee Thomason39ede242012-01-20 11:27:56 -080056class StrPair
57{
Lee Thomasond34f52c2012-01-20 12:55:24 -080058public:
Lee Thomason39ede242012-01-20 11:27:56 -080059 enum {
Lee Thomasone4422302012-01-20 17:59:50 -080060 NEEDS_ENTITY_PROCESSING = 0x01,
Lee Thomason18d68bd2012-01-26 18:17:26 -080061 NEEDS_NEWLINE_NORMALIZATION = 0x02,
62
63 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
64 ATTRIBUTE_NAME = 0,
65 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
66 COMMENT = NEEDS_NEWLINE_NORMALIZATION,
Lee Thomason39ede242012-01-20 11:27:56 -080067 };
68
69 StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
Lee Thomasone4422302012-01-20 17:59:50 -080070 void Set( char* start, char* end, int flags ) {
Lee Thomason39ede242012-01-20 11:27:56 -080071 this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
72 }
73 const char* GetStr();
Lee Thomasone4422302012-01-20 17:59:50 -080074 bool Empty() const { return start == end; }
Lee Thomason39ede242012-01-20 11:27:56 -080075
Lee Thomason2c85a712012-01-31 08:24:24 -080076 void SetInternedStr( const char* str ) { this->start = (char*) str; this->end = 0; this->flags = 0; }
77
Lee Thomason39ede242012-01-20 11:27:56 -080078private:
Lee Thomasone4422302012-01-20 17:59:50 -080079 enum {
80 NEEDS_FLUSH = 0x100
81 };
82
Lee Thomason39ede242012-01-20 11:27:56 -080083 // After parsing, if *end != 0, it can be set to zero.
84 int flags;
Lee Thomasone4422302012-01-20 17:59:50 -080085 char* start;
Lee Thomason39ede242012-01-20 11:27:56 -080086 char* end;
87};
88
U-Lama\Lee560bd472011-12-28 19:42:49 -080089
Lee Thomason2c85a712012-01-31 08:24:24 -080090template <class T, int INIT>
91class DynArray
92{
93public:
94 DynArray< T, INIT >()
95 {
96 mem = pool;
97 allocated = INIT;
98 size = 0;
99 }
100 ~DynArray()
101 {
102 if ( mem != pool ) {
103 delete mem;
104 }
105 }
106 void Push( T t )
107 {
108 EnsureCapacity( size+1 );
109 mem[size++] = t;
110 }
111
112 T* PushArr( int count )
113 {
114 EnsureCapacity( size+count );
115 T* ret = &mem[size];
116 size += count;
117 return ret;
118 }
119 T Pop() {
120 return mem[--size];
121 }
122 void PopArr( int count )
123 {
124 TIXMLASSERT( size >= count );
125 size -= count;
126 }
127
128 bool Empty() const { return size == 0; }
129 T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
130 const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
131 int Size() const { return size; }
132 const T* Mem() const { return mem; }
133 T* Mem() { return mem; }
134
135
136private:
137 void EnsureCapacity( int cap ) {
138 if ( cap > allocated ) {
139 int newAllocated = cap * 2;
140 T* newMem = new T[newAllocated];
141 memcpy( newMem, mem, sizeof(T)*size ); // warning: not using constructors, only works for PODs
142 if ( mem != pool ) delete [] mem;
143 mem = newMem;
144 allocated = newAllocated;
145 }
146 }
147
148 T* mem;
149 T pool[INIT];
150 int allocated; // objects allocated
151 int size; // number objects in use
152};
153
Lee Thomasond1983222012-02-06 08:41:24 -0800154class MemPool
155{
156public:
157 MemPool() {}
158 virtual ~MemPool() {}
159
160 virtual int ItemSize() const = 0;
161 virtual void* Alloc() = 0;
162 virtual void Free( void* ) = 0;
163};
164
165template< int SIZE >
166class MemPoolT : public MemPool
167{
168public:
Lee Thomason455c9d42012-02-06 09:14:14 -0800169 MemPoolT() : root(0), currentAllocs(0), nAllocs(0), maxAllocs(0) {}
Lee Thomasond1983222012-02-06 08:41:24 -0800170 ~MemPoolT() {
171 // Delete the blocks.
172 for( int i=0; i<blockPtrs.Size(); ++i ) {
173 delete blockPtrs[i];
174 }
175 }
176
177 virtual int ItemSize() const { return SIZE; }
Lee Thomason455c9d42012-02-06 09:14:14 -0800178 int CurrentAllocs() const { return currentAllocs; }
Lee Thomasond1983222012-02-06 08:41:24 -0800179
180 virtual void* Alloc() {
181 if ( !root ) {
182 // Need a new block.
183 Block* block = new Block();
184 blockPtrs.Push( block );
185
186 for( int i=0; i<COUNT-1; ++i ) {
187 block->chunk[i].next = &block->chunk[i+1];
188 }
189 block->chunk[COUNT-1].next = 0;
190 root = block->chunk;
191 }
192 void* result = root;
193 root = root->next;
Lee Thomason455c9d42012-02-06 09:14:14 -0800194
195 ++currentAllocs;
196 if ( currentAllocs > maxAllocs ) maxAllocs = currentAllocs;
197 nAllocs++;
Lee Thomasond1983222012-02-06 08:41:24 -0800198 return result;
199 }
200 virtual void Free( void* mem ) {
201 if ( !mem ) return;
Lee Thomason455c9d42012-02-06 09:14:14 -0800202 --currentAllocs;
Lee Thomasond1983222012-02-06 08:41:24 -0800203 Chunk* chunk = (Chunk*)mem;
204 memset( chunk, 0xfe, sizeof(Chunk) );
205 chunk->next = root;
206 root = chunk;
207 }
Lee Thomason455c9d42012-02-06 09:14:14 -0800208 void Trace( const char* name ) {
Lee Thomason43f59302012-02-06 18:18:11 -0800209 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
210 name, maxAllocs, maxAllocs*SIZE/1024, currentAllocs, SIZE, nAllocs, blockPtrs.Size() );
Lee Thomason455c9d42012-02-06 09:14:14 -0800211 }
Lee Thomasond1983222012-02-06 08:41:24 -0800212
213private:
214 enum { COUNT = 1024/SIZE };
215 union Chunk {
216 Chunk* next;
217 char mem[SIZE];
218 };
219 struct Block {
220 Chunk chunk[COUNT];
221 };
222 DynArray< Block*, 10 > blockPtrs;
223 Chunk* root;
Lee Thomason455c9d42012-02-06 09:14:14 -0800224
225 int currentAllocs;
226 int nAllocs;
227 int maxAllocs;
Lee Thomasond1983222012-02-06 08:41:24 -0800228};
229
Lee Thomason2c85a712012-01-31 08:24:24 -0800230
231/*
232class StringStack
233{
234public:
235 StringStack();
236 virtual ~StringStack();
237
238 void Push( const char* str );
239 const char* Pop();
240
241 int NumPositive() const { return nPositive; }
242
243private:
244 DynArray< char, 50 > mem;
245 int nPositive; // number of strings with len > 0
246};
247*/
248
249/*
250class StringPool
251{
252public:
253 enum { INIT_SIZE=20 };
254
255 StringPool() : size( 0 ) {
256 const char** mem = pool.PushArr( INIT_SIZE );
257 memset( (void*)mem, 0, sizeof(char)*INIT_SIZE );
258 }
259 ~StringPool() {}
260
261 const char* Intern( const char* str );
262
263private:
264 // FNV hash
265 int Hash( const char* s ) {
266 #define FNV_32_PRIME ((int)0x01000193)
267 int hval = 0;
268 while (*s) {
269 hval *= FNV_32_PRIME;
270 hval ^= (int)*s++;
271 }
272 return hval;
273 }
274
275 int size;
276 DynArray< const char*, INIT_SIZE > pool; // the hash table
277 StringStack store; // memory for the interned strings
278};
279*/
280
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800281class XMLBase
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800282{
283public:
Lee Thomasond1983222012-02-06 08:41:24 -0800284
285public:
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800286 XMLBase() {}
287 virtual ~XMLBase() {}
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800288
Lee Thomason3f57d272012-01-11 15:30:03 -0800289 static const char* SkipWhiteSpace( const char* p ) { while( isspace( *p ) ) { ++p; } return p; }
290 static char* SkipWhiteSpace( char* p ) { while( isspace( *p ) ) { ++p; } return p; }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800291
292 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
293 int n = 0;
Lee Thomasond34f52c2012-01-20 12:55:24 -0800294 if ( p == q ) {
295 return true;
296 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800297 while( *p && *q && *p == *q && n<nChar ) {
298 ++p; ++q; ++n;
299 }
300 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
301 return true;
302 }
303 return false;
304 }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800305 inline static int IsUTF8Continuation( unsigned char p ) { return p & 0x80; }
306 inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalnum( anyByte ) : 1; }
307 inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalpha( anyByte ) : 1; }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800308
Lee Thomasond1983222012-02-06 08:41:24 -0800309 static char* ParseText( char* in, StrPair* pair, const char* endTag, int strFlags );
310 static char* ParseName( char* in, StrPair* pair );
311
312private:
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800313};
314
Lee Thomason5cae8972012-01-24 18:03:07 -0800315
Lee Thomasond1983222012-02-06 08:41:24 -0800316class XMLNode
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800317{
318 friend class XMLDocument;
319 friend class XMLElement;
320public:
Lee Thomasond1983222012-02-06 08:41:24 -0800321 //void* operator new( size_t size, MemPool* pool );
322 //void operator delete( void* mem, MemPool* pool );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800323
324 XMLNode* InsertEndChild( XMLNode* addThis );
Lee Thomason5cae8972012-01-24 18:03:07 -0800325 virtual void Print( XMLStreamer* streamer );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800326
Lee Thomason2c85a712012-01-31 08:24:24 -0800327 const char* Value() const { return value.GetStr(); }
328 void SetValue( const char* val ) { value.SetInternedStr( val ); }
329
Lee Thomason5492a1c2012-01-23 15:32:10 -0800330 virtual XMLElement* ToElement() { return 0; }
331 virtual XMLText* ToText() { return 0; }
332 virtual XMLComment* ToComment() { return 0; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800333
Lee Thomason2c85a712012-01-31 08:24:24 -0800334 XMLNode* FirstChild() { return firstChild; }
335 XMLElement* FirstChildElement( const char* value=0 );
336
Lee Thomason67d61312012-01-24 16:01:51 -0800337 // fixme: guarentee null terminator to avoid internal checks
338 virtual char* ParseDeep( char* );
339
340 void SetTextParent() { isTextParent = true; }
341 bool IsTextParent() const { return isTextParent; }
342 virtual bool IsClosingElement() const { return false; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800343
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800344protected:
345 XMLNode( XMLDocument* );
Lee Thomasond1983222012-02-06 08:41:24 -0800346 virtual ~XMLNode();
347
Lee Thomason18d68bd2012-01-26 18:17:26 -0800348 void ClearChildren();
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800349
Lee Thomason3f57d272012-01-11 15:30:03 -0800350 XMLDocument* document;
351 XMLNode* parent;
Lee Thomason67d61312012-01-24 16:01:51 -0800352 bool isTextParent;
Lee Thomason2c85a712012-01-31 08:24:24 -0800353 mutable StrPair value;
Lee Thomason3f57d272012-01-11 15:30:03 -0800354
355 XMLNode* firstChild;
356 XMLNode* lastChild;
357
358 XMLNode* prev;
359 XMLNode* next;
360
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800361private:
Lee Thomasond1983222012-02-06 08:41:24 -0800362 MemPool* memPool;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800363 void Unlink( XMLNode* child );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800364};
365
366
Lee Thomason5492a1c2012-01-23 15:32:10 -0800367class XMLText : public XMLNode
368{
Lee Thomason2c85a712012-01-31 08:24:24 -0800369 friend class XMLBase;
370 friend class XMLDocument;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800371public:
Lee Thomason5cae8972012-01-24 18:03:07 -0800372 virtual void Print( XMLStreamer* streamer );
Lee Thomason5492a1c2012-01-23 15:32:10 -0800373 const char* Value() { return value.GetStr(); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800374 void SetValue( const char* );
375
Lee Thomason5492a1c2012-01-23 15:32:10 -0800376 virtual XMLText* ToText() { return this; }
377
378 char* ParseDeep( char* );
379
380protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800381 XMLText( XMLDocument* doc ) : XMLNode( doc ) {}
Lee Thomasond1983222012-02-06 08:41:24 -0800382 virtual ~XMLText() {}
Lee Thomason5492a1c2012-01-23 15:32:10 -0800383
384private:
Lee Thomason5492a1c2012-01-23 15:32:10 -0800385};
386
387
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800388class XMLComment : public XMLNode
389{
Lee Thomason2c85a712012-01-31 08:24:24 -0800390 friend class XMLBase;
391 friend class XMLDocument;
Lee Thomason3f57d272012-01-11 15:30:03 -0800392public:
Lee Thomason5cae8972012-01-24 18:03:07 -0800393 virtual void Print( XMLStreamer* );
Lee Thomason5492a1c2012-01-23 15:32:10 -0800394 virtual XMLComment* ToComment() { return this; }
Lee Thomasonce0763e2012-01-11 15:43:54 -0800395
Lee Thomasond34f52c2012-01-20 12:55:24 -0800396 const char* Value() { return value.GetStr(); }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800397
Lee Thomasonce0763e2012-01-11 15:43:54 -0800398 char* ParseDeep( char* );
399
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800400protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800401 XMLComment( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800402 virtual ~XMLComment();
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800403
Lee Thomason3f57d272012-01-11 15:30:03 -0800404private:
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800405};
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800406
407
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800408class XMLAttribute : public XMLBase
409{
410 friend class XMLElement;
411public:
Lee Thomason5cae8972012-01-24 18:03:07 -0800412 virtual void Print( XMLStreamer* streamer );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800413
414private:
Lee Thomasond1983222012-02-06 08:41:24 -0800415 XMLAttribute( XMLElement* element ) : next( 0 ) {}
416 virtual ~XMLAttribute() {}
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800417 char* ParseDeep( char* p );
418
Lee Thomason22aead12012-01-23 13:29:35 -0800419 StrPair name;
Lee Thomasond34f52c2012-01-20 12:55:24 -0800420 StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800421 XMLAttribute* next;
Lee Thomason43f59302012-02-06 18:18:11 -0800422 MemPool* memPool;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800423};
424
425
426class XMLElement : public XMLNode
427{
Lee Thomason2c85a712012-01-31 08:24:24 -0800428 friend class XMLBase;
429 friend class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800430public:
Lee Thomason2c85a712012-01-31 08:24:24 -0800431 const char* Name() const { return Value(); }
432 void SetName( const char* str ) { SetValue( str ); }
433
Lee Thomason5cae8972012-01-24 18:03:07 -0800434 virtual void Print( XMLStreamer* );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800435
436 virtual XMLElement* ToElement() { return this; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800437
Lee Thomason2c85a712012-01-31 08:24:24 -0800438 // internal:
439 virtual bool IsClosingElement() const { return closing; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800440 char* ParseDeep( char* p );
441
442protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800443 XMLElement( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800444 virtual ~XMLElement();
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800445
446private:
Lee Thomason67d61312012-01-24 16:01:51 -0800447 char* ParseAttributes( char* p, bool *closedElement );
448
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800449 bool closing;
450 XMLAttribute* rootAttribute;
451 XMLAttribute* lastAttribute;
452};
453
454
Lee Thomason67d61312012-01-24 16:01:51 -0800455class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800456{
Lee Thomasond1983222012-02-06 08:41:24 -0800457 friend class XMLElement;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800458public:
Lee Thomason18d68bd2012-01-26 18:17:26 -0800459 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800460 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800461
Lee Thomason7c913cd2012-01-26 18:32:34 -0800462 int Parse( const char* );
463 int Load( const char* );
464 int Load( FILE* );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800465
Lee Thomason5cae8972012-01-24 18:03:07 -0800466 void Print( XMLStreamer* streamer=0 );
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800467
Lee Thomason2c85a712012-01-31 08:24:24 -0800468 XMLElement* NewElement( const char* name );
469
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800470 enum {
Lee Thomason18d68bd2012-01-26 18:17:26 -0800471 NO_ERROR = 0,
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800472 ERROR_ELEMENT_MISMATCH,
473 ERROR_PARSING_ELEMENT,
474 ERROR_PARSING_ATTRIBUTE
475 };
Lee Thomason67d61312012-01-24 16:01:51 -0800476 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800477
Lee Thomason7c913cd2012-01-26 18:32:34 -0800478 bool Error() const { return errorID != NO_ERROR; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800479 int GetErrorID() const { return errorID; }
480 const char* GetErrorStr1() const { return errorStr1; }
481 const char* GetErrorStr2() const { return errorStr2; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800482
Lee Thomasond1983222012-02-06 08:41:24 -0800483 char* Identify( char* p, XMLNode** node );
Lee Thomason2c85a712012-01-31 08:24:24 -0800484
Lee Thomason3f57d272012-01-11 15:30:03 -0800485private:
Lee Thomasond1983222012-02-06 08:41:24 -0800486
Lee Thomason3f57d272012-01-11 15:30:03 -0800487 XMLDocument( const XMLDocument& ); // intentionally not implemented
Lee Thomason18d68bd2012-01-26 18:17:26 -0800488 void InitDocument();
489
Lee Thomason7c913cd2012-01-26 18:32:34 -0800490 int errorID;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800491 const char* errorStr1;
492 const char* errorStr2;
493 char* charBuffer;
Lee Thomason2c85a712012-01-31 08:24:24 -0800494 //StringStack stringPool;
Lee Thomasond1983222012-02-06 08:41:24 -0800495
496 MemPoolT< sizeof(XMLElement) > elementPool;
497 MemPoolT< sizeof(XMLAttribute) > attributePool;
498 MemPoolT< sizeof(XMLText) > textPool;
499 MemPoolT< sizeof(XMLComment) > commentPool;
Lee Thomason5cae8972012-01-24 18:03:07 -0800500};
501
Lee Thomason7c913cd2012-01-26 18:32:34 -0800502
Lee Thomason5cae8972012-01-24 18:03:07 -0800503class XMLStreamer
504{
505public:
506 XMLStreamer( FILE* file );
507 ~XMLStreamer() {}
508
509 void OpenElement( const char* name, bool textParent );
510 void PushAttribute( const char* name, const char* value );
511 void CloseElement();
512
513 void PushText( const char* text );
514 void PushComment( const char* comment );
515
516private:
517 void SealElement();
518 void PrintSpace( int depth );
Lee Thomason857b8682012-01-25 17:50:25 -0800519 void PrintString( const char* ); // prints out, after detecting entities.
Lee Thomason2c85a712012-01-31 08:24:24 -0800520 bool TextOnStack() const {
521 for( int i=0; i<text.Size(); ++i ) {
522 if ( text[i] == 'T' )
523 return true;
524 }
525 return false;
526 }
Lee Thomason5cae8972012-01-24 18:03:07 -0800527
528 FILE* fp;
529 int depth;
530 bool elementJustOpened;
Lee Thomason857b8682012-01-25 17:50:25 -0800531 enum {
Lee Thomason951d8832012-01-26 08:47:06 -0800532 ENTITY_RANGE = 64
Lee Thomason857b8682012-01-25 17:50:25 -0800533 };
534 bool entityFlag[ENTITY_RANGE];
Lee Thomason5cae8972012-01-24 18:03:07 -0800535
Lee Thomason2c85a712012-01-31 08:24:24 -0800536 DynArray< const char*, 10 > stack;
537 DynArray< char, 10 > text;
Lee Thomason5cae8972012-01-24 18:03:07 -0800538};
539
540
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800541}; // tinyxml2
542
U-Lama\Lee560bd472011-12-28 19:42:49 -0800543
544
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800545#endif // TINYXML2_INCLUDED