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