blob: 95f9738dc44015260775340946f094aefb44c0cf [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#include "tinyxml2.h"
2
3#include <stdio.h>
4#include <stdlib.h>
Lee Thomasonec5a7b42012-02-13 18:16:52 -08005#include <string.h>
U-Lama\Leee13c3e62011-12-28 14:36:55 -08006
Lee Thomason1ff38e02012-02-14 18:18:16 -08007#if defined( WIN32 )
8 #include <crtdbg.h>
9 _CrtMemState startMemState;
10 _CrtMemState endMemState;
11#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -080012
U-Lama\Leee13c3e62011-12-28 14:36:55 -080013using namespace tinyxml2;
Lee Thomasonec5a7b42012-02-13 18:16:52 -080014int gPass = 0;
15int gFail = 0;
16
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080017//#define DREAM_ONLY
18
19/*
20int gNew = 0;
21int gNewTotal = 0;
22
23void* operator new( size_t size )
24{
25 ++gNew;
26 return malloc( size );
27}
28
29void* operator new[]( size_t size )
30{
31 ++gNew;
32 return malloc( size );
33}
34
35void operator delete[]( void* mem )
36{
37 free( mem );
38}
39
40void operator delete( void* mem )
41{
42 free( mem );
43}
44*/
45
46
U-Stream\Lee09a11c52012-02-17 08:31:16 -080047bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080048{
49 bool pass = !strcmp( expected, found );
50 if ( pass )
51 printf ("[pass]");
52 else
53 printf ("[fail]");
54
U-Stream\Lee09a11c52012-02-17 08:31:16 -080055 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080056 printf (" %s\n", testString);
57 else
58 printf (" %s [%s][%s]\n", testString, expected, found);
59
60 if ( pass )
61 ++gPass;
62 else
63 ++gFail;
64 return pass;
65}
66
67
U-Stream\Lee09a11c52012-02-17 08:31:16 -080068bool XMLTest( const char* testString, int expected, int found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080069{
70 bool pass = ( expected == found );
71 if ( pass )
72 printf ("[pass]");
73 else
74 printf ("[fail]");
75
U-Stream\Lee09a11c52012-02-17 08:31:16 -080076 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080077 printf (" %s\n", testString);
78 else
79 printf (" %s [%d][%d]\n", testString, expected, found);
80
81 if ( pass )
82 ++gPass;
83 else
84 ++gFail;
85 return pass;
86}
Lee Thomasonec5a7b42012-02-13 18:16:52 -080087
U-Lama\Leee13c3e62011-12-28 14:36:55 -080088
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -080089void NullLineEndings( char* p )
90{
91 while( p && *p ) {
92 if ( *p == '\n' || *p == '\r' ) {
93 *p = 0;
94 return;
95 }
96 ++p;
97 }
98}
99
100
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800101int main( int argc, const char* argv )
102{
Lee Thomason1ff38e02012-02-14 18:18:16 -0800103 #if defined( WIN32 )
104 _CrtMemCheckpoint( &startMemState );
105 #endif
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800106#ifndef DREAM_ONLY
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800107#if 0
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800108 {
Lee Thomasonfde6a752012-01-14 18:08:12 -0800109 static const char* test = "<!--hello world\n"
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800110 " line 2\r"
111 " line 3\r\n"
112 " line 4\n\r"
113 " line 5\r-->";
114
115 XMLDocument doc;
116 doc.Parse( test );
Lee Thomason50adb4c2012-02-13 15:07:09 -0800117 doc.Print();
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800118 }
119#endif
Lee Thomason50adb4c2012-02-13 15:07:09 -0800120#if 0
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800121 {
Lee Thomason43f59302012-02-06 18:18:11 -0800122 static const char* test[] = { "<element />",
123 "<element></element>",
124 "<element><subelement/></element>",
125 "<element><subelement></subelement></element>",
126 "<element><subelement><subsub/></subelement></element>",
127 "<!--comment beside elements--><element><subelement></subelement></element>",
128 "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
129 "<element attrib1='foo' attrib2=\"bar\" ></element>",
130 "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
131 "<element>Text inside element.</element>",
132 "<element><b></b></element>",
133 "<element>Text inside and <b>bolded</b> in the element.</element>",
134 "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
Lee Thomason8ee79892012-01-25 17:44:30 -0800135 "<element>This &amp; That.</element>",
Lee Thomason18d68bd2012-01-26 18:17:26 -0800136 "<element attrib='This&lt;That' />",
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800137 0
138 };
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800139 for( int i=0; test[i]; ++i ) {
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800140 XMLDocument doc;
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800141 doc.Parse( test[i] );
Lee Thomason5cae8972012-01-24 18:03:07 -0800142 doc.Print();
Lee Thomasonec975ce2012-01-23 11:42:06 -0800143 printf( "----------------------------------------------\n" );
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800144 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800145 }
Lee Thomason50adb4c2012-02-13 15:07:09 -0800146#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800147#if 0
Lee Thomason2c85a712012-01-31 08:24:24 -0800148 {
149 static const char* test = "<element>Text before.</element>";
150 XMLDocument doc;
151 doc.Parse( test );
152 XMLElement* root = doc.FirstChildElement();
153 XMLElement* newElement = doc.NewElement( "Subelement" );
154 root->InsertEndChild( newElement );
155 doc.Print();
156 }
Lee Thomasond1983222012-02-06 08:41:24 -0800157 {
158 XMLDocument* doc = new XMLDocument();
159 static const char* test = "<element><sub/></element>";
160 doc->Parse( test );
161 delete doc;
162 }
Lee Thomason56bdd022012-02-09 18:16:58 -0800163#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800164 {
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800165#if 0
Lee Thomason1ff38e02012-02-14 18:18:16 -0800166 // Test: Programmatic DOM
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800167 // Build:
168 // <element>
169 // <!--comment-->
170 // <sub attrib="1" />
171 // <sub attrib="2" />
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800172 // <sub attrib="3" >& Text!</sub>
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800173 // <element>
174
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800175 XMLDocument* doc = new XMLDocument();
Lee Thomason1ff38e02012-02-14 18:18:16 -0800176 XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
177
178 XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
179 for( int i=0; i<3; ++i ) {
180 sub[i]->SetAttribute( "attrib", i );
181 }
182 element->InsertEndChild( sub[2] );
183 XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
184 element->InsertAfterChild( comment, sub[0] );
185 element->InsertAfterChild( sub[0], sub[1] );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800186 sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800187 doc->Print();
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800188 XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
189 XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
190 XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
191 XMLTest( "Programmatic DOM", "& Text!",
192 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800193
194 // And now deletion:
195 element->DeleteChild( sub[2] );
196 doc->DeleteNode( comment );
197
198 element->FirstChildElement()->SetAttribute( "attrib", true );
199 element->LastChildElement()->DeleteAttribute( "attrib" );
200
201 XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
202 int value = 10;
203 int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
204 XMLTest( "Programmatic DOM", result, NO_ATTRIBUTE );
205 XMLTest( "Programmatic DOM", value, 10 );
206
207 doc->Print();
208
209 XMLStreamer streamer;
210 doc->Print( &streamer );
211 printf( "%s", streamer.CStr() );
212
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800213 delete doc;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800214#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800215 }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800216#endif
217 {
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800218#if 0
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800219 // Test: Dream
220 // XML1 : 1,187,569 bytes in 31,209 allocations
221 // XML2 : 469,073 bytes in 323 allocations
222 //int newStart = gNew;
223 XMLDocument doc;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800224 doc.LoadFile( "dream.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800225
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800226 doc.SaveFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800227 doc.PrintError();
228
229 XMLTest( "Dream", "xml version=\"1.0\"",
230 doc.FirstChild()->ToDeclaration()->Value() );
231 XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
232 XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
233 doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
234 XMLTest( "Dream", "And Robin shall restore amends.",
235 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
236 XMLTest( "Dream", "And Robin shall restore amends.",
237 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
238
239 XMLDocument doc2;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800240 doc2.LoadFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800241 XMLTest( "Dream-out", "xml version=\"1.0\"",
242 doc2.FirstChild()->ToDeclaration()->Value() );
243 XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
244 XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
245 doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
246 XMLTest( "Dream-out", "And Robin shall restore amends.",
247 doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
248
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800249#endif
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800250 //gNewTotal = gNew - newStart;
251 }
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800252
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800253#if 0
254 {
255 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
256 "<passages count=\"006\" formatversion=\"20020620\">\n"
257 " <wrong error>\n"
258 "</passages>";
259
260 XMLDocument doc;
261 doc.Parse( error );
262 XMLTest( "Bad XML", doc.ErrorID(), ERROR_PARSING_ATTRIBUTE );
263 }
264
265 {
266 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
267
268 XMLDocument doc;
269 doc.Parse( str );
270
271 XMLElement* ele = doc.FirstChildElement();
272
273 int iVal, result;
274 double dVal;
275
276 result = ele->QueryDoubleAttribute( "attr0", &dVal );
277 XMLTest( "Query attribute: int as double", result, XML_NO_ERROR );
278 XMLTest( "Query attribute: int as double", (int)dVal, 1 );
279 result = ele->QueryDoubleAttribute( "attr1", &dVal );
280 XMLTest( "Query attribute: double as double", (int)dVal, 2 );
281 result = ele->QueryIntAttribute( "attr1", &iVal );
282 XMLTest( "Query attribute: double as int", result, XML_NO_ERROR );
283 XMLTest( "Query attribute: double as int", iVal, 2 );
284 result = ele->QueryIntAttribute( "attr2", &iVal );
285 XMLTest( "Query attribute: not a number", result, WRONG_ATTRIBUTE_TYPE );
286 result = ele->QueryIntAttribute( "bar", &iVal );
287 XMLTest( "Query attribute: does not exist", result, NO_ATTRIBUTE );
288 }
289
290 {
291 const char* str = "<doc/>";
292
293 XMLDocument doc;
294 doc.Parse( str );
295
296 XMLElement* ele = doc.FirstChildElement();
297
298 int iVal;
299 double dVal;
300
301 ele->SetAttribute( "str", "strValue" );
302 ele->SetAttribute( "int", 1 );
303 ele->SetAttribute( "double", -1.0 );
304
305 const char* cStr = ele->Attribute( "str" );
306 ele->QueryIntAttribute( "int", &iVal );
307 ele->QueryDoubleAttribute( "double", &dVal );
308
309 XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
310 XMLTest( "Attribute round trip. int.", 1, iVal );
311 XMLTest( "Attribute round trip. double.", -1, (int)dVal );
312 }
313
314#endif
315 {
316 XMLDocument doc;
317 doc.LoadFile( "utf8test.xml" );
318
319 // Get the attribute "value" from the "Russian" element and check it.
320 XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
321 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
322 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
323
324 XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
325
326 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
327 0xd1U, 0x81U, 0xd1U, 0x81U,
328 0xd0U, 0xbaU, 0xd0U, 0xb8U,
329 0xd0U, 0xb9U, 0 };
330 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
331
332 XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
333 XMLTest( "UTF-8: Browsing russian element name.",
334 russianText,
335 text->Value() );
336
337 // Now try for a round trip.
338 doc.SaveFile( "utf8testout.xml" );
339
340 // Check the round trip.
341 char savedBuf[256];
342 char verifyBuf[256];
343 int okay = 0;
344
345 FILE* saved = fopen( "utf8testout.xml", "r" );
346 FILE* verify = fopen( "utf8testverify.xml", "r" );
347
348 if ( saved && verify )
349 {
350 okay = 1;
351 while ( fgets( verifyBuf, 256, verify ) )
352 {
353 fgets( savedBuf, 256, saved );
354 NullLineEndings( verifyBuf );
355 NullLineEndings( savedBuf );
356
357 if ( strcmp( verifyBuf, savedBuf ) )
358 {
359 printf( "verify:%s<\n", verifyBuf );
360 printf( "saved :%s<\n", savedBuf );
361 okay = 0;
362 break;
363 }
364 }
365 }
366 if ( saved )
367 fclose( saved );
368 if ( verify )
369 fclose( verify );
370 XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
371 }
372
373
374#if defined( WIN32 )
Lee Thomason1ff38e02012-02-14 18:18:16 -0800375 _CrtMemCheckpoint( &endMemState );
376 //_CrtMemDumpStatistics( &endMemState );
377
378 _CrtMemState diffMemState;
379 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
380 _CrtMemDumpStatistics( &diffMemState );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800381 //printf( "new total=%d\n", gNewTotal );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800382 #endif
383
384 printf ("\nPass %d, Fail %d\n", gPass, gFail);
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800385 return 0;
386}