Changeset 738 for code/branches/FICN/src/tinyxml/tinyxml.cc
- Timestamp:
- Dec 31, 2007, 12:06:33 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/FICN/src/tinyxml/tinyxml.cc
r471 r738 1 1 /* 2 2 www.sourceforge.net/projects/tinyxml 3 Original code (2.0 and earlier )copyright (c) 2000-200 2Lee Thomason (www.grinninglizard.com)3 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) 4 4 5 5 This software is provided 'as-is', without any express or implied … … 24 24 25 25 #include <ctype.h> 26 #include "tinyxml.h"27 26 28 27 #ifdef TIXML_USE_STL 29 28 #include <sstream> 29 #include <iostream> 30 30 #endif 31 31 32 #include "tinyxml.h" 33 32 34 33 35 bool TiXmlBase::condenseWhiteSpace = true; 34 36 35 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream ) 36 { 37 TIXML_STRING buffer; 38 PutString( str, &buffer ); 39 (*stream) << buffer; 40 } 41 42 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) 37 // Microsoft compiler security 38 FILE* TiXmlFOpen( const char* filename, const char* mode ) 39 { 40 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) 41 FILE* fp = 0; 42 errno_t err = fopen_s( &fp, filename, mode ); 43 if ( !err && fp ) 44 return fp; 45 return 0; 46 #else 47 return fopen( filename, mode ); 48 #endif 49 } 50 51 void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) 43 52 { 44 53 int i=0; … … 48 57 unsigned char c = (unsigned char) str[i]; 49 58 50 if ( c == '&' 59 if ( c == '&' 51 60 && i < ( (int)str.length() - 2 ) 52 61 && str[i+1] == '#' … … 101 110 // Below 32 is symbolic. 102 111 char buf[ 32 ]; 103 104 #if defined(TIXML_SNPRINTF) 112 113 #if defined(TIXML_SNPRINTF) 105 114 TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); 106 115 #else 107 116 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); 108 #endif 117 #endif 109 118 110 119 //*ME: warning C4267: convert 'size_t' to 'int' … … 122 131 } 123 132 } 124 125 126 // <-- Strange class for a bug fix. Search for STL_STRING_BUG127 TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )128 {129 buffer = new char[ str.length()+1 ];130 if ( buffer )131 {132 strcpy( buffer, str.c_str() );133 }134 }135 136 137 TiXmlBase::StringToBuffer::~StringToBuffer()138 {139 delete [] buffer;140 }141 // End strange bug fix. -->142 133 143 134 … … 163 154 node = node->next; 164 155 delete temp; 165 } 156 } 166 157 } 167 158 … … 170 161 { 171 162 target->SetValue (value.c_str() ); 172 target->userData = userData; 163 target->userData = userData; 173 164 } 174 165 … … 184 175 node = node->next; 185 176 delete temp; 186 } 177 } 187 178 188 179 firstChild = 0; … … 193 184 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) 194 185 { 186 assert( node->parent == 0 || node->parent == this ); 187 assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); 188 189 if ( node->Type() == TiXmlNode::DOCUMENT ) 190 { 191 delete node; 192 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); 193 return 0; 194 } 195 195 196 node->parent = this; 196 197 … … 210 211 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) 211 212 { 213 if ( addThis.Type() == TiXmlNode::DOCUMENT ) 214 { 215 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); 216 return 0; 217 } 212 218 TiXmlNode* node = addThis.Clone(); 213 219 if ( !node ) … … 219 225 220 226 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) 221 { 222 if ( !beforeThis || beforeThis->parent != this ) 223 return 0; 227 { 228 if ( !beforeThis || beforeThis->parent != this ) { 229 return 0; 230 } 231 if ( addThis.Type() == TiXmlNode::DOCUMENT ) 232 { 233 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); 234 return 0; 235 } 224 236 225 237 TiXmlNode* node = addThis.Clone(); … … 246 258 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) 247 259 { 248 if ( !afterThis || afterThis->parent != this ) 249 return 0; 260 if ( !afterThis || afterThis->parent != this ) { 261 return 0; 262 } 263 if ( addThis.Type() == TiXmlNode::DOCUMENT ) 264 { 265 if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); 266 return 0; 267 } 250 268 251 269 TiXmlNode* node = addThis.Clone(); … … 301 319 { 302 320 if ( removeThis->parent != this ) 303 { 321 { 304 322 assert( 0 ); 305 323 return false; … … 332 350 333 351 334 TiXmlNode* TiXmlNode::FirstChild( const char * _value ) 335 { 336 TiXmlNode* node;337 for ( node = firstChild; node; node = node->next)352 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const 353 { 354 const TiXmlNode* node; 355 for ( node = lastChild; node; node = node->prev ) 338 356 { 339 357 if ( strcmp( node->Value(), _value ) == 0 ) … … 344 362 345 363 346 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const 364 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const 365 { 366 if ( !previous ) 367 { 368 return FirstChild(); 369 } 370 else 371 { 372 assert( previous->parent == this ); 373 return previous->NextSibling(); 374 } 375 } 376 377 378 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const 379 { 380 if ( !previous ) 381 { 382 return FirstChild( val ); 383 } 384 else 385 { 386 assert( previous->parent == this ); 387 return previous->NextSibling( val ); 388 } 389 } 390 391 392 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 347 393 { 348 394 const TiXmlNode* node; 349 for ( node = lastChild; node; node = node->prev)395 for ( node = next; node; node = node->next ) 350 396 { 351 397 if ( strcmp( node->Value(), _value ) == 0 ) … … 355 401 } 356 402 357 TiXmlNode* TiXmlNode::LastChild( const char * _value ) 358 { 359 TiXmlNode* node; 360 for ( node = lastChild; node; node = node->prev ) 403 404 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const 405 { 406 const TiXmlNode* node; 407 for ( node = prev; node; node = node->prev ) 361 408 { 362 409 if ( strcmp( node->Value(), _value ) == 0 ) … … 366 413 } 367 414 368 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const369 {370 if ( !previous )371 {372 return FirstChild();373 }374 else375 {376 assert( previous->parent == this );377 return previous->NextSibling();378 }379 }380 381 TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )382 {383 if ( !previous )384 {385 return FirstChild();386 }387 else388 {389 assert( previous->parent == this );390 return previous->NextSibling();391 }392 }393 394 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const395 {396 if ( !previous )397 {398 return FirstChild( val );399 }400 else401 {402 assert( previous->parent == this );403 return previous->NextSibling( val );404 }405 }406 407 TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )408 {409 if ( !previous )410 {411 return FirstChild( val );412 }413 else414 {415 assert( previous->parent == this );416 return previous->NextSibling( val );417 }418 }419 420 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const421 {422 const TiXmlNode* node;423 for ( node = next; node; node = node->next )424 {425 if ( strcmp( node->Value(), _value ) == 0 )426 return node;427 }428 return 0;429 }430 431 TiXmlNode* TiXmlNode::NextSibling( const char * _value )432 {433 TiXmlNode* node;434 for ( node = next; node; node = node->next )435 {436 if ( strcmp( node->Value(), _value ) == 0 )437 return node;438 }439 return 0;440 }441 442 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const443 {444 const TiXmlNode* node;445 for ( node = prev; node; node = node->prev )446 {447 if ( strcmp( node->Value(), _value ) == 0 )448 return node;449 }450 return 0;451 }452 453 TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )454 {455 TiXmlNode* node;456 for ( node = prev; node; node = node->prev )457 {458 if ( strcmp( node->Value(), _value ) == 0 )459 return node;460 }461 return 0;462 }463 415 464 416 void TiXmlElement::RemoveAttribute( const char * name ) 465 417 { 418 #ifdef TIXML_USE_STL 419 TIXML_STRING str( name ); 420 TiXmlAttribute* node = attributeSet.Find( str ); 421 #else 466 422 TiXmlAttribute* node = attributeSet.Find( name ); 423 #endif 467 424 if ( node ) 468 425 { … … 486 443 } 487 444 488 TiXmlElement* TiXmlNode::FirstChildElement()489 {490 TiXmlNode* node;491 492 for ( node = FirstChild();493 node;494 node = node->NextSibling() )495 {496 if ( node->ToElement() )497 return node->ToElement();498 }499 return 0;500 }501 445 502 446 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const … … 514 458 } 515 459 516 TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) 517 { 518 TiXmlNode* node; 519 520 for ( node = FirstChild( _value ); 460 461 const TiXmlElement* TiXmlNode::NextSiblingElement() const 462 { 463 const TiXmlNode* node; 464 465 for ( node = NextSibling(); 466 node; 467 node = node->NextSibling() ) 468 { 469 if ( node->ToElement() ) 470 return node->ToElement(); 471 } 472 return 0; 473 } 474 475 476 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const 477 { 478 const TiXmlNode* node; 479 480 for ( node = NextSibling( _value ); 521 481 node; 522 482 node = node->NextSibling( _value ) ) … … 528 488 } 529 489 530 const TiXmlElement* TiXmlNode::NextSiblingElement() const531 {532 const TiXmlNode* node;533 534 for ( node = NextSibling();535 node;536 node = node->NextSibling() )537 {538 if ( node->ToElement() )539 return node->ToElement();540 }541 return 0;542 }543 544 TiXmlElement* TiXmlNode::NextSiblingElement()545 {546 TiXmlNode* node;547 548 for ( node = NextSibling();549 node;550 node = node->NextSibling() )551 {552 if ( node->ToElement() )553 return node->ToElement();554 }555 return 0;556 }557 558 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const559 {560 const TiXmlNode* node;561 562 for ( node = NextSibling( _value );563 node;564 node = node->NextSibling( _value ) )565 {566 if ( node->ToElement() )567 return node->ToElement();568 }569 return 0;570 }571 572 TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )573 {574 TiXmlNode* node;575 576 for ( node = NextSibling( _value );577 node;578 node = node->NextSibling( _value ) )579 {580 if ( node->ToElement() )581 return node->ToElement();582 }583 return 0;584 }585 586 490 587 491 const TiXmlDocument* TiXmlNode::GetDocument() const … … 597 501 } 598 502 599 TiXmlDocument* TiXmlNode::GetDocument()600 {601 TiXmlNode* node;602 603 for( node = this; node; node = node->parent )604 {605 if ( node->ToDocument() )606 return node->ToDocument();607 }608 return 0;609 }610 503 611 504 TiXmlElement::TiXmlElement (const char * _value) … … 618 511 619 512 #ifdef TIXML_USE_STL 620 TiXmlElement::TiXmlElement( const std::string& _value ) 513 TiXmlElement::TiXmlElement( const std::string& _value ) 621 514 : TiXmlNode( TiXmlNode::ELEMENT ) 622 515 { … … 631 524 { 632 525 firstChild = lastChild = 0; 633 copy.CopyTo( this ); 526 copy.CopyTo( this ); 634 527 } 635 528 … … 660 553 661 554 662 const char * TiXmlElement::Attribute( const char* name ) const555 const char* TiXmlElement::Attribute( const char* name ) const 663 556 { 664 557 const TiXmlAttribute* node = attributeSet.Find( name ); 665 666 558 if ( node ) 667 559 return node->Value(); 668 669 560 return 0; 670 561 } 671 562 672 563 673 const char * TiXmlElement::Attribute( const char * name, int* i ) const 674 { 675 const char * s = Attribute( name ); 564 #ifdef TIXML_USE_STL 565 const std::string* TiXmlElement::Attribute( const std::string& name ) const 566 { 567 const TiXmlAttribute* node = attributeSet.Find( name ); 568 if ( node ) 569 return &node->ValueStr(); 570 return 0; 571 } 572 #endif 573 574 575 const char* TiXmlElement::Attribute( const char* name, int* i ) const 576 { 577 const char* s = Attribute( name ); 676 578 if ( i ) 677 579 { 678 if ( s ) 580 if ( s ) { 679 581 *i = atoi( s ); 680 else 582 } 583 else { 681 584 *i = 0; 585 } 682 586 } 683 587 return s; … … 685 589 686 590 687 const char * TiXmlElement::Attribute( const char * name, double* d ) const 688 { 689 const char * s = Attribute( name ); 591 #ifdef TIXML_USE_STL 592 const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const 593 { 594 const std::string* s = Attribute( name ); 595 if ( i ) 596 { 597 if ( s ) { 598 *i = atoi( s->c_str() ); 599 } 600 else { 601 *i = 0; 602 } 603 } 604 return s; 605 } 606 #endif 607 608 609 const char* TiXmlElement::Attribute( const char* name, double* d ) const 610 { 611 const char* s = Attribute( name ); 690 612 if ( d ) 691 613 { 692 if ( s ) 614 if ( s ) { 693 615 *d = atof( s ); 694 else 616 } 617 else { 695 618 *d = 0; 619 } 696 620 } 697 621 return s; 698 622 } 623 624 625 #ifdef TIXML_USE_STL 626 const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const 627 { 628 const std::string* s = Attribute( name ); 629 if ( d ) 630 { 631 if ( s ) { 632 *d = atof( s->c_str() ); 633 } 634 else { 635 *d = 0; 636 } 637 } 638 return s; 639 } 640 #endif 699 641 700 642 … … 704 646 if ( !node ) 705 647 return TIXML_NO_ATTRIBUTE; 706 707 648 return node->QueryIntValue( ival ); 708 649 } 709 650 710 651 711 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const 652 #ifdef TIXML_USE_STL 653 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const 712 654 { 713 655 const TiXmlAttribute* node = attributeSet.Find( name ); 714 656 if ( !node ) 715 657 return TIXML_NO_ATTRIBUTE; 716 658 return node->QueryIntValue( ival ); 659 } 660 #endif 661 662 663 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const 664 { 665 const TiXmlAttribute* node = attributeSet.Find( name ); 666 if ( !node ) 667 return TIXML_NO_ATTRIBUTE; 717 668 return node->QueryDoubleValue( dval ); 718 669 } 719 670 720 671 672 #ifdef TIXML_USE_STL 673 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const 674 { 675 const TiXmlAttribute* node = attributeSet.Find( name ); 676 if ( !node ) 677 return TIXML_NO_ATTRIBUTE; 678 return node->QueryDoubleValue( dval ); 679 } 680 #endif 681 682 721 683 void TiXmlElement::SetAttribute( const char * name, int val ) 722 { 684 { 723 685 char buf[64]; 724 #if defined(TIXML_SNPRINTF) 686 #if defined(TIXML_SNPRINTF) 725 687 TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); 726 688 #else … … 731 693 732 694 695 #ifdef TIXML_USE_STL 696 void TiXmlElement::SetAttribute( const std::string& name, int val ) 697 { 698 std::ostringstream oss; 699 oss << val; 700 SetAttribute( name, oss.str() ); 701 } 702 #endif 703 704 733 705 void TiXmlElement::SetDoubleAttribute( const char * name, double val ) 734 { 706 { 735 707 char buf[256]; 736 #if defined(TIXML_SNPRINTF) 708 #if defined(TIXML_SNPRINTF) 737 709 TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); 738 710 #else … … 743 715 744 716 745 void TiXmlElement::SetAttribute( const char * name, const char * _value ) 717 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) 718 { 719 #ifdef TIXML_USE_STL 720 TIXML_STRING _name( cname ); 721 TIXML_STRING _value( cvalue ); 722 #else 723 const char* _name = cname; 724 const char* _value = cvalue; 725 #endif 726 727 TiXmlAttribute* node = attributeSet.Find( _name ); 728 if ( node ) 729 { 730 node->SetValue( _value ); 731 return; 732 } 733 734 TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); 735 if ( attrib ) 736 { 737 attributeSet.Add( attrib ); 738 } 739 else 740 { 741 TiXmlDocument* document = GetDocument(); 742 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); 743 } 744 } 745 746 747 #ifdef TIXML_USE_STL 748 void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) 746 749 { 747 750 TiXmlAttribute* node = attributeSet.Find( name ); … … 763 766 } 764 767 } 768 #endif 769 765 770 766 771 void TiXmlElement::Print( FILE* cfile, int depth ) const 767 772 { 768 773 int i; 769 for ( i=0; i<depth; i++ )770 {774 assert( cfile ); 775 for ( i=0; i<depth; i++ ) { 771 776 fprintf( cfile, " " ); 772 777 } … … 809 814 } 810 815 fprintf( cfile, "\n" ); 811 for( i=0; i<depth; ++i ) 812 fprintf( cfile, " " ); 816 for( i=0; i<depth; ++i ) { 817 fprintf( cfile, " " ); 818 } 813 819 fprintf( cfile, "</%s>", value.c_str() ); 814 }815 }816 817 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const818 {819 (*stream) << "<" << value;820 821 const TiXmlAttribute* attrib;822 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )823 {824 (*stream) << " ";825 attrib->StreamOut( stream );826 }827 828 // If this node has children, give it a closing tag. Else829 // make it an empty tag.830 TiXmlNode* node;831 if ( firstChild )832 {833 (*stream) << ">";834 835 for ( node = firstChild; node; node=node->NextSibling() )836 {837 node->StreamOut( stream );838 }839 (*stream) << "</" << value << ">";840 }841 else842 {843 (*stream) << " />";844 820 } 845 821 } … … 851 827 TiXmlNode::CopyTo( target ); 852 828 853 // Element class: 829 // Element class: 854 830 // Clone the attributes, then clone the children. 855 831 const TiXmlAttribute* attribute = 0; … … 868 844 } 869 845 846 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const 847 { 848 if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 849 { 850 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) 851 { 852 if ( !node->Accept( visitor ) ) 853 break; 854 } 855 } 856 return visitor->VisitExit( *this ); 857 } 858 870 859 871 860 TiXmlNode* TiXmlElement::Clone() const … … 936 925 { 937 926 // See STL_STRING_BUG below. 938 StringToBuffer buf( value ); 939 940 if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) 941 return true; 942 943 return false; 927 //StringToBuffer buf( value ); 928 929 return LoadFile( Value(), encoding ); 944 930 } 945 931 … … 948 934 { 949 935 // See STL_STRING_BUG below. 950 StringToBuffer buf( value ); 951 952 if ( buf.buffer && SaveFile( buf.buffer ) ) 953 return true; 954 955 return false; 956 } 957 958 bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) 959 { 960 // Delete the existing data: 961 Clear(); 962 location.Clear(); 963 936 // StringToBuffer buf( value ); 937 // 938 // if ( buf.buffer && SaveFile( buf.buffer ) ) 939 // return true; 940 // 941 // return false; 942 return SaveFile( Value() ); 943 } 944 945 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) 946 { 964 947 // There was a really terrifying little bug here. The code: 965 948 // value = filename … … 968 951 // address as it's c_str() method, and so bad things happen. Looks 969 952 // like a bug in the Microsoft STL implementation. 970 // See STL_STRING_BUG above.971 // Fixed with the StringToBuffer class.953 // Add an extra string to avoid the crash. 954 TIXML_STRING filename( _filename ); 972 955 value = filename; 973 956 974 957 // reading in binary mode so that tinyxml can normalize the EOL 975 FILE* file = fopen( value.c_str (), "rb" );958 FILE* file = TiXmlFOpen( value.c_str (), "rb" ); 976 959 977 960 if ( file ) 978 961 { 979 // Get the file size, so we can pre-allocate the string. HUGE speed impact. 980 long length = 0; 981 fseek( file, 0, SEEK_END ); 982 length = ftell( file ); 983 fseek( file, 0, SEEK_SET ); 984 985 // Strange case, but good to handle up front. 986 if ( length == 0 ) 987 { 988 fclose( file ); 989 return false; 990 } 991 992 // If we have a file, assume it is all one big XML file, and read it in. 993 // The document parser may decide the document ends sooner than the entire file, however. 994 TIXML_STRING data; 995 data.reserve( length ); 996 997 // Subtle bug here. TinyXml did use fgets. But from the XML spec: 998 // 2.11 End-of-Line Handling 999 // <snip> 1000 // <quote> 1001 // ...the XML processor MUST behave as if it normalized all line breaks in external 1002 // parsed entities (including the document entity) on input, before parsing, by translating 1003 // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 1004 // a single #xA character. 1005 // </quote> 1006 // 1007 // It is not clear fgets does that, and certainly isn't clear it works cross platform. 1008 // Generally, you expect fgets to translate from the convention of the OS to the c/unix 1009 // convention, and not work generally. 1010 1011 /* 1012 while( fgets( buf, sizeof(buf), file ) ) 1013 { 1014 data += buf; 1015 } 1016 */ 1017 1018 char* buf = new char[ length+1 ]; 1019 buf[0] = 0; 1020 1021 if ( fread( buf, length, 1, file ) != 1 ) { 1022 //if ( fread( buf, 1, length, file ) != (size_t)length ) { 1023 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 1024 fclose( file ); 1025 return false; 1026 } 962 bool result = LoadFile( file, encoding ); 1027 963 fclose( file ); 1028 1029 const char* lastPos = buf; 1030 const char* p = buf; 1031 1032 buf[length] = 0; 1033 while( *p ) { 1034 assert( p < (buf+length) ); 1035 if ( *p == 0xa ) { 1036 // Newline character. No special rules for this. Append all the characters 1037 // since the last string, and include the newline. 1038 data.append( lastPos, p-lastPos+1 ); // append, include the newline 1039 ++p; // move past the newline 1040 lastPos = p; // and point to the new buffer (may be 0) 964 return result; 965 } 966 else 967 { 968 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 969 return false; 970 } 971 } 972 973 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) 974 { 975 if ( !file ) 976 { 977 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 978 return false; 979 } 980 981 // Delete the existing data: 982 Clear(); 983 location.Clear(); 984 985 // Get the file size, so we can pre-allocate the string. HUGE speed impact. 986 long length = 0; 987 fseek( file, 0, SEEK_END ); 988 length = ftell( file ); 989 fseek( file, 0, SEEK_SET ); 990 991 // Strange case, but good to handle up front. 992 if ( length <= 0 ) 993 { 994 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); 995 return false; 996 } 997 998 // If we have a file, assume it is all one big XML file, and read it in. 999 // The document parser may decide the document ends sooner than the entire file, however. 1000 TIXML_STRING data; 1001 data.reserve( length ); 1002 1003 // Subtle bug here. TinyXml did use fgets. But from the XML spec: 1004 // 2.11 End-of-Line Handling 1005 // <snip> 1006 // <quote> 1007 // ...the XML processor MUST behave as if it normalized all line breaks in external 1008 // parsed entities (including the document entity) on input, before parsing, by translating 1009 // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 1010 // a single #xA character. 1011 // </quote> 1012 // 1013 // It is not clear fgets does that, and certainly isn't clear it works cross platform. 1014 // Generally, you expect fgets to translate from the convention of the OS to the c/unix 1015 // convention, and not work generally. 1016 1017 /* 1018 while( fgets( buf, sizeof(buf), file ) ) 1019 { 1020 data += buf; 1021 } 1022 */ 1023 1024 char* buf = new char[ length+1 ]; 1025 buf[0] = 0; 1026 1027 if ( fread( buf, length, 1, file ) != 1 ) { 1028 delete [] buf; 1029 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 1030 return false; 1031 } 1032 1033 const char* lastPos = buf; 1034 const char* p = buf; 1035 1036 buf[length] = 0; 1037 while( *p ) { 1038 assert( p < (buf+length) ); 1039 if ( *p == 0xa ) { 1040 // Newline character. No special rules for this. Append all the characters 1041 // since the last string, and include the newline. 1042 data.append( lastPos, (p-lastPos+1) ); // append, include the newline 1043 ++p; // move past the newline 1044 lastPos = p; // and point to the new buffer (may be 0) 1045 assert( p <= (buf+length) ); 1046 } 1047 else if ( *p == 0xd ) { 1048 // Carriage return. Append what we have so far, then 1049 // handle moving forward in the buffer. 1050 if ( (p-lastPos) > 0 ) { 1051 data.append( lastPos, p-lastPos ); // do not add the CR 1052 } 1053 data += (char)0xa; // a proper newline 1054 1055 if ( *(p+1) == 0xa ) { 1056 // Carriage return - new line sequence 1057 p += 2; 1058 lastPos = p; 1041 1059 assert( p <= (buf+length) ); 1042 1060 } 1043 else if ( *p == 0xd ) { 1044 // Carriage return. Append what we have so far, then 1045 // handle moving forward in the buffer. 1046 if ( (p-lastPos) > 0 ) { 1047 data.append( lastPos, p-lastPos ); // do not add the CR 1048 } 1049 data += (char)0xa; // a proper newline 1050 1051 if ( *(p+1) == 0xa ) { 1052 // Carriage return - new line sequence 1053 p += 2; 1054 lastPos = p; 1055 assert( p <= (buf+length) ); 1056 } 1057 else { 1058 // it was followed by something else...that is presumably characters again. 1059 ++p; 1060 lastPos = p; 1061 assert( p <= (buf+length) ); 1062 } 1061 else { 1062 // it was followed by something else...that is presumably characters again. 1063 ++p; 1064 lastPos = p; 1065 assert( p <= (buf+length) ); 1063 1066 } 1064 else { 1065 ++p; 1066 } 1067 } 1068 // Handle any left over characters. 1069 if ( p-lastPos ) { 1070 data.append( lastPos, p-lastPos ); 1071 } 1072 delete [] buf; 1073 buf = 0; 1074 1075 Parse( data.c_str(), 0, encoding ); 1076 1077 if ( Error() ) 1078 return false; 1079 else 1080 return true; 1081 } 1082 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 1067 } 1068 else { 1069 ++p; 1070 } 1071 } 1072 // Handle any left over characters. 1073 if ( p-lastPos ) { 1074 data.append( lastPos, p-lastPos ); 1075 } 1076 delete [] buf; 1077 buf = 0; 1078 1079 Parse( data.c_str(), 0, encoding ); 1080 1081 if ( Error() ) 1082 return false; 1083 else 1084 return true; 1085 } 1086 1087 1088 bool TiXmlDocument::SaveFile( const char * filename ) const 1089 { 1090 // The old c stuff lives on... 1091 FILE* fp = TiXmlFOpen( filename, "w" ); 1092 if ( fp ) 1093 { 1094 bool result = SaveFile( fp ); 1095 fclose( fp ); 1096 return result; 1097 } 1083 1098 return false; 1084 1099 } 1085 1100 1086 bool TiXmlDocument::SaveFile( const char * filename ) const 1087 { 1088 // The old c stuff lives on... 1089 FILE* fp = fopen( filename, "w" ); 1090 if ( fp ) 1091 { 1092 if ( useMicrosoftBOM ) 1093 { 1094 const unsigned char TIXML_UTF_LEAD_0 = 0xefU; 1095 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; 1096 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; 1097 1098 fputc( TIXML_UTF_LEAD_0, fp ); 1099 fputc( TIXML_UTF_LEAD_1, fp ); 1100 fputc( TIXML_UTF_LEAD_2, fp ); 1101 } 1102 Print( fp, 0 ); 1103 fclose( fp ); 1104 return true; 1105 } 1106 return false; 1101 1102 bool TiXmlDocument::SaveFile( FILE* fp ) const 1103 { 1104 if ( useMicrosoftBOM ) 1105 { 1106 const unsigned char TIXML_UTF_LEAD_0 = 0xefU; 1107 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; 1108 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; 1109 1110 fputc( TIXML_UTF_LEAD_0, fp ); 1111 fputc( TIXML_UTF_LEAD_1, fp ); 1112 fputc( TIXML_UTF_LEAD_2, fp ); 1113 } 1114 Print( fp, 0 ); 1115 return (ferror(fp) == 0); 1107 1116 } 1108 1117 … … 1113 1122 1114 1123 target->error = error; 1115 target->errorDesc = errorDesc.c_str (); 1124 target->errorId = errorId; 1125 target->errorDesc = errorDesc; 1126 target->tabsize = tabsize; 1127 target->errorLocation = errorLocation; 1128 target->useMicrosoftBOM = useMicrosoftBOM; 1116 1129 1117 1130 TiXmlNode* node = 0; … … 1119 1132 { 1120 1133 target->LinkEndChild( node->Clone() ); 1121 } 1134 } 1122 1135 } 1123 1136 … … 1136 1149 void TiXmlDocument::Print( FILE* cfile, int depth ) const 1137 1150 { 1138 const TiXmlNode* node;1139 for ( node=FirstChild(); node; node=node->NextSibling() )1151 assert( cfile ); 1152 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) 1140 1153 { 1141 1154 node->Print( cfile, depth ); … … 1144 1157 } 1145 1158 1146 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const 1147 { 1148 const TiXmlNode* node; 1149 for ( node=FirstChild(); node; node=node->NextSibling() ) 1150 { 1151 node->StreamOut( out ); 1152 1153 // Special rule for streams: stop after the root element. 1154 // The stream in code will only read one element, so don't 1155 // write more than one. 1156 if ( node->ToElement() ) 1157 break; 1158 } 1159 1160 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const 1161 { 1162 if ( visitor->VisitEnter( *this ) ) 1163 { 1164 for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) 1165 { 1166 if ( !node->Accept( visitor ) ) 1167 break; 1168 } 1169 } 1170 return visitor->VisitExit( *this ); 1159 1171 } 1160 1172 … … 1169 1181 } 1170 1182 1183 /* 1171 1184 TiXmlAttribute* TiXmlAttribute::Next() 1172 1185 { … … 1177 1190 return next; 1178 1191 } 1192 */ 1179 1193 1180 1194 const TiXmlAttribute* TiXmlAttribute::Previous() const … … 1187 1201 } 1188 1202 1203 /* 1189 1204 TiXmlAttribute* TiXmlAttribute::Previous() 1190 1205 { … … 1195 1210 return prev; 1196 1211 } 1197 1198 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const 1212 */ 1213 1214 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const 1199 1215 { 1200 1216 TIXML_STRING n, v; 1201 1217 1202 PutString( name, &n ); 1203 PutString( value, &v ); 1204 1205 if (value.find ('\"') == TIXML_STRING::npos) 1218 EncodeString( name, &n ); 1219 EncodeString( value, &v ); 1220 1221 if (value.find ('\"') == TIXML_STRING::npos) { 1222 if ( cfile ) { 1206 1223 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); 1207 else 1224 } 1225 if ( str ) { 1226 (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; 1227 } 1228 } 1229 else { 1230 if ( cfile ) { 1208 1231 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); 1209 } 1210 1211 1212 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const 1213 { 1214 if (value.find( '\"' ) != TIXML_STRING::npos) 1215 { 1216 PutString( name, stream ); 1217 (*stream) << "=" << "'"; 1218 PutString( value, stream ); 1219 (*stream) << "'"; 1220 } 1221 else 1222 { 1223 PutString( name, stream ); 1224 (*stream) << "=" << "\""; 1225 PutString( value, stream ); 1226 (*stream) << "\""; 1227 } 1228 } 1232 } 1233 if ( str ) { 1234 (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; 1235 } 1236 } 1237 } 1238 1229 1239 1230 1240 int TiXmlAttribute::QueryIntValue( int* ival ) const 1231 1241 { 1232 if ( sscanf( value.c_str(), "%d", ival ) == 1 )1242 if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) 1233 1243 return TIXML_SUCCESS; 1234 1244 return TIXML_WRONG_TYPE; … … 1237 1247 int TiXmlAttribute::QueryDoubleValue( double* dval ) const 1238 1248 { 1239 if ( sscanf( value.c_str(), "%lf", dval ) == 1 )1249 if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) 1240 1250 return TIXML_SUCCESS; 1241 1251 return TIXML_WRONG_TYPE; … … 1245 1255 { 1246 1256 char buf [64]; 1247 #if defined(TIXML_SNPRINTF) 1257 #if defined(TIXML_SNPRINTF) 1248 1258 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); 1249 1259 #else … … 1256 1266 { 1257 1267 char buf [256]; 1258 #if defined(TIXML_SNPRINTF) 1268 #if defined(TIXML_SNPRINTF) 1259 1269 TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); 1260 1270 #else … … 1290 1300 void TiXmlComment::Print( FILE* cfile, int depth ) const 1291 1301 { 1302 assert( cfile ); 1292 1303 for ( int i=0; i<depth; i++ ) 1293 1304 { 1294 fp uts( " ", cfile);1305 fprintf( cfile, " " ); 1295 1306 } 1296 1307 fprintf( cfile, "<!--%s-->", value.c_str() ); 1297 1308 } 1298 1309 1299 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const1300 {1301 (*stream) << "<!--";1302 //PutString( value, stream );1303 (*stream) << value;1304 (*stream) << "-->";1305 }1306 1307 1310 1308 1311 void TiXmlComment::CopyTo( TiXmlComment* target ) const 1309 1312 { 1310 1313 TiXmlNode::CopyTo( target ); 1314 } 1315 1316 1317 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const 1318 { 1319 return visitor->Visit( *this ); 1311 1320 } 1312 1321 … … 1326 1335 void TiXmlText::Print( FILE* cfile, int depth ) const 1327 1336 { 1337 assert( cfile ); 1328 1338 if ( cdata ) 1329 1339 { … … 1333 1343 fprintf( cfile, " " ); 1334 1344 } 1335 fprintf( cfile, "<![CDATA[" ); 1336 fprintf( cfile, "%s", value.c_str() ); // unformatted output 1337 fprintf( cfile, "]]>\n" ); 1345 fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output 1338 1346 } 1339 1347 else 1340 1348 { 1341 1349 TIXML_STRING buffer; 1342 PutString( value, &buffer );1350 EncodeString( value, &buffer ); 1343 1351 fprintf( cfile, "%s", buffer.c_str() ); 1344 }1345 }1346 1347 1348 void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const1349 {1350 if ( cdata )1351 {1352 (*stream) << "<![CDATA[" << value << "]]>";1353 }1354 else1355 {1356 PutString( value, stream );1357 1352 } 1358 1353 } … … 1366 1361 1367 1362 1363 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const 1364 { 1365 return visitor->Visit( *this ); 1366 } 1367 1368 1368 1369 TiXmlNode* TiXmlText::Clone() const 1369 { 1370 { 1370 1371 TiXmlText* clone = 0; 1371 1372 clone = new TiXmlText( "" ); … … 1406 1407 : TiXmlNode( TiXmlNode::DECLARATION ) 1407 1408 { 1408 copy.CopyTo( this ); 1409 copy.CopyTo( this ); 1409 1410 } 1410 1411 … … 1417 1418 1418 1419 1419 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const 1420 { 1421 fprintf (cfile, "<?xml "); 1422 1423 if ( !version.empty() ) 1424 fprintf (cfile, "version=\"%s\" ", version.c_str ()); 1425 if ( !encoding.empty() ) 1426 fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); 1427 if ( !standalone.empty() ) 1428 fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); 1429 fprintf (cfile, "?>"); 1430 } 1431 1432 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const 1433 { 1434 (*stream) << "<?xml "; 1435 1436 if ( !version.empty() ) 1437 { 1438 (*stream) << "version=\""; 1439 PutString( version, stream ); 1440 (*stream) << "\" "; 1441 } 1442 if ( !encoding.empty() ) 1443 { 1444 (*stream) << "encoding=\""; 1445 PutString( encoding, stream ); 1446 (*stream ) << "\" "; 1447 } 1448 if ( !standalone.empty() ) 1449 { 1450 (*stream) << "standalone=\""; 1451 PutString( standalone, stream ); 1452 (*stream) << "\" "; 1453 } 1454 (*stream) << "?>"; 1420 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const 1421 { 1422 if ( cfile ) fprintf( cfile, "<?xml " ); 1423 if ( str ) (*str) += "<?xml "; 1424 1425 if ( !version.empty() ) { 1426 if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ()); 1427 if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; } 1428 } 1429 if ( !encoding.empty() ) { 1430 if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); 1431 if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; } 1432 } 1433 if ( !standalone.empty() ) { 1434 if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); 1435 if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; } 1436 } 1437 if ( cfile ) fprintf( cfile, "?>" ); 1438 if ( str ) (*str) += "?>"; 1455 1439 } 1456 1440 … … 1466 1450 1467 1451 1452 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const 1453 { 1454 return visitor->Visit( *this ); 1455 } 1456 1457 1468 1458 TiXmlNode* TiXmlDeclaration::Clone() const 1469 { 1459 { 1470 1460 TiXmlDeclaration* clone = new TiXmlDeclaration(); 1471 1461 … … 1486 1476 1487 1477 1488 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const1489 {1490 (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown.1491 }1492 1493 1494 1478 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const 1495 1479 { 1496 1480 TiXmlNode::CopyTo( target ); 1481 } 1482 1483 1484 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const 1485 { 1486 return visitor->Visit( *this ); 1497 1487 } 1498 1488 … … 1526 1516 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) 1527 1517 { 1518 #ifdef TIXML_USE_STL 1519 assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. 1520 #else 1528 1521 assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. 1522 #endif 1529 1523 1530 1524 addMe->next = &sentinel; … … 1553 1547 } 1554 1548 1555 const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const 1556 { 1557 const TiXmlAttribute* node; 1558 1559 for( node = sentinel.next; node != &sentinel; node = node->next )1549 1550 #ifdef TIXML_USE_STL 1551 const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const 1552 { 1553 for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) 1560 1554 { 1561 1555 if ( node->name == name ) … … 1565 1559 } 1566 1560 1567 TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) 1568 { 1569 TiXmlAttribute* node; 1570 1571 for( node = sentinel.next; node != &sentinel; node = node->next ) 1561 /* 1562 TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) 1563 { 1564 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) 1572 1565 { 1573 1566 if ( node->name == name ) … … 1576 1569 return 0; 1577 1570 } 1578 1579 #ifdef TIXML_USE_STL 1580 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) 1571 */ 1572 #endif 1573 1574 1575 const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const 1576 { 1577 for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) 1578 { 1579 if ( strcmp( node->name.c_str(), name ) == 0 ) 1580 return node; 1581 } 1582 return 0; 1583 } 1584 1585 /* 1586 TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) 1587 { 1588 for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) 1589 { 1590 if ( strcmp( node->name.c_str(), name ) == 0 ) 1591 return node; 1592 } 1593 return 0; 1594 } 1595 */ 1596 1597 #ifdef TIXML_USE_STL 1598 std::istream& operator>> (std::istream & in, TiXmlNode & base) 1581 1599 { 1582 1600 TIXML_STRING tag; … … 1590 1608 1591 1609 1592 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) 1593 { 1594 base.StreamOut (& out); 1610 #ifdef TIXML_USE_STL 1611 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) 1612 { 1613 TiXmlPrinter printer; 1614 printer.SetStreamPrinting(); 1615 base.Accept( &printer ); 1616 out << printer.Str(); 1617 1595 1618 return out; 1596 1619 } 1597 1620 1598 1621 1599 #ifdef TIXML_USE_STL 1600 std::string & operator<< (std::string& out, const TiXmlNode& base ) 1601 { 1602 std::ostringstream os_stream( std::ostringstream::out);1603 base.StreamOut( &os_stream);1604 1605 out.append( os_stream.str() ); 1606 1622 std::string& operator<< (std::string& out, const TiXmlNode& base ) 1623 { 1624 TiXmlPrinter printer; 1625 printer.SetStreamPrinting(); 1626 base.Accept( &printer ); 1627 out.append( printer.Str() ); 1628 1629 return out; 1607 1630 } 1608 1631 #endif … … 1731 1754 return TiXmlHandle( 0 ); 1732 1755 } 1756 1757 1758 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) 1759 { 1760 return true; 1761 } 1762 1763 bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) 1764 { 1765 return true; 1766 } 1767 1768 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) 1769 { 1770 DoIndent(); 1771 buffer += "<"; 1772 buffer += element.Value(); 1773 1774 for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) 1775 { 1776 buffer += " "; 1777 attrib->Print( 0, 0, &buffer ); 1778 } 1779 1780 if ( !element.FirstChild() ) 1781 { 1782 buffer += " />"; 1783 DoLineBreak(); 1784 } 1785 else 1786 { 1787 buffer += ">"; 1788 if ( element.FirstChild()->ToText() 1789 && element.LastChild() == element.FirstChild() 1790 && element.FirstChild()->ToText()->CDATA() == false ) 1791 { 1792 simpleTextPrint = true; 1793 // no DoLineBreak()! 1794 } 1795 else 1796 { 1797 DoLineBreak(); 1798 } 1799 } 1800 ++depth; 1801 return true; 1802 } 1803 1804 1805 bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) 1806 { 1807 --depth; 1808 if ( !element.FirstChild() ) 1809 { 1810 // nothing. 1811 } 1812 else 1813 { 1814 if ( simpleTextPrint ) 1815 { 1816 simpleTextPrint = false; 1817 } 1818 else 1819 { 1820 DoIndent(); 1821 } 1822 buffer += "</"; 1823 buffer += element.Value(); 1824 buffer += ">"; 1825 DoLineBreak(); 1826 } 1827 return true; 1828 } 1829 1830 1831 bool TiXmlPrinter::Visit( const TiXmlText& text ) 1832 { 1833 if ( text.CDATA() ) 1834 { 1835 DoIndent(); 1836 buffer += "<![CDATA["; 1837 buffer += text.Value(); 1838 buffer += "]]>"; 1839 DoLineBreak(); 1840 } 1841 else if ( simpleTextPrint ) 1842 { 1843 TIXML_STRING str; 1844 TiXmlBase::EncodeString( text.ValueTStr(), &str ); 1845 buffer += str; 1846 } 1847 else 1848 { 1849 DoIndent(); 1850 TIXML_STRING str; 1851 TiXmlBase::EncodeString( text.ValueTStr(), &str ); 1852 buffer += str; 1853 DoLineBreak(); 1854 } 1855 return true; 1856 } 1857 1858 1859 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) 1860 { 1861 DoIndent(); 1862 declaration.Print( 0, 0, &buffer ); 1863 DoLineBreak(); 1864 return true; 1865 } 1866 1867 1868 bool TiXmlPrinter::Visit( const TiXmlComment& comment ) 1869 { 1870 DoIndent(); 1871 buffer += "<!--"; 1872 buffer += comment.Value(); 1873 buffer += "-->"; 1874 DoLineBreak(); 1875 return true; 1876 } 1877 1878 1879 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) 1880 { 1881 DoIndent(); 1882 buffer += "<"; 1883 buffer += unknown.Value(); 1884 buffer += ">"; 1885 DoLineBreak(); 1886 return true; 1887 } 1888
Note: See TracChangeset
for help on using the changeset viewer.