blob: 5077c25000540b1dc5723d213ab53998e1f5e6c3 [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#include "tinyxml2.h"
2
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -07003#include <cstdlib>
4#include <cstring>
5#include <ctime>
U-Lama\Leee13c3e62011-12-28 14:36:55 -08006
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -08007#if defined( _MSC_VER )
Lee Thomasone9699e62012-07-25 12:24:23 -07008 #include <direct.h> // _mkdir
Lee Thomason1ff38e02012-02-14 18:18:16 -08009 #include <crtdbg.h>
Lee Thomason6f381b72012-03-02 12:59:39 -080010 #define WIN32_LEAN_AND_MEAN
11 #include <windows.h>
Lee Thomason1ff38e02012-02-14 18:18:16 -080012 _CrtMemState startMemState;
13 _CrtMemState endMemState;
Lee Thomasone9699e62012-07-25 12:24:23 -070014#else
15 #include <sys/stat.h> // mkdir
Lee Thomason1ff38e02012-02-14 18:18:16 -080016#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -080017
U-Lama\Leee13c3e62011-12-28 14:36:55 -080018using namespace tinyxml2;
Lee Thomasonec5a7b42012-02-13 18:16:52 -080019int gPass = 0;
20int gFail = 0;
21
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080022
U-Stream\Lee09a11c52012-02-17 08:31:16 -080023bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080024{
25 bool pass = !strcmp( expected, found );
26 if ( pass )
27 printf ("[pass]");
28 else
29 printf ("[fail]");
30
U-Stream\Lee09a11c52012-02-17 08:31:16 -080031 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080032 printf (" %s\n", testString);
33 else
34 printf (" %s [%s][%s]\n", testString, expected, found);
35
36 if ( pass )
37 ++gPass;
38 else
39 ++gFail;
40 return pass;
41}
42
43
Lee Thomason21be8822012-07-15 17:27:22 -070044template< class T > bool XMLTest( const char* testString, T expected, T found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080045{
46 bool pass = ( expected == found );
47 if ( pass )
48 printf ("[pass]");
49 else
50 printf ("[fail]");
51
U-Stream\Lee09a11c52012-02-17 08:31:16 -080052 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080053 printf (" %s\n", testString);
54 else
Lee Thomasonc8312792012-07-16 12:44:41 -070055 printf (" %s [%d][%d]\n", testString, static_cast<int>(expected), static_cast<int>(found) );
Lee Thomason1ff38e02012-02-14 18:18:16 -080056
57 if ( pass )
58 ++gPass;
59 else
60 ++gFail;
61 return pass;
62}
Lee Thomasonec5a7b42012-02-13 18:16:52 -080063
U-Lama\Leee13c3e62011-12-28 14:36:55 -080064
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -080065void NullLineEndings( char* p )
66{
67 while( p && *p ) {
68 if ( *p == '\n' || *p == '\r' ) {
69 *p = 0;
70 return;
71 }
72 ++p;
73 }
74}
75
76
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -070077// Comments in the header. (Don't know how to get Doxygen to read comments in this file.)
78int example_1()
79{
80 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -030081 doc.LoadFile( "resources/dream.xml" );
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -070082
83 return doc.ErrorID();
84}
85
86
87// Comments in the header. (Don't know how to get Doxygen to read comments in this file.)
88int example_2()
89{
90 static const char* xml = "<element/>";
91 XMLDocument doc;
92 doc.Parse( xml );
93
94 return doc.ErrorID();
95}
96
97
98int example_3()
99{
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700100 static const char* xml =
101 "<?xml version=\"1.0\"?>"
102 "<!DOCTYPE PLAY SYSTEM \"play.dtd\">"
103 "<PLAY>"
104 "<TITLE>A Midsummer Night's Dream</TITLE>"
105 "</PLAY>";
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700106
107 XMLDocument doc;
108 doc.Parse( xml );
109
110 XMLElement* titleElement = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" );
111 const char* title = titleElement->GetText();
112 printf( "Name of play (1): %s\n", title );
113
114 XMLText* textNode = titleElement->FirstChild()->ToText();
115 title = textNode->Value();
116 printf( "Name of play (2): %s\n", title );
117
118 return doc.ErrorID();
119}
120
121
Lee Thomason21be8822012-07-15 17:27:22 -0700122bool example_4()
123{
124 static const char* xml =
125 "<information>"
126 " <attributeApproach v='2' />"
127 " <textApproach>"
128 " <v>2</v>"
129 " </textApproach>"
130 "</information>";
131
132 XMLDocument doc;
133 doc.Parse( xml );
134
135 int v0 = 0;
136 int v1 = 0;
137
138 XMLElement* attributeApproachElement = doc.FirstChildElement()->FirstChildElement( "attributeApproach" );
139 attributeApproachElement->QueryIntAttribute( "v", &v0 );
140
141 XMLElement* textApproachElement = doc.FirstChildElement()->FirstChildElement( "textApproach" );
142 textApproachElement->FirstChildElement( "v" )->QueryIntText( &v1 );
143
144 printf( "Both values are the same: %d and %d\n", v0, v1 );
145
146 return !doc.Error() && ( v0 == v1 );
147}
148
149
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -0700150int main( int /*argc*/, const char ** /*argv*/ )
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800151{
Lee Thomason (grinliz)0a4df402012-02-27 20:50:52 -0800152 #if defined( _MSC_VER ) && defined( DEBUG )
Lee Thomason1ff38e02012-02-14 18:18:16 -0800153 _CrtMemCheckpoint( &startMemState );
154 #endif
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800155
Lee Thomason7f7b1622012-03-24 12:49:03 -0700156 #if defined(_MSC_VER)
157 #pragma warning ( push )
158 #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
159 #endif
160
Lee Thomasone9699e62012-07-25 12:24:23 -0700161 #if defined(_MSC_VER)
162 _mkdir( "resources/out/" );
163 #else
164 mkdir( "resources/out/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
165 #endif
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400166
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300167 FILE* fp = fopen( "resources/dream.xml", "r" );
Lee Thomason7f7b1622012-03-24 12:49:03 -0700168 if ( !fp ) {
169 printf( "Error opening test file 'dream.xml'.\n"
170 "Is your working directory the same as where \n"
171 "the xmltest.cpp and dream.xml file are?\n\n"
172 #if defined( _MSC_VER )
173 "In windows Visual Studio you may need to set\n"
174 "Properties->Debugging->Working Directory to '..'\n"
175 #endif
176 );
177 exit( 1 );
178 }
179 fclose( fp );
180
181 #if defined(_MSC_VER)
182 #pragma warning ( pop )
183 #endif
184
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700185 XMLTest( "Example-1", 0, example_1() );
186 XMLTest( "Example-2", 0, example_2() );
187 XMLTest( "Example-3", 0, example_3() );
Lee Thomason21be8822012-07-15 17:27:22 -0700188 XMLTest( "Example-4", true, example_4() );
Lee Thomason87e475a2012-03-20 11:55:29 -0700189
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700190 /* ------ Example 2: Lookup information. ---- */
Lee Thomason87e475a2012-03-20 11:55:29 -0700191
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800192 {
Lee Thomason43f59302012-02-06 18:18:11 -0800193 static const char* test[] = { "<element />",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400194 "<element></element>",
Lee Thomason43f59302012-02-06 18:18:11 -0800195 "<element><subelement/></element>",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400196 "<element><subelement></subelement></element>",
197 "<element><subelement><subsub/></subelement></element>",
198 "<!--comment beside elements--><element><subelement></subelement></element>",
199 "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
200 "<element attrib1='foo' attrib2=\"bar\" ></element>",
201 "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
Lee Thomason43f59302012-02-06 18:18:11 -0800202 "<element>Text inside element.</element>",
203 "<element><b></b></element>",
204 "<element>Text inside and <b>bolded</b> in the element.</element>",
205 "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
Lee Thomason8ee79892012-01-25 17:44:30 -0800206 "<element>This &amp; That.</element>",
Lee Thomason18d68bd2012-01-26 18:17:26 -0800207 "<element attrib='This&lt;That' />",
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800208 0
209 };
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800210 for( int i=0; test[i]; ++i ) {
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800211 XMLDocument doc;
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800212 doc.Parse( test[i] );
Lee Thomason5cae8972012-01-24 18:03:07 -0800213 doc.Print();
Lee Thomasonec975ce2012-01-23 11:42:06 -0800214 printf( "----------------------------------------------\n" );
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800215 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800216 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800217#if 1
Lee Thomasond6277762012-02-22 16:00:12 -0800218 {
219 static const char* test = "<!--hello world\n"
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400220 " line 2\r"
221 " line 3\r\n"
222 " line 4\n\r"
223 " line 5\r-->";
Lee Thomasond6277762012-02-22 16:00:12 -0800224
225 XMLDocument doc;
226 doc.Parse( test );
227 doc.Print();
228 }
229
Lee Thomason2c85a712012-01-31 08:24:24 -0800230 {
231 static const char* test = "<element>Text before.</element>";
232 XMLDocument doc;
233 doc.Parse( test );
234 XMLElement* root = doc.FirstChildElement();
235 XMLElement* newElement = doc.NewElement( "Subelement" );
236 root->InsertEndChild( newElement );
237 doc.Print();
238 }
Lee Thomasond1983222012-02-06 08:41:24 -0800239 {
240 XMLDocument* doc = new XMLDocument();
241 static const char* test = "<element><sub/></element>";
242 doc->Parse( test );
243 delete doc;
244 }
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800245 {
Lee Thomason1ff38e02012-02-14 18:18:16 -0800246 // Test: Programmatic DOM
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800247 // Build:
248 // <element>
249 // <!--comment-->
250 // <sub attrib="1" />
251 // <sub attrib="2" />
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800252 // <sub attrib="3" >& Text!</sub>
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800253 // <element>
254
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800255 XMLDocument* doc = new XMLDocument();
Lee Thomason1ff38e02012-02-14 18:18:16 -0800256 XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
257
258 XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
259 for( int i=0; i<3; ++i ) {
260 sub[i]->SetAttribute( "attrib", i );
261 }
262 element->InsertEndChild( sub[2] );
263 XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
264 element->InsertAfterChild( comment, sub[0] );
265 element->InsertAfterChild( sub[0], sub[1] );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800266 sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800267 doc->Print();
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800268 XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
269 XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
270 XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
271 XMLTest( "Programmatic DOM", "& Text!",
272 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800273
274 // And now deletion:
275 element->DeleteChild( sub[2] );
276 doc->DeleteNode( comment );
277
278 element->FirstChildElement()->SetAttribute( "attrib", true );
279 element->LastChildElement()->DeleteAttribute( "attrib" );
280
281 XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
282 int value = 10;
283 int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
Lee Thomason21be8822012-07-15 17:27:22 -0700284 XMLTest( "Programmatic DOM", result, (int)XML_NO_ATTRIBUTE );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800285 XMLTest( "Programmatic DOM", value, 10 );
286
287 doc->Print();
288
Lee Thomason7b1b86a2012-06-04 17:01:38 -0700289 {
290 XMLPrinter streamer;
291 doc->Print( &streamer );
292 printf( "%s", streamer.CStr() );
293 }
294 {
295 XMLPrinter streamer( 0, true );
296 doc->Print( &streamer );
297 XMLTest( "Compact mode", "<element><sub attrib=\"1\"/><sub/></element>", streamer.CStr(), false );
298 }
Lee Thomason (grinliz)6b8b0122012-09-08 21:21:00 -0700299 doc->SaveFile( "./resources/out/pretty.xml" );
300 doc->SaveFile( "./resources/out/compact.xml", true );
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800301 delete doc;
302 }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800303 {
304 // Test: Dream
305 // XML1 : 1,187,569 bytes in 31,209 allocations
306 // XML2 : 469,073 bytes in 323 allocations
307 //int newStart = gNew;
308 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300309 doc.LoadFile( "resources/dream.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800310
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400311 doc.SaveFile( "resources/out/dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800312 doc.PrintError();
313
314 XMLTest( "Dream", "xml version=\"1.0\"",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400315 doc.FirstChild()->ToDeclaration()->Value() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800316 XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
317 XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
318 doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
319 XMLTest( "Dream", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400320 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800321 XMLTest( "Dream", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400322 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800323
324 XMLDocument doc2;
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400325 doc2.LoadFile( "resources/out/dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800326 XMLTest( "Dream-out", "xml version=\"1.0\"",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400327 doc2.FirstChild()->ToDeclaration()->Value() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800328 XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
329 XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
330 doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
331 XMLTest( "Dream-out", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400332 doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800333
334 //gNewTotal = gNew - newStart;
335 }
Lee Thomason6f381b72012-03-02 12:59:39 -0800336
337
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800338 {
339 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
340 "<passages count=\"006\" formatversion=\"20020620\">\n"
341 " <wrong error>\n"
342 "</passages>";
343
344 XMLDocument doc;
345 doc.Parse( error );
Lee Thomason21be8822012-07-15 17:27:22 -0700346 XMLTest( "Bad XML", doc.ErrorID(), (int)XML_ERROR_PARSING_ATTRIBUTE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800347 }
348
349 {
350 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
351
352 XMLDocument doc;
353 doc.Parse( str );
354
355 XMLElement* ele = doc.FirstChildElement();
356
357 int iVal, result;
358 double dVal;
359
360 result = ele->QueryDoubleAttribute( "attr0", &dVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700361 XMLTest( "Query attribute: int as double", result, (int)XML_NO_ERROR );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800362 XMLTest( "Query attribute: int as double", (int)dVal, 1 );
363 result = ele->QueryDoubleAttribute( "attr1", &dVal );
364 XMLTest( "Query attribute: double as double", (int)dVal, 2 );
365 result = ele->QueryIntAttribute( "attr1", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700366 XMLTest( "Query attribute: double as int", result, (int)XML_NO_ERROR );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800367 XMLTest( "Query attribute: double as int", iVal, 2 );
368 result = ele->QueryIntAttribute( "attr2", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700369 XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800370 result = ele->QueryIntAttribute( "bar", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700371 XMLTest( "Query attribute: does not exist", result, (int)XML_NO_ATTRIBUTE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800372 }
373
374 {
375 const char* str = "<doc/>";
376
377 XMLDocument doc;
378 doc.Parse( str );
379
380 XMLElement* ele = doc.FirstChildElement();
381
382 int iVal;
383 double dVal;
384
385 ele->SetAttribute( "str", "strValue" );
386 ele->SetAttribute( "int", 1 );
387 ele->SetAttribute( "double", -1.0 );
388
389 const char* cStr = ele->Attribute( "str" );
390 ele->QueryIntAttribute( "int", &iVal );
391 ele->QueryDoubleAttribute( "double", &dVal );
392
Lee Thomason8ba7f7d2012-03-24 13:04:04 -0700393 XMLTest( "Attribute match test", ele->Attribute( "str", "strValue" ), "strValue" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800394 XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
395 XMLTest( "Attribute round trip. int.", 1, iVal );
396 XMLTest( "Attribute round trip. double.", -1, (int)dVal );
397 }
398
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800399 {
400 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300401 doc.LoadFile( "resources/utf8test.xml" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800402
403 // Get the attribute "value" from the "Russian" element and check it.
404 XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
405 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
406 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
407
408 XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
409
410 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
411 0xd1U, 0x81U, 0xd1U, 0x81U,
412 0xd0U, 0xbaU, 0xd0U, 0xb8U,
413 0xd0U, 0xb9U, 0 };
414 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
415
416 XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
417 XMLTest( "UTF-8: Browsing russian element name.",
418 russianText,
419 text->Value() );
420
421 // Now try for a round trip.
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400422 doc.SaveFile( "resources/out/utf8testout.xml" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800423
424 // Check the round trip.
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800425 int okay = 0;
426
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800427
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800428#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800429#pragma warning ( push )
430#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800431#endif
Thomas Roßa6dd8c62012-07-26 20:42:18 +0200432 FILE* saved = fopen( "resources/out/utf8testout.xml", "r" );
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300433 FILE* verify = fopen( "resources/utf8testverify.xml", "r" );
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800434#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800435#pragma warning ( pop )
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800436#endif
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800437
438 if ( saved && verify )
439 {
440 okay = 1;
PKEuSc28ba3a2012-07-16 03:08:47 -0700441 char verifyBuf[256];
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800442 while ( fgets( verifyBuf, 256, verify ) )
443 {
PKEuSc28ba3a2012-07-16 03:08:47 -0700444 char savedBuf[256];
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800445 fgets( savedBuf, 256, saved );
446 NullLineEndings( verifyBuf );
447 NullLineEndings( savedBuf );
448
449 if ( strcmp( verifyBuf, savedBuf ) )
450 {
451 printf( "verify:%s<\n", verifyBuf );
452 printf( "saved :%s<\n", savedBuf );
453 okay = 0;
454 break;
455 }
456 }
457 }
458 if ( saved )
459 fclose( saved );
460 if ( verify )
461 fclose( verify );
462 XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
463 }
464
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800465 // --------GetText()-----------
466 {
467 const char* str = "<foo>This is text</foo>";
468 XMLDocument doc;
469 doc.Parse( str );
470 const XMLElement* element = doc.RootElement();
471
472 XMLTest( "GetText() normal use.", "This is text", element->GetText() );
473
474 str = "<foo><b>This is text</b></foo>";
475 doc.Parse( str );
476 element = doc.RootElement();
477
478 XMLTest( "GetText() contained element.", element->GetText() == 0, true );
479 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800480
Lee Thomasond6277762012-02-22 16:00:12 -0800481
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800482 // ---------- CDATA ---------------
483 {
484 const char* str = "<xmlElement>"
485 "<![CDATA["
486 "I am > the rules!\n"
487 "...since I make symbolic puns"
488 "]]>"
489 "</xmlElement>";
490 XMLDocument doc;
491 doc.Parse( str );
492 doc.Print();
Lee Thomasond6277762012-02-22 16:00:12 -0800493
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800494 XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
495 "I am > the rules!\n...since I make symbolic puns",
Lee Thomasond6277762012-02-22 16:00:12 -0800496 false );
497 }
498
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800499 // ----------- CDATA -------------
500 {
501 const char* str = "<xmlElement>"
502 "<![CDATA["
503 "<b>I am > the rules!</b>\n"
504 "...since I make symbolic puns"
505 "]]>"
506 "</xmlElement>";
507 XMLDocument doc;
508 doc.Parse( str );
509 doc.Print();
510
511 XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
512 "<b>I am > the rules!</b>\n...since I make symbolic puns",
513 false );
514 }
515
516 // InsertAfterChild causes crash.
517 {
518 // InsertBeforeChild and InsertAfterChild causes crash.
519 XMLDocument doc;
520 XMLElement* parent = doc.NewElement( "Parent" );
521 doc.InsertFirstChild( parent );
522
523 XMLElement* childText0 = doc.NewElement( "childText0" );
524 XMLElement* childText1 = doc.NewElement( "childText1" );
525
526 XMLNode* childNode0 = parent->InsertEndChild( childText0 );
527 XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
528
529 XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true );
530 }
Lee Thomasond6277762012-02-22 16:00:12 -0800531
532 {
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800533 // Entities not being written correctly.
534 // From Lynn Allen
Lee Thomasond6277762012-02-22 16:00:12 -0800535
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800536 const char* passages =
537 "<?xml version=\"1.0\" standalone=\"no\" ?>"
538 "<passages count=\"006\" formatversion=\"20020620\">"
539 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
540 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
541 "</passages>";
Lee Thomasond6277762012-02-22 16:00:12 -0800542
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800543 XMLDocument doc;
544 doc.Parse( passages );
545 XMLElement* psg = doc.RootElement()->FirstChildElement();
546 const char* context = psg->Attribute( "context" );
547 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
Lee Thomasond6277762012-02-22 16:00:12 -0800548
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800549 XMLTest( "Entity transformation: read. ", expected, context, true );
Lee Thomasond6277762012-02-22 16:00:12 -0800550
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800551#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800552#pragma warning ( push )
553#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800554#endif
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400555 FILE* textfile = fopen( "resources/out/textfile.txt", "w" );
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800556#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800557#pragma warning ( pop )
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800558#endif
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800559 if ( textfile )
560 {
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800561 XMLPrinter streamer( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800562 psg->Accept( &streamer );
563 fclose( textfile );
564 }
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800565#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800566#pragma warning ( push )
567#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800568#endif
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400569 textfile = fopen( "resources/out/textfile.txt", "r" );
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800570#if defined(_MSC_VER)
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800571#pragma warning ( pop )
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800572#endif
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800573 TIXMLASSERT( textfile );
574 if ( textfile )
575 {
576 char buf[ 1024 ];
577 fgets( buf, 1024, textfile );
578 XMLTest( "Entity transformation: write. ",
579 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
580 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.\"/>\n",
581 buf, false );
PKEuSc28ba3a2012-07-16 03:08:47 -0700582 fclose( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800583 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800584 }
585
586 {
Lee Thomason6f381b72012-03-02 12:59:39 -0800587 // Suppress entities.
588 const char* passages =
589 "<?xml version=\"1.0\" standalone=\"no\" ?>"
590 "<passages count=\"006\" formatversion=\"20020620\">"
591 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.\">Crazy &ttk;</psg>"
592 "</passages>";
593
594 XMLDocument doc( false );
595 doc.Parse( passages );
596
597 XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ),
598 "Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;." );
599 XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(),
600 "Crazy &ttk;" );
601 doc.Print();
602 }
603
604 {
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400605 const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800606
607 XMLDocument doc;
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400608 doc.Parse( test );
609 XMLTest( "dot in names", doc.Error(), false );
610 XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
611 XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800612 }
613
614 {
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400615 const char* test = "<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>";
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800616
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400617 XMLDocument doc;
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800618 doc.Parse( test );
619
620 XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
621 XMLTest( "Entity with one digit.",
622 text->Value(), "1.1 Start easy ignore fin thickness\n",
623 false );
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400624 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800625
626 {
627 // DOCTYPE not preserved (950171)
628 //
629 const char* doctype =
630 "<?xml version=\"1.0\" ?>"
631 "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
632 "<!ELEMENT title (#PCDATA)>"
633 "<!ELEMENT books (title,authors)>"
634 "<element />";
635
636 XMLDocument doc;
637 doc.Parse( doctype );
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400638 doc.SaveFile( "resources/out/test7.xml" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800639 doc.DeleteChild( doc.RootElement() );
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400640 doc.LoadFile( "resources/out/test7.xml" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800641 doc.Print();
642
643 const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
644 XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
645
646 }
647
648 {
649 // Comments do not stream out correctly.
650 const char* doctype =
651 "<!-- Somewhat<evil> -->";
652 XMLDocument doc;
653 doc.Parse( doctype );
654
655 XMLComment* comment = doc.FirstChild()->ToComment();
656
657 XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
658 }
659 {
660 // Double attributes
661 const char* doctype = "<element attr='red' attr='blue' />";
662
663 XMLDocument doc;
664 doc.Parse( doctype );
665
Lee Thomason21be8822012-07-15 17:27:22 -0700666 XMLTest( "Parsing repeated attributes.", (int)XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
Lee Thomason (grinliz)0a4df402012-02-27 20:50:52 -0800667 doc.PrintError();
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800668 }
669
670 {
671 // Embedded null in stream.
672 const char* doctype = "<element att\0r='red' attr='blue' />";
673
674 XMLDocument doc;
675 doc.Parse( doctype );
676 XMLTest( "Embedded null throws error.", true, doc.Error() );
677 }
678
679 {
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -0700680 // Empty documents should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800681 const char* str = " ";
682 XMLDocument doc;
683 doc.Parse( str );
Lee Thomason21be8822012-07-15 17:27:22 -0700684 XMLTest( "Empty document error", (int)XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800685 }
686
687 {
688 // Low entities
689 XMLDocument doc;
690 doc.Parse( "<test>&#x0e;</test>" );
691 const char result[] = { 0x0e, 0 };
692 XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result );
693 doc.Print();
694 }
695
696 {
697 // Attribute values with trailing quotes not handled correctly
698 XMLDocument doc;
699 doc.Parse( "<foo attribute=bar\" />" );
700 XMLTest( "Throw error with bad end quotes.", doc.Error(), true );
701 }
702
703 {
704 // [ 1663758 ] Failure to report error on bad XML
705 XMLDocument xml;
706 xml.Parse("<x>");
707 XMLTest("Missing end tag at end of input", xml.Error(), true);
708 xml.Parse("<x> ");
709 XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
710 xml.Parse("<x></y>");
Lee Thomason21be8822012-07-15 17:27:22 -0700711 XMLTest("Mismatched tags", xml.ErrorID(), (int)XML_ERROR_MISMATCHED_ELEMENT);
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800712 }
713
714
715 {
716 // [ 1475201 ] TinyXML parses entities in comments
717 XMLDocument xml;
718 xml.Parse("<!-- declarations for <head> & <body> -->"
719 "<!-- far &amp; away -->" );
720
721 XMLNode* e0 = xml.FirstChild();
722 XMLNode* e1 = e0->NextSibling();
723 XMLComment* c0 = e0->ToComment();
724 XMLComment* c1 = e1->ToComment();
725
726 XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
727 XMLTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
728 }
729
730 {
731 XMLDocument xml;
732 xml.Parse( "<Parent>"
733 "<child1 att=''/>"
734 "<!-- With this comment, child2 will not be parsed! -->"
735 "<child2 att=''/>"
736 "</Parent>" );
737 xml.Print();
738
739 int count = 0;
740
741 for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild();
742 ele;
743 ele = ele->NextSibling() )
744 {
745 ++count;
746 }
747
748 XMLTest( "Comments iterate correctly.", 3, count );
749 }
750
751 {
752 // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
753 unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
754 buf[60] = 239;
755 buf[61] = 0;
756
757 XMLDocument doc;
758 doc.Parse( (const char*)buf);
759 }
760
761
762 {
763 // bug 1827248 Error while parsing a little bit malformed file
764 // Actually not malformed - should work.
765 XMLDocument xml;
766 xml.Parse( "<attributelist> </attributelist >" );
767 XMLTest( "Handle end tag whitespace", false, xml.Error() );
768 }
769
770 {
771 // This one must not result in an infinite loop
772 XMLDocument xml;
773 xml.Parse( "<infinite>loop" );
774 XMLTest( "Infinite loop test.", true, true );
775 }
776#endif
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800777 {
778 const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>";
779 XMLDocument doc;
780 doc.Parse( pub );
781
782 XMLDocument clone;
783 for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) {
784 XMLNode* copy = node->ShallowClone( &clone );
785 clone.InsertEndChild( copy );
786 }
787
788 clone.Print();
789
790 int count=0;
791 const XMLNode* a=clone.FirstChild();
792 const XMLNode* b=doc.FirstChild();
793 for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) {
794 ++count;
795 XMLTest( "Clone and Equal", true, a->ShallowEqual( b ));
796 }
797 XMLTest( "Clone and Equal", 4, count );
798 }
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800799
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700800 {
801 // This shouldn't crash.
802 XMLDocument doc;
803 if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))
804 {
805 doc.PrintError();
806 }
807 XMLTest( "Error in snprinf handling.", true, doc.Error() );
808 }
Lee Thomason5e3803c2012-04-16 08:57:05 -0700809
810 {
811 // Attribute ordering.
812 static const char* xml = "<element attrib1=\"1\" attrib2=\"2\" attrib3=\"3\" />";
813 XMLDocument doc;
814 doc.Parse( xml );
815 XMLElement* ele = doc.FirstChildElement();
816
817 const XMLAttribute* a = ele->FirstAttribute();
818 XMLTest( "Attribute order", "1", a->Value() );
819 a = a->Next();
820 XMLTest( "Attribute order", "2", a->Value() );
821 a = a->Next();
822 XMLTest( "Attribute order", "3", a->Value() );
823 XMLTest( "Attribute order", "attrib3", a->Name() );
824
825 ele->DeleteAttribute( "attrib2" );
826 a = ele->FirstAttribute();
827 XMLTest( "Attribute order", "1", a->Value() );
828 a = a->Next();
829 XMLTest( "Attribute order", "3", a->Value() );
830
831 ele->DeleteAttribute( "attrib1" );
832 ele->DeleteAttribute( "attrib3" );
833 XMLTest( "Attribute order (empty)", false, ele->FirstAttribute() ? true : false );
834 }
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700835
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700836 {
837 // Make sure an attribute with a space in it succeeds.
Lee Thomason78a773d2012-07-02 10:10:19 -0700838 static const char* xml0 = "<element attribute1= \"Test Attribute\"/>";
839 static const char* xml1 = "<element attribute1 =\"Test Attribute\"/>";
840 static const char* xml2 = "<element attribute1 = \"Test Attribute\"/>";
841 XMLDocument doc0;
842 doc0.Parse( xml0 );
843 XMLDocument doc1;
844 doc1.Parse( xml1 );
845 XMLDocument doc2;
846 doc2.Parse( xml2 );
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700847
Lee Thomason78a773d2012-07-02 10:10:19 -0700848 XMLElement* ele = 0;
849 ele = doc0.FirstChildElement();
850 XMLTest( "Attribute with space #1", "Test Attribute", ele->Attribute( "attribute1" ) );
851 ele = doc1.FirstChildElement();
852 XMLTest( "Attribute with space #2", "Test Attribute", ele->Attribute( "attribute1" ) );
853 ele = doc2.FirstChildElement();
854 XMLTest( "Attribute with space #3", "Test Attribute", ele->Attribute( "attribute1" ) );
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700855 }
856
857 {
858 // Make sure we don't go into an infinite loop.
859 static const char* xml = "<doc><element attribute='attribute'/><element attribute='attribute'/></doc>";
860 XMLDocument doc;
861 doc.Parse( xml );
862 XMLElement* ele0 = doc.FirstChildElement()->FirstChildElement();
863 XMLElement* ele1 = ele0->NextSiblingElement();
864 bool equal = ele0->ShallowEqual( ele1 );
865
866 XMLTest( "Infinite loop in shallow equal.", true, equal );
867 }
868
Lee Thomason5708f812012-03-28 17:46:41 -0700869 // -------- Handles ------------
870 {
871 static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
872 XMLDocument doc;
873 doc.Parse( xml );
Lee Thomason5708f812012-03-28 17:46:41 -0700874
875 XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
876 XMLTest( "Handle, success, mutable", ele->Value(), "sub" );
877
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700878 XMLHandle docH( doc );
879 ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
Lee Thomasond0b19df2012-04-12 08:41:37 -0700880 XMLTest( "Handle, dne, mutable", false, ele != 0 );
Lee Thomason5708f812012-03-28 17:46:41 -0700881 }
882
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700883 {
884 static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
885 XMLDocument doc;
886 doc.Parse( xml );
887 XMLConstHandle docH( doc );
888
889 const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement();
890 XMLTest( "Handle, success, const", ele->Value(), "sub" );
891
892 ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
Lee Thomasond0b19df2012-04-12 08:41:37 -0700893 XMLTest( "Handle, dne, const", false, ele != 0 );
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700894 }
Lee Thomasonf68c4382012-04-28 14:37:11 -0700895 {
896 // Default Declaration & BOM
897 XMLDocument doc;
898 doc.InsertEndChild( doc.NewDeclaration() );
899 doc.SetBOM( true );
900
901 XMLPrinter printer;
902 doc.Print( &printer );
903
904 static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
905 XMLTest( "BOM and default declaration", printer.CStr(), result, false );
Lee Thomason (grinliz)48ea0bc2012-05-26 14:41:14 -0700906 XMLTest( "CStrSize", printer.CStrSize(), 42, false );
Lee Thomasonf68c4382012-04-28 14:37:11 -0700907 }
Lee Thomason21be8822012-07-15 17:27:22 -0700908 {
909 const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
910 XMLDocument doc;
911 doc.Parse( xml );
912 XMLTest( "Ill formed XML", true, doc.Error() );
913 }
914
915 // QueryXYZText
916 {
917 const char* xml = "<point> <x>1.2</x> <y>1</y> <z>38</z> <valid>true</valid> </point>";
918 XMLDocument doc;
919 doc.Parse( xml );
920
921 const XMLElement* pointElement = doc.RootElement();
922
923 int intValue = 0;
924 unsigned unsignedValue = 0;
925 float floatValue = 0;
926 double doubleValue = 0;
927 bool boolValue = false;
928
929 pointElement->FirstChildElement( "y" )->QueryIntText( &intValue );
930 pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
931 pointElement->FirstChildElement( "x" )->QueryFloatText( &floatValue );
932 pointElement->FirstChildElement( "x" )->QueryDoubleText( &doubleValue );
933 pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue );
934
935
936 XMLTest( "QueryIntText", intValue, 1, false );
937 XMLTest( "QueryUnsignedText", unsignedValue, (unsigned)1, false );
938 XMLTest( "QueryFloatText", floatValue, 1.2f, false );
939 XMLTest( "QueryDoubleText", doubleValue, 1.2, false );
940 XMLTest( "QueryBoolText", boolValue, true, false );
941 }
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700942
943
Lee Thomason6f381b72012-03-02 12:59:39 -0800944 // ----------- Performance tracking --------------
945 {
946#if defined( _MSC_VER )
947 __int64 start, end, freq;
948 QueryPerformanceFrequency( (LARGE_INTEGER*) &freq );
949#endif
950
951#if defined(_MSC_VER)
952#pragma warning ( push )
953#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
954#endif
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300955 FILE* fp = fopen( "resources/dream.xml", "r" );
Lee Thomason6f381b72012-03-02 12:59:39 -0800956#if defined(_MSC_VER)
957#pragma warning ( pop )
958#endif
959 fseek( fp, 0, SEEK_END );
960 long size = ftell( fp );
961 fseek( fp, 0, SEEK_SET );
962
963 char* mem = new char[size+1];
964 fread( mem, size, 1, fp );
965 fclose( fp );
966 mem[size] = 0;
967
968#if defined( _MSC_VER )
969 QueryPerformanceCounter( (LARGE_INTEGER*) &start );
970#else
971 clock_t cstart = clock();
972#endif
973 static const int COUNT = 10;
974 for( int i=0; i<COUNT; ++i ) {
975 XMLDocument doc;
976 doc.Parse( mem );
977 }
978#if defined( _MSC_VER )
979 QueryPerformanceCounter( (LARGE_INTEGER*) &end );
980#else
981 clock_t cend = clock();
982#endif
983
984 delete [] mem;
985
986 static const char* note =
987#ifdef DEBUG
988 "DEBUG";
989#else
990 "Release";
991#endif
992
993#if defined( _MSC_VER )
994 printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, 1000.0 * (double)(end-start) / ( (double)freq * (double)COUNT) );
995#else
996 printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, (double)(cend - cstart)/(double)COUNT );
997#endif
998 }
999
Lee Thomason (grinliz)7ca55582012-03-07 21:54:57 -08001000 #if defined( _MSC_VER ) && defined( DEBUG )
Lee Thomason1ff38e02012-02-14 18:18:16 -08001001 _CrtMemCheckpoint( &endMemState );
1002 //_CrtMemDumpStatistics( &endMemState );
1003
1004 _CrtMemState diffMemState;
1005 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
1006 _CrtMemDumpStatistics( &diffMemState );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -08001007 //printf( "new total=%d\n", gNewTotal );
Lee Thomason1ff38e02012-02-14 18:18:16 -08001008 #endif
1009
1010 printf ("\nPass %d, Fail %d\n", gPass, gFail);
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001011 return 0;
Lee Thomason (grinliz)9b093cc2012-02-25 21:30:18 -08001012}