xmltest.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. #include "tinyxml2.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #if defined( WIN32 )
  6. #include <crtdbg.h>
  7. _CrtMemState startMemState;
  8. _CrtMemState endMemState;
  9. #endif
  10. using namespace tinyxml2;
  11. int gPass = 0;
  12. int gFail = 0;
  13. //#define DREAM_ONLY
  14. /*
  15. int gNew = 0;
  16. int gNewTotal = 0;
  17. void* operator new( size_t size )
  18. {
  19. ++gNew;
  20. return malloc( size );
  21. }
  22. void* operator new[]( size_t size )
  23. {
  24. ++gNew;
  25. return malloc( size );
  26. }
  27. void operator delete[]( void* mem )
  28. {
  29. free( mem );
  30. }
  31. void operator delete( void* mem )
  32. {
  33. free( mem );
  34. }
  35. */
  36. bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
  37. {
  38. bool pass = !strcmp( expected, found );
  39. if ( pass )
  40. printf ("[pass]");
  41. else
  42. printf ("[fail]");
  43. if ( !echo )
  44. printf (" %s\n", testString);
  45. else
  46. printf (" %s [%s][%s]\n", testString, expected, found);
  47. if ( pass )
  48. ++gPass;
  49. else
  50. ++gFail;
  51. return pass;
  52. }
  53. bool XMLTest( const char* testString, int expected, int found, bool echo=true )
  54. {
  55. bool pass = ( expected == found );
  56. if ( pass )
  57. printf ("[pass]");
  58. else
  59. printf ("[fail]");
  60. if ( !echo )
  61. printf (" %s\n", testString);
  62. else
  63. printf (" %s [%d][%d]\n", testString, expected, found);
  64. if ( pass )
  65. ++gPass;
  66. else
  67. ++gFail;
  68. return pass;
  69. }
  70. void NullLineEndings( char* p )
  71. {
  72. while( p && *p ) {
  73. if ( *p == '\n' || *p == '\r' ) {
  74. *p = 0;
  75. return;
  76. }
  77. ++p;
  78. }
  79. }
  80. int main( int argc, const char* argv )
  81. {
  82. #if defined( WIN32 )
  83. _CrtMemCheckpoint( &startMemState );
  84. #endif
  85. #ifndef DREAM_ONLY
  86. #if 0
  87. {
  88. static const char* test = "<!--hello world\n"
  89. " line 2\r"
  90. " line 3\r\n"
  91. " line 4\n\r"
  92. " line 5\r-->";
  93. XMLDocument doc;
  94. doc.Parse( test );
  95. doc.Print();
  96. }
  97. #endif
  98. #if 0
  99. {
  100. static const char* test[] = { "<element />",
  101. "<element></element>",
  102. "<element><subelement/></element>",
  103. "<element><subelement></subelement></element>",
  104. "<element><subelement><subsub/></subelement></element>",
  105. "<!--comment beside elements--><element><subelement></subelement></element>",
  106. "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
  107. "<element attrib1='foo' attrib2=\"bar\" ></element>",
  108. "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
  109. "<element>Text inside element.</element>",
  110. "<element><b></b></element>",
  111. "<element>Text inside and <b>bolded</b> in the element.</element>",
  112. "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
  113. "<element>This &amp; That.</element>",
  114. "<element attrib='This&lt;That' />",
  115. 0
  116. };
  117. for( int i=0; test[i]; ++i ) {
  118. XMLDocument doc;
  119. doc.Parse( test[i] );
  120. doc.Print();
  121. printf( "----------------------------------------------\n" );
  122. }
  123. }
  124. #endif
  125. #if 0
  126. {
  127. static const char* test = "<element>Text before.</element>";
  128. XMLDocument doc;
  129. doc.Parse( test );
  130. XMLElement* root = doc.FirstChildElement();
  131. XMLElement* newElement = doc.NewElement( "Subelement" );
  132. root->InsertEndChild( newElement );
  133. doc.Print();
  134. }
  135. {
  136. XMLDocument* doc = new XMLDocument();
  137. static const char* test = "<element><sub/></element>";
  138. doc->Parse( test );
  139. delete doc;
  140. }
  141. #endif
  142. {
  143. #if 0
  144. // Test: Programmatic DOM
  145. // Build:
  146. // <element>
  147. // <!--comment-->
  148. // <sub attrib="1" />
  149. // <sub attrib="2" />
  150. // <sub attrib="3" >& Text!</sub>
  151. // <element>
  152. XMLDocument* doc = new XMLDocument();
  153. XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
  154. XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
  155. for( int i=0; i<3; ++i ) {
  156. sub[i]->SetAttribute( "attrib", i );
  157. }
  158. element->InsertEndChild( sub[2] );
  159. XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
  160. element->InsertAfterChild( comment, sub[0] );
  161. element->InsertAfterChild( sub[0], sub[1] );
  162. sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
  163. doc->Print();
  164. XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
  165. XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
  166. XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
  167. XMLTest( "Programmatic DOM", "& Text!",
  168. doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
  169. // And now deletion:
  170. element->DeleteChild( sub[2] );
  171. doc->DeleteNode( comment );
  172. element->FirstChildElement()->SetAttribute( "attrib", true );
  173. element->LastChildElement()->DeleteAttribute( "attrib" );
  174. XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
  175. int value = 10;
  176. int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
  177. XMLTest( "Programmatic DOM", result, NO_ATTRIBUTE );
  178. XMLTest( "Programmatic DOM", value, 10 );
  179. doc->Print();
  180. XMLStreamer streamer;
  181. doc->Print( &streamer );
  182. printf( "%s", streamer.CStr() );
  183. delete doc;
  184. #endif
  185. }
  186. #endif
  187. {
  188. #if 0
  189. // Test: Dream
  190. // XML1 : 1,187,569 bytes in 31,209 allocations
  191. // XML2 : 469,073 bytes in 323 allocations
  192. //int newStart = gNew;
  193. XMLDocument doc;
  194. doc.LoadFile( "dream.xml" );
  195. doc.SaveFile( "dreamout.xml" );
  196. doc.PrintError();
  197. XMLTest( "Dream", "xml version=\"1.0\"",
  198. doc.FirstChild()->ToDeclaration()->Value() );
  199. XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
  200. XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
  201. doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
  202. XMLTest( "Dream", "And Robin shall restore amends.",
  203. doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
  204. XMLTest( "Dream", "And Robin shall restore amends.",
  205. doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
  206. XMLDocument doc2;
  207. doc2.LoadFile( "dreamout.xml" );
  208. XMLTest( "Dream-out", "xml version=\"1.0\"",
  209. doc2.FirstChild()->ToDeclaration()->Value() );
  210. XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
  211. XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
  212. doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
  213. XMLTest( "Dream-out", "And Robin shall restore amends.",
  214. doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
  215. #endif
  216. //gNewTotal = gNew - newStart;
  217. }
  218. #if 0
  219. {
  220. const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
  221. "<passages count=\"006\" formatversion=\"20020620\">\n"
  222. " <wrong error>\n"
  223. "</passages>";
  224. XMLDocument doc;
  225. doc.Parse( error );
  226. XMLTest( "Bad XML", doc.ErrorID(), ERROR_PARSING_ATTRIBUTE );
  227. }
  228. {
  229. const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
  230. XMLDocument doc;
  231. doc.Parse( str );
  232. XMLElement* ele = doc.FirstChildElement();
  233. int iVal, result;
  234. double dVal;
  235. result = ele->QueryDoubleAttribute( "attr0", &dVal );
  236. XMLTest( "Query attribute: int as double", result, XML_NO_ERROR );
  237. XMLTest( "Query attribute: int as double", (int)dVal, 1 );
  238. result = ele->QueryDoubleAttribute( "attr1", &dVal );
  239. XMLTest( "Query attribute: double as double", (int)dVal, 2 );
  240. result = ele->QueryIntAttribute( "attr1", &iVal );
  241. XMLTest( "Query attribute: double as int", result, XML_NO_ERROR );
  242. XMLTest( "Query attribute: double as int", iVal, 2 );
  243. result = ele->QueryIntAttribute( "attr2", &iVal );
  244. XMLTest( "Query attribute: not a number", result, WRONG_ATTRIBUTE_TYPE );
  245. result = ele->QueryIntAttribute( "bar", &iVal );
  246. XMLTest( "Query attribute: does not exist", result, NO_ATTRIBUTE );
  247. }
  248. {
  249. const char* str = "<doc/>";
  250. XMLDocument doc;
  251. doc.Parse( str );
  252. XMLElement* ele = doc.FirstChildElement();
  253. int iVal;
  254. double dVal;
  255. ele->SetAttribute( "str", "strValue" );
  256. ele->SetAttribute( "int", 1 );
  257. ele->SetAttribute( "double", -1.0 );
  258. const char* cStr = ele->Attribute( "str" );
  259. ele->QueryIntAttribute( "int", &iVal );
  260. ele->QueryDoubleAttribute( "double", &dVal );
  261. XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
  262. XMLTest( "Attribute round trip. int.", 1, iVal );
  263. XMLTest( "Attribute round trip. double.", -1, (int)dVal );
  264. }
  265. #endif
  266. {
  267. XMLDocument doc;
  268. doc.LoadFile( "utf8test.xml" );
  269. // Get the attribute "value" from the "Russian" element and check it.
  270. XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
  271. const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
  272. 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
  273. XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
  274. const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
  275. 0xd1U, 0x81U, 0xd1U, 0x81U,
  276. 0xd0U, 0xbaU, 0xd0U, 0xb8U,
  277. 0xd0U, 0xb9U, 0 };
  278. const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
  279. XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
  280. XMLTest( "UTF-8: Browsing russian element name.",
  281. russianText,
  282. text->Value() );
  283. // Now try for a round trip.
  284. doc.SaveFile( "utf8testout.xml" );
  285. // Check the round trip.
  286. char savedBuf[256];
  287. char verifyBuf[256];
  288. int okay = 0;
  289. FILE* saved = fopen( "utf8testout.xml", "r" );
  290. FILE* verify = fopen( "utf8testverify.xml", "r" );
  291. if ( saved && verify )
  292. {
  293. okay = 1;
  294. while ( fgets( verifyBuf, 256, verify ) )
  295. {
  296. fgets( savedBuf, 256, saved );
  297. NullLineEndings( verifyBuf );
  298. NullLineEndings( savedBuf );
  299. if ( strcmp( verifyBuf, savedBuf ) )
  300. {
  301. printf( "verify:%s<\n", verifyBuf );
  302. printf( "saved :%s<\n", savedBuf );
  303. okay = 0;
  304. break;
  305. }
  306. }
  307. }
  308. if ( saved )
  309. fclose( saved );
  310. if ( verify )
  311. fclose( verify );
  312. XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
  313. }
  314. #if defined( WIN32 )
  315. _CrtMemCheckpoint( &endMemState );
  316. //_CrtMemDumpStatistics( &endMemState );
  317. _CrtMemState diffMemState;
  318. _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
  319. _CrtMemDumpStatistics( &diffMemState );
  320. //printf( "new total=%d\n", gNewTotal );
  321. #endif
  322. printf ("\nPass %d, Fail %d\n", gPass, gFail);
  323. return 0;
  324. }