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