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


win_tinyxml
Author(s): Daniel Stonier
autogenerated on Mon Oct 6 2014 12:28:38