Changeset 738 for code/branches/FICN/src/tinyxml
- Timestamp:
- Dec 31, 2007, 12:06:33 AM (17 years ago)
- Location:
- code/branches/FICN/src/tinyxml
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/FICN/src/tinyxml/tinystr.cc
r660 r738 24 24 25 25 /* 26 * THIS FILE WAS ALTERED BY Tyge L �vset, 7. April 2005.26 * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. 27 27 */ 28 28 … … 33 33 34 34 // Error value for find primitive 35 const TiXmlString::size_type TiXmlString::npos = static_cast< size_type >(-1); 35 const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); 36 36 37 37 38 // Null rep. 38 //FIXME: missing braces around initializer for ‘char [1]’ 39 TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' }; 39 TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; 40 40 41 41 -
code/branches/FICN/src/tinyxml/tinystr.h
r471 r738 43 43 #include <string.h> 44 44 45 /* The support for explicit isn't that universal, and it isn't really 46 required - it is used to check that the TiXmlString class isn't incorrectly 47 used. Be nice to old compilers and macro it here: 48 */ 49 #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) 50 // Microsoft visual studio, version 6 and higher. 51 #define TIXML_EXPLICIT explicit 52 #elif defined(__GNUC__) && (__GNUC__ >= 3 ) 53 // GCC version 3 and higher.s 54 #define TIXML_EXPLICIT explicit 55 #else 56 #define TIXML_EXPLICIT 57 #endif 58 59 45 60 /* 46 61 TiXmlString is an emulation of a subset of the std::string template. … … 54 69 public : 55 70 // The size type used 56 typedef unsigned int size_type;71 typedef size_t size_type; 57 72 58 73 // Error value for find primitive … … 66 81 67 82 // TiXmlString copy constructor 68 TiXmlString ( const TiXmlString & copy)83 TiXmlString ( const TiXmlString & copy) : rep_(0) 69 84 { 70 85 init(copy.length()); … … 73 88 74 89 // TiXmlString constructor, based on a string 75 T iXmlString (const char * copy)90 TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) 76 91 { 77 92 init( static_cast<size_type>( strlen(copy) )); … … 80 95 81 96 // TiXmlString constructor, based on a string 82 T iXmlString (const char * str, size_type len)97 TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) 83 98 { 84 99 init(len); -
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 -
code/branches/FICN/src/tinyxml/tinyxml.h
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 … … 26 26 #ifndef TINYXML_INCLUDED 27 27 #define TINYXML_INCLUDED 28 29 #define TIXML_USE_STL30 28 31 29 #ifdef _MSC_VER … … 46 44 #endif 47 45 48 #if defined( DEBUG ) && defined( _MSC_VER )49 #include <windows.h>50 #define TIXML_LOG OutputDebugString51 #else52 #define TIXML_LOG printf53 #endif54 55 46 #ifdef TIXML_USE_STL 56 47 #include <string> 57 48 #include <iostream> 58 #define TIXML_STRING std::string 59 #define TIXML_ISTREAM std::istream 60 #define TIXML_OSTREAM std::ostream 49 #include <sstream> 50 #define TIXML_STRING std::string 61 51 #else 62 52 #include "tinystr.h" 63 #define TIXML_STRING TiXmlString 64 #define TIXML_OSTREAM TiXmlOutStream 53 #define TIXML_STRING TiXmlString 65 54 #endif 66 55 … … 69 58 // but it gets closer. There are too many compilers for me to fully 70 59 // test. If you get compilation troubles, undefine TIXML_SAFE 71 72 #define TIXML_SAFE // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress. 60 #define TIXML_SAFE 61 73 62 #ifdef TIXML_SAFE 74 #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) 63 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) 64 // Microsoft visual studio, version 2005 and higher. 65 #define TIXML_SNPRINTF _snprintf_s 66 #define TIXML_SNSCANF _snscanf_s 67 #define TIXML_SSCANF sscanf_s 68 #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) 75 69 // Microsoft visual studio, version 6 and higher. 76 70 //#pragma message( "Using _sn* functions." ) 77 71 #define TIXML_SNPRINTF _snprintf 78 72 #define TIXML_SNSCANF _snscanf 73 #define TIXML_SSCANF sscanf 79 74 #elif defined(__GNUC__) && (__GNUC__ >= 3 ) 80 75 // GCC version 3 and higher.s … … 82 77 #define TIXML_SNPRINTF snprintf 83 78 #define TIXML_SNSCANF snscanf 84 #endif 85 #endif 79 #define TIXML_SSCANF sscanf 80 #else 81 #define TIXML_SSCANF sscanf 82 #endif 83 #endif 86 84 87 85 class TiXmlDocument; … … 95 93 96 94 const int TIXML_MAJOR_VERSION = 2; 97 const int TIXML_MINOR_VERSION = 4;98 const int TIXML_PATCH_VERSION = 2;99 100 /* Internal structure for tracking location of items 95 const int TIXML_MINOR_VERSION = 5; 96 const int TIXML_PATCH_VERSION = 3; 97 98 /* Internal structure for tracking location of items 101 99 in the XML file. 102 100 */ … … 111 109 112 110 111 /** 112 If you call the Accept() method, it requires being passed a TiXmlVisitor 113 class to handle callbacks. For nodes that contain other nodes (Document, Element) 114 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves 115 are simple called with Visit(). 116 117 If you return 'true' from a Visit method, recursive parsing will continue. If you return 118 false, <b>no children of this node or its sibilings</b> will be Visited. 119 120 All flavors of Visit methods have a default implementation that returns 'true' (continue 121 visiting). You need to only override methods that are interesting to you. 122 123 Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. 124 125 You should never change the document from a callback. 126 127 @sa TiXmlNode::Accept() 128 */ 129 class TiXmlVisitor 130 { 131 public: 132 virtual ~TiXmlVisitor() {} 133 134 /// Visit a document. 135 virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } 136 /// Visit a document. 137 virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } 138 139 /// Visit an element. 140 virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } 141 /// Visit an element. 142 virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } 143 144 /// Visit a declaration 145 virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } 146 /// Visit a text node 147 virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } 148 /// Visit a comment node 149 virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } 150 /// Visit an unknow node 151 virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } 152 }; 153 113 154 // Only used by Attribute::Query functions 114 enum 115 { 155 enum 156 { 116 157 TIXML_SUCCESS, 117 158 TIXML_NO_ATTRIBUTE, … … 159 200 160 201 public: 161 TiXmlBase() : userData(0) {} 162 virtual ~TiXmlBase() {} 163 164 /** All TinyXml classes can print themselves to a filestream. 165 This is a formatted print, and will insert tabs and newlines. 166 202 TiXmlBase() : userData(0) {} 203 virtual ~TiXmlBase() {} 204 205 /** All TinyXml classes can print themselves to a filestream 206 or the string class (TiXmlString in non-STL mode, std::string 207 in STL mode.) Either or both cfile and str can be null. 208 209 This is a formatted print, and will insert 210 tabs and newlines. 211 167 212 (For an unformatted stream, use the << operator.) 168 213 */ … … 173 218 are provided to set whether or not TinyXml will condense all white space 174 219 into a single space or not. The default is to condense. Note changing this 175 value sis not thread safe.220 value is not thread safe. 176 221 */ 177 222 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } … … 201 246 int Column() const { return location.col + 1; } ///< See Row() 202 247 203 void SetUserData( void* user ) { userData = user; } 204 void* GetUserData() { return userData; } 248 void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. 249 void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. 250 const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. 205 251 206 252 // Table that returs, for a given lead byte, the total number of bytes … … 208 254 static const int utf8ByteTable[256]; 209 255 210 virtual const char* Parse( const char* p, 211 TiXmlParsingData* data, 256 virtual const char* Parse( const char* p, 257 TiXmlParsingData* data, 212 258 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; 259 260 /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 261 or they will be transformed into entities! 262 */ 263 static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); 213 264 214 265 enum … … 230 281 TIXML_ERROR_EMBEDDED_NULL, 231 282 TIXML_ERROR_PARSING_CDATA, 283 TIXML_ERROR_DOCUMENT_TOP_ONLY, 232 284 233 285 TIXML_ERROR_STRING_COUNT … … 236 288 protected: 237 289 238 // See STL_STRING_BUG 239 // Utility class to overcome a bug. 240 class StringToBuffer 241 { 242 public: 243 StringToBuffer( const TIXML_STRING& str ); 244 ~StringToBuffer(); 245 char* buffer; 246 }; 247 248 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); 249 inline static bool IsWhiteSpace( char c ) 250 { 251 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 252 } 253 254 virtual void StreamOut (TIXML_OSTREAM *) const = 0; 290 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); 291 inline static bool IsWhiteSpace( char c ) 292 { 293 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 294 } 295 inline static bool IsWhiteSpace( int c ) 296 { 297 if ( c < 256 ) 298 return IsWhiteSpace( (char) c ); 299 return false; // Again, only truly correct for English/Latin...but usually works. 300 } 255 301 256 302 #ifdef TIXML_USE_STL 257 static bool StreamWhiteSpace( TIXML_ISTREAM* in, TIXML_STRING * tag );258 static bool StreamTo( TIXML_ISTREAM* in, int character, TIXML_STRING * tag );303 static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); 304 static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); 259 305 #endif 260 306 … … 285 331 if ( encoding == TIXML_ENCODING_UTF8 ) 286 332 { 287 *length = utf8ByteTable[ *(( unsigned char*)p) ];333 *length = utf8ByteTable[ *((const unsigned char*)p) ]; 288 334 assert( *length >= 0 && *length < 5 ); 289 335 } … … 316 362 } 317 363 318 // Puts a string to a stream, expanding entities as it goes.319 // Note this should not contian the '<', '>', etc, or they will be transformed into entities!320 static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );321 322 static void PutString( const TIXML_STRING& str, TIXML_STRING* out );323 324 364 // Return true if the next characters in the stream are any of the endTag sequences. 325 365 // Ignore case only works for english, and should only be relied on when comparing … … 336 376 /// Field containing a generic user pointer 337 377 void* userData; 338 378 339 379 // None of these methods are reliable for any language except English. 340 380 // Good for approximation, not great for accuracy. … … 388 428 389 429 public: 390 #ifdef TIXML_USE_STL 430 #ifdef TIXML_USE_STL 391 431 392 432 /** An input stream operator, for every class. Tolerant of newlines and … … 402 442 a node to a stream is very well defined. You'll get a nice stream 403 443 of output, without any extra whitespace or newlines. 404 444 405 445 But reading is not as well defined. (As it always is.) If you create 406 446 a TiXmlElement (for example) and read that from an input stream, … … 410 450 A TiXmlDocument will read nodes until it reads a root element, and 411 451 all the children of that root element. 412 */ 452 */ 413 453 friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); 414 454 … … 416 456 friend std::string& operator<< (std::string& out, const TiXmlNode& base ); 417 457 418 #else419 // Used internally, not part of the public API.420 friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);421 458 #endif 422 459 … … 459 496 #endif 460 497 498 const TIXML_STRING& ValueTStr() const { return value; } 499 461 500 /** Changes the value of the node. Defined as: 462 501 @verbatim … … 472 511 #ifdef TIXML_USE_STL 473 512 /// STL std::string form. 474 void SetValue( const std::string& _value ) 475 { 476 StringToBuffer buf( _value ); 477 SetValue( buf.buffer ? buf.buffer : "" ); 478 } 513 void SetValue( const std::string& _value ) { value = _value; } 479 514 #endif 480 515 … … 486 521 const TiXmlNode* Parent() const { return parent; } 487 522 488 const TiXmlNode* FirstChild() const { return firstChild; }///< The first child of this node. Will be null if there are no children.489 TiXmlNode* FirstChild() { return firstChild; }523 const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. 524 TiXmlNode* FirstChild() { return firstChild; } 490 525 const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. 491 TiXmlNode* FirstChild( const char * value ); ///< The first child of this node with the matching 'value'. Will be null if none found. 492 526 /// The first child of this node with the matching 'value'. Will be null if none found. 527 TiXmlNode* FirstChild( const char * _value ) { 528 // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) 529 // call the method, cast the return back to non-const. 530 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); 531 } 493 532 const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. 494 533 TiXmlNode* LastChild() { return lastChild; } 534 495 535 const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. 496 TiXmlNode* LastChild( const char * value ); 536 TiXmlNode* LastChild( const char * _value ) { 537 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); 538 } 497 539 498 540 #ifdef TIXML_USE_STL … … 520 562 */ 521 563 const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; 522 TiXmlNode* IterateChildren( TiXmlNode* previous ); 564 TiXmlNode* IterateChildren( const TiXmlNode* previous ) { 565 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); 566 } 523 567 524 568 /// This flavor of IterateChildren searches for children with a particular 'value' 525 569 const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; 526 TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ); 570 TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { 571 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); 572 } 527 573 528 574 #ifdef TIXML_USE_STL 529 575 const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. 530 TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.576 TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. 531 577 #endif 532 578 … … 572 618 /// Navigate to a sibling node. 573 619 const TiXmlNode* PreviousSibling( const char * ) const; 574 TiXmlNode* PreviousSibling( const char * ); 620 TiXmlNode* PreviousSibling( const char *_prev ) { 621 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); 622 } 575 623 576 624 #ifdef TIXML_USE_STL … … 587 635 /// Navigate to a sibling node with the given 'value'. 588 636 const TiXmlNode* NextSibling( const char * ) const; 589 TiXmlNode* NextSibling( const char * ); 637 TiXmlNode* NextSibling( const char* _next ) { 638 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); 639 } 590 640 591 641 /** Convenience function to get through elements. … … 594 644 */ 595 645 const TiXmlElement* NextSiblingElement() const; 596 TiXmlElement* NextSiblingElement(); 646 TiXmlElement* NextSiblingElement() { 647 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); 648 } 597 649 598 650 /** Convenience function to get through elements. … … 601 653 */ 602 654 const TiXmlElement* NextSiblingElement( const char * ) const; 603 TiXmlElement* NextSiblingElement( const char * ); 655 TiXmlElement* NextSiblingElement( const char *_next ) { 656 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); 657 } 604 658 605 659 #ifdef TIXML_USE_STL … … 610 664 /// Convenience function to get through elements. 611 665 const TiXmlElement* FirstChildElement() const; 612 TiXmlElement* FirstChildElement(); 666 TiXmlElement* FirstChildElement() { 667 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); 668 } 613 669 614 670 /// Convenience function to get through elements. 615 const TiXmlElement* FirstChildElement( const char * value ) const; 616 TiXmlElement* FirstChildElement( const char * value ); 671 const TiXmlElement* FirstChildElement( const char * _value ) const; 672 TiXmlElement* FirstChildElement( const char * _value ) { 673 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); 674 } 617 675 618 676 #ifdef TIXML_USE_STL … … 631 689 */ 632 690 const TiXmlDocument* GetDocument() const; 633 TiXmlDocument* GetDocument(); 691 TiXmlDocument* GetDocument() { 692 return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); 693 } 634 694 635 695 /// Returns true if this node has no children. 636 696 bool NoChildren() const { return !firstChild; } 637 697 638 const TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.639 const TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (const TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.640 const TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (const TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.641 const TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (const TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.642 const TiXmlText* ToText() const { return ( this && type == TEXT ) ? (const TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.643 const TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.644 645 TiXmlDocument* ToDocument() { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.646 TiXmlElement* ToElement() { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.647 TiXmlComment* ToComment() { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.648 TiXmlUnknown* ToUnknown() { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.649 TiXmlText* ToText() { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.650 TiXmlDeclaration* ToDeclaration() { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return nullnot of the requested type.698 virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 699 virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 700 virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 701 virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 702 virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 703 virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 704 705 virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 706 virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 707 virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 708 virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 709 virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 710 virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. 651 711 652 712 /** Create an exact duplicate of this node and return it. The memory must be deleted 653 by the caller. 713 by the caller. 654 714 */ 655 715 virtual TiXmlNode* Clone() const = 0; 716 717 /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 718 XML tree will be conditionally visited and the host will be called back 719 via the TiXmlVisitor interface. 720 721 This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse 722 the XML for the callbacks, so the performance of TinyXML is unchanged by using this 723 interface versus any other.) 724 725 The interface has been based on ideas from: 726 727 - http://www.saxproject.org/ 728 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern 729 730 Which are both good references for "visiting". 731 732 An example of using Accept(): 733 @verbatim 734 TiXmlPrinter printer; 735 tinyxmlDoc.Accept( &printer ); 736 const char* xmlcstr = printer.CStr(); 737 @endverbatim 738 */ 739 virtual bool Accept( TiXmlVisitor* visitor ) const = 0; 656 740 657 741 protected: … … 664 748 #ifdef TIXML_USE_STL 665 749 // The real work of the input operator. 666 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;750 virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; 667 751 #endif 668 752 … … 726 810 } 727 811 728 const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. 729 const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. 812 const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. 813 const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. 814 #ifdef TIXML_USE_STL 815 const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. 816 #endif 730 817 int IntValue() const; ///< Return the value of this attribute, converted to an integer. 731 818 double DoubleValue() const; ///< Return the value of this attribute, converted to a double. 732 819 820 // Get the tinyxml string representation 821 const TIXML_STRING& NameTStr() const { return name; } 822 733 823 /** QueryIntValue examines the value string. It is an alternative to the 734 824 IntValue() method with richer error checking. 735 If the value is an integer, it is stored in 'value' and 825 If the value is an integer, it is stored in 'value' and 736 826 the call returns TIXML_SUCCESS. If it is not 737 827 an integer, it returns TIXML_WRONG_TYPE. … … 752 842 #ifdef TIXML_USE_STL 753 843 /// STL std::string form. 754 void SetName( const std::string& _name ) 755 { 756 StringToBuffer buf( _name ); 757 SetName ( buf.buffer ? buf.buffer : "error" ); 758 } 759 /// STL std::string form. 760 void SetValue( const std::string& _value ) 761 { 762 StringToBuffer buf( _value ); 763 SetValue( buf.buffer ? buf.buffer : "error" ); 764 } 844 void SetName( const std::string& _name ) { name = _name; } 845 /// STL std::string form. 846 void SetValue( const std::string& _value ) { value = _value; } 765 847 #endif 766 848 767 849 /// Get the next sibling attribute in the DOM. Returns null at end. 768 850 const TiXmlAttribute* Next() const; 769 TiXmlAttribute* Next(); 851 TiXmlAttribute* Next() { 852 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 853 } 854 770 855 /// Get the previous sibling attribute in the DOM. Returns null at beginning. 771 856 const TiXmlAttribute* Previous() const; 772 TiXmlAttribute* Previous(); 857 TiXmlAttribute* Previous() { 858 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 859 } 773 860 774 861 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } … … 782 869 783 870 // Prints this Attribute to a FILE stream. 784 virtual void Print( FILE* cfile, int depth ) const; 785 786 virtual void StreamOut( TIXML_OSTREAM * out ) const; 871 virtual void Print( FILE* cfile, int depth ) const { 872 Print( cfile, depth, 0 ); 873 } 874 void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; 875 787 876 // [internal use] 788 877 // Set the document pointer so the attribute can report errors. … … 803 892 /* A class used to manage a group of attributes. 804 893 It is only used internally, both by the ELEMENT and the DECLARATION. 805 894 806 895 The set can be changed transparent to the Element and Declaration 807 896 classes that use it, but NOT transparent to the Attribute … … 827 916 TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } 828 917 829 const TiXmlAttribute* Find( const char * name ) const; 830 TiXmlAttribute* Find( const char * name ); 918 const TiXmlAttribute* Find( const char* _name ) const; 919 TiXmlAttribute* Find( const char* _name ) { 920 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); 921 } 922 #ifdef TIXML_USE_STL 923 const TiXmlAttribute* Find( const std::string& _name ) const; 924 TiXmlAttribute* Find( const std::string& _name ) { 925 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); 926 } 927 928 #endif 831 929 832 930 private: … … 884 982 /** QueryIntAttribute examines the attribute - it is an alternative to the 885 983 Attribute() method with richer error checking. 886 If the attribute is an integer, it is stored in 'value' and 984 If the attribute is an integer, it is stored in 'value' and 887 985 the call returns TIXML_SUCCESS. If it is not 888 986 an integer, it returns TIXML_WRONG_TYPE. If the attribute 889 987 does not exist, then TIXML_NO_ATTRIBUTE is returned. 890 */ 988 */ 891 989 int QueryIntAttribute( const char* name, int* _value ) const; 892 990 /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). … … 902 1000 } 903 1001 1002 #ifdef TIXML_USE_STL 1003 /** Template form of the attribute query which will try to read the 1004 attribute into the specified type. Very easy, very powerful, but 1005 be careful to make sure to call this with the correct type. 1006 1007 NOTE: This method doesn't work correctly for 'string' types. 1008 1009 @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE 1010 */ 1011 template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const 1012 { 1013 const TiXmlAttribute* node = attributeSet.Find( name ); 1014 if ( !node ) 1015 return TIXML_NO_ATTRIBUTE; 1016 1017 std::stringstream sstream( node->ValueStr() ); 1018 sstream >> *outValue; 1019 if ( !sstream.fail() ) 1020 return TIXML_SUCCESS; 1021 return TIXML_WRONG_TYPE; 1022 } 1023 /* 1024 This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" 1025 but template specialization is hard to get working cross-compiler. Leaving the bug for now. 1026 1027 // The above will fail for std::string because the space character is used as a seperator. 1028 // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string 1029 template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const 1030 { 1031 const TiXmlAttribute* node = attributeSet.Find( name ); 1032 if ( !node ) 1033 return TIXML_NO_ATTRIBUTE; 1034 *outValue = node->ValueStr(); 1035 return TIXML_SUCCESS; 1036 } 1037 */ 1038 #endif 1039 904 1040 /** Sets an attribute of name to a given value. The attribute 905 1041 will be created if it does not exist, or changed if it does. … … 908 1044 909 1045 #ifdef TIXML_USE_STL 910 const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); }911 const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); }912 const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); }913 int QueryIntAttribute( const std::string& name, int* _value ) const { return QueryIntAttribute( name.c_str(), _value ); }914 int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }1046 const std::string* Attribute( const std::string& name ) const; 1047 const std::string* Attribute( const std::string& name, int* i ) const; 1048 const std::string* Attribute( const std::string& name, double* d ) const; 1049 int QueryIntAttribute( const std::string& name, int* _value ) const; 1050 int QueryDoubleAttribute( const std::string& name, double* _value ) const; 915 1051 916 1052 /// STL std::string form. 917 void SetAttribute( const std::string& name, const std::string& _value ) 918 { 919 StringToBuffer n( name ); 920 StringToBuffer v( _value ); 921 if ( n.buffer && v.buffer ) 922 SetAttribute (n.buffer, v.buffer ); 923 } 1053 void SetAttribute( const std::string& name, const std::string& _value ); 924 1054 ///< STL std::string form. 925 void SetAttribute( const std::string& name, int _value ) 926 { 927 StringToBuffer n( name ); 928 if ( n.buffer ) 929 SetAttribute (n.buffer, _value); 930 } 1055 void SetAttribute( const std::string& name, int _value ); 931 1056 #endif 932 1057 … … 956 1081 and concise, GetText() is limited compared to getting the TiXmlText child 957 1082 and accessing it directly. 958 1083 959 1084 If the first child of 'this' is a TiXmlText, the GetText() 960 1085 returns the character string of the Text node, else null is returned. … … 966 1091 @endverbatim 967 1092 968 'str' will be a pointer to "This is text". 969 1093 'str' will be a pointer to "This is text". 1094 970 1095 Note that this function can be misleading. If the element foo was created from 971 1096 this XML: 972 1097 @verbatim 973 <foo><b>This is text</b></foo> 1098 <foo><b>This is text</b></foo> 974 1099 @endverbatim 975 1100 … … 977 1102 another element. From this XML: 978 1103 @verbatim 979 <foo>This is <b>text</b></foo> 1104 <foo>This is <b>text</b></foo> 980 1105 @endverbatim 981 1106 GetText() will return "This is ". 982 1107 983 WARNING: GetText() accesses a child node - don't become confused with the 984 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 1108 WARNING: GetText() accesses a child node - don't become confused with the 1109 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 985 1110 safe type casts on the referenced node. 986 1111 */ … … 997 1122 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 998 1123 1124 virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1125 virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1126 1127 /** Walk the XML tree visiting this node and all of its children. 1128 */ 1129 virtual bool Accept( TiXmlVisitor* visitor ) const; 1130 999 1131 protected: 1000 1132 … … 1004 1136 // Used to be public [internal use] 1005 1137 #ifdef TIXML_USE_STL 1006 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); 1007 #endif 1008 virtual void StreamOut( TIXML_OSTREAM * out ) const; 1009 1138 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1139 #endif 1010 1140 /* [internal use] 1011 1141 Reads the "value" of the element -- another element, or text. … … 1027 1157 /// Constructs an empty comment. 1028 1158 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} 1159 /// Construct a comment from text. 1160 TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { 1161 SetValue( _value ); 1162 } 1029 1163 TiXmlComment( const TiXmlComment& ); 1030 1164 void operator=( const TiXmlComment& base ); … … 1034 1168 /// Returns a copy of this Comment. 1035 1169 virtual TiXmlNode* Clone() const; 1036 // /Write this Comment to a FILE stream.1170 // Write this Comment to a FILE stream. 1037 1171 virtual void Print( FILE* cfile, int depth ) const; 1038 1172 … … 1042 1176 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 1043 1177 1178 virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1179 virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1180 1181 /** Walk the XML tree visiting this node and all of its children. 1182 */ 1183 virtual bool Accept( TiXmlVisitor* visitor ) const; 1184 1044 1185 protected: 1045 1186 void CopyTo( TiXmlComment* target ) const; … … 1047 1188 // used to be public 1048 1189 #ifdef TIXML_USE_STL 1049 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag );1050 #endif 1051 virtual void StreamOut( TIXML_OSTREAM * out ) const;1190 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1191 #endif 1192 // virtual void StreamOut( TIXML_OSTREAM * out ) const; 1052 1193 1053 1194 private: … … 1056 1197 1057 1198 1058 /** XML text. A text node can have 2 ways to output the next. "normal" output 1199 /** XML text. A text node can have 2 ways to output the next. "normal" output 1059 1200 and CDATA. It will default to the mode it was parsed from the XML file and 1060 you generally want to leave it alone, but you can change the output mode with 1201 you generally want to leave it alone, but you can change the output mode with 1061 1202 SetCDATA() and query it with CDATA(). 1062 1203 */ … … 1065 1206 friend class TiXmlElement; 1066 1207 public: 1067 /** Constructor for text element. By default, it is treated as 1208 /** Constructor for text element. By default, it is treated as 1068 1209 normal, encoded text. If you want it be output as a CDATA text 1069 1210 element, set the parameter _cdata to 'true' … … 1088 1229 void operator=( const TiXmlText& base ) { base.CopyTo( this ); } 1089 1230 1090 // /Write this text object to a FILE stream.1231 // Write this text object to a FILE stream. 1091 1232 virtual void Print( FILE* cfile, int depth ) const; 1092 1233 1093 1234 /// Queries whether this represents text using a CDATA section. 1094 bool CDATA() 1235 bool CDATA() const { return cdata; } 1095 1236 /// Turns on or off a CDATA representation of text. 1096 1237 void SetCDATA( bool _cdata ) { cdata = _cdata; } 1097 1238 1098 1239 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 1240 1241 virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1242 virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1243 1244 /** Walk the XML tree visiting this node and all of its children. 1245 */ 1246 virtual bool Accept( TiXmlVisitor* content ) const; 1099 1247 1100 1248 protected : … … 1103 1251 void CopyTo( TiXmlText* target ) const; 1104 1252 1105 virtual void StreamOut ( TIXML_OSTREAM * out ) const;1106 1253 bool Blank() const; // returns true if all white space and new lines 1107 1254 // [internal use] 1108 1255 #ifdef TIXML_USE_STL 1109 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag );1256 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1110 1257 #endif 1111 1258 … … 1160 1307 /// Creates a copy of this Declaration and returns it. 1161 1308 virtual TiXmlNode* Clone() const; 1162 /// Print this declaration to a FILE stream. 1163 virtual void Print( FILE* cfile, int depth ) const; 1309 // Print this declaration to a FILE stream. 1310 virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; 1311 virtual void Print( FILE* cfile, int depth ) const { 1312 Print( cfile, depth, 0 ); 1313 } 1164 1314 1165 1315 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 1316 1317 virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1318 virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1319 1320 /** Walk the XML tree visiting this node and all of its children. 1321 */ 1322 virtual bool Accept( TiXmlVisitor* visitor ) const; 1166 1323 1167 1324 protected: … … 1169 1326 // used to be public 1170 1327 #ifdef TIXML_USE_STL 1171 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); 1172 #endif 1173 virtual void StreamOut ( TIXML_OSTREAM * out) const; 1328 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1329 #endif 1174 1330 1175 1331 private: … … 1199 1355 /// Creates a copy of this Unknown and returns it. 1200 1356 virtual TiXmlNode* Clone() const; 1201 // /Print this Unknown to a FILE stream.1357 // Print this Unknown to a FILE stream. 1202 1358 virtual void Print( FILE* cfile, int depth ) const; 1203 1359 1204 1360 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); 1361 1362 virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1363 virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1364 1365 /** Walk the XML tree visiting this node and all of its children. 1366 */ 1367 virtual bool Accept( TiXmlVisitor* content ) const; 1205 1368 1206 1369 protected: … … 1208 1371 1209 1372 #ifdef TIXML_USE_STL 1210 virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); 1211 #endif 1212 virtual void StreamOut ( TIXML_OSTREAM * out ) const; 1373 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1374 #endif 1213 1375 1214 1376 private: … … 1250 1412 /// Save a file using the given filename. Returns true if successful. 1251 1413 bool SaveFile( const char * filename ) const; 1414 /** Load a file using the given FILE*. Returns true if successful. Note that this method 1415 doesn't stream - the entire object pointed at by the FILE* 1416 will be interpreted as an XML file. TinyXML doesn't stream in XML from the current 1417 file location. Streaming may be added in the future. 1418 */ 1419 bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); 1420 /// Save a file using the given FILE*. Returns true if successful. 1421 bool SaveFile( FILE* ) const; 1252 1422 1253 1423 #ifdef TIXML_USE_STL 1254 1424 bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. 1255 1425 { 1256 StringToBuffer f( filename ); 1257 return ( f.buffer && LoadFile( f.buffer, encoding )); 1426 // StringToBuffer f( filename ); 1427 // return ( f.buffer && LoadFile( f.buffer, encoding )); 1428 return LoadFile( filename.c_str(), encoding ); 1258 1429 } 1259 1430 bool SaveFile( const std::string& filename ) const ///< STL std::string version. 1260 1431 { 1261 StringToBuffer f( filename ); 1262 return ( f.buffer && SaveFile( f.buffer )); 1432 // StringToBuffer f( filename ); 1433 // return ( f.buffer && SaveFile( f.buffer )); 1434 return SaveFile( filename.c_str() ); 1263 1435 } 1264 1436 #endif … … 1281 1453 - The ErrorDesc() method will return the name of the error. (very useful) 1282 1454 - The ErrorRow() and ErrorCol() will return the location of the error (if known) 1283 */ 1455 */ 1284 1456 bool Error() const { return error; } 1285 1457 … … 1292 1464 int ErrorId() const { return errorId; } 1293 1465 1294 /** Returns the location (if known) of the error. The first column is column 1, 1466 /** Returns the location (if known) of the error. The first column is column 1, 1295 1467 and the first row is row 1. A value of 0 means the row and column wasn't applicable 1296 1468 (memory errors, for example, have no row/column) or the parser lost the error. (An … … 1299 1471 @sa SetTabSize, Row, Column 1300 1472 */ 1301 int ErrorRow() { return errorLocation.row+1; }1302 int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()1473 int ErrorRow() const { return errorLocation.row+1; } 1474 int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() 1303 1475 1304 1476 /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) 1305 1477 to report the correct values for row and column. It does not change the output 1306 1478 or input in any way. 1307 1479 1308 1480 By calling this method, with a tab size 1309 1481 greater than 0, the row and column of each node and attribute is stored … … 1333 1505 state is automatically cleared if you Parse a new XML block. 1334 1506 */ 1335 void ClearError() { error = false; 1336 errorId = 0; 1337 errorDesc = ""; 1338 errorLocation.row = errorLocation.col = 0; 1339 //errorLocation.last = 0; 1507 void ClearError() { error = false; 1508 errorId = 0; 1509 errorDesc = ""; 1510 errorLocation.row = errorLocation.col = 0; 1511 //errorLocation.last = 0; 1340 1512 } 1341 1513 1342 /** Dump the document to standard out. */1514 /** Write the document to standard out using formatted printing ("pretty print"). */ 1343 1515 void Print() const { Print( stdout, 0 ); } 1516 1517 /* Write the document to a string using formatted printing ("pretty print"). This 1518 will allocate a character array (new char[]) and return it as a pointer. The 1519 calling code pust call delete[] on the return char* to avoid a memory leak. 1520 */ 1521 //char* PrintToMemory() const; 1344 1522 1345 1523 /// Print this Document to a FILE stream. … … 1348 1526 void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); 1349 1527 1528 virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1529 virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. 1530 1531 /** Walk the XML tree visiting this node and all of its children. 1532 */ 1533 virtual bool Accept( TiXmlVisitor* content ) const; 1534 1350 1535 protected : 1351 virtual void StreamOut ( TIXML_OSTREAM * out) const;1352 1536 // [internal use] 1353 1537 virtual TiXmlNode* Clone() const; 1354 1538 #ifdef TIXML_USE_STL 1355 virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag );1539 virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); 1356 1540 #endif 1357 1541 … … 1383 1567 @endverbatim 1384 1568 1385 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 1569 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 1386 1570 easy to write a *lot* of code that looks like: 1387 1571 … … 1403 1587 1404 1588 And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity 1405 of such code. A TiXmlHandle checks for null pointers so it is perfectly safe 1589 of such code. A TiXmlHandle checks for null pointers so it is perfectly safe 1406 1590 and correct to use: 1407 1591 1408 1592 @verbatim 1409 1593 TiXmlHandle docHandle( &document ); 1410 TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ). Element();1594 TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); 1411 1595 if ( child2 ) 1412 1596 { … … 1424 1608 1425 1609 @verbatim 1426 int i=0; 1610 int i=0; 1427 1611 while ( true ) 1428 1612 { 1429 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ). Element();1613 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); 1430 1614 if ( !child ) 1431 1615 break; … … 1435 1619 @endverbatim 1436 1620 1437 It seems reasonable, but it is in fact two embedded while loops. The Child method is 1438 a linear walk to find the element, so this code would iterate much more than it needs 1621 It seems reasonable, but it is in fact two embedded while loops. The Child method is 1622 a linear walk to find the element, so this code would iterate much more than it needs 1439 1623 to. Instead, prefer: 1440 1624 1441 1625 @verbatim 1442 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ). Element();1626 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); 1443 1627 1444 1628 for( child; child; child=child->NextSiblingElement() ) … … 1466 1650 TiXmlHandle FirstChildElement( const char * value ) const; 1467 1651 1468 /** Return a handle to the "index" child with the given name. 1652 /** Return a handle to the "index" child with the given name. 1469 1653 The first child is 0, the second 1, etc. 1470 1654 */ 1471 1655 TiXmlHandle Child( const char* value, int index ) const; 1472 /** Return a handle to the "index" child. 1656 /** Return a handle to the "index" child. 1473 1657 The first child is 0, the second 1, etc. 1474 1658 */ 1475 1659 TiXmlHandle Child( int index ) const; 1476 /** Return a handle to the "index" child element with the given name. 1660 /** Return a handle to the "index" child element with the given name. 1477 1661 The first child element is 0, the second 1, etc. Note that only TiXmlElements 1478 1662 are indexed: other types are not counted. 1479 1663 */ 1480 1664 TiXmlHandle ChildElement( const char* value, int index ) const; 1481 /** Return a handle to the "index" child element. 1665 /** Return a handle to the "index" child element. 1482 1666 The first child element is 0, the second 1, etc. Note that only TiXmlElements 1483 1667 are indexed: other types are not counted. … … 1493 1677 #endif 1494 1678 1495 /// Return the handle as a TiXmlNode. This may return null. 1496 TiXmlNode* Node() const { return node; } 1497 /// Return the handle as a TiXmlElement. This may return null. 1498 TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } 1499 /// Return the handle as a TiXmlText. This may return null. 1500 TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } 1501 /// Return the handle as a TiXmlUnknown. This may return null; 1502 TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } 1679 /** Return the handle as a TiXmlNode. This may return null. 1680 */ 1681 TiXmlNode* ToNode() const { return node; } 1682 /** Return the handle as a TiXmlElement. This may return null. 1683 */ 1684 TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } 1685 /** Return the handle as a TiXmlText. This may return null. 1686 */ 1687 TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } 1688 /** Return the handle as a TiXmlUnknown. This may return null. 1689 */ 1690 TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } 1691 1692 /** @deprecated use ToNode. 1693 Return the handle as a TiXmlNode. This may return null. 1694 */ 1695 TiXmlNode* Node() const { return ToNode(); } 1696 /** @deprecated use ToElement. 1697 Return the handle as a TiXmlElement. This may return null. 1698 */ 1699 TiXmlElement* Element() const { return ToElement(); } 1700 /** @deprecated use ToText() 1701 Return the handle as a TiXmlText. This may return null. 1702 */ 1703 TiXmlText* Text() const { return ToText(); } 1704 /** @deprecated use ToUnknown() 1705 Return the handle as a TiXmlUnknown. This may return null. 1706 */ 1707 TiXmlUnknown* Unknown() const { return ToUnknown(); } 1503 1708 1504 1709 private: … … 1506 1711 }; 1507 1712 1713 1714 /** Print to memory functionality. The TiXmlPrinter is useful when you need to: 1715 1716 -# Print to memory (especially in non-STL mode) 1717 -# Control formatting (line endings, etc.) 1718 1719 When constructed, the TiXmlPrinter is in its default "pretty printing" mode. 1720 Before calling Accept() you can call methods to control the printing 1721 of the XML document. After TiXmlNode::Accept() is called, the printed document can 1722 be accessed via the CStr(), Str(), and Size() methods. 1723 1724 TiXmlPrinter uses the Visitor API. 1725 @verbatim 1726 TiXmlPrinter printer; 1727 printer.SetIndent( "\t" ); 1728 1729 doc.Accept( &printer ); 1730 fprintf( stdout, "%s", printer.CStr() ); 1731 @endverbatim 1732 */ 1733 class TiXmlPrinter : public TiXmlVisitor 1734 { 1735 public: 1736 TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), 1737 buffer(), indent( " " ), lineBreak( "\n" ) {} 1738 1739 virtual bool VisitEnter( const TiXmlDocument& doc ); 1740 virtual bool VisitExit( const TiXmlDocument& doc ); 1741 1742 virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); 1743 virtual bool VisitExit( const TiXmlElement& element ); 1744 1745 virtual bool Visit( const TiXmlDeclaration& declaration ); 1746 virtual bool Visit( const TiXmlText& text ); 1747 virtual bool Visit( const TiXmlComment& comment ); 1748 virtual bool Visit( const TiXmlUnknown& unknown ); 1749 1750 /** Set the indent characters for printing. By default 4 spaces 1751 but tab (\t) is also useful, or null/empty string for no indentation. 1752 */ 1753 void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } 1754 /// Query the indention string. 1755 const char* Indent() { return indent.c_str(); } 1756 /** Set the line breaking string. By default set to newline (\n). 1757 Some operating systems prefer other characters, or can be 1758 set to the null/empty string for no indenation. 1759 */ 1760 void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } 1761 /// Query the current line breaking string. 1762 const char* LineBreak() { return lineBreak.c_str(); } 1763 1764 /** Switch over to "stream printing" which is the most dense formatting without 1765 linebreaks. Common when the XML is needed for network transmission. 1766 */ 1767 void SetStreamPrinting() { indent = ""; 1768 lineBreak = ""; 1769 } 1770 /// Return the result. 1771 const char* CStr() { return buffer.c_str(); } 1772 /// Return the length of the result string. 1773 size_t Size() { return buffer.size(); } 1774 1775 #ifdef TIXML_USE_STL 1776 /// Return the result. 1777 const std::string& Str() { return buffer; } 1778 #endif 1779 1780 private: 1781 void DoIndent() { 1782 for( int i=0; i<depth; ++i ) 1783 buffer += indent; 1784 } 1785 void DoLineBreak() { 1786 buffer += lineBreak; 1787 } 1788 1789 int depth; 1790 bool simpleTextPrint; 1791 TIXML_STRING buffer; 1792 TIXML_STRING indent; 1793 TIXML_STRING lineBreak; 1794 }; 1795 1796 1508 1797 #ifdef _MSC_VER 1509 1798 #pragma warning( pop ) -
code/branches/FICN/src/tinyxml/tinyxmlerror.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 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 7 7 damages arising from the use of this software. 8 8 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 11 11 redistribute it freely, subject to the following restrictions: 12 12 … … 50 50 "Error null (0) or unexpected EOF found in input stream.", 51 51 "Error parsing CDATA.", 52 "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", 52 53 }; -
code/branches/FICN/src/tinyxml/tinyxmlparser.cc
r471 r738 3 3 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) 4 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 7 7 damages arising from the use of this software. 8 8 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 11 11 redistribute it freely, subject to the following restrictions: 12 12 13 1. The origin of this software must not be misrepresented; you must 13 1. The origin of this software must not be misrepresented; you must 14 14 not claim that you wrote the original software. If you use this 15 15 software in a product, an acknowledgment in the product documentation 16 16 would be appreciated but is not required. 17 17 18 2. Altered source versions must be plainly marked as such, and 18 2. Altered source versions must be plainly marked as such, and 19 19 must not be misrepresented as being the original software. 20 20 21 3. This notice may not be removed or altered from any source 21 3. This notice may not be removed or altered from any source 22 22 distribution. 23 23 */ 24 24 25 #include "tinyxml.h"26 25 #include <ctype.h> 27 26 #include <stddef.h> 28 27 28 #include "tinyxml.h" 29 29 30 //#define DEBUG_PARSER 31 #if defined( DEBUG_PARSER ) 32 # if defined( DEBUG ) && defined( _MSC_VER ) 33 # include <windows.h> 34 # define TIXML_LOG OutputDebugString 35 # else 36 # define TIXML_LOG printf 37 # endif 38 #endif 30 39 31 40 // Note tha "PutString" hardcodes the same list. This 32 41 // is less flexible than it appears. Changing the entries 33 // or order will break putstring. 34 TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 42 // or order will break putstring. 43 TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 35 44 { 36 45 { "&", 5, '&' }, … … 46 55 // sequence from the lead byte. 1 placed for invalid sequences -- 47 56 // although the result will be junk, pass it through as much as possible. 48 // Beware of the non-characters in UTF-8: 57 // Beware of the non-characters in UTF-8: 49 58 // ef bb bf (Microsoft "lead bytes") 50 59 // ef bf be 51 // ef bf bf 60 // ef bf bf 52 61 53 62 const unsigned char TIXML_UTF_LEAD_0 = 0xefU; … … 55 64 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; 56 65 57 const int TiXmlBase::utf8ByteTable[256] = 66 const int TiXmlBase::utf8ByteTable[256] = 58 67 { 59 68 // 0 1 2 3 4 5 6 7 8 9 a b c d e f … … 67 76 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range 68 77 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid 69 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 70 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 71 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 78 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 79 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 80 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 72 81 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte 73 82 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 … … 83 92 const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 84 93 85 if (input < 0x80) 94 if (input < 0x80) 86 95 *length = 1; 87 96 else if ( input < 0x800 ) … … 97 106 98 107 // Scary scary fall throughs. 99 switch (*length) 108 switch (*length) 100 109 { 101 110 case 4: 102 --output; 103 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 111 --output; 112 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 104 113 input >>= 6; 105 114 case 3: 106 --output; 107 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 115 --output; 116 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 108 117 input >>= 6; 109 118 case 2: 110 --output; 111 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 119 --output; 120 *output = (char)((input | BYTE_MARK) & BYTE_MASK); 112 121 input >>= 6; 113 122 case 1: 114 --output; 123 --output; 115 124 *output = (char)(input | FIRST_BYTE_MARK[*length]); 116 125 } … … 122 131 // This will only work for low-ascii, everything else is assumed to be a valid 123 132 // letter. I'm not sure this is the best approach, but it is quite tricky trying 124 // to figure out alhabetical vs. not across encoding. So take a very 133 // to figure out alhabetical vs. not across encoding. So take a very 125 134 // conservative approach. 126 135 … … 143 152 // This will only work for low-ascii, everything else is assumed to be a valid 144 153 // letter. I'm not sure this is the best approach, but it is quite tricky trying 145 // to figure out alhabetical vs. not across encoding. So take a very 154 // to figure out alhabetical vs. not across encoding. So take a very 146 155 // conservative approach. 147 156 … … 216 225 // bump down to the next line 217 226 ++row; 218 col = 0; 227 col = 0; 219 228 // Eat the character 220 229 ++p; … … 258 267 // 0-width spaces. 259 268 if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) 260 p += 3; 269 p += 3; 261 270 else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) 262 p += 3; 271 p += 3; 263 272 else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) 264 p += 3; 273 p += 3; 265 274 else 266 275 { p +=3; ++col; } // A normal character. … … 278 287 { 279 288 // Eat the 1 to 4 byte utf8 character. 280 int step = TiXmlBase::utf8ByteTable[*(( unsigned char*)p)];289 int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; 281 290 if ( step == 0 ) 282 291 step = 1; // Error case from bad encoding, but handle gracefully. … … 314 323 { 315 324 const unsigned char* pU = (const unsigned char*)p; 316 325 317 326 // Skip the stupid Microsoft UTF-8 Byte order marks 318 327 if ( *(pU+0)==TIXML_UTF_LEAD_0 319 && *(pU+1)==TIXML_UTF_LEAD_1 328 && *(pU+1)==TIXML_UTF_LEAD_1 320 329 && *(pU+2)==TIXML_UTF_LEAD_2 ) 321 330 { … … 354 363 355 364 #ifdef TIXML_USE_STL 356 /*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM* in, TIXML_STRING * tag )365 /*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) 357 366 { 358 367 for( ;; ) … … 369 378 } 370 379 371 /*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM* in, int character, TIXML_STRING * tag )380 /*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) 372 381 { 373 382 //assert( character > 0 && character < 128 ); // else it won't work in utf-8 … … 387 396 #endif 388 397 398 // One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The 399 // "assign" optimization removes over 10% of the execution time. 400 // 389 401 const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) 390 402 { 403 // Oddly, not supported on some comilers, 404 //name->clear(); 405 // So use this: 391 406 *name = ""; 392 407 assert( p ); … … 399 414 // hyphens, or colons. (Colons are valid ony for namespaces, 400 415 // but tinyxml can't tell namespaces from names.) 401 if ( p && *p 416 if ( p && *p 402 417 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) 403 418 { 419 const char* start = p; 404 420 while( p && *p 405 && ( IsAlphaNum( (unsigned char ) *p, encoding ) 421 && ( IsAlphaNum( (unsigned char ) *p, encoding ) 406 422 || *p == '_' 407 423 || *p == '-' … … 409 425 || *p == ':' ) ) 410 426 { 411 (*name) += *p;427 //(*name) += *p; // expensive 412 428 ++p; 429 } 430 if ( p-start > 0 ) { 431 name->assign( start, p-start ); 413 432 } 414 433 return p; … … 451 470 else if ( *q >= 'A' && *q <= 'F' ) 452 471 ucs += mult * (*q - 'A' + 10 ); 453 else 472 else 454 473 return 0; 455 474 mult *= 16; … … 474 493 if ( *q >= '0' && *q <= '9' ) 475 494 ucs += mult * (*q - '0'); 476 else 495 else 477 496 return 0; 478 497 mult *= 10; … … 507 526 // So it wasn't an entity, its unrecognized, or something like that. 508 527 *value = *p; // Don't put back the last one, since we return it! 528 //*length = 1; // Leave unrecognized entities - this doesn't really work. 529 // Just writes strange XML. 509 530 return p+1; 510 531 } … … 551 572 } 552 573 553 const char* TiXmlBase::ReadText( const char* p, 554 TIXML_STRING * text, 555 bool trimWhiteSpace, 556 const char* endTag, 574 const char* TiXmlBase::ReadText( const char* p, 575 TIXML_STRING * text, 576 bool trimWhiteSpace, 577 const char* endTag, 557 578 bool caseInsensitive, 558 579 TiXmlEncoding encoding ) … … 611 632 } 612 633 } 613 return p + strlen( endTag ); 634 if ( p ) 635 p += strlen( endTag ); 636 return p; 614 637 } 615 638 616 639 #ifdef TIXML_USE_STL 617 640 618 void TiXmlDocument::StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag )641 void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) 619 642 { 620 643 // The basic issue with a document is that we don't know what we're … … 625 648 // sub-tag can orient itself. 626 649 627 if ( !StreamTo( in, '<', tag ) ) 650 if ( !StreamTo( in, '<', tag ) ) 628 651 { 629 652 SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); … … 647 670 if ( in->good() ) 648 671 { 649 // We now have something we presume to be a node of 672 // We now have something we presume to be a node of 650 673 // some sort. Identify it, and call the node to 651 674 // continue streaming. … … 756 779 else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) 757 780 encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice 758 else 781 else 759 782 encoding = TIXML_ENCODING_LEGACY; 760 783 } … … 774 797 775 798 void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) 776 { 799 { 777 800 // The first error in a chain is more accurate - don't set again! 778 801 if ( error ) … … 811 834 } 812 835 813 // What is this thing? 836 // What is this thing? 814 837 // - Elements start with a letter or underscore, but xml is reserved. 815 838 // - Comments: <!-- … … 884 907 #ifdef TIXML_USE_STL 885 908 886 void TiXmlElement::StreamIn ( TIXML_ISTREAM* in, TIXML_STRING * tag)909 void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag) 887 910 { 888 911 // We're called with some amount of pre-parsing. That is, some of "this" … … 899 922 } 900 923 (*tag) += (char) c ; 901 924 902 925 if ( c == '>' ) 903 926 break; … … 909 932 // If not, identify and stream. 910 933 911 if ( tag->at( tag->length() - 1 ) == '>' 934 if ( tag->at( tag->length() - 1 ) == '>' 912 935 && tag->at( tag->length() - 2 ) == '/' ) 913 936 { … … 919 942 // There is more. Could be: 920 943 // text 944 // cdata text (which looks like another node) 921 945 // closing tag 922 946 // another node. … … 926 950 927 951 // Do we have text? 928 if ( in->good() && in->peek() != '<' ) 952 if ( in->good() && in->peek() != '<' ) 929 953 { 930 954 // Yep, text. … … 959 983 return; 960 984 } 961 985 962 986 if ( c == '>' ) 963 987 break; … … 965 989 *tag += (char) c; 966 990 in->get(); 991 992 // Early out if we find the CDATA id. 993 if ( c == '[' && tag->size() >= 9 ) 994 { 995 size_t len = tag->size(); 996 const char* start = tag->c_str() + len - 9; 997 if ( strcmp( start, "<![CDATA[" ) == 0 ) { 998 assert( !closingTag ); 999 break; 1000 } 1001 } 967 1002 968 1003 if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) … … 1068 1103 if ( *p != '>' ) 1069 1104 { 1070 if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); 1105 if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); 1071 1106 return 0; 1072 1107 } … … 1080 1115 ++p; 1081 1116 p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens. 1082 if ( !p || !*p ) 1117 if ( !p || !*p ) { 1118 // We were looking for the end tag, but found nothing. 1119 // Fix for [ 1663758 ] Failure to report error on bad XML 1120 if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); 1083 1121 return 0; 1122 } 1084 1123 1085 1124 // We should find the end tag now … … 1106 1145 1107 1146 attrib->SetDocument( document ); 1108 const char*pErr = p;1147 pErr = p; 1109 1148 p = attrib->Parse( p, data, encoding ); 1110 1149 … … 1117 1156 1118 1157 // Handle the strange case of double attributes: 1158 #ifdef TIXML_USE_STL 1159 TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() ); 1160 #else 1119 1161 TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); 1162 #endif 1120 1163 if ( node ) 1121 1164 { … … 1168 1211 else 1169 1212 delete textNode; 1170 } 1171 else 1213 } 1214 else 1172 1215 { 1173 1216 // We hit a '<' … … 1185 1228 p = node->Parse( p, data, encoding ); 1186 1229 LinkEndChild( node ); 1187 } 1230 } 1188 1231 else 1189 1232 { … … 1199 1242 { 1200 1243 if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding ); 1201 } 1244 } 1202 1245 return p; 1203 1246 } … … 1205 1248 1206 1249 #ifdef TIXML_USE_STL 1207 void TiXmlUnknown::StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag )1250 void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag ) 1208 1251 { 1209 1252 while ( in->good() ) 1210 1253 { 1211 int c = in->get(); 1254 int c = in->get(); 1212 1255 if ( c <= 0 ) 1213 1256 { … … 1222 1265 { 1223 1266 // All is well. 1224 return; 1267 return; 1225 1268 } 1226 1269 } … … 1263 1306 1264 1307 #ifdef TIXML_USE_STL 1265 void TiXmlComment::StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag )1308 void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag ) 1266 1309 { 1267 1310 while ( in->good() ) 1268 1311 { 1269 int c = in->get(); 1312 int c = in->get(); 1270 1313 if ( c <= 0 ) 1271 1314 { … … 1278 1321 (*tag) += (char) c; 1279 1322 1280 if ( c == '>' 1323 if ( c == '>' 1281 1324 && tag->at( tag->length() - 2 ) == '-' 1282 1325 && tag->at( tag->length() - 3 ) == '-' ) 1283 1326 { 1284 1327 // All is well. 1285 return; 1328 return; 1286 1329 } 1287 1330 } … … 1311 1354 } 1312 1355 p += strlen( startTag ); 1313 p = ReadText( p, &value, false, endTag, false, encoding ); 1356 1357 // [ 1475201 ] TinyXML parses entities in comments 1358 // Oops - ReadText doesn't work, because we don't want to parse the entities. 1359 // p = ReadText( p, &value, false, endTag, false, encoding ); 1360 // 1361 // from the XML spec: 1362 /* 1363 [Definition: Comments may appear anywhere in a document outside other markup; in addition, 1364 they may appear within the document type declaration at places allowed by the grammar. 1365 They are not part of the document's character data; an XML processor MAY, but need not, 1366 make it possible for an application to retrieve the text of comments. For compatibility, 1367 the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity 1368 references MUST NOT be recognized within comments. 1369 1370 An example of a comment: 1371 1372 <!-- declarations for <head> & <body> --> 1373 */ 1374 1375 value = ""; 1376 // Keep all the white space. 1377 while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) 1378 { 1379 value.append( p, 1 ); 1380 ++p; 1381 } 1382 if ( p ) 1383 p += strlen( endTag ); 1384 1314 1385 return p; 1315 1386 } … … 1321 1392 if ( !p || !*p ) return 0; 1322 1393 1323 int tabsize = 4;1324 if ( document )1325 tabsize = document->TabSize();1394 // int tabsize = 4; 1395 // if ( document ) 1396 // tabsize = document->TabSize(); 1326 1397 1327 1398 if ( data ) … … 1352 1423 return 0; 1353 1424 } 1354 1425 1355 1426 const char* end; 1356 1357 if ( *p == '\'' ) 1427 const char SINGLE_QUOTE = '\''; 1428 const char DOUBLE_QUOTE = '\"'; 1429 1430 if ( *p == SINGLE_QUOTE ) 1358 1431 { 1359 1432 ++p; 1360 end = "\'"; 1433 end = "\'"; // single quote in string 1361 1434 p = ReadText( p, &value, false, end, false, encoding ); 1362 1435 } 1363 else if ( *p == '"')1436 else if ( *p == DOUBLE_QUOTE ) 1364 1437 { 1365 1438 ++p; 1366 end = "\""; 1439 end = "\""; // double quote in string 1367 1440 p = ReadText( p, &value, false, end, false, encoding ); 1368 1441 } … … 1373 1446 // its best, even without them. 1374 1447 value = ""; 1375 while ( p && *p // existence1448 while ( p && *p // existence 1376 1449 && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace 1377 && *p != '/' && *p != '>' ) // tag end 1378 { 1450 && *p != '/' && *p != '>' ) // tag end 1451 { 1452 if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { 1453 // [ 1451649 ] Attribute values with trailing quotes not handled correctly 1454 // We did not have an opening quote but seem to have a 1455 // closing one. Give up and throw an error. 1456 if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); 1457 return 0; 1458 } 1379 1459 value += *p; 1380 1460 ++p; … … 1385 1465 1386 1466 #ifdef TIXML_USE_STL 1387 void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) 1388 { 1389 if ( cdata ) 1390 { 1391 int c = in->get(); 1467 void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) 1468 { 1469 while ( in->good() ) 1470 { 1471 int c = in->peek(); 1472 if ( !cdata && (c == '<' ) ) 1473 { 1474 return; 1475 } 1392 1476 if ( c <= 0 ) 1393 1477 { … … 1399 1483 1400 1484 (*tag) += (char) c; 1401 1402 if ( c == '>' 1403 && tag->at( tag->length() - 2 ) == ']' 1404 && tag->at( tag->length() - 3 ) == ']' ) 1405 { 1406 // All is well. 1407 return; 1408 } 1409 } 1410 else 1411 { 1412 while ( in->good() ) 1413 { 1414 int c = in->peek(); 1415 if ( c == '<' ) 1485 in->get(); // "commits" the peek made above 1486 1487 if ( cdata && c == '>' && tag->size() >= 3 ) { 1488 size_t len = tag->size(); 1489 if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { 1490 // terminator of cdata. 1416 1491 return; 1417 if ( c <= 0 ) 1418 { 1419 TiXmlDocument* document = GetDocument(); 1420 if ( document ) 1421 document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); 1422 return; 1423 } 1424 1425 (*tag) += (char) c; 1426 in->get(); 1492 } 1427 1493 } 1428 1494 } … … 1464 1530 } 1465 1531 1466 TIXML_STRING dummy; 1532 TIXML_STRING dummy; 1467 1533 p = ReadText( p, &dummy, false, endTag, false, encoding ); 1468 1534 return p; … … 1481 1547 1482 1548 #ifdef TIXML_USE_STL 1483 void TiXmlDeclaration::StreamIn( TIXML_ISTREAM* in, TIXML_STRING * tag )1549 void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) 1484 1550 { 1485 1551 while ( in->good() ) … … 1538 1604 { 1539 1605 TiXmlAttribute attrib; 1540 p = attrib.Parse( p, data, _encoding ); 1606 p = attrib.Parse( p, data, _encoding ); 1541 1607 version = attrib.Value(); 1542 1608 } … … 1544 1610 { 1545 1611 TiXmlAttribute attrib; 1546 p = attrib.Parse( p, data, _encoding ); 1612 p = attrib.Parse( p, data, _encoding ); 1547 1613 encoding = attrib.Value(); 1548 1614 } … … 1550 1616 { 1551 1617 TiXmlAttribute attrib; 1552 p = attrib.Parse( p, data, _encoding ); 1618 p = attrib.Parse( p, data, _encoding ); 1553 1619 standalone = attrib.Value(); 1554 1620 }
Note: See TracChangeset
for help on using the changeset viewer.