blob: a1f76034fa49dd849d76aba910618605d30b274e [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.
378 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 Thomason67d61312012-01-24 16:01:51 -0800465 virtual char* ParseDeep( char* );
Lee Thomason67d61312012-01-24 16:01:51 -0800466 virtual bool IsClosingElement() const { return false; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800467
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800468protected:
469 XMLNode( XMLDocument* );
Lee Thomasond1983222012-02-06 08:41:24 -0800470 virtual ~XMLNode();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800471 XMLNode( const XMLNode& ); // not supported
472 void operator=( const XMLNode& ); // not supported
Lee Thomasond1983222012-02-06 08:41:24 -0800473
Lee Thomason3f57d272012-01-11 15:30:03 -0800474 XMLDocument* document;
475 XMLNode* parent;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800476 mutable StrPair value;
Lee Thomason3f57d272012-01-11 15:30:03 -0800477
478 XMLNode* firstChild;
479 XMLNode* lastChild;
480
481 XMLNode* prev;
482 XMLNode* next;
483
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800484private:
Lee Thomasond1983222012-02-06 08:41:24 -0800485 MemPool* memPool;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800486 void Unlink( XMLNode* child );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800487};
488
489
Lee Thomason5492a1c2012-01-23 15:32:10 -0800490class XMLText : public XMLNode
491{
Lee Thomason2c85a712012-01-31 08:24:24 -0800492 friend class XMLBase;
493 friend class XMLDocument;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800494public:
Lee Thomason56bdd022012-02-09 18:16:58 -0800495 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800496
Lee Thomason751da522012-02-10 08:50:51 -0800497 virtual XMLText* ToText() { return this; }
498 virtual const XMLText* ToText() const { return this; }
Lee Thomason5492a1c2012-01-23 15:32:10 -0800499
Lee Thomason50f97b22012-02-11 16:33:40 -0800500 void SetCData( bool value ) { isCData = true; }
501 bool CData() const { return isCData; }
502
Lee Thomason5492a1c2012-01-23 15:32:10 -0800503 char* ParseDeep( char* );
504
505protected:
Lee Thomason50f97b22012-02-11 16:33:40 -0800506 XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {}
507 virtual ~XMLText() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800508 XMLText( const XMLText& ); // not supported
509 void operator=( const XMLText& ); // not supported
Lee Thomason5492a1c2012-01-23 15:32:10 -0800510
511private:
Lee Thomason50f97b22012-02-11 16:33:40 -0800512 bool isCData;
Lee Thomason5492a1c2012-01-23 15:32:10 -0800513};
514
515
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800516class XMLComment : public XMLNode
517{
Lee Thomason2c85a712012-01-31 08:24:24 -0800518 friend class XMLDocument;
Lee Thomason3f57d272012-01-11 15:30:03 -0800519public:
Lee Thomason751da522012-02-10 08:50:51 -0800520 virtual XMLComment* ToComment() { return this; }
521 virtual const XMLComment* ToComment() const { return this; }
Lee Thomasonce0763e2012-01-11 15:43:54 -0800522
Lee Thomason56bdd022012-02-09 18:16:58 -0800523 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800524
Lee Thomasonce0763e2012-01-11 15:43:54 -0800525 char* ParseDeep( char* );
526
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800527protected:
Lee Thomason2c85a712012-01-31 08:24:24 -0800528 XMLComment( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800529 virtual ~XMLComment();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800530 XMLComment( const XMLComment& ); // not supported
531 void operator=( const XMLComment& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800532
Lee Thomason3f57d272012-01-11 15:30:03 -0800533private:
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800534};
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800535
536
Lee Thomason50f97b22012-02-11 16:33:40 -0800537class XMLDeclaration : public XMLNode
538{
539 friend class XMLDocument;
540public:
541 virtual XMLDeclaration* ToDeclaration() { return this; }
542 virtual const XMLDeclaration* ToDeclaration() const { return this; }
543
544 virtual bool Accept( XMLVisitor* visitor ) const;
545
546 char* ParseDeep( char* );
547
548protected:
549 XMLDeclaration( XMLDocument* doc );
550 virtual ~XMLDeclaration();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800551 XMLDeclaration( const XMLDeclaration& ); // not supported
552 void operator=( const XMLDeclaration& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800553};
554
555
556class XMLUnknown : public XMLNode
557{
558 friend class XMLDocument;
559public:
560 virtual XMLUnknown* ToUnknown() { return this; }
561 virtual const XMLUnknown* ToUnknown() const { return this; }
562
563 virtual bool Accept( XMLVisitor* visitor ) const;
564
565 char* ParseDeep( char* );
566
567protected:
568 XMLUnknown( XMLDocument* doc );
569 virtual ~XMLUnknown();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800570 XMLUnknown( const XMLUnknown& ); // not supported
571 void operator=( const XMLUnknown& ); // not supported
Lee Thomason50f97b22012-02-11 16:33:40 -0800572};
573
574
Lee Thomason1ff38e02012-02-14 18:18:16 -0800575enum {
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800576 XML_NO_ERROR = 0,
577
Lee Thomason1ff38e02012-02-14 18:18:16 -0800578 NO_ATTRIBUTE,
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800579 WRONG_ATTRIBUTE_TYPE,
580
581 ERROR_FILE_NOT_FOUND,
582 ERROR_ELEMENT_MISMATCH,
583 ERROR_PARSING_ELEMENT,
584 ERROR_PARSING_ATTRIBUTE,
585 ERROR_IDENTIFYING_TAG,
586 ERROR_PARSING_TEXT,
587 ERROR_PARSING_CDATA,
588 ERROR_PARSING_COMMENT,
589 ERROR_PARSING_DECLARATION,
590 ERROR_PARSING_UNKNOWN
Lee Thomason1ff38e02012-02-14 18:18:16 -0800591};
592
593
Lee Thomason56bdd022012-02-09 18:16:58 -0800594class XMLAttribute
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800595{
596 friend class XMLElement;
597public:
Lee Thomason751da522012-02-10 08:50:51 -0800598 const char* Name() const { return name.GetStr(); }
599 const char* Value() const { return value.GetStr(); }
600 const XMLAttribute* Next() const { return next; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800601
U-Stream\Leeae25a442012-02-17 17:48:16 -0800602 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( &i ); return i; }
603 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( &i ); return i; }
604 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( &b ); return b; }
605 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( &d ); return d; }
606 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( &f ); return f; }
607
Lee Thomason1ff38e02012-02-14 18:18:16 -0800608 int QueryIntAttribute( int* value ) const;
609 int QueryUnsignedAttribute( unsigned int* value ) const;
610 int QueryBoolAttribute( bool* value ) const;
611 int QueryDoubleAttribute( double* value ) const;
612 int QueryFloatAttribute( float* value ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800613
Lee Thomason1ff38e02012-02-14 18:18:16 -0800614 void SetAttribute( const char* value );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800615 void SetAttribute( int value );
616 void SetAttribute( unsigned value );
617 void SetAttribute( bool value );
618 void SetAttribute( double value );
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800619 void SetAttribute( float value );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800620
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800621private:
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800622 enum { BUF_SIZE = 200 };
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800623
Lee Thomasond1983222012-02-06 08:41:24 -0800624 XMLAttribute( XMLElement* element ) : next( 0 ) {}
625 virtual ~XMLAttribute() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800626 XMLAttribute( const XMLAttribute& ); // not supported
627 void operator=( const XMLAttribute& ); // not supported
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800628 void SetName( const char* name );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800629
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800630 char* ParseDeep( char* p );
631
Lee Thomason751da522012-02-10 08:50:51 -0800632 mutable StrPair name;
633 mutable StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800634 XMLAttribute* next;
Lee Thomason43f59302012-02-06 18:18:11 -0800635 MemPool* memPool;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800636};
637
638
639class XMLElement : public XMLNode
640{
Lee Thomason2c85a712012-01-31 08:24:24 -0800641 friend class XMLBase;
642 friend class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800643public:
Lee Thomason2c85a712012-01-31 08:24:24 -0800644 const char* Name() const { return Value(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800645 void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800646
Lee Thomason751da522012-02-10 08:50:51 -0800647 virtual XMLElement* ToElement() { return this; }
648 virtual const XMLElement* ToElement() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800649 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800650
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800651 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 -0800652
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800653 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; }
654 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
655 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; }
656 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; }
657 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; }
658
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800659 int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); }
660 int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); }
661 int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); }
662 int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); }
663 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 -0800664
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800665 void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
666 void SetAttribute( const char* name, int value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
667 void SetAttribute( const char* name, unsigned value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
668 void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
669 void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800670
U-Stream\Leeae25a442012-02-17 17:48:16 -0800671 /**
672 Tests: Programmatic DOM
673 */
674 void DeleteAttribute( const char* name );
Lee Thomason751da522012-02-10 08:50:51 -0800675
676 const XMLAttribute* FirstAttribute() const { return rootAttribute; }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800677 const XMLAttribute* FindAttribute( const char* name ) const;
Lee Thomason751da522012-02-10 08:50:51 -0800678
Lee Thomason50f97b22012-02-11 16:33:40 -0800679 const char* GetText() const;
Lee Thomason751da522012-02-10 08:50:51 -0800680
Lee Thomason2c85a712012-01-31 08:24:24 -0800681 // internal:
682 virtual bool IsClosingElement() const { return closing; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800683 char* ParseDeep( char* p );
684
Lee Thomason50adb4c2012-02-13 15:07:09 -0800685private:
Lee Thomason2c85a712012-01-31 08:24:24 -0800686 XMLElement( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800687 virtual ~XMLElement();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800688 XMLElement( const XMLElement& ); // not supported
689 void operator=( const XMLElement& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800690
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800691 XMLAttribute* FindAttribute( const char* name );
692 XMLAttribute* FindOrCreateAttribute( const char* name );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800693 void LinkAttribute( XMLAttribute* attrib );
Lee Thomason67d61312012-01-24 16:01:51 -0800694 char* ParseAttributes( char* p, bool *closedElement );
695
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800696 bool closing;
697 XMLAttribute* rootAttribute;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800698};
699
700
Lee Thomason67d61312012-01-24 16:01:51 -0800701class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800702{
Lee Thomasond1983222012-02-06 08:41:24 -0800703 friend class XMLElement;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800704public:
Lee Thomason18d68bd2012-01-26 18:17:26 -0800705 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800706 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800707
Lee Thomason751da522012-02-10 08:50:51 -0800708 virtual XMLDocument* ToDocument() { return this; }
709 virtual const XMLDocument* ToDocument() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800710
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800711 int Parse( const char* xml );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800712 int LoadFile( const char* filename );
713 int LoadFile( FILE* );
714 void SaveFile( const char* filename );
715
716 bool HasBOM() const { return writeBOM; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800717
Lee Thomason5cae8972012-01-24 18:03:07 -0800718 void Print( XMLStreamer* streamer=0 );
Lee Thomason56bdd022012-02-09 18:16:58 -0800719 virtual bool Accept( XMLVisitor* visitor ) const;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800720
Lee Thomason1ff38e02012-02-14 18:18:16 -0800721 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800722 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800723 */
Lee Thomason2c85a712012-01-31 08:24:24 -0800724 XMLElement* NewElement( const char* name );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800725 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800726 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800727 */
728 XMLComment* NewComment( const char* comment );
729 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800730 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800731 */
732 XMLText* NewText( const char* text );
Lee Thomason2c85a712012-01-31 08:24:24 -0800733
U-Stream\Leeae25a442012-02-17 17:48:16 -0800734 /**
735 Tests: Programmatic DOM
736 */
737 void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); }
738
Lee Thomason67d61312012-01-24 16:01:51 -0800739 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800740
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800741 bool Error() const { return errorID != XML_NO_ERROR; }
742 int ErrorID() const { return errorID; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800743 const char* GetErrorStr1() const { return errorStr1; }
744 const char* GetErrorStr2() const { return errorStr2; }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800745 void PrintError() const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800746
Lee Thomasond1983222012-02-06 08:41:24 -0800747 char* Identify( char* p, XMLNode** node );
Lee Thomason2c85a712012-01-31 08:24:24 -0800748
Lee Thomason3f57d272012-01-11 15:30:03 -0800749private:
Lee Thomason50adb4c2012-02-13 15:07:09 -0800750 XMLDocument( const XMLDocument& ); // not supported
751 void operator=( const XMLDocument& ); // not supported
Lee Thomason18d68bd2012-01-26 18:17:26 -0800752 void InitDocument();
753
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800754 bool writeBOM;
Lee Thomason7c913cd2012-01-26 18:32:34 -0800755 int errorID;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800756 const char* errorStr1;
757 const char* errorStr2;
758 char* charBuffer;
Lee Thomasond1983222012-02-06 08:41:24 -0800759
760 MemPoolT< sizeof(XMLElement) > elementPool;
761 MemPoolT< sizeof(XMLAttribute) > attributePool;
762 MemPoolT< sizeof(XMLText) > textPool;
763 MemPoolT< sizeof(XMLComment) > commentPool;
Lee Thomason5cae8972012-01-24 18:03:07 -0800764};
765
Lee Thomason7c913cd2012-01-26 18:32:34 -0800766
Lee Thomason751da522012-02-10 08:50:51 -0800767class XMLStreamer : public XMLVisitor
Lee Thomason5cae8972012-01-24 18:03:07 -0800768{
769public:
U-Stream\Leeae25a442012-02-17 17:48:16 -0800770 XMLStreamer( FILE* file=0 );
Lee Thomason5cae8972012-01-24 18:03:07 -0800771 ~XMLStreamer() {}
772
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800773 void PushHeader( bool writeBOM, bool writeDeclaration );
Lee Thomason56bdd022012-02-09 18:16:58 -0800774 void OpenElement( const char* name );
Lee Thomason5cae8972012-01-24 18:03:07 -0800775 void PushAttribute( const char* name, const char* value );
776 void CloseElement();
777
Lee Thomason50f97b22012-02-11 16:33:40 -0800778 void PushText( const char* text, bool cdata=false );
Lee Thomason5cae8972012-01-24 18:03:07 -0800779 void PushComment( const char* comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800780 void PushDeclaration( const char* value );
781 void PushUnknown( const char* value );
Lee Thomason5cae8972012-01-24 18:03:07 -0800782
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800783 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
Lee Thomason751da522012-02-10 08:50:51 -0800784 virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
785
786 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
787 virtual bool VisitExit( const XMLElement& element );
788
789 virtual bool Visit( const XMLText& text );
790 virtual bool Visit( const XMLComment& comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800791 virtual bool Visit( const XMLDeclaration& declaration );
792 virtual bool Visit( const XMLUnknown& unknown );
Lee Thomason751da522012-02-10 08:50:51 -0800793
U-Stream\Leeae25a442012-02-17 17:48:16 -0800794 const char* CStr() const { return buffer.Mem(); }
Lee Thomason751da522012-02-10 08:50:51 -0800795
Lee Thomason5cae8972012-01-24 18:03:07 -0800796private:
797 void SealElement();
798 void PrintSpace( int depth );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800799 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
U-Stream\Leeae25a442012-02-17 17:48:16 -0800800 void Print( const char* format, ... );
Lee Thomason5cae8972012-01-24 18:03:07 -0800801
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800802 bool elementJustOpened;
803 bool firstElement;
Lee Thomason5cae8972012-01-24 18:03:07 -0800804 FILE* fp;
805 int depth;
Lee Thomason56bdd022012-02-09 18:16:58 -0800806 int textDepth;
807
Lee Thomason857b8682012-01-25 17:50:25 -0800808 enum {
Lee Thomason951d8832012-01-26 08:47:06 -0800809 ENTITY_RANGE = 64
Lee Thomason857b8682012-01-25 17:50:25 -0800810 };
811 bool entityFlag[ENTITY_RANGE];
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800812 bool restrictedEntityFlag[ENTITY_RANGE];
Lee Thomason5cae8972012-01-24 18:03:07 -0800813
Lee Thomason2c85a712012-01-31 08:24:24 -0800814 DynArray< const char*, 10 > stack;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800815 DynArray< char, 20 > buffer, accumulator;
Lee Thomason5cae8972012-01-24 18:03:07 -0800816};
817
818
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800819}; // tinyxml2
820
U-Lama\Lee560bd472011-12-28 19:42:49 -0800821
822
U-Stream\Leeae25a442012-02-17 17:48:16 -0800823#endif // TINYXML2_INCLUDED