tinyxml2.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #ifndef TINYXML2_INCLUDED
  2. #define TINYXML2_INCLUDED
  3. #include <limits.h>
  4. #include <ctype.h>
  5. #include <stdio.h>
  6. #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
  7. #ifndef DEBUG
  8. #define DEBUG
  9. #endif
  10. #endif
  11. #if defined(DEBUG)
  12. #if defined(_MSC_VER)
  13. #define TIXMLASSERT( x ) if ( !(x)) { _asm { int 3 } } //if ( !(x)) WinDebugBreak()
  14. #elif defined (ANDROID_NDK)
  15. #include <android/log.h>
  16. #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
  17. #else
  18. #include <assert.h>
  19. #define TIXMLASSERT assert
  20. #endif
  21. #else
  22. #define TIXMLASSERT( x ) {}
  23. #endif
  24. namespace tinyxml2
  25. {
  26. class XMLDocument;
  27. class XMLElement;
  28. class XMLAttribute;
  29. class XMLComment;
  30. class XMLNode;
  31. class XMLText;
  32. // internal - move to separate namespace
  33. struct CharBuffer
  34. {
  35. size_t length;
  36. char mem[1];
  37. static CharBuffer* Construct( const char* in );
  38. static void Free( CharBuffer* );
  39. };
  40. // FIXME: refactor to be the basis for all string handling.
  41. class StrPair
  42. {
  43. public:
  44. enum {
  45. NEEDS_ENTITY_PROCESSING = 0x01,
  46. NEEDS_NEWLINE_NORMALIZATION = 0x02
  47. };
  48. StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
  49. void Set( char* start, char* end, int flags ) {
  50. this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
  51. }
  52. const char* GetStr();
  53. bool Empty() const { return start == end; }
  54. private:
  55. enum {
  56. NEEDS_FLUSH = 0x100
  57. };
  58. // After parsing, if *end != 0, it can be set to zero.
  59. int flags;
  60. char* start;
  61. char* end;
  62. };
  63. class XMLBase
  64. {
  65. public:
  66. XMLBase() {}
  67. virtual ~XMLBase() {}
  68. protected:
  69. static const char* SkipWhiteSpace( const char* p ) { while( isspace( *p ) ) { ++p; } return p; }
  70. static char* SkipWhiteSpace( char* p ) { while( isspace( *p ) ) { ++p; } return p; }
  71. inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
  72. int n = 0;
  73. if ( p == q ) {
  74. return true;
  75. }
  76. while( *p && *q && *p == *q && n<nChar ) {
  77. ++p; ++q; ++n;
  78. }
  79. if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {
  80. return true;
  81. }
  82. return false;
  83. }
  84. inline static int IsUTF8Continuation( unsigned char p ) { return p & 0x80; }
  85. inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalnum( anyByte ) : 1; }
  86. inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte <= 127 ) ? isalpha( anyByte ) : 1; }
  87. char* ParseText( char* in, StrPair* pair, const char* endTag );
  88. char* ParseName( char* in, StrPair* pair );
  89. char* Identify( XMLDocument* document, char* p, XMLNode** node );
  90. };
  91. class XMLNode : public XMLBase
  92. {
  93. friend class XMLDocument;
  94. friend class XMLElement;
  95. public:
  96. virtual ~XMLNode();
  97. XMLNode* InsertEndChild( XMLNode* addThis );
  98. virtual void Print( FILE* cfile, int depth );
  99. virtual XMLElement* ToElement() { return 0; }
  100. virtual XMLText* ToText() { return 0; }
  101. virtual XMLComment* ToComment() { return 0; }
  102. virtual char* ParseDeep( char* ) { TIXMLASSERT( 0 ); }
  103. protected:
  104. XMLNode( XMLDocument* );
  105. void Unlink( XMLNode* child );
  106. XMLDocument* document;
  107. XMLNode* parent;
  108. XMLNode* firstChild;
  109. XMLNode* lastChild;
  110. XMLNode* prev;
  111. XMLNode* next;
  112. private:
  113. void PrintSpace( FILE* cfile, int depth ); // prints leading spaces.
  114. };
  115. class XMLText : public XMLNode
  116. {
  117. public:
  118. XMLText( XMLDocument* doc ) : XMLNode( doc ) {}
  119. virtual ~XMLText() {}
  120. virtual void Print( FILE* cfile, int depth );
  121. const char* Value() { return value.GetStr(); }
  122. virtual XMLText* ToText() { return this; }
  123. char* ParseDeep( char* );
  124. protected:
  125. private:
  126. StrPair value;
  127. };
  128. class XMLComment : public XMLNode
  129. {
  130. public:
  131. XMLComment( XMLDocument* doc );
  132. virtual ~XMLComment();
  133. virtual void Print( FILE* cfile, int depth );
  134. virtual XMLComment* ToComment() { return this; }
  135. const char* Value() { return value.GetStr(); }
  136. char* ParseDeep( char* );
  137. protected:
  138. private:
  139. StrPair value;
  140. };
  141. class XMLAttribute : public XMLBase
  142. {
  143. friend class XMLElement;
  144. public:
  145. XMLAttribute( XMLElement* element ) : next( 0 ) {}
  146. virtual ~XMLAttribute() {}
  147. virtual void Print( FILE* cfile );
  148. private:
  149. char* ParseDeep( char* p );
  150. StrPair name;
  151. StrPair value;
  152. XMLAttribute* next;
  153. };
  154. class XMLElement : public XMLNode
  155. {
  156. public:
  157. XMLElement( XMLDocument* doc );
  158. virtual ~XMLElement();
  159. const char* Name() { return name.GetStr(); }
  160. virtual void Print( FILE* cfile, int depth );
  161. virtual XMLElement* ToElement() { return this; }
  162. bool Closing() const { return closing; }
  163. char* ParseDeep( char* p );
  164. protected:
  165. private:
  166. StrPair name;
  167. bool closing;
  168. XMLAttribute* rootAttribute;
  169. XMLAttribute* lastAttribute;
  170. };
  171. class XMLDocument : public XMLBase
  172. {
  173. public:
  174. XMLDocument();
  175. ~XMLDocument();
  176. bool Parse( const char* );
  177. void Print( FILE* cfile=stdout, int depth=0 );
  178. XMLNode* Root() { return root; }
  179. XMLNode* RootElement();
  180. enum {
  181. ERROR_ELEMENT_MISMATCH,
  182. ERROR_PARSING_ELEMENT,
  183. ERROR_PARSING_ATTRIBUTE
  184. };
  185. void SetError( int error, const char* str1, const char* str2 ) {}
  186. private:
  187. XMLDocument( const XMLDocument& ); // intentionally not implemented
  188. XMLNode* root;
  189. CharBuffer* charBuffer;
  190. };
  191. }; // tinyxml2
  192. #endif // TINYXML2_INCLUDED