blob: 7185472f0de0f18254f5f7229a9b8be4c5d2b5e9 [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 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,
Lee Thomasond6277762012-02-22 16:00:12 -0800590 ERROR_PARSING_UNKNOWN,
591 ERROR_EMPTY_DOCUMENT,
592 ERROR_MISMATCHED_ELEMENT
Lee Thomason1ff38e02012-02-14 18:18:16 -0800593};
594
595
Lee Thomason56bdd022012-02-09 18:16:58 -0800596class XMLAttribute
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800597{
598 friend class XMLElement;
599public:
Lee Thomason751da522012-02-10 08:50:51 -0800600 const char* Name() const { return name.GetStr(); }
601 const char* Value() const { return value.GetStr(); }
602 const XMLAttribute* Next() const { return next; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800603
U-Stream\Leeae25a442012-02-17 17:48:16 -0800604 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( &i ); return i; }
605 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( &i ); return i; }
606 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( &b ); return b; }
607 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( &d ); return d; }
608 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( &f ); return f; }
609
Lee Thomason1ff38e02012-02-14 18:18:16 -0800610 int QueryIntAttribute( int* value ) const;
611 int QueryUnsignedAttribute( unsigned int* value ) const;
612 int QueryBoolAttribute( bool* value ) const;
613 int QueryDoubleAttribute( double* value ) const;
614 int QueryFloatAttribute( float* value ) const;
Lee Thomason50adb4c2012-02-13 15:07:09 -0800615
Lee Thomason1ff38e02012-02-14 18:18:16 -0800616 void SetAttribute( const char* value );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800617 void SetAttribute( int value );
618 void SetAttribute( unsigned value );
619 void SetAttribute( bool value );
620 void SetAttribute( double value );
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800621 void SetAttribute( float value );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800622
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800623private:
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800624 enum { BUF_SIZE = 200 };
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800625
Lee Thomasond1983222012-02-06 08:41:24 -0800626 XMLAttribute( XMLElement* element ) : next( 0 ) {}
627 virtual ~XMLAttribute() {}
Lee Thomason50adb4c2012-02-13 15:07:09 -0800628 XMLAttribute( const XMLAttribute& ); // not supported
629 void operator=( const XMLAttribute& ); // not supported
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800630 void SetName( const char* name );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800631
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800632 char* ParseDeep( char* p );
633
Lee Thomason751da522012-02-10 08:50:51 -0800634 mutable StrPair name;
635 mutable StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800636 XMLAttribute* next;
Lee Thomason43f59302012-02-06 18:18:11 -0800637 MemPool* memPool;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800638};
639
640
641class XMLElement : public XMLNode
642{
Lee Thomason2c85a712012-01-31 08:24:24 -0800643 friend class XMLBase;
644 friend class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800645public:
Lee Thomason2c85a712012-01-31 08:24:24 -0800646 const char* Name() const { return Value(); }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800647 void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); }
Lee Thomason2c85a712012-01-31 08:24:24 -0800648
Lee Thomason751da522012-02-10 08:50:51 -0800649 virtual XMLElement* ToElement() { return this; }
650 virtual const XMLElement* ToElement() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800651 virtual bool Accept( XMLVisitor* visitor ) const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800652
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800653 const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); }
Lee Thomason751da522012-02-10 08:50:51 -0800654
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800655 int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; }
656 unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; }
657 bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; }
658 double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; }
659 float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; }
660
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800661 int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); }
662 int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); }
663 int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); }
664 int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); }
665 int QueryFloatAttribute( const char* name, float* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryFloatAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800666
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800667 void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
668 void SetAttribute( const char* name, int value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
669 void SetAttribute( const char* name, unsigned value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
670 void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
671 void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
Lee Thomason50f97b22012-02-11 16:33:40 -0800672
U-Stream\Leeae25a442012-02-17 17:48:16 -0800673 /**
674 Tests: Programmatic DOM
675 */
676 void DeleteAttribute( const char* name );
Lee Thomason751da522012-02-10 08:50:51 -0800677
678 const XMLAttribute* FirstAttribute() const { return rootAttribute; }
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800679 const XMLAttribute* FindAttribute( const char* name ) const;
Lee Thomason751da522012-02-10 08:50:51 -0800680
Lee Thomason50f97b22012-02-11 16:33:40 -0800681 const char* GetText() const;
Lee Thomason751da522012-02-10 08:50:51 -0800682
Lee Thomason2c85a712012-01-31 08:24:24 -0800683 // internal:
684 virtual bool IsClosingElement() const { return closing; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800685 char* ParseDeep( char* p );
686
Lee Thomason50adb4c2012-02-13 15:07:09 -0800687private:
Lee Thomason2c85a712012-01-31 08:24:24 -0800688 XMLElement( XMLDocument* doc );
Lee Thomasond1983222012-02-06 08:41:24 -0800689 virtual ~XMLElement();
Lee Thomason50adb4c2012-02-13 15:07:09 -0800690 XMLElement( const XMLElement& ); // not supported
691 void operator=( const XMLElement& ); // not supported
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800692
Lee Thomason1a1d4a72012-02-15 09:09:25 -0800693 XMLAttribute* FindAttribute( const char* name );
694 XMLAttribute* FindOrCreateAttribute( const char* name );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800695 void LinkAttribute( XMLAttribute* attrib );
Lee Thomason67d61312012-01-24 16:01:51 -0800696 char* ParseAttributes( char* p, bool *closedElement );
697
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800698 bool closing;
699 XMLAttribute* rootAttribute;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800700};
701
702
Lee Thomason67d61312012-01-24 16:01:51 -0800703class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800704{
Lee Thomasond1983222012-02-06 08:41:24 -0800705 friend class XMLElement;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800706public:
Lee Thomason18d68bd2012-01-26 18:17:26 -0800707 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800708 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800709
Lee Thomason751da522012-02-10 08:50:51 -0800710 virtual XMLDocument* ToDocument() { return this; }
711 virtual const XMLDocument* ToDocument() const { return this; }
Lee Thomason56bdd022012-02-09 18:16:58 -0800712
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800713 int Parse( const char* xml );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800714 int LoadFile( const char* filename );
715 int LoadFile( FILE* );
716 void SaveFile( const char* filename );
717
718 bool HasBOM() const { return writeBOM; }
Lee Thomasond6277762012-02-22 16:00:12 -0800719 XMLElement* RootElement() { return FirstChildElement(); }
720 const XMLElement* RootElement() const { return FirstChildElement(); }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800721
Lee Thomason5cae8972012-01-24 18:03:07 -0800722 void Print( XMLStreamer* streamer=0 );
Lee Thomason56bdd022012-02-09 18:16:58 -0800723 virtual bool Accept( XMLVisitor* visitor ) const;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800724
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 */
Lee Thomason2c85a712012-01-31 08:24:24 -0800728 XMLElement* NewElement( const char* name );
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 */
732 XMLComment* NewComment( const char* comment );
733 /**
U-Stream\Leeae25a442012-02-17 17:48:16 -0800734 Tests: Programmatic DOM
Lee Thomason1ff38e02012-02-14 18:18:16 -0800735 */
736 XMLText* NewText( const char* text );
Lee Thomason2c85a712012-01-31 08:24:24 -0800737
U-Stream\Leeae25a442012-02-17 17:48:16 -0800738 /**
739 Tests: Programmatic DOM
740 */
741 void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); }
742
Lee Thomason67d61312012-01-24 16:01:51 -0800743 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason18d68bd2012-01-26 18:17:26 -0800744
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800745 bool Error() const { return errorID != XML_NO_ERROR; }
746 int ErrorID() const { return errorID; }
Lee Thomason18d68bd2012-01-26 18:17:26 -0800747 const char* GetErrorStr1() const { return errorStr1; }
748 const char* GetErrorStr2() const { return errorStr2; }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800749 void PrintError() const;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800750
Lee Thomasond1983222012-02-06 08:41:24 -0800751 char* Identify( char* p, XMLNode** node );
Lee Thomason2c85a712012-01-31 08:24:24 -0800752
Lee Thomason3f57d272012-01-11 15:30:03 -0800753private:
Lee Thomason50adb4c2012-02-13 15:07:09 -0800754 XMLDocument( const XMLDocument& ); // not supported
755 void operator=( const XMLDocument& ); // not supported
Lee Thomason18d68bd2012-01-26 18:17:26 -0800756 void InitDocument();
757
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800758 bool writeBOM;
Lee Thomason7c913cd2012-01-26 18:32:34 -0800759 int errorID;
Lee Thomason18d68bd2012-01-26 18:17:26 -0800760 const char* errorStr1;
761 const char* errorStr2;
762 char* charBuffer;
Lee Thomasond1983222012-02-06 08:41:24 -0800763
764 MemPoolT< sizeof(XMLElement) > elementPool;
765 MemPoolT< sizeof(XMLAttribute) > attributePool;
766 MemPoolT< sizeof(XMLText) > textPool;
767 MemPoolT< sizeof(XMLComment) > commentPool;
Lee Thomason5cae8972012-01-24 18:03:07 -0800768};
769
Lee Thomason7c913cd2012-01-26 18:32:34 -0800770
Lee Thomason751da522012-02-10 08:50:51 -0800771class XMLStreamer : public XMLVisitor
Lee Thomason5cae8972012-01-24 18:03:07 -0800772{
773public:
U-Stream\Leeae25a442012-02-17 17:48:16 -0800774 XMLStreamer( FILE* file=0 );
Lee Thomason5cae8972012-01-24 18:03:07 -0800775 ~XMLStreamer() {}
776
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800777 void PushHeader( bool writeBOM, bool writeDeclaration );
Lee Thomason56bdd022012-02-09 18:16:58 -0800778 void OpenElement( const char* name );
Lee Thomason5cae8972012-01-24 18:03:07 -0800779 void PushAttribute( const char* name, const char* value );
780 void CloseElement();
781
Lee Thomason50f97b22012-02-11 16:33:40 -0800782 void PushText( const char* text, bool cdata=false );
Lee Thomason5cae8972012-01-24 18:03:07 -0800783 void PushComment( const char* comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800784 void PushDeclaration( const char* value );
785 void PushUnknown( const char* value );
Lee Thomason5cae8972012-01-24 18:03:07 -0800786
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800787 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
Lee Thomason751da522012-02-10 08:50:51 -0800788 virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; }
789
790 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
791 virtual bool VisitExit( const XMLElement& element );
792
793 virtual bool Visit( const XMLText& text );
794 virtual bool Visit( const XMLComment& comment );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800795 virtual bool Visit( const XMLDeclaration& declaration );
796 virtual bool Visit( const XMLUnknown& unknown );
Lee Thomason751da522012-02-10 08:50:51 -0800797
U-Stream\Leeae25a442012-02-17 17:48:16 -0800798 const char* CStr() const { return buffer.Mem(); }
Lee Thomason751da522012-02-10 08:50:51 -0800799
Lee Thomason5cae8972012-01-24 18:03:07 -0800800private:
801 void SealElement();
802 void PrintSpace( int depth );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800803 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
U-Stream\Leeae25a442012-02-17 17:48:16 -0800804 void Print( const char* format, ... );
Lee Thomason5cae8972012-01-24 18:03:07 -0800805
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800806 bool elementJustOpened;
807 bool firstElement;
Lee Thomason5cae8972012-01-24 18:03:07 -0800808 FILE* fp;
809 int depth;
Lee Thomason56bdd022012-02-09 18:16:58 -0800810 int textDepth;
811
Lee Thomason857b8682012-01-25 17:50:25 -0800812 enum {
Lee Thomason951d8832012-01-26 08:47:06 -0800813 ENTITY_RANGE = 64
Lee Thomason857b8682012-01-25 17:50:25 -0800814 };
815 bool entityFlag[ENTITY_RANGE];
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800816 bool restrictedEntityFlag[ENTITY_RANGE];
Lee Thomason5cae8972012-01-24 18:03:07 -0800817
Lee Thomason2c85a712012-01-31 08:24:24 -0800818 DynArray< const char*, 10 > stack;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800819 DynArray< char, 20 > buffer, accumulator;
Lee Thomason5cae8972012-01-24 18:03:07 -0800820};
821
822
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800823}; // tinyxml2
824
U-Lama\Lee560bd472011-12-28 19:42:49 -0800825
826
U-Stream\Leeae25a442012-02-17 17:48:16 -0800827#endif // TINYXML2_INCLUDED