• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #if defined( _MSC_VER )
2 	#if !defined( _CRT_SECURE_NO_WARNINGS )
3 		#define _CRT_SECURE_NO_WARNINGS		// This test file is not intended to be secure.
4 	#endif
5 #endif
6 
7 #include "tinyxml2.h"
8 #include <cerrno>
9 #include <cstdlib>
10 #include <cstring>
11 #include <ctime>
12 
13 #if defined( _MSC_VER ) || defined (WIN32)
14 	#include <crtdbg.h>
15 	#define WIN32_LEAN_AND_MEAN
16 	#include <windows.h>
17 	_CrtMemState startMemState;
18 	_CrtMemState endMemState;
19 #else
20 	#include <sys/stat.h>
21 	#include <sys/types.h>
22 #endif
23 
24 using namespace tinyxml2;
25 using namespace std;
26 int gPass = 0;
27 int gFail = 0;
28 
29 
XMLTest(const char * testString,const char * expected,const char * found,bool echo=true,bool extraNL=false)30 bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true, bool extraNL=false )
31 {
32 	bool pass;
33 	if ( !expected && !found )
34 		pass = true;
35 	else if ( !expected || !found )
36 		pass = false;
37 	else
38 		pass = !strcmp( expected, found );
39 	if ( pass )
40 		printf ("[pass]");
41 	else
42 		printf ("[fail]");
43 
44 	if ( !echo ) {
45 		printf (" %s\n", testString);
46 	}
47 	else {
48 		if ( extraNL ) {
49 			printf( " %s\n", testString );
50 			printf( "%s\n", expected );
51 			printf( "%s\n", found );
52 		}
53 		else {
54 			printf (" %s [%s][%s]\n", testString, expected, found);
55 		}
56 	}
57 
58 	if ( pass )
59 		++gPass;
60 	else
61 		++gFail;
62 	return pass;
63 }
64 
XMLTest(const char * testString,XMLError expected,XMLError found,bool echo=true,bool extraNL=false)65 bool XMLTest(const char* testString, XMLError expected, XMLError found, bool echo = true, bool extraNL = false)
66 {
67     return XMLTest(testString, XMLDocument::ErrorIDToName(expected), XMLDocument::ErrorIDToName(found), echo, extraNL);
68 }
69 
XMLTest(const char * testString,bool expected,bool found,bool echo=true,bool extraNL=false)70 bool XMLTest(const char* testString, bool expected, bool found, bool echo = true, bool extraNL = false)
71 {
72     return XMLTest(testString, expected ? "true" : "false", found ? "true" : "false", echo, extraNL);
73 }
74 
XMLTest(const char * testString,T expected,T found,bool echo=true)75 template< class T > bool XMLTest( const char* testString, T expected, T found, bool echo=true )
76 {
77 	bool pass = ( expected == found );
78 	if ( pass )
79 		printf ("[pass]");
80 	else
81 		printf ("[fail]");
82 
83 	if ( !echo )
84 		printf (" %s\n", testString);
85 	else
86 		printf (" %s [%d][%d]\n", testString, static_cast<int>(expected), static_cast<int>(found) );
87 
88 	if ( pass )
89 		++gPass;
90 	else
91 		++gFail;
92 	return pass;
93 }
94 
95 
NullLineEndings(char * p)96 void NullLineEndings( char* p )
97 {
98 	while( p && *p ) {
99 		if ( *p == '\n' || *p == '\r' ) {
100 			*p = 0;
101 			return;
102 		}
103 		++p;
104 	}
105 }
106 
107 
example_1()108 int example_1()
109 {
110 	XMLDocument doc;
111 	doc.LoadFile( "resources/dream.xml" );
112 
113 	return doc.ErrorID();
114 }
115 /** @page Example-1 Load an XML File
116  *  @dontinclude ./xmltest.cpp
117  *  Basic XML file loading.
118  *  The basic syntax to load an XML file from
119  *  disk and check for an error. (ErrorID()
120  *  will return 0 for no error.)
121  *  @skip example_1()
122  *  @until }
123  */
124 
125 
example_2()126 int example_2()
127 {
128 	static const char* xml = "<element/>";
129 	XMLDocument doc;
130 	doc.Parse( xml );
131 
132 	return doc.ErrorID();
133 }
134 /** @page Example-2 Parse an XML from char buffer
135  *  @dontinclude ./xmltest.cpp
136  *  Basic XML string parsing.
137  *  The basic syntax to parse an XML for
138  *  a char* and check for an error. (ErrorID()
139  *  will return 0 for no error.)
140  *  @skip example_2()
141  *  @until }
142  */
143 
144 
example_3()145 int example_3()
146 {
147 	static const char* xml =
148 		"<?xml version=\"1.0\"?>"
149 		"<!DOCTYPE PLAY SYSTEM \"play.dtd\">"
150 		"<PLAY>"
151 		"<TITLE>A Midsummer Night's Dream</TITLE>"
152 		"</PLAY>";
153 
154 	XMLDocument doc;
155 	doc.Parse( xml );
156 
157 	XMLElement* titleElement = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" );
158 	const char* title = titleElement->GetText();
159 	printf( "Name of play (1): %s\n", title );
160 
161 	XMLText* textNode = titleElement->FirstChild()->ToText();
162 	title = textNode->Value();
163 	printf( "Name of play (2): %s\n", title );
164 
165 	return doc.ErrorID();
166 }
167 /** @page Example-3 Get information out of XML
168 	@dontinclude ./xmltest.cpp
169 	In this example, we navigate a simple XML
170 	file, and read some interesting text. Note
171 	that this example doesn't use error
172 	checking; working code should check for null
173 	pointers when walking an XML tree, or use
174 	XMLHandle.
175 
176 	(The XML is an excerpt from "dream.xml").
177 
178 	@skip example_3()
179 	@until </PLAY>";
180 
181 	The structure of the XML file is:
182 
183 	<ul>
184 		<li>(declaration)</li>
185 		<li>(dtd stuff)</li>
186 		<li>Element "PLAY"</li>
187 		<ul>
188 			<li>Element "TITLE"</li>
189 			<ul>
190 			    <li>Text "A Midsummer Night's Dream"</li>
191 			</ul>
192 		</ul>
193 	</ul>
194 
195 	For this example, we want to print out the
196 	title of the play. The text of the title (what
197 	we want) is child of the "TITLE" element which
198 	is a child of the "PLAY" element.
199 
200 	We want to skip the declaration and dtd, so the
201 	method FirstChildElement() is a good choice. The
202 	FirstChildElement() of the Document is the "PLAY"
203 	Element, the FirstChildElement() of the "PLAY" Element
204 	is the "TITLE" Element.
205 
206 	@until ( "TITLE" );
207 
208 	We can then use the convenience function GetText()
209 	to get the title of the play.
210 
211 	@until title );
212 
213 	Text is just another Node in the XML DOM. And in
214 	fact you should be a little cautious with it, as
215 	text nodes can contain elements.
216 
217 	@verbatim
218 	Consider: A Midsummer Night's <b>Dream</b>
219 	@endverbatim
220 
221 	It is more correct to actually query the Text Node
222 	if in doubt:
223 
224 	@until title );
225 
226 	Noting that here we use FirstChild() since we are
227 	looking for XMLText, not an element, and ToText()
228 	is a cast from a Node to a XMLText.
229 */
230 
231 
example_4()232 bool example_4()
233 {
234 	static const char* xml =
235 		"<information>"
236 		"	<attributeApproach v='2' />"
237 		"	<textApproach>"
238 		"		<v>2</v>"
239 		"	</textApproach>"
240 		"</information>";
241 
242 	XMLDocument doc;
243 	doc.Parse( xml );
244 
245 	int v0 = 0;
246 	int v1 = 0;
247 
248 	XMLElement* attributeApproachElement = doc.FirstChildElement()->FirstChildElement( "attributeApproach" );
249 	attributeApproachElement->QueryIntAttribute( "v", &v0 );
250 
251 	XMLElement* textApproachElement = doc.FirstChildElement()->FirstChildElement( "textApproach" );
252 	textApproachElement->FirstChildElement( "v" )->QueryIntText( &v1 );
253 
254 	printf( "Both values are the same: %d and %d\n", v0, v1 );
255 
256 	return !doc.Error() && ( v0 == v1 );
257 }
258 /** @page Example-4 Read attributes and text information.
259 	@dontinclude ./xmltest.cpp
260 
261 	There are fundamentally 2 ways of writing a key-value
262 	pair into an XML file. (Something that's always annoyed
263 	me about XML.) Either by using attributes, or by writing
264 	the key name into an element and the value into
265 	the text node wrapped by the element. Both approaches
266 	are illustrated in this example, which shows two ways
267 	to encode the value "2" into the key "v":
268 
269 	@skip example_4()
270 	@until "</information>";
271 
272 	TinyXML-2 has accessors for both approaches.
273 
274 	When using an attribute, you navigate to the XMLElement
275 	with that attribute and use the QueryIntAttribute()
276 	group of methods. (Also QueryFloatAttribute(), etc.)
277 
278 	@skip XMLElement* attributeApproachElement
279 	@until &v0 );
280 
281 	When using the text approach, you need to navigate
282 	down one more step to the XMLElement that contains
283 	the text. Note the extra FirstChildElement( "v" )
284 	in the code below. The value of the text can then
285 	be safely queried with the QueryIntText() group
286 	of methods. (Also QueryFloatText(), etc.)
287 
288 	@skip XMLElement* textApproachElement
289 	@until &v1 );
290 */
291 
292 
main(int argc,const char ** argv)293 int main( int argc, const char ** argv )
294 {
295 	#if defined( _MSC_VER ) && defined( DEBUG )
296 		_CrtMemCheckpoint( &startMemState );
297 		// Enable MS Visual C++ debug heap memory leaks dump on exit
298 		_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
299 		{
300 			int leaksOnStart = _CrtDumpMemoryLeaks();
301 			XMLTest( "No leaks on start?", FALSE, leaksOnStart );
302 		}
303 	#endif
304 
305 	{
306 		TIXMLASSERT( true );
307 	}
308 
309 	if ( argc > 1 ) {
310 		XMLDocument* doc = new XMLDocument();
311 		clock_t startTime = clock();
312 		doc->LoadFile( argv[1] );
313  		clock_t loadTime = clock();
314 		int errorID = doc->ErrorID();
315 		delete doc; doc = 0;
316  		clock_t deleteTime = clock();
317 
318 		printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID );
319 		if ( !errorID ) {
320 			printf( "Load time=%u\n",   (unsigned)(loadTime - startTime) );
321 			printf( "Delete time=%u\n", (unsigned)(deleteTime - loadTime) );
322 			printf( "Total time=%u\n",  (unsigned)(deleteTime - startTime) );
323 		}
324 		exit(0);
325 	}
326 
327 	FILE* fp = fopen( "resources/dream.xml", "r" );
328 	if ( !fp ) {
329 		printf( "Error opening test file 'dream.xml'.\n"
330 				"Is your working directory the same as where \n"
331 				"the xmltest.cpp and dream.xml file are?\n\n"
332 	#if defined( _MSC_VER )
333 				"In windows Visual Studio you may need to set\n"
334 				"Properties->Debugging->Working Directory to '..'\n"
335 	#endif
336 			  );
337 		exit( 1 );
338 	}
339 	fclose( fp );
340 
341 	XMLTest( "Example-1", 0, example_1() );
342 	XMLTest( "Example-2", 0, example_2() );
343 	XMLTest( "Example-3", 0, example_3() );
344 	XMLTest( "Example-4", true, example_4() );
345 
346 	/* ------ Example 2: Lookup information. ---- */
347 
348 	{
349 		static const char* test[] = {	"<element />",
350 										"<element></element>",
351 										"<element><subelement/></element>",
352 										"<element><subelement></subelement></element>",
353 										"<element><subelement><subsub/></subelement></element>",
354 										"<!--comment beside elements--><element><subelement></subelement></element>",
355 										"<!--comment beside elements, this time with spaces-->  \n <element>  <subelement> \n </subelement> </element>",
356 										"<element attrib1='foo' attrib2=\"bar\" ></element>",
357 										"<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
358 										"<element>Text inside element.</element>",
359 										"<element><b></b></element>",
360 										"<element>Text inside and <b>bolded</b> in the element.</element>",
361 										"<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
362 										"<element>This &amp; That.</element>",
363 										"<element attrib='This&lt;That' />",
364 										0
365 		};
366 		for( int i=0; test[i]; ++i ) {
367 			XMLDocument doc;
368 			doc.Parse( test[i] );
369 			XMLTest( "Element test", false, doc.Error() );
370 			doc.Print();
371 			printf( "----------------------------------------------\n" );
372 		}
373 	}
374 #if 1
375 	{
376 		static const char* test = "<!--hello world\n"
377 								  "          line 2\r"
378 								  "          line 3\r\n"
379 								  "          line 4\n\r"
380 								  "          line 5\r-->";
381 
382 		XMLDocument doc;
383 		doc.Parse( test );
384 		XMLTest( "Hello world declaration", false, doc.Error() );
385 		doc.Print();
386 	}
387 
388 	{
389 		// This test is pre-test for the next one
390 		// (where Element1 is inserted "after itself".
391 		// This code didn't use to crash.
392 		XMLDocument doc;
393 		XMLElement* element1 = doc.NewElement("Element1");
394 		XMLElement* element2 = doc.NewElement("Element2");
395 		doc.InsertEndChild(element1);
396 		doc.InsertEndChild(element2);
397 		doc.InsertAfterChild(element2, element2);
398 		doc.InsertAfterChild(element2, element2);
399 	}
400 
401 	{
402 		XMLDocument doc;
403 		XMLElement* element1 = doc.NewElement("Element1");
404 		XMLElement* element2 = doc.NewElement("Element2");
405 		doc.InsertEndChild(element1);
406 		doc.InsertEndChild(element2);
407 
408 		// This insertion "after itself"
409 		// used to cause invalid memory access and crash
410 		doc.InsertAfterChild(element1, element1);
411 		doc.InsertAfterChild(element1, element1);
412 		doc.InsertAfterChild(element2, element2);
413 		doc.InsertAfterChild(element2, element2);
414 	}
415 
416 	{
417 		static const char* test = "<element>Text before.</element>";
418 		XMLDocument doc;
419 		doc.Parse( test );
420 		XMLTest( "Element text before", false, doc.Error() );
421 		XMLElement* root = doc.FirstChildElement();
422 		XMLElement* newElement = doc.NewElement( "Subelement" );
423 		root->InsertEndChild( newElement );
424 		doc.Print();
425 	}
426 	{
427 		XMLDocument* doc = new XMLDocument();
428 		static const char* test = "<element><sub/></element>";
429 		doc->Parse( test );
430 		XMLTest( "Element with sub element", false, doc->Error() );
431 		delete doc;
432 	}
433 	{
434 		// Test: Programmatic DOM nodes insertion return values
435 		XMLDocument doc;
436 
437 		XMLNode* first = doc.NewElement( "firstElement" );
438 		XMLTest( "New element", true, first != 0 );
439 		XMLNode* firstAfterInsertion = doc.InsertFirstChild( first );
440 		XMLTest( "New element inserted first", true, firstAfterInsertion == first );
441 
442 		XMLNode* last = doc.NewElement( "lastElement" );
443 		XMLTest( "New element", true, last != 0 );
444 		XMLNode* lastAfterInsertion = doc.InsertEndChild( last );
445 		XMLTest( "New element inserted last", true, lastAfterInsertion == last );
446 
447 		XMLNode* middle = doc.NewElement( "middleElement" );
448 		XMLTest( "New element", true, middle != 0 );
449 		XMLNode* middleAfterInsertion = doc.InsertAfterChild( first, middle );
450 		XMLTest( "New element inserted middle", true, middleAfterInsertion == middle );
451 	}
452 	{
453 		// Test: Programmatic DOM
454 		// Build:
455 		//		<element>
456 		//			<!--comment-->
457 		//			<sub attrib="1" />
458 		//			<sub attrib="2" />
459 		//			<sub attrib="3" >& Text!</sub>
460 		//		<element>
461 
462 		XMLDocument* doc = new XMLDocument();
463 		XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
464 
465 		XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
466 		for( int i=0; i<3; ++i ) {
467 			sub[i]->SetAttribute( "attrib", i );
468 		}
469 		element->InsertEndChild( sub[2] );
470 
471 		const int dummyInitialValue = 1000;
472 		int dummyValue = dummyInitialValue;
473 
474 		XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
475 		comment->SetUserData(&dummyValue);
476 		element->InsertAfterChild( comment, sub[0] );
477 		element->InsertAfterChild( sub[0], sub[1] );
478 		sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
479 		doc->Print();
480 		XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
481 		XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
482 		XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
483 		XMLTest( "Programmatic DOM", "& Text!",
484 				 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
485 		XMLTest("User data - pointer", true, &dummyValue == comment->GetUserData(), false);
486 		XMLTest("User data - value behind pointer", dummyInitialValue, dummyValue, false);
487 
488 		// And now deletion:
489 		element->DeleteChild( sub[2] );
490 		doc->DeleteNode( comment );
491 
492 		element->FirstChildElement()->SetAttribute( "attrib", true );
493 		element->LastChildElement()->DeleteAttribute( "attrib" );
494 
495 		XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
496 		const int defaultIntValue = 10;
497 		const int replacementIntValue = 20;
498 		int value1 = defaultIntValue;
499 		int value2 = doc->FirstChildElement()->LastChildElement()->IntAttribute( "attrib", replacementIntValue );
500 		XMLError result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value1 );
501 		XMLTest( "Programmatic DOM", XML_NO_ATTRIBUTE, result );
502 		XMLTest( "Programmatic DOM", defaultIntValue, value1 );
503 		XMLTest( "Programmatic DOM", replacementIntValue, value2 );
504 
505 		doc->Print();
506 
507 		{
508 			XMLPrinter streamer;
509 			doc->Print( &streamer );
510 			printf( "%s", streamer.CStr() );
511 		}
512 		{
513 			XMLPrinter streamer( 0, true );
514 			doc->Print( &streamer );
515 			XMLTest( "Compact mode", "<element><sub attrib=\"true\"/><sub/></element>", streamer.CStr(), false );
516 		}
517 		doc->SaveFile( "./resources/out/pretty.xml" );
518 		XMLTest( "Save pretty.xml", false, doc->Error() );
519 		doc->SaveFile( "./resources/out/compact.xml", true );
520 		XMLTest( "Save compact.xml", false, doc->Error() );
521 		delete doc;
522 	}
523 	{
524 		// Test: Dream
525 		// XML1 : 1,187,569 bytes	in 31,209 allocations
526 		// XML2 :   469,073	bytes	in    323 allocations
527 		//int newStart = gNew;
528 		XMLDocument doc;
529 		doc.LoadFile( "resources/dream.xml" );
530 		XMLTest( "Load dream.xml", false, doc.Error() );
531 
532 		doc.SaveFile( "resources/out/dreamout.xml" );
533 		XMLTest( "Save dreamout.xml", false, doc.Error() );
534 		doc.PrintError();
535 
536 		XMLTest( "Dream", "xml version=\"1.0\"",
537 						  doc.FirstChild()->ToDeclaration()->Value() );
538 		XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
539 		XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
540 						  doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
541 		XMLTest( "Dream", "And Robin shall restore amends.",
542 						  doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
543 		XMLTest( "Dream", "And Robin shall restore amends.",
544 						  doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
545 
546 		XMLDocument doc2;
547 		doc2.LoadFile( "resources/out/dreamout.xml" );
548 		XMLTest( "Load dreamout.xml", false, doc2.Error() );
549 		XMLTest( "Dream-out", "xml version=\"1.0\"",
550 						  doc2.FirstChild()->ToDeclaration()->Value() );
551 		XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
552 		XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
553 						  doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
554 		XMLTest( "Dream-out", "And Robin shall restore amends.",
555 						  doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
556 
557 		//gNewTotal = gNew - newStart;
558 	}
559 
560 
561 	{
562 		const char* error =	"<?xml version=\"1.0\" standalone=\"no\" ?>\n"
563 							"<passages count=\"006\" formatversion=\"20020620\">\n"
564 							"    <wrong error>\n"
565 							"</passages>";
566 
567 		XMLDocument doc;
568 		doc.Parse( error );
569 		XMLTest( "Bad XML", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() );
570 	}
571 
572 	{
573 		const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
574 
575 		XMLDocument doc;
576 		doc.Parse( str );
577 		XMLTest( "Top level attributes", false, doc.Error() );
578 
579 		XMLElement* ele = doc.FirstChildElement();
580 
581 		int iVal;
582 		XMLError result;
583 		double dVal;
584 
585 		result = ele->QueryDoubleAttribute( "attr0", &dVal );
586 		XMLTest( "Query attribute: int as double", XML_SUCCESS, result);
587 		XMLTest( "Query attribute: int as double", 1, (int)dVal );
588 		XMLTest( "Query attribute: int as double", 1, (int)ele->DoubleAttribute("attr0"));
589 
590 		result = ele->QueryDoubleAttribute( "attr1", &dVal );
591 		XMLTest( "Query attribute: double as double", XML_SUCCESS, result);
592 		XMLTest( "Query attribute: double as double", 2.0, dVal );
593 		XMLTest( "Query attribute: double as double", 2.0, ele->DoubleAttribute("attr1") );
594 
595 		result = ele->QueryIntAttribute( "attr1", &iVal );
596 		XMLTest( "Query attribute: double as int", XML_SUCCESS, result);
597 		XMLTest( "Query attribute: double as int", 2, iVal );
598 
599 		result = ele->QueryIntAttribute( "attr2", &iVal );
600 		XMLTest( "Query attribute: not a number", XML_WRONG_ATTRIBUTE_TYPE, result );
601 		XMLTest( "Query attribute: not a number", 4.0, ele->DoubleAttribute("attr2", 4.0) );
602 
603 		result = ele->QueryIntAttribute( "bar", &iVal );
604 		XMLTest( "Query attribute: does not exist", XML_NO_ATTRIBUTE, result );
605 		XMLTest( "Query attribute: does not exist", true, ele->BoolAttribute("bar", true) );
606 	}
607 
608 	{
609 		const char* str = "<doc/>";
610 
611 		XMLDocument doc;
612 		doc.Parse( str );
613 		XMLTest( "Empty top element", false, doc.Error() );
614 
615 		XMLElement* ele = doc.FirstChildElement();
616 
617 		int iVal, iVal2;
618 		double dVal, dVal2;
619 
620 		ele->SetAttribute( "str", "strValue" );
621 		ele->SetAttribute( "int", 1 );
622 		ele->SetAttribute( "double", -1.0 );
623 
624 		const char* cStr = ele->Attribute( "str" );
625 		{
626 			XMLError queryResult = ele->QueryIntAttribute( "int", &iVal );
627 			XMLTest( "Query int attribute", XML_SUCCESS, queryResult);
628 		}
629 		{
630 			XMLError queryResult = ele->QueryDoubleAttribute( "double", &dVal );
631 			XMLTest( "Query double attribute", XML_SUCCESS, queryResult);
632 		}
633 
634 		{
635 			int queryResult = ele->QueryAttribute( "int", &iVal2 );
636 			XMLTest( "Query int attribute generic", (int)XML_SUCCESS, queryResult);
637 		}
638 		{
639 			int queryResult = ele->QueryAttribute( "double", &dVal2 );
640 			XMLTest( "Query double attribute generic", (int)XML_SUCCESS, queryResult);
641 		}
642 
643 		XMLTest( "Attribute match test", "strValue", ele->Attribute( "str", "strValue" ) );
644 		XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
645 		XMLTest( "Attribute round trip. int.", 1, iVal );
646 		XMLTest( "Attribute round trip. double.", -1, (int)dVal );
647 		XMLTest( "Alternate query", true, iVal == iVal2 );
648 		XMLTest( "Alternate query", true, dVal == dVal2 );
649 		XMLTest( "Alternate query", true, iVal == ele->IntAttribute("int") );
650 		XMLTest( "Alternate query", true, dVal == ele->DoubleAttribute("double") );
651 	}
652 
653 	{
654 		XMLDocument doc;
655 		doc.LoadFile( "resources/utf8test.xml" );
656 		XMLTest( "Load utf8test.xml", false, doc.Error() );
657 
658 		// Get the attribute "value" from the "Russian" element and check it.
659 		XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
660 		const unsigned char correctValue[] = {	0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
661 												0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
662 
663 		XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
664 
665 		const unsigned char russianElementName[] = {	0xd0U, 0xa0U, 0xd1U, 0x83U,
666 														0xd1U, 0x81U, 0xd1U, 0x81U,
667 														0xd0U, 0xbaU, 0xd0U, 0xb8U,
668 														0xd0U, 0xb9U, 0 };
669 		const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
670 
671 		XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
672 		XMLTest( "UTF-8: Browsing russian element name.",
673 				 russianText,
674 				 text->Value() );
675 
676 		// Now try for a round trip.
677 		doc.SaveFile( "resources/out/utf8testout.xml" );
678 		XMLTest( "UTF-8: Save testout.xml", false, doc.Error() );
679 
680 		// Check the round trip.
681 		bool roundTripOkay = false;
682 
683 		FILE* saved  = fopen( "resources/out/utf8testout.xml", "r" );
684 		XMLTest( "UTF-8: Open utf8testout.xml", true, saved != 0 );
685 
686 		FILE* verify = fopen( "resources/utf8testverify.xml", "r" );
687 		XMLTest( "UTF-8: Open utf8testverify.xml", true, verify != 0 );
688 
689 		if ( saved && verify )
690 		{
691 			roundTripOkay = true;
692 			char verifyBuf[256];
693 			while ( fgets( verifyBuf, 256, verify ) )
694 			{
695 				char savedBuf[256];
696 				fgets( savedBuf, 256, saved );
697 				NullLineEndings( verifyBuf );
698 				NullLineEndings( savedBuf );
699 
700 				if ( strcmp( verifyBuf, savedBuf ) )
701 				{
702 					printf( "verify:%s<\n", verifyBuf );
703 					printf( "saved :%s<\n", savedBuf );
704 					roundTripOkay = false;
705 					break;
706 				}
707 			}
708 		}
709 		if ( saved )
710 			fclose( saved );
711 		if ( verify )
712 			fclose( verify );
713 		XMLTest( "UTF-8: Verified multi-language round trip.", true, roundTripOkay );
714 	}
715 
716 	// --------GetText()-----------
717 	{
718 		const char* str = "<foo>This is  text</foo>";
719 		XMLDocument doc;
720 		doc.Parse( str );
721 		XMLTest( "Double whitespace", false, doc.Error() );
722 		const XMLElement* element = doc.RootElement();
723 
724 		XMLTest( "GetText() normal use.", "This is  text", element->GetText() );
725 
726 		str = "<foo><b>This is text</b></foo>";
727 		doc.Parse( str );
728 		XMLTest( "Bold text simulation", false, doc.Error() );
729 		element = doc.RootElement();
730 
731 		XMLTest( "GetText() contained element.", element->GetText() == 0, true );
732 	}
733 
734 
735 	// --------SetText()-----------
736 	{
737 		const char* str = "<foo></foo>";
738 		XMLDocument doc;
739 		doc.Parse( str );
740 		XMLTest( "Empty closed element", false, doc.Error() );
741 		XMLElement* element = doc.RootElement();
742 
743 		element->SetText("darkness.");
744 		XMLTest( "SetText() normal use (open/close).", "darkness.", element->GetText() );
745 
746 		element->SetText("blue flame.");
747 		XMLTest( "SetText() replace.", "blue flame.", element->GetText() );
748 
749 		str = "<foo/>";
750 		doc.Parse( str );
751 		XMLTest( "Empty self-closed element", false, doc.Error() );
752 		element = doc.RootElement();
753 
754 		element->SetText("The driver");
755 		XMLTest( "SetText() normal use. (self-closing)", "The driver", element->GetText() );
756 
757 		element->SetText("<b>horses</b>");
758 		XMLTest( "SetText() replace with tag-like text.", "<b>horses</b>", element->GetText() );
759 		//doc.Print();
760 
761 		str = "<foo><bar>Text in nested element</bar></foo>";
762 		doc.Parse( str );
763 		XMLTest( "Text in nested element", false, doc.Error() );
764 		element = doc.RootElement();
765 
766 		element->SetText("wolves");
767 		XMLTest( "SetText() prefix to nested non-text children.", "wolves", element->GetText() );
768 
769 		str = "<foo/>";
770 		doc.Parse( str );
771 		XMLTest( "Empty self-closed element round 2", false, doc.Error() );
772 		element = doc.RootElement();
773 
774 		element->SetText( "str" );
775 		XMLTest( "SetText types", "str", element->GetText() );
776 
777 		element->SetText( 1 );
778 		XMLTest( "SetText types", "1", element->GetText() );
779 
780 		element->SetText( 1U );
781 		XMLTest( "SetText types", "1", element->GetText() );
782 
783 		element->SetText( true );
784 		XMLTest( "SetText types", "true", element->GetText() );
785 
786 		element->SetText( 1.5f );
787 		XMLTest( "SetText types", "1.5", element->GetText() );
788 
789 		element->SetText( 1.5 );
790 		XMLTest( "SetText types", "1.5", element->GetText() );
791 	}
792 
793 	// ---------- Attributes ---------
794 	{
795 		static const int64_t BIG = -123456789012345678;
796 		XMLDocument doc;
797 		XMLElement* element = doc.NewElement("element");
798 		doc.InsertFirstChild(element);
799 
800 		{
801 			element->SetAttribute("attrib", int(-100));
802 			{
803 				int v = 0;
804 				XMLError queryResult = element->QueryIntAttribute("attrib", &v);
805 				XMLTest("Attribute: int", XML_SUCCESS, queryResult, true);
806 				XMLTest("Attribute: int", -100, v, true);
807 			}
808 			{
809 				int v = 0;
810 				int queryResult = element->QueryAttribute("attrib", &v);
811 				XMLTest("Attribute: int", (int)XML_SUCCESS, queryResult, true);
812 				XMLTest("Attribute: int", -100, v, true);
813 			}
814 			XMLTest("Attribute: int", -100, element->IntAttribute("attrib"), true);
815 		}
816 		{
817 			element->SetAttribute("attrib", unsigned(100));
818 			{
819 				unsigned v = 0;
820 				XMLError queryResult = element->QueryUnsignedAttribute("attrib", &v);
821 				XMLTest("Attribute: unsigned", XML_SUCCESS, queryResult, true);
822 				XMLTest("Attribute: unsigned", unsigned(100), v, true);
823 			}
824 			{
825 				unsigned v = 0;
826 				int queryResult = element->QueryAttribute("attrib", &v);
827 				XMLTest("Attribute: unsigned", (int)XML_SUCCESS, queryResult, true);
828 				XMLTest("Attribute: unsigned", unsigned(100), v, true);
829 			}
830 			XMLTest("Attribute: unsigned", unsigned(100), element->UnsignedAttribute("attrib"), true);
831 		}
832 		{
833 			element->SetAttribute("attrib", BIG);
834 			{
835 				int64_t v = 0;
836 				XMLError queryResult = element->QueryInt64Attribute("attrib", &v);
837 				XMLTest("Attribute: int64_t", XML_SUCCESS, queryResult, true);
838 				XMLTest("Attribute: int64_t", BIG, v, true);
839 			}
840 			{
841 				int64_t v = 0;
842 				int queryResult = element->QueryAttribute("attrib", &v);
843 				XMLTest("Attribute: int64_t", (int)XML_SUCCESS, queryResult, true);
844 				XMLTest("Attribute: int64_t", BIG, v, true);
845 			}
846 			XMLTest("Attribute: int64_t", BIG, element->Int64Attribute("attrib"), true);
847 		}
848 		{
849 			element->SetAttribute("attrib", true);
850 			{
851 				bool v = false;
852 				XMLError queryResult = element->QueryBoolAttribute("attrib", &v);
853 				XMLTest("Attribute: bool", XML_SUCCESS, queryResult, true);
854 				XMLTest("Attribute: bool", true, v, true);
855 			}
856 			{
857 				bool v = false;
858 				int queryResult = element->QueryAttribute("attrib", &v);
859 				XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
860 				XMLTest("Attribute: bool", true, v, true);
861 			}
862 			XMLTest("Attribute: bool", true, element->BoolAttribute("attrib"), true);
863 		}
864 		{
865 			element->SetAttribute("attrib", true);
866 			const char* result = element->Attribute("attrib");
867 			XMLTest("Bool true is 'true'", "true", result);
868 
869 			XMLUtil::SetBoolSerialization("1", "0");
870 			element->SetAttribute("attrib", true);
871 			result = element->Attribute("attrib");
872 			XMLTest("Bool true is '1'", "1", result);
873 
874 			XMLUtil::SetBoolSerialization(0, 0);
875 		}
876 		{
877 			element->SetAttribute("attrib", 100.0);
878 			{
879 				double v = 0;
880 				XMLError queryResult = element->QueryDoubleAttribute("attrib", &v);
881 				XMLTest("Attribute: double", XML_SUCCESS, queryResult, true);
882 				XMLTest("Attribute: double", 100.0, v, true);
883 			}
884 			{
885 				double v = 0;
886 				int queryResult = element->QueryAttribute("attrib", &v);
887 				XMLTest("Attribute: bool", (int)XML_SUCCESS, queryResult, true);
888 				XMLTest("Attribute: double", 100.0, v, true);
889 			}
890 			XMLTest("Attribute: double", 100.0, element->DoubleAttribute("attrib"), true);
891 		}
892 		{
893 			element->SetAttribute("attrib", 100.0f);
894 			{
895 				float v = 0;
896 				XMLError queryResult = element->QueryFloatAttribute("attrib", &v);
897 				XMLTest("Attribute: float", XML_SUCCESS, queryResult, true);
898 				XMLTest("Attribute: float", 100.0f, v, true);
899 			}
900 			{
901 				float v = 0;
902 				int queryResult = element->QueryAttribute("attrib", &v);
903 				XMLTest("Attribute: float", (int)XML_SUCCESS, queryResult, true);
904 				XMLTest("Attribute: float", 100.0f, v, true);
905 			}
906 			XMLTest("Attribute: float", 100.0f, element->FloatAttribute("attrib"), true);
907 		}
908 		{
909 			element->SetText(BIG);
910 			int64_t v = 0;
911 			XMLError queryResult = element->QueryInt64Text(&v);
912 			XMLTest("Element: int64_t", XML_SUCCESS, queryResult, true);
913 			XMLTest("Element: int64_t", BIG, v, true);
914 		}
915 	}
916 
917 	// ---------- XMLPrinter stream mode ------
918 	{
919 		{
920 			FILE* printerfp = fopen("resources/out/printer.xml", "w");
921 			XMLTest("Open printer.xml", true, printerfp != 0);
922 			XMLPrinter printer(printerfp);
923 			printer.OpenElement("foo");
924 			printer.PushAttribute("attrib-text", "text");
925 			printer.PushAttribute("attrib-int", int(1));
926 			printer.PushAttribute("attrib-unsigned", unsigned(2));
927 			printer.PushAttribute("attrib-int64", int64_t(3));
928 			printer.PushAttribute("attrib-bool", true);
929 			printer.PushAttribute("attrib-double", 4.0);
930 			printer.CloseElement();
931 			fclose(printerfp);
932 		}
933 		{
934 			XMLDocument doc;
935 			doc.LoadFile("resources/out/printer.xml");
936 			XMLTest("XMLPrinter Stream mode: load", XML_SUCCESS, doc.ErrorID(), true);
937 
938 			const XMLDocument& cdoc = doc;
939 
940 			const XMLAttribute* attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-text");
941 			XMLTest("attrib-text", "text", attrib->Value(), true);
942 			attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-int");
943 			XMLTest("attrib-int", int(1), attrib->IntValue(), true);
944 			attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-unsigned");
945 			XMLTest("attrib-unsigned", unsigned(2), attrib->UnsignedValue(), true);
946 			attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-int64");
947 			XMLTest("attrib-int64", int64_t(3), attrib->Int64Value(), true);
948 			attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-bool");
949 			XMLTest("attrib-bool", true, attrib->BoolValue(), true);
950 			attrib = cdoc.FirstChildElement("foo")->FindAttribute("attrib-double");
951 			XMLTest("attrib-double", 4.0, attrib->DoubleValue(), true);
952 		}
953 
954 	}
955 
956 
957 	// ---------- CDATA ---------------
958 	{
959 		const char* str =	"<xmlElement>"
960 								"<![CDATA["
961 									"I am > the rules!\n"
962 									"...since I make symbolic puns"
963 								"]]>"
964 							"</xmlElement>";
965 		XMLDocument doc;
966 		doc.Parse( str );
967 		XMLTest( "CDATA symbolic puns round 1", false, doc.Error() );
968 		doc.Print();
969 
970 		XMLTest( "CDATA parse.", "I am > the rules!\n...since I make symbolic puns",
971 								 doc.FirstChildElement()->FirstChild()->Value(),
972 								 false );
973 	}
974 
975 	// ----------- CDATA -------------
976 	{
977 		const char* str =	"<xmlElement>"
978 								"<![CDATA["
979 									"<b>I am > the rules!</b>\n"
980 									"...since I make symbolic puns"
981 								"]]>"
982 							"</xmlElement>";
983 		XMLDocument doc;
984 		doc.Parse( str );
985 		XMLTest( "CDATA symbolic puns round 2", false, doc.Error() );
986 		doc.Print();
987 
988 		XMLTest( "CDATA parse. [ tixml1:1480107 ]",
989 								 "<b>I am > the rules!</b>\n...since I make symbolic puns",
990 								 doc.FirstChildElement()->FirstChild()->Value(),
991 								 false );
992 	}
993 
994 	// InsertAfterChild causes crash.
995 	{
996 		// InsertBeforeChild and InsertAfterChild causes crash.
997 		XMLDocument doc;
998 		XMLElement* parent = doc.NewElement( "Parent" );
999 		doc.InsertFirstChild( parent );
1000 
1001 		XMLElement* childText0 = doc.NewElement( "childText0" );
1002 		XMLElement* childText1 = doc.NewElement( "childText1" );
1003 
1004 		XMLNode* childNode0 = parent->InsertEndChild( childText0 );
1005 		XMLTest( "InsertEndChild() return", true, childNode0 == childText0 );
1006 		XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
1007 		XMLTest( "InsertAfterChild() return", true, childNode1 == childText1 );
1008 
1009 		XMLTest( "Test InsertAfterChild on empty node. ", true, ( childNode1 == parent->LastChild() ) );
1010 	}
1011 
1012 	{
1013 		// Entities not being written correctly.
1014 		// From Lynn Allen
1015 
1016 		const char* passages =
1017 			"<?xml version=\"1.0\" standalone=\"no\" ?>"
1018 			"<passages count=\"006\" formatversion=\"20020620\">"
1019 				"<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
1020 				" It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
1021 			"</passages>";
1022 
1023 		XMLDocument doc;
1024 		doc.Parse( passages );
1025 		XMLTest( "Entity transformation parse round 1", false, doc.Error() );
1026 		XMLElement* psg = doc.RootElement()->FirstChildElement();
1027 		const char* context = psg->Attribute( "context" );
1028 		const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
1029 
1030 		XMLTest( "Entity transformation: read. ", expected, context, true );
1031 
1032 		const char* textFilePath = "resources/out/textfile.txt";
1033 		FILE* textfile = fopen( textFilePath, "w" );
1034 		XMLTest( "Entity transformation: open text file for writing", true, textfile != 0, true );
1035 		if ( textfile )
1036 		{
1037 			XMLPrinter streamer( textfile );
1038 			bool acceptResult = psg->Accept( &streamer );
1039 			fclose( textfile );
1040 			XMLTest( "Entity transformation: Accept", true, acceptResult );
1041 		}
1042 
1043 		textfile = fopen( textFilePath, "r" );
1044 		XMLTest( "Entity transformation: open text file for reading", true, textfile != 0, true );
1045 		if ( textfile )
1046 		{
1047 			char buf[ 1024 ];
1048 			fgets( buf, 1024, textfile );
1049 			XMLTest( "Entity transformation: write. ",
1050 					 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
1051 					 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.\"/>\n",
1052 					 buf, false );
1053 			fclose( textfile );
1054 		}
1055 	}
1056 
1057 	{
1058 		// Suppress entities.
1059 		const char* passages =
1060 			"<?xml version=\"1.0\" standalone=\"no\" ?>"
1061 			"<passages count=\"006\" formatversion=\"20020620\">"
1062 				"<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.\">Crazy &ttk;</psg>"
1063 			"</passages>";
1064 
1065 		XMLDocument doc( false );
1066 		doc.Parse( passages );
1067 		XMLTest( "Entity transformation parse round 2", false, doc.Error() );
1068 
1069 		XMLTest( "No entity parsing.",
1070 				 "Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.",
1071 				 doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ) );
1072 		XMLTest( "No entity parsing.", "Crazy &ttk;",
1073 				 doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value() );
1074 		doc.Print();
1075 	}
1076 
1077 	{
1078 		const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
1079 
1080 		XMLDocument doc;
1081 		doc.Parse( test );
1082 		XMLTest( "dot in names", false, doc.Error() );
1083 		XMLTest( "dot in names", "a.elem", doc.FirstChildElement()->Name() );
1084 		XMLTest( "dot in names", "2.0", doc.FirstChildElement()->Attribute( "xmi.version" ) );
1085 	}
1086 
1087 	{
1088 		const char* test = "<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>";
1089 
1090 		XMLDocument doc;
1091 		doc.Parse( test );
1092 		XMLTest( "fin thickness", false, doc.Error() );
1093 
1094 		XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
1095 		XMLTest( "Entity with one digit.",
1096 				 "1.1 Start easy ignore fin thickness\n", text->Value(),
1097 				 false );
1098 	}
1099 
1100 	{
1101 		// DOCTYPE not preserved (950171)
1102 		//
1103 		const char* doctype =
1104 			"<?xml version=\"1.0\" ?>"
1105 			"<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
1106 			"<!ELEMENT title (#PCDATA)>"
1107 			"<!ELEMENT books (title,authors)>"
1108 			"<element />";
1109 
1110 		XMLDocument doc;
1111 		doc.Parse( doctype );
1112 		XMLTest( "PLAY SYSTEM parse", false, doc.Error() );
1113 		doc.SaveFile( "resources/out/test7.xml" );
1114 		XMLTest( "PLAY SYSTEM save", false, doc.Error() );
1115 		doc.DeleteChild( doc.RootElement() );
1116 		doc.LoadFile( "resources/out/test7.xml" );
1117 		XMLTest( "PLAY SYSTEM load", false, doc.Error() );
1118 		doc.Print();
1119 
1120 		const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
1121 		XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
1122 
1123 	}
1124 
1125 	{
1126 		// Comments do not stream out correctly.
1127 		const char* doctype =
1128 			"<!-- Somewhat<evil> -->";
1129 		XMLDocument doc;
1130 		doc.Parse( doctype );
1131 		XMLTest( "Comment somewhat evil", false, doc.Error() );
1132 
1133 		XMLComment* comment = doc.FirstChild()->ToComment();
1134 
1135 		XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
1136 	}
1137 	{
1138 		// Double attributes
1139 		const char* doctype = "<element attr='red' attr='blue' />";
1140 
1141 		XMLDocument doc;
1142 		doc.Parse( doctype );
1143 
1144 		XMLTest( "Parsing repeated attributes.", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() );	// is an  error to tinyxml (didn't use to be, but caused issues)
1145 		doc.PrintError();
1146 	}
1147 
1148 	{
1149 		// Embedded null in stream.
1150 		const char* doctype = "<element att\0r='red' attr='blue' />";
1151 
1152 		XMLDocument doc;
1153 		doc.Parse( doctype );
1154 		XMLTest( "Embedded null throws error.", true, doc.Error() );
1155 	}
1156 
1157 	{
1158 		// Empty documents should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717
1159 		const char* str = "";
1160 		XMLDocument doc;
1161 		doc.Parse( str );
1162 		XMLTest( "Empty document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
1163 	}
1164 
1165 	{
1166 		// Documents with all whitespaces should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717
1167 		const char* str = "    ";
1168 		XMLDocument doc;
1169 		doc.Parse( str );
1170 		XMLTest( "All whitespaces document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
1171 	}
1172 
1173 	{
1174 		// Low entities
1175 		XMLDocument doc;
1176 		doc.Parse( "<test>&#x0e;</test>" );
1177 		XMLTest( "Hex values", false, doc.Error() );
1178 		const char result[] = { 0x0e, 0 };
1179 		XMLTest( "Low entities.", result, doc.FirstChildElement()->GetText() );
1180 		doc.Print();
1181 	}
1182 
1183 	{
1184 		// Attribute values with trailing quotes not handled correctly
1185 		XMLDocument doc;
1186 		doc.Parse( "<foo attribute=bar\" />" );
1187 		XMLTest( "Throw error with bad end quotes.", true, doc.Error() );
1188 	}
1189 
1190 	{
1191 		// [ 1663758 ] Failure to report error on bad XML
1192 		XMLDocument xml;
1193 		xml.Parse("<x>");
1194 		XMLTest("Missing end tag at end of input", true, xml.Error());
1195 		xml.Parse("<x> ");
1196 		XMLTest("Missing end tag with trailing whitespace", true, xml.Error());
1197 		xml.Parse("<x></y>");
1198 		XMLTest("Mismatched tags", XML_ERROR_MISMATCHED_ELEMENT, xml.ErrorID() );
1199 	}
1200 
1201 
1202 	{
1203 		// [ 1475201 ] TinyXML parses entities in comments
1204 		XMLDocument xml;
1205 		xml.Parse("<!-- declarations for <head> & <body> -->"
1206 				  "<!-- far &amp; away -->" );
1207 		XMLTest( "Declarations for head and body", false, xml.Error() );
1208 
1209 		XMLNode* e0 = xml.FirstChild();
1210 		XMLNode* e1 = e0->NextSibling();
1211 		XMLComment* c0 = e0->ToComment();
1212 		XMLComment* c1 = e1->ToComment();
1213 
1214 		XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
1215 		XMLTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
1216 	}
1217 
1218 	{
1219 		XMLDocument xml;
1220 		xml.Parse( "<Parent>"
1221 						"<child1 att=''/>"
1222 						"<!-- With this comment, child2 will not be parsed! -->"
1223 						"<child2 att=''/>"
1224 					"</Parent>" );
1225 		XMLTest( "Comments iteration", false, xml.Error() );
1226 		xml.Print();
1227 
1228 		int count = 0;
1229 
1230 		for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild();
1231 			 ele;
1232 			 ele = ele->NextSibling() )
1233 		{
1234 			++count;
1235 		}
1236 
1237 		XMLTest( "Comments iterate correctly.", 3, count );
1238 	}
1239 
1240 	{
1241 		// trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
1242 		unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
1243 		buf[60] = 239;
1244 		buf[61] = 0;
1245 
1246 		XMLDocument doc;
1247 		doc.Parse( (const char*)buf);
1248 		XMLTest( "Broken CDATA", true, doc.Error() );
1249 	}
1250 
1251 
1252 	{
1253 		// bug 1827248 Error while parsing a little bit malformed file
1254 		// Actually not malformed - should work.
1255 		XMLDocument xml;
1256 		xml.Parse( "<attributelist> </attributelist >" );
1257 		XMLTest( "Handle end tag whitespace", false, xml.Error() );
1258 	}
1259 
1260 	{
1261 		// This one must not result in an infinite loop
1262 		XMLDocument xml;
1263 		xml.Parse( "<infinite>loop" );
1264 		XMLTest( "No closing element", true, xml.Error() );
1265 		XMLTest( "Infinite loop test.", true, true );
1266 	}
1267 #endif
1268 	{
1269 		const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>";
1270 		XMLDocument doc;
1271 		doc.Parse( pub );
1272 		XMLTest( "Trailing DOCTYPE", false, doc.Error() );
1273 
1274 		XMLDocument clone;
1275 		for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) {
1276 			XMLNode* copy = node->ShallowClone( &clone );
1277 			clone.InsertEndChild( copy );
1278 		}
1279 
1280 		clone.Print();
1281 
1282 		int count=0;
1283 		const XMLNode* a=clone.FirstChild();
1284 		const XMLNode* b=doc.FirstChild();
1285 		for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) {
1286 			++count;
1287 			XMLTest( "Clone and Equal", true, a->ShallowEqual( b ));
1288 		}
1289 		XMLTest( "Clone and Equal", 4, count );
1290 	}
1291 
1292 	{
1293 		// Deep Cloning of root element.
1294 		XMLDocument doc2;
1295 		XMLPrinter printer1;
1296 		{
1297 			// Make sure doc1 is deleted before we test doc2
1298 			const char* xml =
1299 				"<root>"
1300 				"    <child1 foo='bar'/>"
1301 				"    <!-- comment thing -->"
1302 				"    <child2 val='1'>Text</child2>"
1303 				"</root>";
1304 			XMLDocument doc;
1305 			doc.Parse(xml);
1306 			XMLTest( "Parse before deep cloning root element", false, doc.Error() );
1307 
1308 			doc.Print(&printer1);
1309 			XMLNode* root = doc.RootElement()->DeepClone(&doc2);
1310 			doc2.InsertFirstChild(root);
1311 		}
1312 		XMLPrinter printer2;
1313 		doc2.Print(&printer2);
1314 
1315 		XMLTest("Deep clone of element.", printer1.CStr(), printer2.CStr(), true);
1316 	}
1317 
1318 	{
1319 		// Deep Cloning of sub element.
1320 		XMLDocument doc2;
1321 		XMLPrinter printer1;
1322 		{
1323 			// Make sure doc1 is deleted before we test doc2
1324 			const char* xml =
1325 				"<?xml version ='1.0'?>"
1326 				"<root>"
1327 				"    <child1 foo='bar'/>"
1328 				"    <!-- comment thing -->"
1329 				"    <child2 val='1'>Text</child2>"
1330 				"</root>";
1331 			XMLDocument doc;
1332 			doc.Parse(xml);
1333 			XMLTest( "Parse before deep cloning sub element", false, doc.Error() );
1334 
1335 			const XMLElement* subElement = doc.FirstChildElement("root")->FirstChildElement("child2");
1336 			bool acceptResult = subElement->Accept(&printer1);
1337 			XMLTest( "Accept before deep cloning", true, acceptResult );
1338 
1339 			XMLNode* clonedSubElement = subElement->DeepClone(&doc2);
1340 			doc2.InsertFirstChild(clonedSubElement);
1341 		}
1342 		XMLPrinter printer2;
1343 		doc2.Print(&printer2);
1344 
1345 		XMLTest("Deep clone of sub-element.", printer1.CStr(), printer2.CStr(), true);
1346 	}
1347 
1348 	{
1349 		// Deep cloning of document.
1350 		XMLDocument doc2;
1351 		XMLPrinter printer1;
1352 		{
1353 			// Make sure doc1 is deleted before we test doc2
1354 			const char* xml =
1355 				"<?xml version ='1.0'?>"
1356 				"<!-- Top level comment. -->"
1357 				"<root>"
1358 				"    <child1 foo='bar'/>"
1359 				"    <!-- comment thing -->"
1360 				"    <child2 val='1'>Text</child2>"
1361 				"</root>";
1362 			XMLDocument doc;
1363 			doc.Parse(xml);
1364 			XMLTest( "Parse before deep cloning document", false, doc.Error() );
1365 			doc.Print(&printer1);
1366 
1367 			doc.DeepCopy(&doc2);
1368 		}
1369 		XMLPrinter printer2;
1370 		doc2.Print(&printer2);
1371 
1372 		XMLTest("DeepCopy of document.", printer1.CStr(), printer2.CStr(), true);
1373 	}
1374 
1375 
1376  	{
1377 		// This shouldn't crash.
1378 		XMLDocument doc;
1379 		if(XML_SUCCESS != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))
1380 		{
1381 			doc.PrintError();
1382 		}
1383 		XMLTest( "Error in snprinf handling.", true, doc.Error() );
1384 	}
1385 
1386 	{
1387 		// Attribute ordering.
1388 		static const char* xml = "<element attrib1=\"1\" attrib2=\"2\" attrib3=\"3\" />";
1389 		XMLDocument doc;
1390 		doc.Parse( xml );
1391 		XMLTest( "Parse for attribute ordering", false, doc.Error() );
1392 		XMLElement* ele = doc.FirstChildElement();
1393 
1394 		const XMLAttribute* a = ele->FirstAttribute();
1395 		XMLTest( "Attribute order", "1", a->Value() );
1396 		a = a->Next();
1397 		XMLTest( "Attribute order", "2", a->Value() );
1398 		a = a->Next();
1399 		XMLTest( "Attribute order", "3", a->Value() );
1400 		XMLTest( "Attribute order", "attrib3", a->Name() );
1401 
1402 		ele->DeleteAttribute( "attrib2" );
1403 		a = ele->FirstAttribute();
1404 		XMLTest( "Attribute order", "1", a->Value() );
1405 		a = a->Next();
1406 		XMLTest( "Attribute order", "3", a->Value() );
1407 
1408 		ele->DeleteAttribute( "attrib1" );
1409 		ele->DeleteAttribute( "attrib3" );
1410 		XMLTest( "Attribute order (empty)", true, ele->FirstAttribute() == 0 );
1411 	}
1412 
1413 	{
1414 		// Make sure an attribute with a space in it succeeds.
1415 		static const char* xml0 = "<element attribute1= \"Test Attribute\"/>";
1416 		static const char* xml1 = "<element attribute1 =\"Test Attribute\"/>";
1417 		static const char* xml2 = "<element attribute1 = \"Test Attribute\"/>";
1418 		XMLDocument doc0;
1419 		doc0.Parse( xml0 );
1420 		XMLTest( "Parse attribute with space 1", false, doc0.Error() );
1421 		XMLDocument doc1;
1422 		doc1.Parse( xml1 );
1423 		XMLTest( "Parse attribute with space 2", false, doc1.Error() );
1424 		XMLDocument doc2;
1425 		doc2.Parse( xml2 );
1426 		XMLTest( "Parse attribute with space 3", false, doc2.Error() );
1427 
1428 		XMLElement* ele = 0;
1429 		ele = doc0.FirstChildElement();
1430 		XMLTest( "Attribute with space #1", "Test Attribute", ele->Attribute( "attribute1" ) );
1431 		ele = doc1.FirstChildElement();
1432 		XMLTest( "Attribute with space #2", "Test Attribute", ele->Attribute( "attribute1" ) );
1433 		ele = doc2.FirstChildElement();
1434 		XMLTest( "Attribute with space #3", "Test Attribute", ele->Attribute( "attribute1" ) );
1435 	}
1436 
1437 	{
1438 		// Make sure we don't go into an infinite loop.
1439 		static const char* xml = "<doc><element attribute='attribute'/><element attribute='attribute'/></doc>";
1440 		XMLDocument doc;
1441 		doc.Parse( xml );
1442 		XMLTest( "Parse two elements with attribute", false, doc.Error() );
1443 		XMLElement* ele0 = doc.FirstChildElement()->FirstChildElement();
1444 		XMLElement* ele1 = ele0->NextSiblingElement();
1445 		bool equal = ele0->ShallowEqual( ele1 );
1446 
1447 		XMLTest( "Infinite loop in shallow equal.", true, equal );
1448 	}
1449 
1450 	// -------- Handles ------------
1451 	{
1452 		static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
1453 		XMLDocument doc;
1454 		doc.Parse( xml );
1455 		XMLTest( "Parse element with attribute and nested element round 1", false, doc.Error() );
1456 
1457 		XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
1458 		XMLTest( "Handle, success, mutable", "sub", ele->Value() );
1459 
1460 		XMLHandle docH( doc );
1461 		ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
1462 		XMLTest( "Handle, dne, mutable", true, ele == 0 );
1463 	}
1464 
1465 	{
1466 		static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
1467 		XMLDocument doc;
1468 		doc.Parse( xml );
1469 		XMLTest( "Parse element with attribute and nested element round 2", false, doc.Error() );
1470 		XMLConstHandle docH( doc );
1471 
1472 		const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement();
1473 		XMLTest( "Handle, success, const", "sub", ele->Value() );
1474 
1475 		ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
1476 		XMLTest( "Handle, dne, const", true, ele == 0 );
1477 	}
1478 	{
1479 		// Default Declaration & BOM
1480 		XMLDocument doc;
1481 		doc.InsertEndChild( doc.NewDeclaration() );
1482 		doc.SetBOM( true );
1483 
1484 		XMLPrinter printer;
1485 		doc.Print( &printer );
1486 
1487 		static const char* result  = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
1488 		XMLTest( "BOM and default declaration", result, printer.CStr(), false );
1489 		XMLTest( "CStrSize", 42, printer.CStrSize(), false );
1490 	}
1491 	{
1492 		const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
1493 		XMLDocument doc;
1494 		doc.Parse( xml );
1495 		XMLTest( "Ill formed XML", true, doc.Error() );
1496 	}
1497 
1498 	// QueryXYZText
1499 	{
1500 		const char* xml = "<point> <x>1.2</x> <y>1</y> <z>38</z> <valid>true</valid> </point>";
1501 		XMLDocument doc;
1502 		doc.Parse( xml );
1503 		XMLTest( "Parse points", false, doc.Error() );
1504 
1505 		const XMLElement* pointElement = doc.RootElement();
1506 
1507 		{
1508 			int intValue = 0;
1509 			XMLError queryResult = pointElement->FirstChildElement( "y" )->QueryIntText( &intValue );
1510 			XMLTest( "QueryIntText result", XML_SUCCESS, queryResult, false );
1511 			XMLTest( "QueryIntText", 1, intValue, false );
1512 		}
1513 
1514 		{
1515 			unsigned unsignedValue = 0;
1516 			XMLError queryResult = pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
1517 			XMLTest( "QueryUnsignedText result", XML_SUCCESS, queryResult, false );
1518 			XMLTest( "QueryUnsignedText", (unsigned)1, unsignedValue, false );
1519 		}
1520 
1521 		{
1522 			float floatValue = 0;
1523 			XMLError queryResult = pointElement->FirstChildElement( "x" )->QueryFloatText( &floatValue );
1524 			XMLTest( "QueryFloatText result", XML_SUCCESS, queryResult, false );
1525 			XMLTest( "QueryFloatText", 1.2f, floatValue, false );
1526 		}
1527 
1528 		{
1529 			double doubleValue = 0;
1530 			XMLError queryResult = pointElement->FirstChildElement( "x" )->QueryDoubleText( &doubleValue );
1531 			XMLTest( "QueryDoubleText result", XML_SUCCESS, queryResult, false );
1532 			XMLTest( "QueryDoubleText", 1.2, doubleValue, false );
1533 		}
1534 
1535 		{
1536 			bool boolValue = false;
1537 			XMLError queryResult = pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue );
1538 			XMLTest( "QueryBoolText result", XML_SUCCESS, queryResult, false );
1539 			XMLTest( "QueryBoolText", true, boolValue, false );
1540 		}
1541 	}
1542 
1543 	{
1544 		const char* xml = "<element><_sub/><:sub/><sub:sub/><sub-sub/></element>";
1545 		XMLDocument doc;
1546 		doc.Parse( xml );
1547 		XMLTest( "Non-alpha element lead letter parses.", false, doc.Error() );
1548 	}
1549 
1550     {
1551         const char* xml = "<element _attr1=\"foo\" :attr2=\"bar\"></element>";
1552         XMLDocument doc;
1553         doc.Parse( xml );
1554         XMLTest("Non-alpha attribute lead character parses.", false, doc.Error());
1555     }
1556 
1557     {
1558         const char* xml = "<3lement></3lement>";
1559         XMLDocument doc;
1560         doc.Parse( xml );
1561         XMLTest("Element names with lead digit fail to parse.", true, doc.Error());
1562     }
1563 
1564 	{
1565 		const char* xml = "<element/>WOA THIS ISN'T GOING TO PARSE";
1566 		XMLDocument doc;
1567 		doc.Parse( xml, 10 );
1568 		XMLTest( "Set length of incoming data", false, doc.Error() );
1569 	}
1570 
1571     {
1572         XMLDocument doc;
1573         XMLTest( "Document is initially empty", true, doc.NoChildren() );
1574         doc.Clear();
1575         XMLTest( "Empty is empty after Clear()", true, doc.NoChildren() );
1576         doc.LoadFile( "resources/dream.xml" );
1577         XMLTest( "Load dream.xml", false, doc.Error() );
1578         XMLTest( "Document has something to Clear()", false, doc.NoChildren() );
1579         doc.Clear();
1580         XMLTest( "Document Clear()'s", true, doc.NoChildren() );
1581     }
1582 
1583     {
1584         XMLDocument doc;
1585         XMLTest( "No error initially", false, doc.Error() );
1586         XMLError error = doc.Parse( "This is not XML" );
1587         XMLTest( "Error after invalid XML", true, doc.Error() );
1588         XMLTest( "Error after invalid XML", error, doc.ErrorID() );
1589         doc.Clear();
1590         XMLTest( "No error after Clear()", false, doc.Error() );
1591     }
1592 
1593 	// ----------- Whitespace ------------
1594 	{
1595 		const char* xml = "<element>"
1596 							"<a> This \nis &apos;  text  &apos; </a>"
1597 							"<b>  This is &apos; text &apos;  \n</b>"
1598 							"<c>This  is  &apos;  \n\n text &apos;</c>"
1599 						  "</element>";
1600 		XMLDocument doc( true, COLLAPSE_WHITESPACE );
1601 		doc.Parse( xml );
1602 		XMLTest( "Parse with whitespace collapsing and &apos", false, doc.Error() );
1603 
1604 		const XMLElement* element = doc.FirstChildElement();
1605 		for( const XMLElement* parent = element->FirstChildElement();
1606 			 parent;
1607 			 parent = parent->NextSiblingElement() )
1608 		{
1609 			XMLTest( "Whitespace collapse", "This is ' text '", parent->GetText() );
1610 		}
1611 	}
1612 
1613 #if 0
1614 	{
1615 		// Passes if assert doesn't fire.
1616 		XMLDocument xmlDoc;
1617 
1618 	    xmlDoc.NewDeclaration();
1619 	    xmlDoc.NewComment("Configuration file");
1620 
1621 	    XMLElement *root = xmlDoc.NewElement("settings");
1622 	    root->SetAttribute("version", 2);
1623 	}
1624 #endif
1625 
1626 	{
1627 		const char* xml = "<element>    </element>";
1628 		XMLDocument doc( true, COLLAPSE_WHITESPACE );
1629 		doc.Parse( xml );
1630 		XMLTest( "Parse with all whitespaces", false, doc.Error() );
1631 		XMLTest( "Whitespace  all space", true, 0 == doc.FirstChildElement()->FirstChild() );
1632 	}
1633 
1634 	{
1635 		// An assert should not fire.
1636 		const char* xml = "<element/>";
1637 		XMLDocument doc;
1638 		doc.Parse( xml );
1639 		XMLTest( "Parse with self-closed element", false, doc.Error() );
1640 		XMLElement* ele = doc.NewElement( "unused" );		// This will get cleaned up with the 'doc' going out of scope.
1641 		XMLTest( "Tracking unused elements", true, ele != 0, false );
1642 	}
1643 
1644 
1645 	{
1646 		const char* xml = "<parent><child>abc</child></parent>";
1647 		XMLDocument doc;
1648 		doc.Parse( xml );
1649 		XMLTest( "Parse for printing of sub-element", false, doc.Error() );
1650 		XMLElement* ele = doc.FirstChildElement( "parent")->FirstChildElement( "child");
1651 
1652 		XMLPrinter printer;
1653 		bool acceptResult = ele->Accept( &printer );
1654 		XMLTest( "Accept of sub-element", true, acceptResult );
1655 		XMLTest( "Printing of sub-element", "<child>abc</child>\n", printer.CStr(), false );
1656 	}
1657 
1658 
1659 	{
1660 		XMLDocument doc;
1661 		XMLError error = doc.LoadFile( "resources/empty.xml" );
1662 		XMLTest( "Loading an empty file", XML_ERROR_EMPTY_DOCUMENT, error );
1663 		XMLTest( "Loading an empty file and ErrorName as string", "XML_ERROR_EMPTY_DOCUMENT", doc.ErrorName() );
1664 		doc.PrintError();
1665 	}
1666 
1667 	{
1668         // BOM preservation
1669         static const char* xml_bom_preservation  = "\xef\xbb\xbf<element/>\n";
1670         {
1671 			XMLDocument doc;
1672 			XMLTest( "BOM preservation (parse)", XML_SUCCESS, doc.Parse( xml_bom_preservation ), false );
1673             XMLPrinter printer;
1674             doc.Print( &printer );
1675 
1676             XMLTest( "BOM preservation (compare)", xml_bom_preservation, printer.CStr(), false, true );
1677 			doc.SaveFile( "resources/bomtest.xml" );
1678 			XMLTest( "Save bomtest.xml", false, doc.Error() );
1679         }
1680 		{
1681 			XMLDocument doc;
1682 			doc.LoadFile( "resources/bomtest.xml" );
1683 			XMLTest( "Load bomtest.xml", false, doc.Error() );
1684 			XMLTest( "BOM preservation (load)", true, doc.HasBOM(), false );
1685 
1686             XMLPrinter printer;
1687             doc.Print( &printer );
1688             XMLTest( "BOM preservation (compare)", xml_bom_preservation, printer.CStr(), false, true );
1689 		}
1690 	}
1691 
1692 	{
1693 		// Insertion with Removal
1694 		const char* xml = "<?xml version=\"1.0\" ?>"
1695 			"<root>"
1696 			"<one>"
1697 			"<subtree>"
1698 			"<elem>element 1</elem>text<!-- comment -->"
1699 			"</subtree>"
1700 			"</one>"
1701 			"<two/>"
1702 			"</root>";
1703 		const char* xmlInsideTwo = "<?xml version=\"1.0\" ?>"
1704 			"<root>"
1705 			"<one/>"
1706 			"<two>"
1707 			"<subtree>"
1708 			"<elem>element 1</elem>text<!-- comment -->"
1709 			"</subtree>"
1710 			"</two>"
1711 			"</root>";
1712 		const char* xmlAfterOne = "<?xml version=\"1.0\" ?>"
1713 			"<root>"
1714 			"<one/>"
1715 			"<subtree>"
1716 			"<elem>element 1</elem>text<!-- comment -->"
1717 			"</subtree>"
1718 			"<two/>"
1719 			"</root>";
1720 		const char* xmlAfterTwo = "<?xml version=\"1.0\" ?>"
1721 			"<root>"
1722 			"<one/>"
1723 			"<two/>"
1724 			"<subtree>"
1725 			"<elem>element 1</elem>text<!-- comment -->"
1726 			"</subtree>"
1727 			"</root>";
1728 
1729 		XMLDocument doc;
1730 		doc.Parse(xml);
1731 		XMLTest( "Insertion with removal parse round 1", false, doc.Error() );
1732 		XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
1733 		XMLElement* two = doc.RootElement()->FirstChildElement("two");
1734 		two->InsertFirstChild(subtree);
1735 		XMLPrinter printer1(0, true);
1736 		bool acceptResult = doc.Accept(&printer1);
1737 		XMLTest("Move node from within <one> to <two> - Accept()", true, acceptResult);
1738 		XMLTest("Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());
1739 
1740 		doc.Parse(xml);
1741 		XMLTest( "Insertion with removal parse round 2", false, doc.Error() );
1742 		subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
1743 		two = doc.RootElement()->FirstChildElement("two");
1744 		doc.RootElement()->InsertAfterChild(two, subtree);
1745 		XMLPrinter printer2(0, true);
1746 		acceptResult = doc.Accept(&printer2);
1747 		XMLTest("Move node from within <one> after <two> - Accept()", true, acceptResult);
1748 		XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false);
1749 
1750 		doc.Parse(xml);
1751 		XMLTest( "Insertion with removal parse round 3", false, doc.Error() );
1752 		XMLNode* one = doc.RootElement()->FirstChildElement("one");
1753 		subtree = one->FirstChildElement("subtree");
1754 		doc.RootElement()->InsertAfterChild(one, subtree);
1755 		XMLPrinter printer3(0, true);
1756 		acceptResult = doc.Accept(&printer3);
1757 		XMLTest("Move node from within <one> after <one> - Accept()", true, acceptResult);
1758 		XMLTest("Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false);
1759 
1760 		doc.Parse(xml);
1761 		XMLTest( "Insertion with removal parse round 4", false, doc.Error() );
1762 		subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
1763 		two = doc.RootElement()->FirstChildElement("two");
1764 		doc.RootElement()->InsertEndChild(subtree);
1765 		XMLPrinter printer4(0, true);
1766 		acceptResult = doc.Accept(&printer4);
1767 		XMLTest("Move node from within <one> after <two> - Accept()", true, acceptResult);
1768 		XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false);
1769 	}
1770 
1771 	{
1772 		const char* xml = "<svg width = \"128\" height = \"128\">"
1773 			"	<text> </text>"
1774 			"</svg>";
1775 		XMLDocument doc;
1776 		doc.Parse(xml);
1777 		XMLTest( "Parse svg with text", false, doc.Error() );
1778 		doc.Print();
1779 	}
1780 
1781 	{
1782 		// Test that it doesn't crash.
1783 		const char* xml = "<?xml version=\"1.0\"?><root><sample><field0><1</field0><field1>2</field1></sample></root>";
1784 		XMLDocument doc;
1785 		doc.Parse(xml);
1786 		XMLTest( "Parse root-sample-field0", true, doc.Error() );
1787 		doc.PrintError();
1788 	}
1789 
1790 #if 1
1791 		// the question being explored is what kind of print to use:
1792 		// https://github.com/leethomason/tinyxml2/issues/63
1793 	{
1794 		//const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9' attrC='1.0e-10' attrD='1001000000.000000' attrE='0.1234567890123456789'/>";
1795 		const char* xml = "<element/>";
1796 		XMLDocument doc;
1797 		doc.Parse( xml );
1798 		XMLTest( "Parse self-closed empty element", false, doc.Error() );
1799 		doc.FirstChildElement()->SetAttribute( "attrA-f64", 123456789.123456789 );
1800 		doc.FirstChildElement()->SetAttribute( "attrB-f64", 1.001e9 );
1801 		doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e9 );
1802 		doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e20 );
1803 		doc.FirstChildElement()->SetAttribute( "attrD-f64", 1.0e-10 );
1804 		doc.FirstChildElement()->SetAttribute( "attrD-f64", 0.123456789 );
1805 
1806 		doc.FirstChildElement()->SetAttribute( "attrA-f32", 123456789.123456789f );
1807 		doc.FirstChildElement()->SetAttribute( "attrB-f32", 1.001e9f );
1808 		doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e9f );
1809 		doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e20f );
1810 		doc.FirstChildElement()->SetAttribute( "attrD-f32", 1.0e-10f );
1811 		doc.FirstChildElement()->SetAttribute( "attrD-f32", 0.123456789f );
1812 
1813 		doc.Print();
1814 
1815 		/* The result of this test is platform, compiler, and library version dependent. :("
1816 		XMLPrinter printer;
1817 		doc.Print( &printer );
1818 		XMLTest( "Float and double formatting.",
1819 			"<element attrA-f64=\"123456789.12345679\" attrB-f64=\"1001000000\" attrC-f64=\"1e+20\" attrD-f64=\"0.123456789\" attrA-f32=\"1.2345679e+08\" attrB-f32=\"1.001e+09\" attrC-f32=\"1e+20\" attrD-f32=\"0.12345679\"/>\n",
1820 			printer.CStr(),
1821 			true );
1822 		*/
1823 	}
1824 #endif
1825 
1826     {
1827         // Issue #184
1828         // If it doesn't assert, it passes. Caused by objects
1829         // getting created during parsing which are then
1830         // inaccessible in the memory pools.
1831         const char* xmlText = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>";
1832         {
1833             XMLDocument doc;
1834             doc.Parse(xmlText);
1835             XMLTest( "Parse hex no closing tag round 1", true, doc.Error() );
1836         }
1837         {
1838             XMLDocument doc;
1839             doc.Parse(xmlText);
1840             XMLTest( "Parse hex no closing tag round 2", true, doc.Error() );
1841             doc.Clear();
1842         }
1843     }
1844 
1845     {
1846         // If this doesn't assert in DEBUG, all is well.
1847         tinyxml2::XMLDocument doc;
1848         tinyxml2::XMLElement *pRoot = doc.NewElement("Root");
1849         doc.DeleteNode(pRoot);
1850     }
1851 
1852     {
1853         XMLDocument doc;
1854         XMLElement* root = doc.NewElement( "Root" );
1855         XMLTest( "Node document before insertion", true, &doc == root->GetDocument() );
1856         doc.InsertEndChild( root );
1857         XMLTest( "Node document after insertion", true, &doc == root->GetDocument() );
1858     }
1859 
1860     {
1861         // If this doesn't assert in DEBUG, all is well.
1862         XMLDocument doc;
1863         XMLElement* unlinkedRoot = doc.NewElement( "Root" );
1864         XMLElement* linkedRoot = doc.NewElement( "Root" );
1865         doc.InsertFirstChild( linkedRoot );
1866         unlinkedRoot->GetDocument()->DeleteNode( linkedRoot );
1867         unlinkedRoot->GetDocument()->DeleteNode( unlinkedRoot );
1868     }
1869 
1870 	{
1871 		// Should not assert in DEBUG
1872 		XMLPrinter printer;
1873 	}
1874 
1875 	{
1876 		// Issue 291. Should not crash
1877 		const char* xml = "&#0</a>";
1878 		XMLDocument doc;
1879 		doc.Parse( xml );
1880 		XMLTest( "Parse hex with closing tag", false, doc.Error() );
1881 
1882 		XMLPrinter printer;
1883 		doc.Print( &printer );
1884 	}
1885 	{
1886 		// Issue 299. Can print elements that are not linked in.
1887 		// Will crash if issue not fixed.
1888 		XMLDocument doc;
1889 		XMLElement* newElement = doc.NewElement( "printme" );
1890 		XMLPrinter printer;
1891 		bool acceptResult = newElement->Accept( &printer );
1892 		XMLTest( "printme - Accept()", true, acceptResult );
1893 		// Delete the node to avoid possible memory leak report in debug output
1894 		doc.DeleteNode( newElement );
1895 	}
1896 	{
1897 		// Issue 302. Clear errors from LoadFile/SaveFile
1898 		XMLDocument doc;
1899 		XMLTest( "Issue 302. Should be no error initially", "XML_SUCCESS", doc.ErrorName() );
1900 		doc.SaveFile( "./no/such/path/pretty.xml" );
1901 		XMLTest( "Issue 302. Fail to save", "XML_ERROR_FILE_COULD_NOT_BE_OPENED", doc.ErrorName() );
1902 		doc.SaveFile( "./resources/out/compact.xml", true );
1903 		XMLTest( "Issue 302. Subsequent success in saving", "XML_SUCCESS", doc.ErrorName() );
1904 	}
1905 
1906 	{
1907 		// If a document fails to load then subsequent
1908 		// successful loads should clear the error
1909 		XMLDocument doc;
1910 		XMLTest( "Should be no error initially", false, doc.Error() );
1911 		doc.LoadFile( "resources/no-such-file.xml" );
1912 		XMLTest( "No such file - should fail", true, doc.Error() );
1913 
1914 		doc.LoadFile( "resources/dream.xml" );
1915 		XMLTest( "Error should be cleared", false, doc.Error() );
1916 	}
1917 
1918 	{
1919 		// Check that declarations are allowed only at beginning of document
1920 	    const char* xml0 = "<?xml version=\"1.0\" ?>"
1921 	                       "   <!-- xml version=\"1.1\" -->"
1922 	                       "<first />";
1923 	    const char* xml1 = "<?xml version=\"1.0\" ?>"
1924 	                       "<?xml-stylesheet type=\"text/xsl\" href=\"Anything.xsl\"?>"
1925 	                       "<first />";
1926 	    const char* xml2 = "<first />"
1927 	                       "<?xml version=\"1.0\" ?>";
1928 	    const char* xml3 = "<first></first>"
1929 	                       "<?xml version=\"1.0\" ?>";
1930 
1931 	    const char* xml4 = "<first><?xml version=\"1.0\" ?></first>";
1932 
1933 	    XMLDocument doc;
1934 	    doc.Parse(xml0);
1935 	    XMLTest("Test that the code changes do not affect normal parsing", false, doc.Error() );
1936 	    doc.Parse(xml1);
1937 	    XMLTest("Test that the second declaration is allowed", false, doc.Error() );
1938 	    doc.Parse(xml2);
1939 	    XMLTest("Test that declaration after a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
1940 	    doc.Parse(xml3);
1941 	    XMLTest("Test that declaration after a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
1942 	    doc.Parse(xml4);
1943 	    XMLTest("Test that declaration inside a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
1944 	}
1945 
1946     {
1947 	    // No matter - before or after successfully parsing a text -
1948 	    // calling XMLDocument::Value() used to cause an assert in debug.
1949 	    // Null must be retured.
1950 	    const char* validXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1951 	                           "<first />"
1952 	                           "<second />";
1953 	    XMLDocument* doc = new XMLDocument();
1954 	    XMLTest( "XMLDocument::Value() returns null?", NULL, doc->Value() );
1955 	    doc->Parse( validXml );
1956 	    XMLTest( "Parse to test XMLDocument::Value()", false, doc->Error());
1957 	    XMLTest( "XMLDocument::Value() returns null?", NULL, doc->Value() );
1958 	    delete doc;
1959     }
1960 
1961 	{
1962 		XMLDocument doc;
1963 		for( int i = 0; i < XML_ERROR_COUNT; i++ ) {
1964 			const XMLError error = static_cast<XMLError>(i);
1965 			const char* name = XMLDocument::ErrorIDToName(error);
1966 			XMLTest( "ErrorName() after ClearError()", true, name != 0 );
1967 			XMLTest( "ErrorName() after ClearError()", true, strlen(name) > 0 );
1968 		}
1969 	}
1970 
1971 	{
1972 		// Evil memory leaks.
1973 		// If an XMLElement (etc) is allocated via NewElement() (etc.)
1974 		// and NOT added to the XMLDocument, what happens?
1975 		//
1976 		// Previously (buggy):
1977 		//		The memory would be free'd when the XMLDocument is
1978 		//      destructed. But the XMLElement destructor wasn't called, so
1979 		//      memory allocated for the XMLElement text would not be free'd.
1980 		//      In practice this meant strings allocated for the XMLElement
1981 		//      text would be leaked. An edge case, but annoying.
1982 		// Now:
1983 		//      The XMLElement destructor is called. But the unlinked nodes
1984 		//      have to be tracked using a list. This has a minor performance
1985 		//      impact that can become significant if you have a lot of
1986 		//      unlinked nodes. (But why would you do that?)
1987 		// The only way to see this bug was in a Visual C++ runtime debug heap
1988 		// leak tracker. This is compiled in by default on Windows Debug and
1989 		// enabled with _CRTDBG_LEAK_CHECK_DF parameter passed to _CrtSetDbgFlag().
1990 		{
1991 			XMLDocument doc;
1992 			doc.NewElement("LEAK 1");
1993 		}
1994 		{
1995 			XMLDocument doc;
1996 			XMLElement* ele = doc.NewElement("LEAK 2");
1997 			doc.DeleteNode(ele);
1998 		}
1999 	}
2000 
2001 	{
2002 		// Crashing reported via email.
2003 		const char* xml =
2004 			"<playlist id='playlist1'>"
2005 			"<property name='track_name'>voice</property>"
2006 			"<property name='audio_track'>1</property>"
2007 			"<entry out = '604' producer = '4_playlist1' in = '0' />"
2008 			"<blank length = '1' />"
2009 			"<entry out = '1625' producer = '3_playlist' in = '0' />"
2010 			"<blank length = '2' />"
2011 			"<entry out = '946' producer = '2_playlist1' in = '0' />"
2012 			"<blank length = '1' />"
2013 			"<entry out = '128' producer = '1_playlist1' in = '0' />"
2014 			"</playlist>";
2015 
2016 		// It's not a good idea to delete elements as you walk the
2017 		// list. I'm not sure this technically should work; but it's
2018 		// an interesting test case.
2019 		XMLDocument doc;
2020 		XMLError err = doc.Parse(xml);
2021 		XMLTest("Crash bug parsing", XML_SUCCESS, err );
2022 
2023 		XMLElement* playlist = doc.FirstChildElement("playlist");
2024 		XMLTest("Crash bug parsing", true, playlist != 0);
2025 
2026 		{
2027 			const char* elementName = "entry";
2028 			XMLElement* entry = playlist->FirstChildElement(elementName);
2029 			XMLTest("Crash bug parsing", true, entry != 0);
2030 			while (entry) {
2031 				XMLElement* todelete = entry;
2032 				entry = entry->NextSiblingElement(elementName);
2033 				playlist->DeleteChild(todelete);
2034 			}
2035 			entry = playlist->FirstChildElement(elementName);
2036 			XMLTest("Crash bug parsing", true, entry == 0);
2037 		}
2038 		{
2039 			const char* elementName = "blank";
2040 			XMLElement* blank = playlist->FirstChildElement(elementName);
2041 			XMLTest("Crash bug parsing", true, blank != 0);
2042 			while (blank) {
2043 				XMLElement* todelete = blank;
2044 				blank = blank->NextSiblingElement(elementName);
2045 				playlist->DeleteChild(todelete);
2046 			}
2047 			XMLTest("Crash bug parsing", true, blank == 0);
2048 		}
2049 
2050 		tinyxml2::XMLPrinter printer;
2051 		const bool acceptResult = playlist->Accept(&printer);
2052 		XMLTest("Crash bug parsing - Accept()", true, acceptResult);
2053 		printf("%s\n", printer.CStr());
2054 
2055 		// No test; it only need to not crash.
2056 		// Still, wrap it up with a sanity check
2057 		int nProperty = 0;
2058 		for (const XMLElement* p = playlist->FirstChildElement("property"); p; p = p->NextSiblingElement("property")) {
2059 			nProperty++;
2060 		}
2061 		XMLTest("Crash bug parsing", 2, nProperty);
2062 	}
2063 
2064     // ----------- Line Number Tracking --------------
2065     {
2066         struct TestUtil: XMLVisitor
2067         {
2068             TestUtil() : str() {}
2069 
2070             void TestParseError(const char *testString, const char *docStr, XMLError expected_error, int expectedLine)
2071             {
2072                 XMLDocument doc;
2073                 const XMLError parseError = doc.Parse(docStr);
2074 
2075                 XMLTest(testString, parseError, doc.ErrorID());
2076                 XMLTest(testString, true, doc.Error());
2077                 XMLTest(testString, expected_error, parseError);
2078                 XMLTest(testString, expectedLine, doc.ErrorLineNum());
2079             };
2080 
2081             void TestStringLines(const char *testString, const char *docStr, const char *expectedLines)
2082             {
2083                 XMLDocument doc;
2084                 doc.Parse(docStr);
2085                 XMLTest(testString, false, doc.Error());
2086                 TestDocLines(testString, doc, expectedLines);
2087             }
2088 
2089             void TestFileLines(const char *testString, const char *file_name, const char *expectedLines)
2090             {
2091                 XMLDocument doc;
2092                 doc.LoadFile(file_name);
2093                 XMLTest(testString, false, doc.Error());
2094                 TestDocLines(testString, doc, expectedLines);
2095             }
2096 
2097         private:
2098             DynArray<char, 10> str;
2099 
2100             void Push(char type, int lineNum)
2101             {
2102                 str.Push(type);
2103                 str.Push(char('0' + (lineNum / 10)));
2104                 str.Push(char('0' + (lineNum % 10)));
2105             }
2106 
2107             bool VisitEnter(const XMLDocument& doc)
2108             {
2109                 Push('D', doc.GetLineNum());
2110                 return true;
2111             }
2112             bool VisitEnter(const XMLElement& element, const XMLAttribute* firstAttribute)
2113             {
2114                 Push('E', element.GetLineNum());
2115                 for (const XMLAttribute *attr = firstAttribute; attr != 0; attr = attr->Next())
2116                     Push('A', attr->GetLineNum());
2117                 return true;
2118             }
2119             bool Visit(const XMLDeclaration& declaration)
2120             {
2121                 Push('L', declaration.GetLineNum());
2122                 return true;
2123             }
2124             bool Visit(const XMLText& text)
2125             {
2126                 Push('T', text.GetLineNum());
2127                 return true;
2128             }
2129             bool Visit(const XMLComment& comment)
2130             {
2131                 Push('C', comment.GetLineNum());
2132                 return true;
2133             }
2134             bool Visit(const XMLUnknown& unknown)
2135             {
2136                 Push('U', unknown.GetLineNum());
2137                 return true;
2138             }
2139 
2140             void TestDocLines(const char *testString, XMLDocument &doc, const char *expectedLines)
2141             {
2142                 str.Clear();
2143                 const bool acceptResult = doc.Accept(this);
2144                 XMLTest(testString, true, acceptResult);
2145                 str.Push(0);
2146                 XMLTest(testString, expectedLines, str.Mem());
2147             }
2148         } tester;
2149 
2150 		tester.TestParseError("ErrorLine-Parsing", "\n<root>\n foo \n<unclosed/>", XML_ERROR_PARSING, 2);
2151         tester.TestParseError("ErrorLine-Declaration", "<root>\n<?xml version=\"1.0\"?>", XML_ERROR_PARSING_DECLARATION, 2);
2152         tester.TestParseError("ErrorLine-Mismatch", "\n<root>\n</mismatch>", XML_ERROR_MISMATCHED_ELEMENT, 2);
2153         tester.TestParseError("ErrorLine-CData", "\n<root><![CDATA[ \n foo bar \n", XML_ERROR_PARSING_CDATA, 2);
2154         tester.TestParseError("ErrorLine-Text", "\n<root>\n foo bar \n", XML_ERROR_PARSING_TEXT, 3);
2155         tester.TestParseError("ErrorLine-Comment", "\n<root>\n<!-- >\n", XML_ERROR_PARSING_COMMENT, 3);
2156         tester.TestParseError("ErrorLine-Declaration", "\n<root>\n<? >\n", XML_ERROR_PARSING_DECLARATION, 3);
2157         tester.TestParseError("ErrorLine-Unknown", "\n<root>\n<! \n", XML_ERROR_PARSING_UNKNOWN, 3);
2158         tester.TestParseError("ErrorLine-Element", "\n<root>\n<unclosed \n", XML_ERROR_PARSING_ELEMENT, 3);
2159         tester.TestParseError("ErrorLine-Attribute", "\n<root>\n<unclosed \n att\n", XML_ERROR_PARSING_ATTRIBUTE, 4);
2160         tester.TestParseError("ErrorLine-ElementClose", "\n<root>\n<unclosed \n/unexpected", XML_ERROR_PARSING_ELEMENT, 3);
2161 
2162 		tester.TestStringLines(
2163             "LineNumbers-String",
2164 
2165             "<?xml version=\"1.0\"?>\n"					// 1 Doc, DecL
2166                 "<root a='b' \n"						// 2 Element Attribute
2167                 "c='d'> d <blah/>  \n"					// 3 Attribute Text Element
2168                 "newline in text \n"					// 4 Text
2169                 "and second <zxcv/><![CDATA[\n"			// 5 Element Text
2170                 " cdata test ]]><!-- comment -->\n"		// 6 Comment
2171                 "<! unknown></root>",					// 7 Unknown
2172 
2173             "D01L01E02A02A03T03E03T04E05T05C06U07");
2174 
2175 		tester.TestStringLines(
2176             "LineNumbers-CRLF",
2177 
2178             "\r\n"										// 1 Doc (arguably should be line 2)
2179             "<?xml version=\"1.0\"?>\n"					// 2 DecL
2180             "<root>\r\n"								// 3 Element
2181             "\n"										// 4
2182             "text contining new line \n"				// 5 Text
2183             " and also containing crlf \r\n"			// 6
2184             "<sub><![CDATA[\n"							// 7 Element Text
2185             "cdata containing new line \n"				// 8
2186             " and also containing cflr\r\n"				// 9
2187             "]]></sub><sub2/></root>",					// 10 Element
2188 
2189             "D01L02E03T05E07T07E10");
2190 
2191 		tester.TestFileLines(
2192             "LineNumbers-File",
2193             "resources/utf8test.xml",
2194             "D01L01E02E03A03A03T03E04A04A04T04E05A05A05T05E06A06A06T06E07A07A07T07E08A08A08T08E09T09E10T10");
2195     }
2196 
2197     {
2198     	const char* xml = "<Hello>Text</Error>";
2199     	XMLDocument doc;
2200     	doc.Parse(xml);
2201     	XMLTest("Test mismatched elements.", true, doc.Error());
2202     	XMLTest("Test mismatched elements.", XML_ERROR_MISMATCHED_ELEMENT, doc.ErrorID());
2203     	// For now just make sure calls work & doesn't crash.
2204     	// May solidify the error output in the future.
2205     	printf("%s\n", doc.ErrorStr());
2206     	doc.PrintError();
2207     }
2208 
2209     // ----------- Performance tracking --------------
2210 	{
2211 #if defined( _MSC_VER )
2212 		__int64 start, end, freq;
2213 		QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
2214 #endif
2215 
2216 		FILE* perfFP = fopen("resources/dream.xml", "r");
2217 		XMLTest("Open dream.xml", true, perfFP != 0);
2218 		fseek(perfFP, 0, SEEK_END);
2219 		long size = ftell(perfFP);
2220 		fseek(perfFP, 0, SEEK_SET);
2221 
2222 		char* mem = new char[size + 1];
2223 		memset(mem, 0xfe, size);
2224 		size_t bytesRead = fread(mem, 1, size, perfFP);
2225 		XMLTest("Read dream.xml", true, uint32_t(size) >= uint32_t(bytesRead));
2226 		fclose(perfFP);
2227 		mem[size] = 0;
2228 
2229 #if defined( _MSC_VER )
2230 		QueryPerformanceCounter((LARGE_INTEGER*)&start);
2231 #else
2232 		clock_t cstart = clock();
2233 #endif
2234 		bool parseDreamXmlFailed = false;
2235 		static const int COUNT = 10;
2236 		for (int i = 0; i < COUNT; ++i) {
2237 			XMLDocument doc;
2238 			doc.Parse(mem);
2239 			parseDreamXmlFailed = parseDreamXmlFailed || doc.Error();
2240 		}
2241 #if defined( _MSC_VER )
2242 		QueryPerformanceCounter((LARGE_INTEGER*)&end);
2243 #else
2244 		clock_t cend = clock();
2245 #endif
2246 		XMLTest( "Parse dream.xml", false, parseDreamXmlFailed );
2247 
2248 		delete[] mem;
2249 
2250 		static const char* note =
2251 #ifdef DEBUG
2252 			"DEBUG";
2253 #else
2254 			"Release";
2255 #endif
2256 
2257 #if defined( _MSC_VER )
2258 		const double duration = 1000.0 * (double)(end - start) / ((double)freq * (double)COUNT);
2259 #else
2260 		const double duration = (double)(cend - cstart) / (double)COUNT;
2261 #endif
2262 		printf("\nParsing dream.xml (%s): %.3f milli-seconds\n", note, duration);
2263 	}
2264 
2265 #if defined( _MSC_VER ) &&  defined( DEBUG )
2266 	{
2267 		_CrtMemCheckpoint( &endMemState );
2268 
2269 		_CrtMemState diffMemState;
2270 		_CrtMemDifference( &diffMemState, &startMemState, &endMemState );
2271 		_CrtMemDumpStatistics( &diffMemState );
2272 
2273 		{
2274 			int leaksBeforeExit = _CrtDumpMemoryLeaks();
2275 			XMLTest( "No leaks before exit?", FALSE, leaksBeforeExit );
2276 		}
2277 	}
2278 #endif
2279 
2280 	printf ("\nPass %d, Fail %d\n", gPass, gFail);
2281 
2282 	return gFail;
2283 }
2284