00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <ctype.h>
00064 #include "tinyxml.h"
00065
00066 #ifdef TIXML_USE_STL
00067 #include <sstream>
00068 #include <iostream>
00069 #endif
00070
00071 namespace RTT { namespace marsh {
00072
00073 bool TiXmlBase::condenseWhiteSpace = true;
00074
00075 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
00076 {
00077 TIXML_STRING buffer;
00078 PutString( str, &buffer );
00079 (*stream) << buffer;
00080 }
00081
00082 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
00083 {
00084 int i=0;
00085
00086 while( i<(int)str.length() )
00087 {
00088 unsigned char c = (unsigned char) str[i];
00089
00090 if ( c == '&'
00091 && i < ( (int)str.length() - 2 )
00092 && str[i+1] == '#'
00093 && str[i+2] == 'x' )
00094 {
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 while ( i<(int)str.length()-1 )
00106 {
00107 outString->append( str.c_str() + i, 1 );
00108 ++i;
00109 if ( str[i] == ';' )
00110 break;
00111 }
00112 }
00113 else if ( c == '&' )
00114 {
00115 outString->append( entity[0].str, entity[0].strLength );
00116 ++i;
00117 }
00118 else if ( c == '<' )
00119 {
00120 outString->append( entity[1].str, entity[1].strLength );
00121 ++i;
00122 }
00123 else if ( c == '>' )
00124 {
00125 outString->append( entity[2].str, entity[2].strLength );
00126 ++i;
00127 }
00128 else if ( c == '\"' )
00129 {
00130 outString->append( entity[3].str, entity[3].strLength );
00131 ++i;
00132 }
00133 else if ( c == '\'' )
00134 {
00135 outString->append( entity[4].str, entity[4].strLength );
00136 ++i;
00137 }
00138 else if ( c < 32 )
00139 {
00140
00141
00142 char buf[ 32 ];
00143
00144 #if defined(TIXML_SNPRINTF)
00145 TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
00146 #else
00147 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
00148 #endif
00149
00150
00151
00152 outString->append( buf, (int)strlen( buf ) );
00153 ++i;
00154 }
00155 else
00156 {
00157
00158
00159 *outString += (char) c;
00160 ++i;
00161 }
00162 }
00163 }
00164
00165
00166
00167 TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
00168 {
00169 buffer = new char[ str.length()+1 ];
00170 if ( buffer )
00171 {
00172 strcpy( buffer, str.c_str() );
00173 }
00174 }
00175
00176
00177 TiXmlBase::StringToBuffer::~StringToBuffer()
00178 {
00179 delete [] buffer;
00180 }
00181
00182
00183
00184 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
00185 {
00186 parent = 0;
00187 type = _type;
00188 firstChild = 0;
00189 lastChild = 0;
00190 prev = 0;
00191 next = 0;
00192 }
00193
00194
00195 TiXmlNode::~TiXmlNode()
00196 {
00197 TiXmlNode* node = firstChild;
00198 TiXmlNode* temp = 0;
00199
00200 while ( node )
00201 {
00202 temp = node;
00203 node = node->next;
00204 delete temp;
00205 }
00206 }
00207
00208
00209 void TiXmlNode::CopyTo( TiXmlNode* target ) const
00210 {
00211 target->SetValue (value.c_str() );
00212 target->userData = userData;
00213 }
00214
00215
00216 void TiXmlNode::Clear()
00217 {
00218 TiXmlNode* node = firstChild;
00219 TiXmlNode* temp = 0;
00220
00221 while ( node )
00222 {
00223 temp = node;
00224 node = node->next;
00225 delete temp;
00226 }
00227
00228 firstChild = 0;
00229 lastChild = 0;
00230 }
00231
00232
00233 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
00234 {
00235 assert( node->parent == 0 || node->parent == this );
00236 assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
00237
00238 node->parent = this;
00239
00240 node->prev = lastChild;
00241 node->next = 0;
00242
00243 if ( lastChild )
00244 lastChild->next = node;
00245 else
00246 firstChild = node;
00247
00248 lastChild = node;
00249 return node;
00250 }
00251
00252
00253 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
00254 {
00255 TiXmlNode* node = addThis.Clone();
00256 if ( !node )
00257 return 0;
00258
00259 return LinkEndChild( node );
00260 }
00261
00262
00263 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
00264 {
00265 if ( !beforeThis || beforeThis->parent != this )
00266 return 0;
00267
00268 TiXmlNode* node = addThis.Clone();
00269 if ( !node )
00270 return 0;
00271 node->parent = this;
00272
00273 node->next = beforeThis;
00274 node->prev = beforeThis->prev;
00275 if ( beforeThis->prev )
00276 {
00277 beforeThis->prev->next = node;
00278 }
00279 else
00280 {
00281 assert( firstChild == beforeThis );
00282 firstChild = node;
00283 }
00284 beforeThis->prev = node;
00285 return node;
00286 }
00287
00288
00289 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
00290 {
00291 if ( !afterThis || afterThis->parent != this )
00292 return 0;
00293
00294 TiXmlNode* node = addThis.Clone();
00295 if ( !node )
00296 return 0;
00297 node->parent = this;
00298
00299 node->prev = afterThis;
00300 node->next = afterThis->next;
00301 if ( afterThis->next )
00302 {
00303 afterThis->next->prev = node;
00304 }
00305 else
00306 {
00307 assert( lastChild == afterThis );
00308 lastChild = node;
00309 }
00310 afterThis->next = node;
00311 return node;
00312 }
00313
00314
00315 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
00316 {
00317 if ( replaceThis->parent != this )
00318 return 0;
00319
00320 TiXmlNode* node = withThis.Clone();
00321 if ( !node )
00322 return 0;
00323
00324 node->next = replaceThis->next;
00325 node->prev = replaceThis->prev;
00326
00327 if ( replaceThis->next )
00328 replaceThis->next->prev = node;
00329 else
00330 lastChild = node;
00331
00332 if ( replaceThis->prev )
00333 replaceThis->prev->next = node;
00334 else
00335 firstChild = node;
00336
00337 delete replaceThis;
00338 node->parent = this;
00339 return node;
00340 }
00341
00342
00343 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
00344 {
00345 if ( removeThis->parent != this )
00346 {
00347 assert( 0 );
00348 return false;
00349 }
00350
00351 if ( removeThis->next )
00352 removeThis->next->prev = removeThis->prev;
00353 else
00354 lastChild = removeThis->prev;
00355
00356 if ( removeThis->prev )
00357 removeThis->prev->next = removeThis->next;
00358 else
00359 firstChild = removeThis->next;
00360
00361 delete removeThis;
00362 return true;
00363 }
00364
00365 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
00366 {
00367 const TiXmlNode* node;
00368 for ( node = firstChild; node; node = node->next )
00369 {
00370 if ( strcmp( node->Value(), _value ) == 0 )
00371 return node;
00372 }
00373 return 0;
00374 }
00375
00376
00377 TiXmlNode* TiXmlNode::FirstChild( const char * _value )
00378 {
00379 TiXmlNode* node;
00380 for ( node = firstChild; node; node = node->next )
00381 {
00382 if ( strcmp( node->Value(), _value ) == 0 )
00383 return node;
00384 }
00385 return 0;
00386 }
00387
00388
00389 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
00390 {
00391 const TiXmlNode* node;
00392 for ( node = lastChild; node; node = node->prev )
00393 {
00394 if ( strcmp( node->Value(), _value ) == 0 )
00395 return node;
00396 }
00397 return 0;
00398 }
00399
00400 TiXmlNode* TiXmlNode::LastChild( const char * _value )
00401 {
00402 TiXmlNode* node;
00403 for ( node = lastChild; node; node = node->prev )
00404 {
00405 if ( strcmp( node->Value(), _value ) == 0 )
00406 return node;
00407 }
00408 return 0;
00409 }
00410
00411 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
00412 {
00413 if ( !previous )
00414 {
00415 return FirstChild();
00416 }
00417 else
00418 {
00419 assert( previous->parent == this );
00420 return previous->NextSibling();
00421 }
00422 }
00423
00424 TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
00425 {
00426 if ( !previous )
00427 {
00428 return FirstChild();
00429 }
00430 else
00431 {
00432 assert( previous->parent == this );
00433 return previous->NextSibling();
00434 }
00435 }
00436
00437 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
00438 {
00439 if ( !previous )
00440 {
00441 return FirstChild( val );
00442 }
00443 else
00444 {
00445 assert( previous->parent == this );
00446 return previous->NextSibling( val );
00447 }
00448 }
00449
00450 TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )
00451 {
00452 if ( !previous )
00453 {
00454 return FirstChild( val );
00455 }
00456 else
00457 {
00458 assert( previous->parent == this );
00459 return previous->NextSibling( val );
00460 }
00461 }
00462
00463 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
00464 {
00465 const TiXmlNode* node;
00466 for ( node = next; node; node = node->next )
00467 {
00468 if ( strcmp( node->Value(), _value ) == 0 )
00469 return node;
00470 }
00471 return 0;
00472 }
00473
00474 TiXmlNode* TiXmlNode::NextSibling( const char * _value )
00475 {
00476 TiXmlNode* node;
00477 for ( node = next; node; node = node->next )
00478 {
00479 if ( strcmp( node->Value(), _value ) == 0 )
00480 return node;
00481 }
00482 return 0;
00483 }
00484
00485 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
00486 {
00487 const TiXmlNode* node;
00488 for ( node = prev; node; node = node->prev )
00489 {
00490 if ( strcmp( node->Value(), _value ) == 0 )
00491 return node;
00492 }
00493 return 0;
00494 }
00495
00496 TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )
00497 {
00498 TiXmlNode* node;
00499 for ( node = prev; node; node = node->prev )
00500 {
00501 if ( strcmp( node->Value(), _value ) == 0 )
00502 return node;
00503 }
00504 return 0;
00505 }
00506
00507 void TiXmlElement::RemoveAttribute( const char * name )
00508 {
00509 TIXML_STRING str( name );
00510 TiXmlAttribute* node = attributeSet.Find( str );
00511 if ( node )
00512 {
00513 attributeSet.Remove( node );
00514 delete node;
00515 }
00516 }
00517
00518 const TiXmlElement* TiXmlNode::FirstChildElement() const
00519 {
00520 const TiXmlNode* node;
00521
00522 for ( node = FirstChild();
00523 node;
00524 node = node->NextSibling() )
00525 {
00526 if ( node->ToElement() )
00527 return node->ToElement();
00528 }
00529 return 0;
00530 }
00531
00532 TiXmlElement* TiXmlNode::FirstChildElement()
00533 {
00534 TiXmlNode* node;
00535
00536 for ( node = FirstChild();
00537 node;
00538 node = node->NextSibling() )
00539 {
00540 if ( node->ToElement() )
00541 return node->ToElement();
00542 }
00543 return 0;
00544 }
00545
00546 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
00547 {
00548 const TiXmlNode* node;
00549
00550 for ( node = FirstChild( _value );
00551 node;
00552 node = node->NextSibling( _value ) )
00553 {
00554 if ( node->ToElement() )
00555 return node->ToElement();
00556 }
00557 return 0;
00558 }
00559
00560 TiXmlElement* TiXmlNode::FirstChildElement( const char * _value )
00561 {
00562 TiXmlNode* node;
00563
00564 for ( node = FirstChild( _value );
00565 node;
00566 node = node->NextSibling( _value ) )
00567 {
00568 if ( node->ToElement() )
00569 return node->ToElement();
00570 }
00571 return 0;
00572 }
00573
00574 const TiXmlElement* TiXmlNode::NextSiblingElement() const
00575 {
00576 const TiXmlNode* node;
00577
00578 for ( node = NextSibling();
00579 node;
00580 node = node->NextSibling() )
00581 {
00582 if ( node->ToElement() )
00583 return node->ToElement();
00584 }
00585 return 0;
00586 }
00587
00588 TiXmlElement* TiXmlNode::NextSiblingElement()
00589 {
00590 TiXmlNode* node;
00591
00592 for ( node = NextSibling();
00593 node;
00594 node = node->NextSibling() )
00595 {
00596 if ( node->ToElement() )
00597 return node->ToElement();
00598 }
00599 return 0;
00600 }
00601
00602 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
00603 {
00604 const TiXmlNode* node;
00605
00606 for ( node = NextSibling( _value );
00607 node;
00608 node = node->NextSibling( _value ) )
00609 {
00610 if ( node->ToElement() )
00611 return node->ToElement();
00612 }
00613 return 0;
00614 }
00615
00616 TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )
00617 {
00618 TiXmlNode* node;
00619
00620 for ( node = NextSibling( _value );
00621 node;
00622 node = node->NextSibling( _value ) )
00623 {
00624 if ( node->ToElement() )
00625 return node->ToElement();
00626 }
00627 return 0;
00628 }
00629
00630
00631 const TiXmlDocument* TiXmlNode::GetDocument() const
00632 {
00633 const TiXmlNode* node;
00634
00635 for( node = this; node; node = node->parent )
00636 {
00637 if ( node->ToDocument() )
00638 return node->ToDocument();
00639 }
00640 return 0;
00641 }
00642
00643 TiXmlDocument* TiXmlNode::GetDocument()
00644 {
00645 TiXmlNode* node;
00646
00647 for( node = this; node; node = node->parent )
00648 {
00649 if ( node->ToDocument() )
00650 return node->ToDocument();
00651 }
00652 return 0;
00653 }
00654
00655 TiXmlElement::TiXmlElement (const char * _value)
00656 : TiXmlNode( TiXmlNode::ELEMENT )
00657 {
00658 firstChild = lastChild = 0;
00659 value = _value;
00660 }
00661
00662
00663 #ifdef TIXML_USE_STL
00664 TiXmlElement::TiXmlElement( const std::string& _value )
00665 : TiXmlNode( TiXmlNode::ELEMENT )
00666 {
00667 firstChild = lastChild = 0;
00668 value = _value;
00669 }
00670 #endif
00671
00672
00673 TiXmlElement::TiXmlElement( const TiXmlElement& copy)
00674 : TiXmlNode( TiXmlNode::ELEMENT )
00675 {
00676 firstChild = lastChild = 0;
00677 copy.CopyTo( this );
00678 }
00679
00680
00681 void TiXmlElement::operator=( const TiXmlElement& base )
00682 {
00683 ClearThis();
00684 base.CopyTo( this );
00685 }
00686
00687
00688 TiXmlElement::~TiXmlElement()
00689 {
00690 ClearThis();
00691 }
00692
00693
00694 void TiXmlElement::ClearThis()
00695 {
00696 Clear();
00697 while( attributeSet.First() )
00698 {
00699 TiXmlAttribute* node = attributeSet.First();
00700 attributeSet.Remove( node );
00701 delete node;
00702 }
00703 }
00704
00705
00706 const char * TiXmlElement::Attribute( const char * name ) const
00707 {
00708 TIXML_STRING str( name );
00709 const TiXmlAttribute* node = attributeSet.Find( str );
00710
00711 if ( node )
00712 return node->Value();
00713
00714 return 0;
00715 }
00716
00717
00718 const char * TiXmlElement::Attribute( const char * name, int* i ) const
00719 {
00720 const char * s = Attribute( name );
00721 if ( i )
00722 {
00723 if ( s )
00724 *i = atoi( s );
00725 else
00726 *i = 0;
00727 }
00728 return s;
00729 }
00730
00731
00732 const char * TiXmlElement::Attribute( const char * name, double* d ) const
00733 {
00734 const char * s = Attribute( name );
00735 if ( d )
00736 {
00737 if ( s )
00738 *d = atof( s );
00739 else
00740 *d = 0;
00741 }
00742 return s;
00743 }
00744
00745
00746 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
00747 {
00748 TIXML_STRING str( name );
00749 const TiXmlAttribute* node = attributeSet.Find( str );
00750 if ( !node )
00751 return TIXML_NO_ATTRIBUTE;
00752
00753 return node->QueryIntValue( ival );
00754 }
00755
00756
00757 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
00758 {
00759 TIXML_STRING str( name );
00760 const TiXmlAttribute* node = attributeSet.Find( str );
00761 if ( !node )
00762 return TIXML_NO_ATTRIBUTE;
00763
00764 return node->QueryDoubleValue( dval );
00765 }
00766
00767
00768 void TiXmlElement::SetAttribute( const char * name, int val )
00769 {
00770 char buf[64];
00771 #if defined(TIXML_SNPRINTF)
00772 TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
00773 #else
00774 sprintf( buf, "%d", val );
00775 #endif
00776 SetAttribute( name, buf );
00777 }
00778
00779
00780 #ifdef TIXML_USE_STL
00781 void TiXmlElement::SetAttribute( const std::string& name, int val )
00782 {
00783 std::ostringstream oss;
00784 oss << val;
00785 SetAttribute( name, oss.str() );
00786 }
00787 #endif
00788
00789
00790 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
00791 {
00792 char buf[256];
00793 #if defined(TIXML_SNPRINTF)
00794 TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
00795 #else
00796 sprintf( buf, "%f", val );
00797 #endif
00798 SetAttribute( name, buf );
00799 }
00800
00801
00802 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
00803 {
00804 TIXML_STRING _name( cname );
00805 TIXML_STRING _value( cvalue );
00806
00807 TiXmlAttribute* node = attributeSet.Find( _name );
00808 if ( node )
00809 {
00810 node->SetValue( cvalue );
00811 return;
00812 }
00813
00814 TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
00815 if ( attrib )
00816 {
00817 attributeSet.Add( attrib );
00818 }
00819 else
00820 {
00821 TiXmlDocument* document = GetDocument();
00822 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
00823 }
00824 }
00825
00826
00827 #ifdef TIXML_USE_STL
00828 void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
00829 {
00830 TiXmlAttribute* node = attributeSet.Find( name );
00831 if ( node )
00832 {
00833 node->SetValue( _value );
00834 return;
00835 }
00836
00837 TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
00838 if ( attrib )
00839 {
00840 attributeSet.Add( attrib );
00841 }
00842 else
00843 {
00844 TiXmlDocument* document = GetDocument();
00845 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
00846 }
00847 }
00848 #endif
00849
00850
00851 void TiXmlElement::Print( FILE* cfile, int depth ) const
00852 {
00853 int i;
00854 for ( i=0; i<depth; i++ )
00855 {
00856 fprintf( cfile, " " );
00857 }
00858
00859 fprintf( cfile, "<%s", value.c_str() );
00860
00861 const TiXmlAttribute* attrib;
00862 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
00863 {
00864 fprintf( cfile, " " );
00865 attrib->Print( cfile, depth );
00866 }
00867
00868
00869
00870
00871
00872 TiXmlNode* node;
00873 if ( !firstChild )
00874 {
00875 fprintf( cfile, " />" );
00876 }
00877 else if ( firstChild == lastChild && firstChild->ToText() )
00878 {
00879 fprintf( cfile, ">" );
00880 firstChild->Print( cfile, depth + 1 );
00881 fprintf( cfile, "</%s>", value.c_str() );
00882 }
00883 else
00884 {
00885 fprintf( cfile, ">" );
00886
00887 for ( node = firstChild; node; node=node->NextSibling() )
00888 {
00889 if ( !node->ToText() )
00890 {
00891 fprintf( cfile, "\n" );
00892 }
00893 node->Print( cfile, depth+1 );
00894 }
00895 fprintf( cfile, "\n" );
00896 for( i=0; i<depth; ++i )
00897 fprintf( cfile, " " );
00898 fprintf( cfile, "</%s>", value.c_str() );
00899 }
00900 }
00901
00902 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
00903 {
00904 (*stream) << "<" << value;
00905
00906 const TiXmlAttribute* attrib;
00907 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
00908 {
00909 (*stream) << " ";
00910 attrib->StreamOut( stream );
00911 }
00912
00913
00914
00915 TiXmlNode* node;
00916 if ( firstChild )
00917 {
00918 (*stream) << ">";
00919
00920 for ( node = firstChild; node; node=node->NextSibling() )
00921 {
00922 node->StreamOut( stream );
00923 }
00924 (*stream) << "</" << value << ">";
00925 }
00926 else
00927 {
00928 (*stream) << " />";
00929 }
00930 }
00931
00932
00933 void TiXmlElement::CopyTo( TiXmlElement* target ) const
00934 {
00935
00936 TiXmlNode::CopyTo( target );
00937
00938
00939
00940 const TiXmlAttribute* attribute = 0;
00941 for( attribute = attributeSet.First();
00942 attribute;
00943 attribute = attribute->Next() )
00944 {
00945 target->SetAttribute( attribute->Name(), attribute->Value() );
00946 }
00947
00948 TiXmlNode* node = 0;
00949 for ( node = firstChild; node; node = node->NextSibling() )
00950 {
00951 target->LinkEndChild( node->Clone() );
00952 }
00953 }
00954
00955
00956 TiXmlNode* TiXmlElement::Clone() const
00957 {
00958 TiXmlElement* clone = new TiXmlElement( Value() );
00959 if ( !clone )
00960 return 0;
00961
00962 CopyTo( clone );
00963 return clone;
00964 }
00965
00966
00967 const char* TiXmlElement::GetText() const
00968 {
00969 const TiXmlNode* child = this->FirstChild();
00970 if ( child ) {
00971 const TiXmlText* childText = child->ToText();
00972 if ( childText ) {
00973 return childText->Value();
00974 }
00975 }
00976 return 0;
00977 }
00978
00979
00980 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
00981 {
00982 tabsize = 4;
00983 useMicrosoftBOM = false;
00984 ClearError();
00985 }
00986
00987 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
00988 {
00989 tabsize = 4;
00990 useMicrosoftBOM = false;
00991 value = documentName;
00992 ClearError();
00993 }
00994
00995
00996 #ifdef TIXML_USE_STL
00997 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
00998 {
00999 tabsize = 4;
01000 useMicrosoftBOM = false;
01001 value = documentName;
01002 ClearError();
01003 }
01004 #endif
01005
01006
01007 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
01008 {
01009 copy.CopyTo( this );
01010 }
01011
01012
01013 void TiXmlDocument::operator=( const TiXmlDocument& copy )
01014 {
01015 Clear();
01016 copy.CopyTo( this );
01017 }
01018
01019
01020 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
01021 {
01022
01023 StringToBuffer buf( value );
01024
01025 if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
01026 return true;
01027
01028 return false;
01029 }
01030
01031
01032 bool TiXmlDocument::SaveFile() const
01033 {
01034
01035 StringToBuffer buf( value );
01036
01037 if ( buf.buffer && SaveFile( buf.buffer ) )
01038 return true;
01039
01040 return false;
01041 }
01042
01043 bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
01044 {
01045
01046
01047
01048
01049
01050
01051
01052
01053 value = filename;
01054
01055
01056 FILE* file = fopen( value.c_str (), "rb" );
01057
01058 if ( file )
01059 {
01060 bool result = LoadFile( file, encoding );
01061 fclose( file );
01062 return result;
01063 }
01064 else
01065 {
01066 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
01067 return false;
01068 }
01069 }
01070
01071 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
01072 {
01073 if ( !file )
01074 {
01075 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
01076 return false;
01077 }
01078
01079
01080 Clear();
01081 location.Clear();
01082
01083
01084 long length = 0;
01085 fseek( file, 0, SEEK_END );
01086 length = ftell( file );
01087 fseek( file, 0, SEEK_SET );
01088
01089
01090 if ( length == 0 )
01091 {
01092 SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
01093 return false;
01094 }
01095
01096
01097
01098 TIXML_STRING data;
01099 data.reserve( length );
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 char* buf = new char[ length+1 ];
01123 buf[0] = 0;
01124
01125 if ( fread( buf, length, 1, file ) != 1 ) {
01126 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
01127 return false;
01128 }
01129
01130 const char* lastPos = buf;
01131 const char* p = buf;
01132
01133 buf[length] = 0;
01134 while( *p ) {
01135 assert( p < (buf+length) );
01136 if ( *p == 0xa ) {
01137
01138
01139 data.append( lastPos, (p-lastPos+1) );
01140 ++p;
01141 lastPos = p;
01142 assert( p <= (buf+length) );
01143 }
01144 else if ( *p == 0xd ) {
01145
01146
01147 if ( (p-lastPos) > 0 ) {
01148 data.append( lastPos, p-lastPos );
01149 }
01150 data += (char)0xa;
01151
01152 if ( *(p+1) == 0xa ) {
01153
01154 p += 2;
01155 lastPos = p;
01156 assert( p <= (buf+length) );
01157 }
01158 else {
01159
01160 ++p;
01161 lastPos = p;
01162 assert( p <= (buf+length) );
01163 }
01164 }
01165 else {
01166 ++p;
01167 }
01168 }
01169
01170 if ( p-lastPos ) {
01171 data.append( lastPos, p-lastPos );
01172 }
01173 delete [] buf;
01174 buf = 0;
01175
01176 Parse( data.c_str(), 0, encoding );
01177
01178 if ( Error() )
01179 return false;
01180 else
01181 return true;
01182 }
01183
01184
01185 bool TiXmlDocument::SaveFile( const char * filename ) const
01186 {
01187
01188 FILE* fp = fopen( filename, "w" );
01189 if ( fp )
01190 {
01191 bool result = SaveFile( fp );
01192 fclose( fp );
01193 return result;
01194 }
01195 return false;
01196 }
01197
01198
01199 bool TiXmlDocument::SaveFile( FILE* fp ) const
01200 {
01201 if ( useMicrosoftBOM )
01202 {
01203 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
01204 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
01205 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
01206
01207 fputc( TIXML_UTF_LEAD_0, fp );
01208 fputc( TIXML_UTF_LEAD_1, fp );
01209 fputc( TIXML_UTF_LEAD_2, fp );
01210 }
01211 Print( fp, 0 );
01212 return true;
01213 }
01214
01215
01216 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
01217 {
01218 TiXmlNode::CopyTo( target );
01219
01220 target->error = error;
01221 target->errorDesc = errorDesc.c_str ();
01222
01223 TiXmlNode* node = 0;
01224 for ( node = firstChild; node; node = node->NextSibling() )
01225 {
01226 target->LinkEndChild( node->Clone() );
01227 }
01228 }
01229
01230
01231 TiXmlNode* TiXmlDocument::Clone() const
01232 {
01233 TiXmlDocument* clone = new TiXmlDocument();
01234 if ( !clone )
01235 return 0;
01236
01237 CopyTo( clone );
01238 return clone;
01239 }
01240
01241
01242 void TiXmlDocument::Print( FILE* cfile, int depth ) const
01243 {
01244 const TiXmlNode* node;
01245 for ( node=FirstChild(); node; node=node->NextSibling() )
01246 {
01247 node->Print( cfile, depth );
01248 fprintf( cfile, "\n" );
01249 }
01250 }
01251
01252 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
01253 {
01254 const TiXmlNode* node;
01255 for ( node=FirstChild(); node; node=node->NextSibling() )
01256 {
01257 node->StreamOut( out );
01258
01259
01260
01261
01262 if ( node->ToElement() )
01263 break;
01264 }
01265 }
01266
01267
01268 const TiXmlAttribute* TiXmlAttribute::Next() const
01269 {
01270
01271
01272 if ( next->value.empty() && next->name.empty() )
01273 return 0;
01274 return next;
01275 }
01276
01277 TiXmlAttribute* TiXmlAttribute::Next()
01278 {
01279
01280
01281 if ( next->value.empty() && next->name.empty() )
01282 return 0;
01283 return next;
01284 }
01285
01286 const TiXmlAttribute* TiXmlAttribute::Previous() const
01287 {
01288
01289
01290 if ( prev->value.empty() && prev->name.empty() )
01291 return 0;
01292 return prev;
01293 }
01294
01295 TiXmlAttribute* TiXmlAttribute::Previous()
01296 {
01297
01298
01299 if ( prev->value.empty() && prev->name.empty() )
01300 return 0;
01301 return prev;
01302 }
01303
01304 void TiXmlAttribute::Print( FILE* cfile, int ) const
01305 {
01306 TIXML_STRING n, v;
01307
01308 PutString( name, &n );
01309 PutString( value, &v );
01310
01311 if (value.find ('\"') == TIXML_STRING::npos)
01312 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
01313 else
01314 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
01315 }
01316
01317
01318 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
01319 {
01320 if (value.find( '\"' ) != TIXML_STRING::npos)
01321 {
01322 PutString( name, stream );
01323 (*stream) << "=" << "'";
01324 PutString( value, stream );
01325 (*stream) << "'";
01326 }
01327 else
01328 {
01329 PutString( name, stream );
01330 (*stream) << "=" << "\"";
01331 PutString( value, stream );
01332 (*stream) << "\"";
01333 }
01334 }
01335
01336 int TiXmlAttribute::QueryIntValue( int* ival ) const
01337 {
01338 if ( sscanf( value.c_str(), "%d", ival ) == 1 )
01339 return TIXML_SUCCESS;
01340 return TIXML_WRONG_TYPE;
01341 }
01342
01343 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
01344 {
01345 if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
01346 return TIXML_SUCCESS;
01347 return TIXML_WRONG_TYPE;
01348 }
01349
01350 void TiXmlAttribute::SetIntValue( int _value )
01351 {
01352 char buf [64];
01353 #if defined(TIXML_SNPRINTF)
01354 TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
01355 #else
01356 sprintf (buf, "%d", _value);
01357 #endif
01358 SetValue (buf);
01359 }
01360
01361 void TiXmlAttribute::SetDoubleValue( double _value )
01362 {
01363 char buf [256];
01364 #if defined(TIXML_SNPRINTF)
01365 TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
01366 #else
01367 sprintf (buf, "%lf", _value);
01368 #endif
01369 SetValue (buf);
01370 }
01371
01372 int TiXmlAttribute::IntValue() const
01373 {
01374 return atoi (value.c_str ());
01375 }
01376
01377 double TiXmlAttribute::DoubleValue() const
01378 {
01379 return atof (value.c_str ());
01380 }
01381
01382
01383 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
01384 {
01385 copy.CopyTo( this );
01386 }
01387
01388
01389 void TiXmlComment::operator=( const TiXmlComment& base )
01390 {
01391 Clear();
01392 base.CopyTo( this );
01393 }
01394
01395
01396 void TiXmlComment::Print( FILE* cfile, int depth ) const
01397 {
01398 for ( int i=0; i<depth; i++ )
01399 {
01400 fputs( " ", cfile );
01401 }
01402 fprintf( cfile, "<!--%s-->", value.c_str() );
01403 }
01404
01405 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
01406 {
01407 (*stream) << "<!--";
01408
01409 (*stream) << value;
01410 (*stream) << "-->";
01411 }
01412
01413
01414 void TiXmlComment::CopyTo( TiXmlComment* target ) const
01415 {
01416 TiXmlNode::CopyTo( target );
01417 }
01418
01419
01420 TiXmlNode* TiXmlComment::Clone() const
01421 {
01422 TiXmlComment* clone = new TiXmlComment();
01423
01424 if ( !clone )
01425 return 0;
01426
01427 CopyTo( clone );
01428 return clone;
01429 }
01430
01431
01432 void TiXmlText::Print( FILE* cfile, int depth ) const
01433 {
01434 if ( cdata )
01435 {
01436 int i;
01437 fprintf( cfile, "\n" );
01438 for ( i=0; i<depth; i++ ) {
01439 fprintf( cfile, " " );
01440 }
01441 fprintf( cfile, "<![CDATA[" );
01442 fprintf( cfile, "%s", value.c_str() );
01443 fprintf( cfile, "]]>\n" );
01444 }
01445 else
01446 {
01447 TIXML_STRING buffer;
01448 PutString( value, &buffer );
01449 fprintf( cfile, "%s", buffer.c_str() );
01450 }
01451 }
01452
01453
01454 void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
01455 {
01456 if ( cdata )
01457 {
01458 (*stream) << "<![CDATA[" << value << "]]>";
01459 }
01460 else
01461 {
01462 PutString( value, stream );
01463 }
01464 }
01465
01466
01467 void TiXmlText::CopyTo( TiXmlText* target ) const
01468 {
01469 TiXmlNode::CopyTo( target );
01470 target->cdata = cdata;
01471 }
01472
01473
01474 TiXmlNode* TiXmlText::Clone() const
01475 {
01476 TiXmlText* clone = 0;
01477 clone = new TiXmlText( "" );
01478
01479 if ( !clone )
01480 return 0;
01481
01482 CopyTo( clone );
01483 return clone;
01484 }
01485
01486
01487 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
01488 const char * _encoding,
01489 const char * _standalone )
01490 : TiXmlNode( TiXmlNode::DECLARATION )
01491 {
01492 version = _version;
01493 encoding = _encoding;
01494 standalone = _standalone;
01495 }
01496
01497
01498 #ifdef TIXML_USE_STL
01499 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
01500 const std::string& _encoding,
01501 const std::string& _standalone )
01502 : TiXmlNode( TiXmlNode::DECLARATION )
01503 {
01504 version = _version;
01505 encoding = _encoding;
01506 standalone = _standalone;
01507 }
01508 #endif
01509
01510
01511 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
01512 : TiXmlNode( TiXmlNode::DECLARATION )
01513 {
01514 copy.CopyTo( this );
01515 }
01516
01517
01518 void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
01519 {
01520 Clear();
01521 copy.CopyTo( this );
01522 }
01523
01524
01525 void TiXmlDeclaration::Print( FILE* cfile, int ) const
01526 {
01527 fprintf (cfile, "<?xml ");
01528
01529 if ( !version.empty() )
01530 fprintf (cfile, "version=\"%s\" ", version.c_str ());
01531 if ( !encoding.empty() )
01532 fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
01533 if ( !standalone.empty() )
01534 fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
01535 fprintf (cfile, "?>");
01536 }
01537
01538 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
01539 {
01540 (*stream) << "<?xml ";
01541
01542 if ( !version.empty() )
01543 {
01544 (*stream) << "version=\"";
01545 PutString( version, stream );
01546 (*stream) << "\" ";
01547 }
01548 if ( !encoding.empty() )
01549 {
01550 (*stream) << "encoding=\"";
01551 PutString( encoding, stream );
01552 (*stream ) << "\" ";
01553 }
01554 if ( !standalone.empty() )
01555 {
01556 (*stream) << "standalone=\"";
01557 PutString( standalone, stream );
01558 (*stream) << "\" ";
01559 }
01560 (*stream) << "?>";
01561 }
01562
01563
01564 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
01565 {
01566 TiXmlNode::CopyTo( target );
01567
01568 target->version = version;
01569 target->encoding = encoding;
01570 target->standalone = standalone;
01571 }
01572
01573
01574 TiXmlNode* TiXmlDeclaration::Clone() const
01575 {
01576 TiXmlDeclaration* clone = new TiXmlDeclaration();
01577
01578 if ( !clone )
01579 return 0;
01580
01581 CopyTo( clone );
01582 return clone;
01583 }
01584
01585
01586 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
01587 {
01588 for ( int i=0; i<depth; i++ )
01589 fprintf( cfile, " " );
01590 fprintf( cfile, "<%s>", value.c_str() );
01591 }
01592
01593
01594 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
01595 {
01596 (*stream) << "<" << value << ">";
01597 }
01598
01599
01600 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
01601 {
01602 TiXmlNode::CopyTo( target );
01603 }
01604
01605
01606 TiXmlNode* TiXmlUnknown::Clone() const
01607 {
01608 TiXmlUnknown* clone = new TiXmlUnknown();
01609
01610 if ( !clone )
01611 return 0;
01612
01613 CopyTo( clone );
01614 return clone;
01615 }
01616
01617
01618 TiXmlAttributeSet::TiXmlAttributeSet()
01619 {
01620 sentinel.next = &sentinel;
01621 sentinel.prev = &sentinel;
01622 }
01623
01624
01625 TiXmlAttributeSet::~TiXmlAttributeSet()
01626 {
01627 assert( sentinel.next == &sentinel );
01628 assert( sentinel.prev == &sentinel );
01629 }
01630
01631
01632 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
01633 {
01634 assert( !Find( TIXML_STRING( addMe->Name() ) ) );
01635
01636 addMe->next = &sentinel;
01637 addMe->prev = sentinel.prev;
01638
01639 sentinel.prev->next = addMe;
01640 sentinel.prev = addMe;
01641 }
01642
01643 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
01644 {
01645 TiXmlAttribute* node;
01646
01647 for( node = sentinel.next; node != &sentinel; node = node->next )
01648 {
01649 if ( node == removeMe )
01650 {
01651 node->prev->next = node->next;
01652 node->next->prev = node->prev;
01653 node->next = 0;
01654 node->prev = 0;
01655 return;
01656 }
01657 }
01658 assert( 0 );
01659 }
01660
01661 const TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const
01662 {
01663 const TiXmlAttribute* node;
01664
01665 for( node = sentinel.next; node != &sentinel; node = node->next )
01666 {
01667 if ( node->name == name )
01668 return node;
01669 }
01670 return 0;
01671 }
01672
01673 TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name )
01674 {
01675 TiXmlAttribute* node;
01676
01677 for( node = sentinel.next; node != &sentinel; node = node->next )
01678 {
01679 if ( node->name == name )
01680 return node;
01681 }
01682 return 0;
01683 }
01684
01685 #ifdef TIXML_USE_STL
01686 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
01687 {
01688 TIXML_STRING tag;
01689 tag.reserve( 8 * 1000 );
01690 base.StreamIn( &in, &tag );
01691
01692 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
01693 return in;
01694 }
01695 #endif
01696
01697
01698 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
01699 {
01700 base.StreamOut (& out);
01701 return out;
01702 }
01703
01704
01705 #ifdef TIXML_USE_STL
01706 std::string & operator<< (std::string& out, const TiXmlNode& base )
01707 {
01708 std::ostringstream os_stream( std::ostringstream::out );
01709 base.StreamOut( &os_stream );
01710
01711 out.append( os_stream.str() );
01712 return out;
01713 }
01714 #endif
01715
01716
01717 TiXmlHandle TiXmlHandle::FirstChild() const
01718 {
01719 if ( node )
01720 {
01721 TiXmlNode* child = node->FirstChild();
01722 if ( child )
01723 return TiXmlHandle( child );
01724 }
01725 return TiXmlHandle( 0 );
01726 }
01727
01728
01729 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
01730 {
01731 if ( node )
01732 {
01733 TiXmlNode* child = node->FirstChild( value );
01734 if ( child )
01735 return TiXmlHandle( child );
01736 }
01737 return TiXmlHandle( 0 );
01738 }
01739
01740
01741 TiXmlHandle TiXmlHandle::FirstChildElement() const
01742 {
01743 if ( node )
01744 {
01745 TiXmlElement* child = node->FirstChildElement();
01746 if ( child )
01747 return TiXmlHandle( child );
01748 }
01749 return TiXmlHandle( 0 );
01750 }
01751
01752
01753 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
01754 {
01755 if ( node )
01756 {
01757 TiXmlElement* child = node->FirstChildElement( value );
01758 if ( child )
01759 return TiXmlHandle( child );
01760 }
01761 return TiXmlHandle( 0 );
01762 }
01763
01764
01765 TiXmlHandle TiXmlHandle::Child( int count ) const
01766 {
01767 if ( node )
01768 {
01769 int i;
01770 TiXmlNode* child = node->FirstChild();
01771 for ( i=0;
01772 child && i<count;
01773 child = child->NextSibling(), ++i )
01774 {
01775
01776 }
01777 if ( child )
01778 return TiXmlHandle( child );
01779 }
01780 return TiXmlHandle( 0 );
01781 }
01782
01783
01784 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
01785 {
01786 if ( node )
01787 {
01788 int i;
01789 TiXmlNode* child = node->FirstChild( value );
01790 for ( i=0;
01791 child && i<count;
01792 child = child->NextSibling( value ), ++i )
01793 {
01794
01795 }
01796 if ( child )
01797 return TiXmlHandle( child );
01798 }
01799 return TiXmlHandle( 0 );
01800 }
01801
01802
01803 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
01804 {
01805 if ( node )
01806 {
01807 int i;
01808 TiXmlElement* child = node->FirstChildElement();
01809 for ( i=0;
01810 child && i<count;
01811 child = child->NextSiblingElement(), ++i )
01812 {
01813
01814 }
01815 if ( child )
01816 return TiXmlHandle( child );
01817 }
01818 return TiXmlHandle( 0 );
01819 }
01820
01821
01822 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
01823 {
01824 if ( node )
01825 {
01826 int i;
01827 TiXmlElement* child = node->FirstChildElement( value );
01828 for ( i=0;
01829 child && i<count;
01830 child = child->NextSiblingElement( value ), ++i )
01831 {
01832
01833 }
01834 if ( child )
01835 return TiXmlHandle( child );
01836 }
01837 return TiXmlHandle( 0 );
01838 }
01839
01840 }}