blob: 4fbd33c84ac3fd912d71b4af99304f4454a0464a [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#ifndef TINYXML2_INCLUDED
2#define TINYXML2_INCLUDED
3
U-Lama\Lee4cee6112011-12-31 14:58:18 -08004#include <limits.h>
Lee Thomasonce0763e2012-01-11 15:43:54 -08005#include <ctype.h>
6#include <stdio.h>
U-Lama\Lee4cee6112011-12-31 14:58:18 -08007
8#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
9 #ifndef DEBUG
10 #define DEBUG
11 #endif
12#endif
13
14
15#if defined(DEBUG)
16 #if defined(_MSC_VER)
17 #define TIXMLASSERT( x ) if ( !(x)) { _asm { int 3 } } //if ( !(x)) WinDebugBreak()
18 #elif defined (ANDROID_NDK)
19 #include <android/log.h>
20 #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
21 #else
22 #include <assert.h>
23 #define TIXMLASSERT assert
24 #endif
25#else
26 #define TIXMLASSERT( x ) {}
27#endif
28
U-Lama\Leee13c3e62011-12-28 14:36:55 -080029
30namespace tinyxml2
31{
Lee Thomasonce0763e2012-01-11 15:43:54 -080032class XMLDocument;
Lee Thomason8a5dfee2012-01-18 17:43:40 -080033class XMLElement;
34class XMLAttribute;
35class XMLComment;
36class XMLNode;
Lee Thomason5492a1c2012-01-23 15:32:10 -080037class XMLText;
U-Lama\Leee13c3e62011-12-28 14:36:55 -080038
U-Lama\Lee560bd472011-12-28 19:42:49 -080039// internal - move to separate namespace
40struct CharBuffer
41{
42 size_t length;
43 char mem[1];
44
45 static CharBuffer* Construct( const char* in );
46 static void Free( CharBuffer* );
47};
48
Lee Thomason39ede242012-01-20 11:27:56 -080049// FIXME: refactor to be the basis for all string handling.
50class StrPair
51{
Lee Thomasond34f52c2012-01-20 12:55:24 -080052public:
Lee Thomason39ede242012-01-20 11:27:56 -080053 enum {
Lee Thomasone4422302012-01-20 17:59:50 -080054 NEEDS_ENTITY_PROCESSING = 0x01,
55 NEEDS_NEWLINE_NORMALIZATION = 0x02
Lee Thomason39ede242012-01-20 11:27:56 -080056 };
57
58 StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
Lee Thomasone4422302012-01-20 17:59:50 -080059 void Set( char* start, char* end, int flags ) {
Lee Thomason39ede242012-01-20 11:27:56 -080060 this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
61 }
62 const char* GetStr();
Lee Thomasone4422302012-01-20 17:59:50 -080063 bool Empty() const { return start == end; }
Lee Thomason39ede242012-01-20 11:27:56 -080064
65private:
Lee Thomasone4422302012-01-20 17:59:50 -080066 enum {
67 NEEDS_FLUSH = 0x100
68 };
69
Lee Thomason39ede242012-01-20 11:27:56 -080070 // After parsing, if *end != 0, it can be set to zero.
71 int flags;
Lee Thomasone4422302012-01-20 17:59:50 -080072 char* start;
Lee Thomason39ede242012-01-20 11:27:56 -080073 char* end;
74};
75
U-Lama\Lee560bd472011-12-28 19:42:49 -080076
Lee Thomason8a5dfee2012-01-18 17:43:40 -080077class XMLBase
U-Lama\Leee13c3e62011-12-28 14:36:55 -080078{
79public:
Lee Thomason8a5dfee2012-01-18 17:43:40 -080080 XMLBase() {}
81 virtual ~XMLBase() {}
U-Lama\Lee4cee6112011-12-31 14:58:18 -080082
83protected:
Lee Thomason3f57d272012-01-11 15:30:03 -080084 static const char* SkipWhiteSpace( const char* p ) { while( isspace( *p ) ) { ++p; } return p; }
85 static char* SkipWhiteSpace( char* p ) { while( isspace( *p ) ) { ++p; } return p; }
U-Lama\Lee4cee6112011-12-31 14:58:18 -080086
87 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
88 int n = 0;
Lee Thomasond34f52c2012-01-20 12:55:24 -080089 if ( p == q ) {
90 return true;
91 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -080092 while( *p && *q && *p == *q && n<nChar ) {
93 ++p; ++q; ++n;
94 }
95 if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
96 return true;
97 }
98 return false;
99 }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800100 inline static int IsUTF8Continuation( unsigned char p ) { return p & 0x80; }
101 inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalnum( anyByte ) : 1; }
102 inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalpha( anyByte ) : 1; }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800103
Lee Thomasone4422302012-01-20 17:59:50 -0800104 char* ParseText( char* in, StrPair* pair, const char* endTag );
Lee Thomason39ede242012-01-20 11:27:56 -0800105 char* ParseName( char* in, StrPair* pair );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800106 char* Identify( XMLDocument* document, char* p, XMLNode** node );
107};
108
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800109class XMLNode : public XMLBase
110{
111 friend class XMLDocument;
112 friend class XMLElement;
113public:
114 virtual ~XMLNode();
115
116 XMLNode* InsertEndChild( XMLNode* addThis );
117 virtual void Print( FILE* cfile, int depth );
118
Lee Thomason5492a1c2012-01-23 15:32:10 -0800119 virtual XMLElement* ToElement() { return 0; }
120 virtual XMLText* ToText() { return 0; }
121 virtual XMLComment* ToComment() { return 0; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800122
Lee Thomason67d61312012-01-24 16:01:51 -0800123 // fixme: guarentee null terminator to avoid internal checks
124 virtual char* ParseDeep( char* );
125
126 void SetTextParent() { isTextParent = true; }
127 bool IsTextParent() const { return isTextParent; }
128 virtual bool IsClosingElement() const { return false; }
Lee Thomason3f57d272012-01-11 15:30:03 -0800129
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800130protected:
131 XMLNode( XMLDocument* );
Lee Thomasond923c672012-01-23 08:44:25 -0800132 void Unlink( XMLNode* child );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800133
Lee Thomason3f57d272012-01-11 15:30:03 -0800134 XMLDocument* document;
135 XMLNode* parent;
Lee Thomason67d61312012-01-24 16:01:51 -0800136 bool isTextParent;
Lee Thomason3f57d272012-01-11 15:30:03 -0800137
138 XMLNode* firstChild;
139 XMLNode* lastChild;
140
141 XMLNode* prev;
142 XMLNode* next;
143
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800144private:
Lee Thomason85403d82012-01-11 15:55:05 -0800145 void PrintSpace( FILE* cfile, int depth ); // prints leading spaces.
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800146
147};
148
149
Lee Thomason5492a1c2012-01-23 15:32:10 -0800150class XMLText : public XMLNode
151{
152public:
153 XMLText( XMLDocument* doc ) : XMLNode( doc ) {}
154 virtual ~XMLText() {}
155
156 virtual void Print( FILE* cfile, int depth );
157 const char* Value() { return value.GetStr(); }
158 virtual XMLText* ToText() { return this; }
159
160 char* ParseDeep( char* );
161
162protected:
163
164private:
165 StrPair value;
166};
167
168
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800169class XMLComment : public XMLNode
170{
Lee Thomason3f57d272012-01-11 15:30:03 -0800171public:
172 XMLComment( XMLDocument* doc );
173 virtual ~XMLComment();
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800174
Lee Thomason85403d82012-01-11 15:55:05 -0800175 virtual void Print( FILE* cfile, int depth );
Lee Thomason5492a1c2012-01-23 15:32:10 -0800176 virtual XMLComment* ToComment() { return this; }
Lee Thomasonce0763e2012-01-11 15:43:54 -0800177
Lee Thomasond34f52c2012-01-20 12:55:24 -0800178 const char* Value() { return value.GetStr(); }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800179
Lee Thomasonce0763e2012-01-11 15:43:54 -0800180 char* ParseDeep( char* );
181
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800182protected:
183
Lee Thomason3f57d272012-01-11 15:30:03 -0800184private:
Lee Thomasond34f52c2012-01-20 12:55:24 -0800185 StrPair value;
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800186};
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800187
188
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800189class XMLAttribute : public XMLBase
190{
191 friend class XMLElement;
192public:
Lee Thomasond34f52c2012-01-20 12:55:24 -0800193 XMLAttribute( XMLElement* element ) : next( 0 ) {}
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800194 virtual ~XMLAttribute() {}
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800195 virtual void Print( FILE* cfile );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800196
197private:
198 char* ParseDeep( char* p );
199
Lee Thomason22aead12012-01-23 13:29:35 -0800200 StrPair name;
Lee Thomasond34f52c2012-01-20 12:55:24 -0800201 StrPair value;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800202 XMLAttribute* next;
203};
204
205
206class XMLElement : public XMLNode
207{
208public:
209 XMLElement( XMLDocument* doc );
210 virtual ~XMLElement();
211
Lee Thomasond34f52c2012-01-20 12:55:24 -0800212 const char* Name() { return name.GetStr(); }
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800213 virtual void Print( FILE* cfile, int depth );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800214
215 virtual XMLElement* ToElement() { return this; }
Lee Thomason67d61312012-01-24 16:01:51 -0800216 virtual bool IsClosingElement() const { return closing; }
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800217
218 char* ParseDeep( char* p );
219
220protected:
221
222private:
Lee Thomason67d61312012-01-24 16:01:51 -0800223 char* ParseAttributes( char* p, bool *closedElement );
224
Lee Thomasond34f52c2012-01-20 12:55:24 -0800225 StrPair name;
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800226 bool closing;
227 XMLAttribute* rootAttribute;
228 XMLAttribute* lastAttribute;
229};
230
231
Lee Thomason67d61312012-01-24 16:01:51 -0800232class XMLDocument : public XMLNode
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800233{
234public:
235 XMLDocument();
Lee Thomason3f57d272012-01-11 15:30:03 -0800236 ~XMLDocument();
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800237
238 bool Parse( const char* );
Lee Thomasonce0763e2012-01-11 15:43:54 -0800239 void Print( FILE* cfile=stdout, int depth=0 );
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800240
Lee Thomason67d61312012-01-24 16:01:51 -0800241 /*
Lee Thomason3f57d272012-01-11 15:30:03 -0800242 XMLNode* Root() { return root; }
243 XMLNode* RootElement();
Lee Thomason67d61312012-01-24 16:01:51 -0800244 */
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800245 enum {
246 ERROR_ELEMENT_MISMATCH,
247 ERROR_PARSING_ELEMENT,
248 ERROR_PARSING_ATTRIBUTE
249 };
Lee Thomason67d61312012-01-24 16:01:51 -0800250 void SetError( int error, const char* str1, const char* str2 );
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800251
Lee Thomason3f57d272012-01-11 15:30:03 -0800252private:
253 XMLDocument( const XMLDocument& ); // intentionally not implemented
U-Lama\Lee560bd472011-12-28 19:42:49 -0800254 CharBuffer* charBuffer;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800255};
256
257
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800258}; // tinyxml2
259
U-Lama\Lee560bd472011-12-28 19:42:49 -0800260
261
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800262#endif // TINYXML2_INCLUDED