tinyxml2.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "tinyxml2.h"
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. using namespace tinyxml2;
  7. // --------- CharBuffer ----------- //
  8. /*static*/ CharBuffer* CharBuffer::Construct( const char* in )
  9. {
  10. size_t len = strlen( in );
  11. size_t size = len + sizeof( CharBuffer );
  12. CharBuffer* cb = (CharBuffer*) malloc( size );
  13. cb->length = len;
  14. strcpy( cb->mem, in );
  15. return cb;
  16. }
  17. /*static*/ void CharBuffer::Free( CharBuffer* cb )
  18. {
  19. free( cb );
  20. }
  21. // --------- XMLNode ----------- //
  22. XMLNode::XMLNode( XMLDocument* doc ) :
  23. document( doc ),
  24. parent( 0 ),
  25. firstChild( 0 ), lastChild( 0 ),
  26. prev( 0 ), next( 0 )
  27. {
  28. }
  29. XMLNode::~XMLNode()
  30. {
  31. XMLNode* node=firstChild;
  32. while( node ) {
  33. XMLNode* temp = node->next;
  34. delete node;
  35. node = temp;
  36. }
  37. }
  38. XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
  39. {
  40. if ( lastChild ) {
  41. TIXMLASSERT( firstChild );
  42. TIXMLASSERT( lastChild->next == 0 );
  43. lastChild->next = addThis;
  44. addThis->prev = lastChild;
  45. lastChild = addThis;
  46. addThis->parent = this;
  47. addThis->next = 0;
  48. }
  49. else {
  50. TIXMLASSERT( firstChild == 0 );
  51. firstChild = lastChild = addThis;
  52. addThis->parent = this;
  53. addThis->prev = 0;
  54. addThis->next = 0;
  55. }
  56. return addThis;
  57. }
  58. void XMLNode::Print( FILE* fp, int depth )
  59. {
  60. for( int i=0; i<depth; ++i ) {
  61. fprintf( fp, " " );
  62. }
  63. }
  64. const char* XMLNode::ParseText( char* p, const char* endTag, char** next )
  65. {
  66. TIXMLASSERT( endTag && *endTag );
  67. char* start = SkipWhiteSpace( p );
  68. if ( !start )
  69. return 0;
  70. char endChar = *endTag;
  71. p = start;
  72. int length = strlen( endTag );
  73. while ( *p ) {
  74. if ( *p == endChar ) {
  75. if ( strncmp( p, endTag, length ) == 0 ) {
  76. *p = 0;
  77. *next = p + length;
  78. return start;
  79. }
  80. }
  81. ++p;
  82. }
  83. return 0;
  84. }
  85. // --------- XMLComment ---------- //
  86. XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
  87. {
  88. }
  89. XMLComment::~XMLComment()
  90. {
  91. }
  92. void XMLComment::Print( FILE* fp, int depth )
  93. {
  94. XMLNode::Print( fp, depth );
  95. fprintf( fp, "<!-- %s -->\n", value );
  96. }
  97. char* XMLComment::ParseDeep( char* p )
  98. {
  99. // Comment parses as text.
  100. value = ParseText( p, "-->", &p );
  101. return p;
  102. }
  103. // --------- XMLDocument ----------- //
  104. XMLDocument::XMLDocument() :
  105. charBuffer( 0 )
  106. {
  107. }
  108. XMLDocument::~XMLDocument()
  109. {
  110. delete root;
  111. delete charBuffer;
  112. }
  113. bool XMLDocument::Parse( const char* p )
  114. {
  115. charBuffer = CharBuffer::Construct( p );
  116. XMLNode* node = 0;
  117. char* q = Identify( charBuffer->mem, &node );
  118. node->ParseDeep( q );
  119. return true;
  120. }
  121. void XMLDocument::Print( FILE* fp, int depth )
  122. {
  123. for( XMLNode* node = root->firstChild; node; node=node->next ) {
  124. node->Print( fp, depth );
  125. }
  126. }
  127. char* XMLDocument::Identify( char* p, XMLNode** node )
  128. {
  129. XMLNode* returnNode = 0;
  130. p = XMLNode::SkipWhiteSpace( p );
  131. if( !p || !*p || *p != '<' )
  132. {
  133. return 0;
  134. }
  135. // What is this thing?
  136. // - Elements start with a letter or underscore, but xml is reserved.
  137. // - Comments: <!--
  138. // - Decleration: <?xml
  139. // - Everthing else is unknown to tinyxml.
  140. //
  141. const char* xmlHeader = { "<?xml" };
  142. const char* commentHeader = { "<!--" };
  143. const char* dtdHeader = { "<!" };
  144. const char* cdataHeader = { "<![CDATA[" };
  145. if ( XMLNode::StringEqual( p, xmlHeader, 5 ) ) {
  146. returnNode = new XMLComment( this );
  147. }
  148. else {
  149. TIXMLASSERT( 0 );
  150. }
  151. *node = returnNode;
  152. return p;
  153. }