00001
00002
00003
00004
00005
00006 #ifdef TIXML_USE_STL
00007 #include <iostream>
00008 #include <sstream>
00009 using namespace std;
00010 #else
00011 #include <stdio.h>
00012 #endif
00013
00014 #if defined( WIN32 ) && defined( TUNE )
00015 #include <crtdbg.h>
00016 _CrtMemState startMemState;
00017 _CrtMemState endMemState;
00018 #endif
00019
00020 #include "OBTtinyxml.h"
00021
00022 namespace OBT
00023 {
00024 static int gPass = 0;
00025 static int gFail = 0;
00026
00027
00028 bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false)
00029 {
00030 bool pass = !strcmp( expected, found );
00031 if ( pass )
00032 printf ("[pass]");
00033 else
00034 printf ("[fail]");
00035
00036 if ( noEcho )
00037 printf (" %s\n", testString);
00038 else
00039 printf (" %s [%s][%s]\n", testString, expected, found);
00040
00041 if ( pass )
00042 ++gPass;
00043 else
00044 ++gFail;
00045 return pass;
00046 }
00047
00048
00049 bool XmlTest( const char* testString, int expected, int found, bool noEcho = false )
00050 {
00051 bool pass = ( expected == found );
00052 if ( pass )
00053 printf ("[pass]");
00054 else
00055 printf ("[fail]");
00056
00057 if ( noEcho )
00058 printf (" %s\n", testString);
00059 else
00060 printf (" %s [%d][%d]\n", testString, expected, found);
00061
00062 if ( pass )
00063 ++gPass;
00064 else
00065 ++gFail;
00066 return pass;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 int main()
00078 {
00079
00080
00081
00082
00083 const char* demoStart =
00084 "<?xml version=\"1.0\" standalone='no' >\n"
00085 "<!-- Our to do list data -->"
00086 "<ToDo>\n"
00087 "<!-- Do I need a secure PDA? -->\n"
00088 "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
00089 "<Item priority=\"2\" distance='none'> Do bills </Item>"
00090 "<Item priority=\"2\" distance='far & back'> Look for Evil Dinosaurs! </Item>"
00091 "</ToDo>";
00092
00093 {
00094
00095 #ifdef TIXML_USE_STL
00096
00097
00098 const char* demoEnd =
00099 "<?xml version=\"1.0\" standalone=\"no\" ?>"
00100 "<!-- Our to do list data -->"
00101 "<ToDo>"
00102 "<!-- Do I need a secure PDA? -->"
00103 "<Item priority=\"2\" distance=\"close\">Go to the"
00104 "<bold>Toy store!"
00105 "</bold>"
00106 "</Item>"
00107 "<Item priority=\"1\" distance=\"far\">Talk to:"
00108 "<Meeting where=\"School\">"
00109 "<Attendee name=\"Marple\" position=\"teacher\" />"
00110 "<Attendee name=\"Voel\" position=\"counselor\" />"
00111 "</Meeting>"
00112 "<Meeting where=\"Lunch\" />"
00113 "</Item>"
00114 "<Item priority=\"2\" distance=\"here\">Do bills"
00115 "</Item>"
00116 "</ToDo>";
00117 #endif
00118
00119
00120 #if defined( WIN32 ) && defined( TUNE )
00121 _CrtMemCheckpoint( &startMemState );
00122 #endif
00123
00124 {
00125
00126
00127 TiXmlDocument doc( "demotest.xml" );
00128 doc.Parse( demoStart );
00129
00130 if ( doc.Error() )
00131 {
00132 printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
00133 exit( 1 );
00134 }
00135 doc.SaveFile();
00136 }
00137
00138 TiXmlDocument doc( "demotest.xml" );
00139 bool loadOkay = doc.LoadFile();
00140
00141 if ( !loadOkay )
00142 {
00143 printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
00144 exit( 1 );
00145 }
00146
00147 printf( "** Demo doc read from disk: ** \n\n" );
00148 printf( "** Printing via doc.Print **\n" );
00149 doc.Print( stdout );
00150
00151 {
00152 printf( "** Printing via TiXmlPrinter **\n" );
00153 TiXmlPrinter printer;
00154 doc.Accept( &printer );
00155 fprintf( stdout, "%s", printer.CStr() );
00156 }
00157 #ifdef TIXML_USE_STL
00158 {
00159 printf( "** Printing via operator<< **\n" );
00160 std::cout << doc;
00161 }
00162 #endif
00163 TiXmlNode* node = 0;
00164 TiXmlElement* todoElement = 0;
00165 TiXmlElement* itemElement = 0;
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 node = doc.FirstChild( "ToDo" );
00176 assert( node );
00177 todoElement = node->ToElement();
00178 assert( todoElement );
00179
00180
00181
00182 node = todoElement->FirstChildElement();
00183 assert( node );
00184 itemElement = node->ToElement();
00185 assert( itemElement );
00186 itemElement->SetAttribute( "priority", 2 );
00187
00188
00189
00190 itemElement = itemElement->NextSiblingElement();
00191 assert( itemElement );
00192 itemElement->SetAttribute( "distance", "here" );
00193
00194
00195
00196
00197 itemElement = itemElement->NextSiblingElement();
00198 todoElement->RemoveChild( itemElement );
00199
00200 itemElement = 0;
00201
00202
00203
00204
00205
00206
00207
00208 TiXmlElement item( "Item" );
00209 item.SetAttribute( "priority", "1" );
00210 item.SetAttribute( "distance", "far" );
00211
00212 TiXmlText text( "Talk to:" );
00213
00214 TiXmlElement meeting1( "Meeting" );
00215 meeting1.SetAttribute( "where", "School" );
00216
00217 TiXmlElement meeting2( "Meeting" );
00218 meeting2.SetAttribute( "where", "Lunch" );
00219
00220 TiXmlElement attendee1( "Attendee" );
00221 attendee1.SetAttribute( "name", "Marple" );
00222 attendee1.SetAttribute( "position", "teacher" );
00223
00224 TiXmlElement attendee2( "Attendee" );
00225 attendee2.SetAttribute( "name", "Voel" );
00226 attendee2.SetAttribute( "position", "counselor" );
00227
00228
00229 meeting1.InsertEndChild( attendee1 );
00230 meeting1.InsertEndChild( attendee2 );
00231
00232 item.InsertEndChild( text );
00233 item.InsertEndChild( meeting1 );
00234 item.InsertEndChild( meeting2 );
00235
00236
00237 node = todoElement->FirstChild( "Item" );
00238 assert( node );
00239 itemElement = node->ToElement();
00240 assert( itemElement );
00241
00242 todoElement->InsertAfterChild( itemElement, item );
00243
00244 printf( "\n** Demo doc processed: ** \n\n" );
00245 doc.Print( stdout );
00246
00247
00248 #ifdef TIXML_USE_STL
00249 printf( "** Demo doc processed to stream: ** \n\n" );
00250 cout << doc << endl << endl;
00251 #endif
00252
00253
00254
00255
00256
00257 int count = 0;
00258 TiXmlElement* element;
00259
00261
00262 #ifdef TIXML_USE_STL
00263 cout << "** Basic structure. **\n";
00264 ostringstream outputStream( ostringstream::out );
00265 outputStream << doc;
00266 XmlTest( "Output stream correct.", string( demoEnd ).c_str(),
00267 outputStream.str().c_str(), true );
00268 #endif
00269
00270 node = doc.RootElement();
00271 assert( node );
00272 XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
00273 XmlTest ( "Root element value is 'ToDo'.", "ToDo", node->Value());
00274
00275 node = node->FirstChild();
00276 XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
00277 node = node->NextSibling();
00278 XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
00279 XmlTest ( "Value is 'Item'.", "Item", node->Value() );
00280
00281 node = node->FirstChild();
00282 XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
00283 XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );
00284
00285
00287 printf ("\n** Iterators. **\n");
00288
00289
00290 count = 0;
00291 for( node = doc.FirstChild();
00292 node;
00293 node = node->NextSibling() )
00294 {
00295 count++;
00296 }
00297 XmlTest( "Top level nodes, using First / Next.", 3, count );
00298
00299 count = 0;
00300 for( node = doc.LastChild();
00301 node;
00302 node = node->PreviousSibling() )
00303 {
00304 count++;
00305 }
00306 XmlTest( "Top level nodes, using Last / Previous.", 3, count );
00307
00308
00309
00310 count = 0;
00311 for( node = doc.IterateChildren( 0 );
00312 node;
00313 node = doc.IterateChildren( node ) )
00314 {
00315 count++;
00316 }
00317 XmlTest( "Top level nodes, using IterateChildren.", 3, count );
00318
00319
00320 count = 0;
00321 for( element = todoElement->FirstChildElement();
00322 element;
00323 element = element->NextSiblingElement() )
00324 {
00325 count++;
00326 }
00327 XmlTest( "Children of the 'ToDo' element, using First / Next.",
00328 3, count );
00329
00330
00331 count = 0;
00332 for( node = todoElement->FirstChild( "Item" );
00333 node;
00334 node = node->NextSibling( "Item" ) )
00335 {
00336 count++;
00337 }
00338 XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );
00339
00340 count = 0;
00341 for( node = todoElement->LastChild( "Item" );
00342 node;
00343 node = node->PreviousSibling( "Item" ) )
00344 {
00345 count++;
00346 }
00347 XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );
00348
00349 #ifdef TIXML_USE_STL
00350 {
00351 cout << "\n** Parsing. **\n";
00352 istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '>' />" );
00353 TiXmlElement element0( "default" );
00354 parse0 >> element0;
00355
00356 XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
00357 XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" ));
00358 XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
00359 XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
00360 }
00361 #endif
00362
00363 {
00364 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
00365 "<passages count=\"006\" formatversion=\"20020620\">\n"
00366 " <wrong error>\n"
00367 "</passages>";
00368
00369 TiXmlDocument docTest;
00370 docTest.Parse( error );
00371 XmlTest( "Error row", docTest.ErrorRow(), 3 );
00372 XmlTest( "Error column", docTest.ErrorCol(), 17 );
00373
00374
00375 }
00376
00377 #ifdef TIXML_USE_STL
00378 {
00380 cout << "\n** Streaming. **\n";
00381
00382
00383
00384
00385 istringstream inputStringStream( outputStream.str() );
00386 TiXmlDocument document0;
00387
00388 inputStringStream >> document0;
00389
00390 ostringstream outputStream0( ostringstream::out );
00391 outputStream0 << document0;
00392
00393 XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(),
00394 outputStream0.str().c_str(), true );
00395
00396 std::string str;
00397 str << document0;
00398
00399 XmlTest( "String printing correct.", string( demoEnd ).c_str(),
00400 str.c_str(), true );
00401 }
00402 #endif
00403 }
00404
00405 {
00406 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
00407
00408 TiXmlDocument doc;
00409 doc.Parse( str );
00410
00411 TiXmlElement* ele = doc.FirstChildElement();
00412
00413 int iVal, result;
00414 double dVal;
00415
00416 result = ele->QueryDoubleAttribute( "attr0", &dVal );
00417 XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
00418 XmlTest( "Query attribute: int as double", (int)dVal, 1 );
00419 result = ele->QueryDoubleAttribute( "attr1", &dVal );
00420 XmlTest( "Query attribute: double as double", (int)dVal, 2 );
00421 result = ele->QueryIntAttribute( "attr1", &iVal );
00422 XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
00423 XmlTest( "Query attribute: double as int", iVal, 2 );
00424 result = ele->QueryIntAttribute( "attr2", &iVal );
00425 XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
00426 result = ele->QueryIntAttribute( "bar", &iVal );
00427 XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
00428 }
00429
00430 {
00431 const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
00432 "</room>";
00433
00434 TiXmlDocument doc;
00435 doc.SetTabSize( 8 );
00436 doc.Parse( str );
00437
00438 TiXmlHandle docHandle( &doc );
00439 TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
00440
00441 assert( docHandle.Node() );
00442 assert( roomHandle.Element() );
00443
00444 TiXmlElement* room = roomHandle.Element();
00445 assert( room );
00446 TiXmlAttribute* doors = room->FirstAttribute();
00447 assert( doors );
00448
00449 XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
00450 XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
00451 XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
00452 XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
00453 }
00454
00455 {
00456 const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
00457 " <!-- Silly example -->\n"
00458 " <door wall='north'>A great door!</door>\n"
00459 "\t<door wall='east'/>"
00460 "</room>";
00461
00462 TiXmlDocument doc;
00463 doc.Parse( str );
00464
00465 TiXmlHandle docHandle( &doc );
00466 TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
00467 TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
00468 TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
00469 TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
00470 TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );
00471
00472 assert( docHandle.Node() );
00473 assert( roomHandle.Element() );
00474 assert( commentHandle.Node() );
00475 assert( textHandle.Text() );
00476 assert( door0Handle.Element() );
00477 assert( door1Handle.Element() );
00478
00479 TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
00480 assert( declaration );
00481 TiXmlElement* room = roomHandle.Element();
00482 assert( room );
00483 TiXmlAttribute* doors = room->FirstAttribute();
00484 assert( doors );
00485 TiXmlText* text = textHandle.Text();
00486 TiXmlComment* comment = commentHandle.Node()->ToComment();
00487 assert( comment );
00488 TiXmlElement* door0 = door0Handle.Element();
00489 TiXmlElement* door1 = door1Handle.Element();
00490
00491 XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
00492 XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
00493 XmlTest( "Location tracking: room row", room->Row(), 1 );
00494 XmlTest( "Location tracking: room col", room->Column(), 45 );
00495 XmlTest( "Location tracking: doors row", doors->Row(), 1 );
00496 XmlTest( "Location tracking: doors col", doors->Column(), 51 );
00497 XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
00498 XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
00499 XmlTest( "Location tracking: text row", text->Row(), 3 );
00500 XmlTest( "Location tracking: text col", text->Column(), 24 );
00501 XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
00502 XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
00503 XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
00504 XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 printf ("\n** UTF-8 **\n");
00515 {
00516 TiXmlDocument doc( "utf8test.xml" );
00517 doc.LoadFile();
00518 if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) {
00519 printf( "WARNING: File 'utf8test.xml' not found.\n"
00520 "(Are you running the test from the wrong directory?)\n"
00521 "Could not test UTF-8 functionality.\n" );
00522 }
00523 else
00524 {
00525 TiXmlHandle docH( &doc );
00526
00527 TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
00528 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
00529 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
00530
00531 XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
00532 XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
00533 XmlTest( "UTF-8: Russian value column.", 5, element->Column() );
00534
00535 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
00536 0xd1U, 0x81U, 0xd1U, 0x81U,
00537 0xd0U, 0xbaU, 0xd0U, 0xb8U,
00538 0xd0U, 0xb9U, 0 };
00539 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
00540
00541 TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
00542 XmlTest( "UTF-8: Browsing russian element name.",
00543 russianText,
00544 text->Value(),
00545 true );
00546 XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
00547 XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );
00548
00549 TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
00550 XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
00551 XmlTest( "UTF-8: Document column.", 1, doc.Column() );
00552
00553
00554 doc.SaveFile( "utf8testout.xml" );
00555
00556
00557 char savedBuf[256];
00558 char verifyBuf[256];
00559 int okay = 1;
00560
00561 FILE* saved = fopen( "utf8testout.xml", "r" );
00562 FILE* verify = fopen( "utf8testverify.xml", "r" );
00563 if ( saved && verify )
00564 {
00565 while ( fgets( verifyBuf, 256, verify ) )
00566 {
00567 fgets( savedBuf, 256, saved );
00568 if ( strcmp( verifyBuf, savedBuf ) )
00569 {
00570 okay = 0;
00571 break;
00572 }
00573 }
00574 fclose( saved );
00575 fclose( verify );
00576 }
00577 XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
00578
00579
00580
00581
00582
00583 const char latin[] = "<element>r\x82sum\x82</element>";
00584
00585 TiXmlDocument latinDoc;
00586 latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );
00587
00588 text = latinDoc.FirstChildElement()->FirstChild()->ToText();
00589 XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() );
00590 }
00591 }
00592
00594
00596 printf ("\n** Copy and Assignment **\n");
00597 {
00598 TiXmlElement element( "foo" );
00599 element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );
00600
00601 TiXmlElement elementCopy( element );
00602 TiXmlElement elementAssign( "foo" );
00603 elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
00604 elementAssign = element;
00605
00606 XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
00607 XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
00608 XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
00609 XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
00610 XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) );
00611
00612 TiXmlComment comment;
00613 comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
00614 TiXmlComment commentCopy( comment );
00615 TiXmlComment commentAssign;
00616 commentAssign = commentCopy;
00617 XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
00618 XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );
00619
00620 TiXmlUnknown unknown;
00621 unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
00622 TiXmlUnknown unknownCopy( unknown );
00623 TiXmlUnknown unknownAssign;
00624 unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
00625 unknownAssign = unknownCopy;
00626 XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
00627 XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );
00628
00629 TiXmlText text( "TextNode" );
00630 TiXmlText textCopy( text );
00631 TiXmlText textAssign( "incorrect" );
00632 textAssign = text;
00633 XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
00634 XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );
00635
00636 TiXmlDeclaration dec;
00637 dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
00638 TiXmlDeclaration decCopy( dec );
00639 TiXmlDeclaration decAssign;
00640 decAssign = dec;
00641
00642 XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
00643 XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );
00644
00645 TiXmlDocument doc;
00646 elementCopy.InsertEndChild( textCopy );
00647 doc.InsertEndChild( decAssign );
00648 doc.InsertEndChild( elementCopy );
00649 doc.InsertEndChild( unknownAssign );
00650
00651 TiXmlDocument docCopy( doc );
00652 TiXmlDocument docAssign;
00653 docAssign = docCopy;
00654
00655 #ifdef TIXML_USE_STL
00656 std::string original, copy, assign;
00657 original << doc;
00658 copy << docCopy;
00659 assign << docAssign;
00660 XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
00661 XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );
00662
00663 #endif
00664 }
00665
00667 #ifdef TIXML_USE_STL
00668 printf ("\n** Parsing, no Condense Whitespace **\n");
00669 TiXmlBase::SetCondenseWhiteSpace( false );
00670 {
00671 istringstream parse1( "<start>This is \ntext</start>" );
00672 TiXmlElement text1( "text" );
00673 parse1 >> text1;
00674
00675 XmlTest ( "Condense white space OFF.", "This is \ntext",
00676 text1.FirstChild()->Value(),
00677 true );
00678 }
00679 TiXmlBase::SetCondenseWhiteSpace( true );
00680 #endif
00681
00683
00684 {
00685 const char* str = "<foo>This is text</foo>";
00686 TiXmlDocument doc;
00687 doc.Parse( str );
00688 const TiXmlElement* element = doc.RootElement();
00689
00690 XmlTest( "GetText() normal use.", "This is text", element->GetText() );
00691
00692 str = "<foo><b>This is text</b></foo>";
00693 doc.Clear();
00694 doc.Parse( str );
00695 element = doc.RootElement();
00696
00697 XmlTest( "GetText() contained element.", element->GetText() == 0, true );
00698
00699 str = "<foo>This is <b>text</b></foo>";
00700 doc.Clear();
00701 TiXmlBase::SetCondenseWhiteSpace( false );
00702 doc.Parse( str );
00703 TiXmlBase::SetCondenseWhiteSpace( true );
00704 element = doc.RootElement();
00705
00706 XmlTest( "GetText() partial.", "This is ", element->GetText() );
00707 }
00708
00709
00711
00712 {
00713 const char* str = "<xmlElement>"
00714 "<![CDATA["
00715 "I am > the rules!\n"
00716 "...since I make symbolic puns"
00717 "]]>"
00718 "</xmlElement>";
00719 TiXmlDocument doc;
00720 doc.Parse( str );
00721 doc.Print();
00722
00723 XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
00724 "I am > the rules!\n...since I make symbolic puns",
00725 true );
00726
00727 #ifdef TIXML_USE_STL
00728
00729
00730 doc.Clear();
00731
00732 istringstream parse0( str );
00733 parse0 >> doc;
00734
00735
00736 XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(),
00737 "I am > the rules!\n...since I make symbolic puns",
00738 true );
00739 #endif
00740
00741 TiXmlDocument doc1 = doc;
00742
00743
00744 XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(),
00745 "I am > the rules!\n...since I make symbolic puns",
00746 true );
00747 }
00748 {
00749
00750 char buf[256];
00751 buf[255] = 0;
00752 for( int i=0; i<255; ++i ) {
00753 buf[i] = (char)((i>=32) ? i : 32);
00754 }
00755 TIXML_STRING str( "<xmlElement><![CDATA[" );
00756 str += buf;
00757 str += "]]></xmlElement>";
00758
00759 TiXmlDocument doc;
00760 doc.Parse( str.c_str() );
00761
00762 TiXmlPrinter printer;
00763 printer.SetStreamPrinting();
00764 doc.Accept( &printer );
00765
00766 XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true );
00767
00768 #ifdef TIXML_USE_STL
00769 doc.Clear();
00770 istringstream iss( printer.Str() );
00771 iss >> doc;
00772 std::string out;
00773 out << doc;
00774 XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true );
00775 #endif
00776 }
00777 {
00778
00779
00780 const char* str = "<xmlElement>"
00781 "<![CDATA["
00782 "<b>I am > the rules!</b>\n"
00783 "...since I make symbolic puns"
00784 "]]>"
00785 "</xmlElement>";
00786 TiXmlDocument doc;
00787 doc.Parse( str );
00788 doc.Print();
00789
00790 XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
00791 "<b>I am > the rules!</b>\n...since I make symbolic puns",
00792 true );
00793
00794 #ifdef TIXML_USE_STL
00795
00796 doc.Clear();
00797
00798 istringstream parse0( str );
00799 parse0 >> doc;
00800
00801 XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
00802 "<b>I am > the rules!</b>\n...since I make symbolic puns",
00803 true );
00804 #endif
00805
00806 TiXmlDocument doc1 = doc;
00807
00808
00809 XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(),
00810 "<b>I am > the rules!</b>\n...since I make symbolic puns",
00811 true );
00812 }
00814
00815
00816
00817
00819 printf( "\n** Fuzzing... **\n" );
00820
00821 const int FUZZ_ITERATION = 300;
00822
00823
00824 int len = (int) strlen( demoStart );
00825 for( int i=0; i<FUZZ_ITERATION; ++i )
00826 {
00827 char* demoCopy = new char[ len+1 ];
00828 strcpy( demoCopy, demoStart );
00829
00830 demoCopy[ i%len ] = (char)((i+1)*3);
00831 demoCopy[ (i*7)%len ] = '>';
00832 demoCopy[ (i*11)%len ] = '<';
00833
00834 TiXmlDocument xml;
00835 xml.Parse( demoCopy );
00836
00837 delete [] demoCopy;
00838 }
00839 printf( "** Fuzzing Complete. **\n" );
00840
00842 printf ("\n** Bug regression tests **\n");
00843
00844
00845 {
00846 TiXmlElement parent( "Parent" );
00847 TiXmlElement childText0( "childText0" );
00848 TiXmlElement childText1( "childText1" );
00849 TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
00850 TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );
00851
00852 XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
00853 }
00854
00855 {
00856
00857 TiXmlElement parent( "Parent" );
00858 TiXmlElement childText0( "childText0" );
00859 TiXmlElement childText1( "childText1" );
00860 TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
00861 TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );
00862
00863 XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
00864 }
00865
00866
00867 {
00868
00869 TiXmlText text( "Missing" );
00870
00871 #ifdef TIXML_USE_STL
00872
00873 TiXmlDocument doc;
00874 string name = "missing";
00875 doc.LoadFile( name );
00876
00877 TiXmlText textSTL( name );
00878 #else
00879
00880 TiXmlString a;
00881 TiXmlString b( "Hello" );
00882 TiXmlString c( "ooga" );
00883
00884 c = " World!";
00885 a = b;
00886 a += c;
00887 a = a;
00888
00889 XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
00890 #endif
00891 }
00892
00893
00894 {
00895 TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
00896 bool loadOkay = doc.LoadFile();
00897 loadOkay = true;
00898
00899
00900 }
00901
00902 {
00903
00904
00905
00906 const char* passages =
00907 "<?xml version=\"1.0\" standalone=\"no\" ?>"
00908 "<passages count=\"006\" formatversion=\"20020620\">"
00909 "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'."
00910 " It also has <, >, and &, as well as a fake copyright ©.\"> </psg>"
00911 "</passages>";
00912
00913 TiXmlDocument doc( "passages.xml" );
00914 doc.Parse( passages );
00915 TiXmlElement* psg = doc.RootElement()->FirstChildElement();
00916 const char* context = psg->Attribute( "context" );
00917 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
00918
00919 XmlTest( "Entity transformation: read. ", expected, context, true );
00920
00921 FILE* textfile = fopen( "textfile.txt", "w" );
00922 if ( textfile )
00923 {
00924 psg->Print( textfile, 0 );
00925 fclose( textfile );
00926 }
00927 textfile = fopen( "textfile.txt", "r" );
00928 assert( textfile );
00929 if ( textfile )
00930 {
00931 char buf[ 1024 ];
00932 fgets( buf, 1024, textfile );
00933 XmlTest( "Entity transformation: write. ",
00934 "<psg context=\'Line 5 has "quotation marks" and 'apostrophe marks'."
00935 " It also has <, >, and &, as well as a fake copyright \xC2\xA9.' />",
00936 buf,
00937 true );
00938 }
00939 fclose( textfile );
00940 }
00941
00942 {
00943 FILE* textfile = fopen( "test5.xml", "w" );
00944 if ( textfile )
00945 {
00946 fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile);
00947 fclose(textfile);
00948
00949 TiXmlDocument doc;
00950 doc.LoadFile( "test5.xml" );
00951 XmlTest( "dot in element attributes and names", doc.Error(), 0);
00952 }
00953 }
00954
00955 {
00956 FILE* textfile = fopen( "test6.xml", "w" );
00957 if ( textfile )
00958 {
00959 fputs("<element><Name>1.1 Start easy ignore fin thickness
</Name></element>", textfile );
00960 fclose(textfile);
00961
00962 TiXmlDocument doc;
00963 bool result = doc.LoadFile( "test6.xml" );
00964 XmlTest( "Entity with one digit.", result, true );
00965
00966 TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
00967 XmlTest( "Entity with one digit.",
00968 text->Value(), "1.1 Start easy ignore fin thickness\n" );
00969 }
00970 }
00971
00972 {
00973
00974
00975 const char* doctype =
00976 "<?xml version=\"1.0\" ?>"
00977 "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
00978 "<!ELEMENT title (#PCDATA)>"
00979 "<!ELEMENT books (title,authors)>"
00980 "<element />";
00981
00982 TiXmlDocument doc;
00983 doc.Parse( doctype );
00984 doc.SaveFile( "test7.xml" );
00985 doc.Clear();
00986 doc.LoadFile( "test7.xml" );
00987
00988 TiXmlHandle docH( &doc );
00989 TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
00990 XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
00991 #ifdef TIXML_USE_STL
00992 TiXmlNode* node = docH.Child( 2 ).Node();
00993 std::string str;
00994 str << (*node);
00995 XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
00996 #endif
00997 }
00998
00999 {
01000
01001
01002 const char* doctype =
01003 "<!-- Somewhat<evil> -->";
01004 TiXmlDocument doc;
01005 doc.Parse( doctype );
01006
01007 TiXmlHandle docH( &doc );
01008 TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();
01009
01010 XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
01011 #ifdef TIXML_USE_STL
01012 std::string str;
01013 str << (*comment);
01014 XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
01015 #endif
01016 }
01017
01018 {
01019
01020 TiXmlDocument doc;
01021 TiXmlText* text;
01022 TiXmlHandle docH( &doc );
01023
01024 const char* doctype0 = "<element> This has leading and trailing space </element>";
01025 const char* doctype1 = "<element>This has internal space</element>";
01026 const char* doctype2 = "<element> This has leading, trailing, and internal space </element>";
01027
01028 TiXmlBase::SetCondenseWhiteSpace( false );
01029 doc.Clear();
01030 doc.Parse( doctype0 );
01031 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01032 XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );
01033
01034 doc.Clear();
01035 doc.Parse( doctype1 );
01036 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01037 XmlTest( "White space kept.", "This has internal space", text->Value() );
01038
01039 doc.Clear();
01040 doc.Parse( doctype2 );
01041 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01042 XmlTest( "White space kept.", " This has leading, trailing, and internal space ", text->Value() );
01043
01044 TiXmlBase::SetCondenseWhiteSpace( true );
01045 doc.Clear();
01046 doc.Parse( doctype0 );
01047 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01048 XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );
01049
01050 doc.Clear();
01051 doc.Parse( doctype1 );
01052 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01053 XmlTest( "White space condensed.", "This has internal space", text->Value() );
01054
01055 doc.Clear();
01056 doc.Parse( doctype2 );
01057 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
01058 XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
01059 }
01060
01061 {
01062
01063 const char* doctype = "<element attr='red' attr='blue' />";
01064
01065 TiXmlDocument doc;
01066 doc.Parse( doctype );
01067
01068 XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() );
01069 XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
01070 }
01071
01072 {
01073
01074 const char* doctype = "<element att\0r='red' attr='blue' />";
01075
01076 TiXmlDocument doc;
01077 doc.Parse( doctype );
01078 XmlTest( "Embedded null throws error.", true, doc.Error() );
01079
01080 #ifdef TIXML_USE_STL
01081 istringstream strm( doctype );
01082 doc.Clear();
01083 doc.ClearError();
01084 strm >> doc;
01085 XmlTest( "Embedded null throws error.", true, doc.Error() );
01086 #endif
01087 }
01088
01089 {
01090
01091 const char* str =
01092 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
01093 "<ä>"
01094 "CöntäntßäöüÄÖÜ"
01095 "</ä>";
01096
01097 TiXmlDocument doc;
01098 doc.Parse( str );
01099
01100 TiXmlHandle docHandle( &doc );
01101 TiXmlHandle aHandle = docHandle.FirstChildElement( "ä" );
01102 TiXmlHandle tHandle = aHandle.Child( 0 );
01103 assert( aHandle.Element() );
01104 assert( tHandle.Text() );
01105 XmlTest( "ISO-8859-1 Parsing.", "CöntäntßäöüÄÖÜ", tHandle.Text()->Value() );
01106 }
01107
01108 {
01109
01110 const char* str = " ";
01111 TiXmlDocument doc;
01112 doc.Parse( str );
01113 XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() );
01114 }
01115 #ifndef TIXML_USE_STL
01116 {
01117
01118 TiXmlString temp;
01119 XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true );
01120
01121 TiXmlString foo;
01122 TiXmlString bar( "" );
01123 XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true );
01124 }
01125
01126 #endif
01127 {
01128
01129 TiXmlBase::SetCondenseWhiteSpace(false);
01130 TiXmlDocument xml;
01131 xml.Parse("<text><break/>This hangs</text>");
01132 XmlTest( "Test safe error return.", xml.Error(), false );
01133 }
01134
01135 {
01136
01137 TiXmlDocument doc;
01138 doc.SetCondenseWhiteSpace(false);
01139 doc.Parse("<p><pb></pb>test</p>");
01140 }
01141 {
01142
01143 TiXmlDocument xml;
01144 xml.Parse( "<test></test>" );
01145 const char result[] = { 0x0e, 0 };
01146 XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result );
01147 xml.Print();
01148 }
01149 {
01150
01151 TiXmlDocument xml;
01152 xml.Parse( "<foo attribute=bar\" />" );
01153 XmlTest( "Throw error with bad end quotes.", xml.Error(), true );
01154 }
01155 #ifdef TIXML_USE_STL
01156 {
01157
01158 TiXmlDocument xml;
01159 xml.Parse( "<foo bar='3' barStr='a string'/>" );
01160
01161 TiXmlElement* ele = xml.FirstChildElement();
01162 double d;
01163 int i;
01164 float f;
01165 bool b;
01166
01167
01168 XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS );
01169 XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS );
01170 XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS );
01171 XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE );
01172 XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE );
01173
01174
01175 XmlTest( "QueryValueAttribute", (d==3.0), true );
01176 XmlTest( "QueryValueAttribute", (i==3), true );
01177 XmlTest( "QueryValueAttribute", (f==3.0f), true );
01178
01179 }
01180 #endif
01181
01182 #ifdef TIXML_USE_STL
01183 {
01184
01185 TiXmlDocument xml;
01186 xml.Parse( "<foo bar='3' />" );
01187 TiXmlElement* ele = xml.FirstChildElement();
01188 double d;
01189 int i;
01190
01191 std::string bar = "bar";
01192
01193 const std::string* atrrib = ele->Attribute( bar );
01194 ele->Attribute( bar, &d );
01195 ele->Attribute( bar, &i );
01196
01197 XmlTest( "Attribute", atrrib->empty(), false );
01198 XmlTest( "Attribute", (d==3.0), true );
01199 XmlTest( "Attribute", (i==3), true );
01200 }
01201 #endif
01202
01203 {
01204
01205 TiXmlDocument xml, xml2;
01206 xml.InsertEndChild( xml2 );
01207 XmlTest( "Document only at top level.", xml.Error(), true );
01208 XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY );
01209 }
01210
01211 {
01212
01213 TiXmlDocument xml;
01214 xml.Parse("<x>");
01215 XmlTest("Missing end tag at end of input", xml.Error(), true);
01216 xml.Parse("<x> ");
01217 XmlTest("Missing end tag with trailing whitespace", xml.Error(), true);
01218 }
01219
01220 {
01221
01222
01223 TiXmlDocument xml;
01224 xml.Parse( "<title><p>text</p\n><title>" );
01225
01226
01227 }
01228
01229 #ifdef TIXML_USE_STL
01230 {
01231
01232 TiXmlDocument xml;
01233 istringstream parse1( "<!-- declarations for <head> & <body> -->"
01234 "<!-- far & away -->" );
01235 parse1 >> xml;
01236
01237 TiXmlNode* e0 = xml.FirstChild();
01238 TiXmlNode* e1 = e0->NextSibling();
01239 TiXmlComment* c0 = e0->ToComment();
01240 TiXmlComment* c1 = e1->ToComment();
01241
01242 XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
01243 XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true );
01244 }
01245 #endif
01246
01247 {
01248
01249 TiXmlDocument xml;
01250 xml.Parse("<!-- declarations for <head> & <body> -->"
01251 "<!-- far & away -->" );
01252
01253 TiXmlNode* e0 = xml.FirstChild();
01254 TiXmlNode* e1 = e0->NextSibling();
01255 TiXmlComment* c0 = e0->ToComment();
01256 TiXmlComment* c1 = e1->ToComment();
01257
01258 XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
01259 XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true );
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 #if defined( WIN32 ) && defined( TUNE )
01284 _CrtMemCheckpoint( &endMemState );
01285
01286
01287 _CrtMemState diffMemState;
01288 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
01289 _CrtMemDumpStatistics( &diffMemState );
01290 #endif
01291
01292 printf ("\nPass %d, Fail %d\n", gPass, gFail);
01293 return gFail;
01294 }
01295
01296 }