Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

D:/Programming/GUI Editor (Source)/tinyxml.cpp

00001 /* 00002 www.sourceforge.net/projects/tinyxml 00003 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to anyone to use this software for any 00010 purpose, including commercial applications, and to alter it and 00011 redistribute it freely, subject to the following restrictions: 00012 00013 1. The origin of this software must not be misrepresented; you must 00014 not claim that you wrote the original software. If you use this 00015 software in a product, an acknowledgment in the product documentation 00016 would be appreciated but is not required. 00017 00018 2. Altered source versions must be plainly marked as such, and 00019 must not be misrepresented as being the original software. 00020 00021 3. This notice may not be removed or altered from any source 00022 distribution. 00023 */ 00024 #include "stdafx.h" 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 // Hexadecimal character reference. 00056 // Pass through unchanged. 00057 // &#xA9; -- copyright symbol, for example. 00058 // 00059 // The -1 is a bug fix from Rob Laveaux. It keeps 00060 // an overflow from happening if there is no ';'. 00061 // There are actually 2 ways to exit this loop - 00062 // while fails (error case) and break (semicolon found). 00063 // However, there is no mechanism (currently) for 00064 // this function to return an error. 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 // Easy pass at non-alpha/numeric/symbol 00101 // Below 32 is symbolic. 00102 char buf[ 32 ]; 00103 sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); 00104 outString->Append( buf, strlen( buf ) ); 00105 ++i; 00106 } 00107 else 00108 { 00109 //char realc = (char) c; 00110 //outString->Append( &realc, 1 ); 00111 *outString += (char) c; // somewhat more efficient function call. 00112 ++i; 00113 } 00114 } 00115 } 00116 00117 00118 // <-- Strange class for a bug fix. Search for STL_STRING_BUG 00119 TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str ) 00120 { 00121 buffer = new char[ str.length()+1 ]; 00122 if ( buffer ) 00123 { 00124 strcpy( buffer, str.c_str() ); 00125 } 00126 } 00127 00128 00129 TiXmlBase::StringToBuffer::~StringToBuffer() 00130 { 00131 delete [] buffer; 00132 } 00133 // End strange bug fix. --> 00134 00135 00136 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() 00137 { 00138 parent = 0; 00139 type = _type; 00140 firstChild = 0; 00141 lastChild = 0; 00142 prev = 0; 00143 next = 0; 00144 } 00145 00146 00147 TiXmlNode::~TiXmlNode() 00148 { 00149 TiXmlNode* node = firstChild; 00150 TiXmlNode* temp = 0; 00151 00152 while ( node ) 00153 { 00154 temp = node; 00155 node = node->next; 00156 delete temp; 00157 } 00158 } 00159 00160 00161 void TiXmlNode::CopyTo( TiXmlNode* target ) const 00162 { 00163 target->SetValue (value.c_str() ); 00164 target->userData = userData; 00165 } 00166 00167 00168 void TiXmlNode::Clear() 00169 { 00170 TiXmlNode* node = firstChild; 00171 TiXmlNode* temp = 0; 00172 00173 while ( node ) 00174 { 00175 temp = node; 00176 node = node->next; 00177 delete temp; 00178 } 00179 00180 firstChild = 0; 00181 lastChild = 0; 00182 } 00183 00184 00185 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) 00186 { 00187 node->parent = this; 00188 00189 node->prev = lastChild; 00190 node->next = 0; 00191 00192 if ( lastChild ) 00193 lastChild->next = node; 00194 else 00195 firstChild = node; // it was an empty list. 00196 00197 lastChild = node; 00198 return node; 00199 } 00200 00201 00202 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) 00203 { 00204 TiXmlNode* node = addThis.Clone(); 00205 if ( !node ) 00206 return 0; 00207 00208 return LinkEndChild( node ); 00209 } 00210 00211 00212 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) 00213 { 00214 if ( !beforeThis || beforeThis->parent != this ) 00215 return 0; 00216 00217 TiXmlNode* node = addThis.Clone(); 00218 if ( !node ) 00219 return 0; 00220 node->parent = this; 00221 00222 node->next = beforeThis; 00223 node->prev = beforeThis->prev; 00224 if ( beforeThis->prev ) 00225 { 00226 beforeThis->prev->next = node; 00227 } 00228 else 00229 { 00230 assert( firstChild == beforeThis ); 00231 firstChild = node; 00232 } 00233 beforeThis->prev = node; 00234 return node; 00235 } 00236 00237 00238 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) 00239 { 00240 if ( !afterThis || afterThis->parent != this ) 00241 return 0; 00242 00243 TiXmlNode* node = addThis.Clone(); 00244 if ( !node ) 00245 return 0; 00246 node->parent = this; 00247 00248 node->prev = afterThis; 00249 node->next = afterThis->next; 00250 if ( afterThis->next ) 00251 { 00252 afterThis->next->prev = node; 00253 } 00254 else 00255 { 00256 assert( lastChild == afterThis ); 00257 lastChild = node; 00258 } 00259 afterThis->next = node; 00260 return node; 00261 } 00262 00263 00264 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) 00265 { 00266 if ( replaceThis->parent != this ) 00267 return 0; 00268 00269 TiXmlNode* node = withThis.Clone(); 00270 if ( !node ) 00271 return 0; 00272 00273 node->next = replaceThis->next; 00274 node->prev = replaceThis->prev; 00275 00276 if ( replaceThis->next ) 00277 replaceThis->next->prev = node; 00278 else 00279 lastChild = node; 00280 00281 if ( replaceThis->prev ) 00282 replaceThis->prev->next = node; 00283 else 00284 firstChild = node; 00285 00286 delete replaceThis; 00287 node->parent = this; 00288 return node; 00289 } 00290 00291 00292 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) 00293 { 00294 if ( removeThis->parent != this ) 00295 { 00296 assert( 0 ); 00297 return false; 00298 } 00299 00300 if ( removeThis->next ) 00301 removeThis->next->prev = removeThis->prev; 00302 else 00303 lastChild = removeThis->prev; 00304 00305 if ( removeThis->prev ) 00306 removeThis->prev->next = removeThis->next; 00307 else 00308 firstChild = removeThis->next; 00309 00310 delete removeThis; 00311 return true; 00312 } 00313 00314 TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const 00315 { 00316 TiXmlNode* node; 00317 for ( node = firstChild; node; node = node->next ) 00318 { 00319 if ( node->SValue() == TIXML_STRING( _value )) 00320 return node; 00321 } 00322 return 0; 00323 } 00324 00325 TiXmlNode* TiXmlNode::LastChild( const char * _value ) const 00326 { 00327 TiXmlNode* node; 00328 for ( node = lastChild; node; node = node->prev ) 00329 { 00330 if ( node->SValue() == TIXML_STRING (_value)) 00331 return node; 00332 } 00333 return 0; 00334 } 00335 00336 TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const 00337 { 00338 if ( !previous ) 00339 { 00340 return FirstChild(); 00341 } 00342 else 00343 { 00344 assert( previous->parent == this ); 00345 return previous->NextSibling(); 00346 } 00347 } 00348 00349 TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const 00350 { 00351 if ( !previous ) 00352 { 00353 return FirstChild( val ); 00354 } 00355 else 00356 { 00357 assert( previous->parent == this ); 00358 return previous->NextSibling( val ); 00359 } 00360 } 00361 00362 TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 00363 { 00364 TiXmlNode* node; 00365 for ( node = next; node; node = node->next ) 00366 { 00367 if ( node->SValue() == TIXML_STRING (_value)) 00368 return node; 00369 } 00370 return 0; 00371 } 00372 00373 00374 TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const 00375 { 00376 TiXmlNode* node; 00377 for ( node = prev; node; node = node->prev ) 00378 { 00379 if ( node->SValue() == TIXML_STRING (_value)) 00380 return node; 00381 } 00382 return 0; 00383 } 00384 00385 void TiXmlElement::RemoveAttribute( const char * name ) 00386 { 00387 TiXmlAttribute* node = attributeSet.Find( name ); 00388 if ( node ) 00389 { 00390 attributeSet.Remove( node ); 00391 delete node; 00392 } 00393 } 00394 00395 TiXmlElement* TiXmlNode::FirstChildElement() const 00396 { 00397 TiXmlNode* node; 00398 00399 for ( node = FirstChild(); 00400 node; 00401 node = node->NextSibling() ) 00402 { 00403 if ( node->ToElement() ) 00404 return node->ToElement(); 00405 } 00406 return 0; 00407 } 00408 00409 TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const 00410 { 00411 TiXmlNode* node; 00412 00413 for ( node = FirstChild( _value ); 00414 node; 00415 node = node->NextSibling( _value ) ) 00416 { 00417 if ( node->ToElement() ) 00418 return node->ToElement(); 00419 } 00420 return 0; 00421 } 00422 00423 00424 TiXmlElement* TiXmlNode::NextSiblingElement() const 00425 { 00426 TiXmlNode* node; 00427 00428 for ( node = NextSibling(); 00429 node; 00430 node = node->NextSibling() ) 00431 { 00432 if ( node->ToElement() ) 00433 return node->ToElement(); 00434 } 00435 return 0; 00436 } 00437 00438 TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const 00439 { 00440 TiXmlNode* node; 00441 00442 for ( node = NextSibling( _value ); 00443 node; 00444 node = node->NextSibling( _value ) ) 00445 { 00446 if ( node->ToElement() ) 00447 return node->ToElement(); 00448 } 00449 return 0; 00450 } 00451 00452 00453 00454 TiXmlDocument* TiXmlNode::GetDocument() const 00455 { 00456 const TiXmlNode* node; 00457 00458 for( node = this; node; node = node->parent ) 00459 { 00460 if ( node->ToDocument() ) 00461 return node->ToDocument(); 00462 } 00463 return 0; 00464 } 00465 00466 00467 TiXmlElement::TiXmlElement (const char * _value) 00468 : TiXmlNode( TiXmlNode::ELEMENT ) 00469 { 00470 firstChild = lastChild = 0; 00471 value = _value; 00472 } 00473 00474 00475 #ifdef TIXML_USE_STL 00476 TiXmlElement::TiXmlElement( const std::string& _value ) 00477 : TiXmlNode( TiXmlNode::ELEMENT ) 00478 { 00479 firstChild = lastChild = 0; 00480 value = _value; 00481 } 00482 #endif 00483 00484 00485 TiXmlElement::TiXmlElement( const TiXmlElement& copy) 00486 : TiXmlNode( TiXmlNode::ELEMENT ) 00487 { 00488 firstChild = lastChild = 0; 00489 copy.CopyTo( this ); 00490 } 00491 00492 00493 void TiXmlElement::operator=( const TiXmlElement& base ) 00494 { 00495 ClearThis(); 00496 base.CopyTo( this ); 00497 } 00498 00499 00500 TiXmlElement::~TiXmlElement() 00501 { 00502 ClearThis(); 00503 } 00504 00505 00506 void TiXmlElement::ClearThis() 00507 { 00508 Clear(); 00509 while( attributeSet.First() ) 00510 { 00511 TiXmlAttribute* node = attributeSet.First(); 00512 attributeSet.Remove( node ); 00513 delete node; 00514 } 00515 } 00516 00517 00518 const char * TiXmlElement::Attribute( const char * name ) const 00519 { 00520 TiXmlAttribute* node = attributeSet.Find( name ); 00521 00522 if ( node ) 00523 return node->pcValue(); 00524 00525 return 0; 00526 } 00527 00528 00529 const char * TiXmlElement::Attribute( const char * name, int* i ) const 00530 { 00531 const char * s = Attribute( name ); 00532 if ( i ) 00533 { 00534 if ( s ) 00535 *i = atoi( s ); 00536 else 00537 *i = 0; 00538 } 00539 return s; 00540 } 00541 00542 00543 const char * TiXmlElement::Attribute( const char * name, double* d ) const 00544 { 00545 const char * s = Attribute( name ); 00546 if ( d ) 00547 { 00548 if ( s ) 00549 *d = atof( s ); 00550 else 00551 *d = 0; 00552 } 00553 return s; 00554 } 00555 00556 00557 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const 00558 { 00559 TiXmlAttribute* node = attributeSet.Find( name ); 00560 if ( !node ) 00561 return TIXML_NO_ATTRIBUTE; 00562 00563 return node->QueryIntValue( ival ); 00564 } 00565 00566 00567 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const 00568 { 00569 TiXmlAttribute* node = attributeSet.Find( name ); 00570 if ( !node ) 00571 return TIXML_NO_ATTRIBUTE; 00572 00573 return node->QueryDoubleValue( dval ); 00574 } 00575 00576 00577 void TiXmlElement::SetAttribute( const char * name, int val ) 00578 { 00579 char buf[64]; 00580 sprintf( buf, "%d", val ); 00581 SetAttribute( name, buf ); 00582 } 00583 00584 00585 void TiXmlElement::SetDoubleAttribute( const char * name, double val ) 00586 { 00587 char buf[128]; 00588 sprintf( buf, "%f", val ); 00589 SetAttribute( name, buf ); 00590 } 00591 00592 00593 void TiXmlElement::SetAttribute( const char * name, const char * _value ) 00594 { 00595 TiXmlAttribute* node = attributeSet.Find( name ); 00596 if ( node ) 00597 { 00598 node->SetValue( _value ); 00599 return; 00600 } 00601 00602 TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); 00603 if ( attrib ) 00604 { 00605 attributeSet.Add( attrib ); 00606 } 00607 else 00608 { 00609 TiXmlDocument* document = GetDocument(); 00610 if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); 00611 } 00612 } 00613 00614 void TiXmlElement::Print( FILE* cfile, int depth ) const 00615 { 00616 int i; 00617 for ( i=0; i<depth; i++ ) 00618 { 00619 fprintf( cfile, " " ); 00620 } 00621 00622 fprintf( cfile, "<%s", value.c_str() ); 00623 00624 TiXmlAttribute* attrib; 00625 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) 00626 { 00627 fprintf( cfile, " " ); 00628 attrib->Print( cfile, depth ); 00629 } 00630 00631 // There are 3 different formatting approaches: 00632 // 1) An element without children is printed as a <foo /> node 00633 // 2) An element with only a text child is printed as <foo> text </foo> 00634 // 3) An element with children is printed on multiple lines. 00635 TiXmlNode* node; 00636 if ( !firstChild ) 00637 { 00638 fprintf( cfile, " />" ); 00639 } 00640 else if ( firstChild == lastChild && firstChild->ToText() ) 00641 { 00642 fprintf( cfile, ">" ); 00643 firstChild->Print( cfile, depth + 1 ); 00644 fprintf( cfile, "</%s>", value.c_str() ); 00645 } 00646 else 00647 { 00648 fprintf( cfile, ">" ); 00649 00650 for ( node = firstChild; node; node=node->NextSibling() ) 00651 { 00652 if ( !node->ToText() ) 00653 { 00654 fprintf( cfile, "\n" ); 00655 } 00656 node->Print( cfile, depth+1 ); 00657 } 00658 fprintf( cfile, "\n" ); 00659 for( i=0; i<depth; ++i ) 00660 fprintf( cfile, " " ); 00661 fprintf( cfile, "</%s>", value.c_str() ); 00662 } 00663 } 00664 00665 void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const 00666 { 00667 (*stream) << "<" << value; 00668 00669 TiXmlAttribute* attrib; 00670 for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) 00671 { 00672 (*stream) << " "; 00673 attrib->StreamOut( stream ); 00674 } 00675 00676 // If this node has children, give it a closing tag. Else 00677 // make it an empty tag. 00678 TiXmlNode* node; 00679 if ( firstChild ) 00680 { 00681 (*stream) << ">"; 00682 00683 for ( node = firstChild; node; node=node->NextSibling() ) 00684 { 00685 node->StreamOut( stream ); 00686 } 00687 (*stream) << "</" << value << ">"; 00688 } 00689 else 00690 { 00691 (*stream) << " />"; 00692 } 00693 } 00694 00695 00696 void TiXmlElement::CopyTo( TiXmlElement* target ) const 00697 { 00698 // superclass: 00699 TiXmlNode::CopyTo( target ); 00700 00701 // Element class: 00702 // Clone the attributes, then clone the children. 00703 TiXmlAttribute* attribute = 0; 00704 for( attribute = attributeSet.First(); 00705 attribute; 00706 attribute = attribute->Next() ) 00707 { 00708 target->SetAttribute( attribute->strName(), attribute->pcValue() ); 00709 } 00710 00711 TiXmlNode* node = 0; 00712 for ( node = firstChild; node; node = node->NextSibling() ) 00713 { 00714 target->LinkEndChild( node->Clone() ); 00715 } 00716 } 00717 00718 00719 TiXmlNode* TiXmlElement::Clone() const 00720 { 00721 TiXmlElement* clone = new TiXmlElement( pcValue() ); 00722 if ( !clone ) 00723 return 0; 00724 00725 CopyTo( clone ); 00726 return clone; 00727 } 00728 00729 00730 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) 00731 { 00732 tabsize = 4; 00733 ClearError(); 00734 } 00735 00736 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) 00737 { 00738 tabsize = 4; 00739 value = documentName; 00740 ClearError(); 00741 } 00742 00743 00744 #ifdef TIXML_USE_STL 00745 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) 00746 { 00747 tabsize = 4; 00748 value = documentName; 00749 ClearError(); 00750 } 00751 #endif 00752 00753 00754 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) 00755 { 00756 copy.CopyTo( this ); 00757 } 00758 00759 00760 void TiXmlDocument::operator=( const TiXmlDocument& copy ) 00761 { 00762 Clear(); 00763 copy.CopyTo( this ); 00764 } 00765 00766 00767 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) 00768 { 00769 // See STL_STRING_BUG below. 00770 StringToBuffer buf( value ); 00771 00772 if ( buf.buffer && LoadFile( buf.buffer, encoding ) ) 00773 return true; 00774 00775 return false; 00776 } 00777 00778 00779 bool TiXmlDocument::SaveFile() const 00780 { 00781 // See STL_STRING_BUG below. 00782 StringToBuffer buf( value ); 00783 00784 if ( buf.buffer && SaveFile( buf.buffer ) ) 00785 return true; 00786 00787 return false; 00788 } 00789 00790 bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding ) 00791 { 00792 // Delete the existing data: 00793 Clear(); 00794 location.Clear(); 00795 00796 // There was a really terrifying little bug here. The code: 00797 // value = filename 00798 // in the STL case, cause the assignment method of the std::string to 00799 // be called. What is strange, is that the std::string had the same 00800 // address as it's c_str() method, and so bad things happen. Looks 00801 // like a bug in the Microsoft STL implementation. 00802 // See STL_STRING_BUG above. 00803 // Fixed with the StringToBuffer class. 00804 value = filename; 00805 00806 FILE* file = fopen( value.c_str (), "r" ); 00807 00808 if ( file ) 00809 { 00810 // Get the file size, so we can pre-allocate the string. HUGE speed impact. 00811 long length = 0; 00812 fseek( file, 0, SEEK_END ); 00813 length = ftell( file ); 00814 fseek( file, 0, SEEK_SET ); 00815 00816 // Strange case, but good to handle up front. 00817 if ( length == 0 ) 00818 { 00819 fclose( file ); 00820 return false; 00821 } 00822 00823 // If we have a file, assume it is all one big XML file, and read it in. 00824 // The document parser may decide the document ends sooner than the entire file, however. 00825 TIXML_STRING data; 00826 data.reserve( length ); 00827 00828 const int BUF_SIZE = 2048; 00829 char buf[BUF_SIZE]; 00830 00831 while( fgets( buf, BUF_SIZE, file ) ) 00832 { 00833 data += buf; 00834 } 00835 fclose( file ); 00836 00837 Parse( data.c_str(), 0, encoding ); 00838 00839 if ( Error() ) 00840 return false; 00841 else 00842 return true; 00843 } 00844 SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); 00845 return false; 00846 } 00847 00848 bool TiXmlDocument::SaveFile( const char * filename ) const 00849 { 00850 // The old c stuff lives on... 00851 FILE* fp = fopen( filename, "w" ); 00852 if ( fp ) 00853 { 00854 Print( fp, 0 ); 00855 fclose( fp ); 00856 return true; 00857 } 00858 return false; 00859 } 00860 00861 00862 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const 00863 { 00864 TiXmlNode::CopyTo( target ); 00865 00866 target->error = error; 00867 target->errorDesc = errorDesc.c_str (); 00868 00869 TiXmlNode* node = 0; 00870 for ( node = firstChild; node; node = node->NextSibling() ) 00871 { 00872 target->LinkEndChild( node->Clone() ); 00873 } 00874 } 00875 00876 00877 TiXmlNode* TiXmlDocument::Clone() const 00878 { 00879 TiXmlDocument* clone = new TiXmlDocument(); 00880 if ( !clone ) 00881 return 0; 00882 00883 CopyTo( clone ); 00884 return clone; 00885 } 00886 00887 00888 void TiXmlDocument::Print( FILE* cfile, int depth ) const 00889 { 00890 TiXmlNode* node; 00891 for ( node=FirstChild(); node; node=node->NextSibling() ) 00892 { 00893 node->Print( cfile, depth ); 00894 fprintf( cfile, "\n" ); 00895 } 00896 } 00897 00898 void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const 00899 { 00900 TiXmlNode* node; 00901 for ( node=FirstChild(); node; node=node->NextSibling() ) 00902 { 00903 node->StreamOut( out ); 00904 00905 // Special rule for streams: stop after the root element. 00906 // The stream in code will only read one element, so don't 00907 // write more than one. 00908 if ( node->ToElement() ) 00909 break; 00910 } 00911 } 00912 00913 00914 TiXmlAttribute* TiXmlAttribute::Next() const 00915 { 00916 // We are using knowledge of the sentinel. The sentinel 00917 // have a value or name. 00918 if ( next->value.empty() && next->name.empty() ) 00919 return 0; 00920 return next; 00921 } 00922 00923 00924 TiXmlAttribute* TiXmlAttribute::Previous() const 00925 { 00926 // We are using knowledge of the sentinel. The sentinel 00927 // have a value or name. 00928 if ( prev->value.empty() && prev->name.empty() ) 00929 return 0; 00930 return prev; 00931 } 00932 00933 00934 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const 00935 { 00936 TIXML_STRING n, v; 00937 00938 PutString( name, &n ); 00939 PutString( value, &v ); 00940 00941 if (value.find ('\"') == TIXML_STRING::npos) 00942 fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); 00943 else 00944 fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); 00945 } 00946 00947 00948 void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const 00949 { 00950 if (value.find( '\"' ) != TIXML_STRING::npos) 00951 { 00952 PutString( name, stream ); 00953 (*stream) << "=" << "'"; 00954 PutString( value, stream ); 00955 (*stream) << "'"; 00956 } 00957 else 00958 { 00959 PutString( name, stream ); 00960 (*stream) << "=" << "\""; 00961 PutString( value, stream ); 00962 (*stream) << "\""; 00963 } 00964 } 00965 00966 int TiXmlAttribute::QueryIntValue( int* ival ) const 00967 { 00968 if ( sscanf( value.c_str(), "%d", ival ) == 1 ) 00969 return TIXML_SUCCESS; 00970 return TIXML_WRONG_TYPE; 00971 } 00972 00973 int TiXmlAttribute::QueryDoubleValue( double* dval ) const 00974 { 00975 if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) 00976 return TIXML_SUCCESS; 00977 return TIXML_WRONG_TYPE; 00978 } 00979 00980 void TiXmlAttribute::SetIntValue( int _value ) 00981 { 00982 char buf [64]; 00983 sprintf (buf, "%d", _value); 00984 SetValue (buf); 00985 } 00986 00987 void TiXmlAttribute::SetDoubleValue( double _value ) 00988 { 00989 char buf [64]; 00990 sprintf (buf, "%lf", _value); 00991 SetValue (buf); 00992 } 00993 00994 const int TiXmlAttribute::IntValue() const 00995 { 00996 return atoi (value.c_str ()); 00997 } 00998 00999 const double TiXmlAttribute::DoubleValue() const 01000 { 01001 return atof (value.c_str ()); 01002 } 01003 01004 01005 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) 01006 { 01007 copy.CopyTo( this ); 01008 } 01009 01010 01011 void TiXmlComment::operator=( const TiXmlComment& base ) 01012 { 01013 Clear(); 01014 base.CopyTo( this ); 01015 } 01016 01017 01018 void TiXmlComment::Print( FILE* cfile, int depth ) const 01019 { 01020 for ( int i=0; i<depth; i++ ) 01021 { 01022 fputs( " ", cfile ); 01023 } 01024 fprintf( cfile, "<!--%s-->", value.c_str() ); 01025 } 01026 01027 void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const 01028 { 01029 (*stream) << "<!--"; 01030 //PutString( value, stream ); 01031 (*stream) << value; 01032 (*stream) << "-->"; 01033 } 01034 01035 01036 void TiXmlComment::CopyTo( TiXmlComment* target ) const 01037 { 01038 TiXmlNode::CopyTo( target ); 01039 } 01040 01041 01042 TiXmlNode* TiXmlComment::Clone() const 01043 { 01044 TiXmlComment* clone = new TiXmlComment(); 01045 01046 if ( !clone ) 01047 return 0; 01048 01049 CopyTo( clone ); 01050 return clone; 01051 } 01052 01053 01054 void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const 01055 { 01056 TIXML_STRING buffer; 01057 PutString( value, &buffer ); 01058 fprintf( cfile, "%s", buffer.c_str() ); 01059 } 01060 01061 01062 void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const 01063 { 01064 PutString( value, stream ); 01065 } 01066 01067 01068 void TiXmlText::CopyTo( TiXmlText* target ) const 01069 { 01070 TiXmlNode::CopyTo( target ); 01071 } 01072 01073 01074 TiXmlNode* TiXmlText::Clone() const 01075 { 01076 TiXmlText* clone = 0; 01077 clone = new TiXmlText( "" ); 01078 01079 if ( !clone ) 01080 return 0; 01081 01082 CopyTo( clone ); 01083 return clone; 01084 } 01085 01086 01087 TiXmlDeclaration::TiXmlDeclaration( const char * _version, 01088 const char * _encoding, 01089 const char * _standalone ) 01090 : TiXmlNode( TiXmlNode::DECLARATION ) 01091 { 01092 version = _version; 01093 encoding = _encoding; 01094 standalone = _standalone; 01095 } 01096 01097 01098 #ifdef TIXML_USE_STL 01099 TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, 01100 const std::string& _encoding, 01101 const std::string& _standalone ) 01102 : TiXmlNode( TiXmlNode::DECLARATION ) 01103 { 01104 version = _version; 01105 encoding = _encoding; 01106 standalone = _standalone; 01107 } 01108 #endif 01109 01110 01111 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) 01112 : TiXmlNode( TiXmlNode::DECLARATION ) 01113 { 01114 copy.CopyTo( this ); 01115 } 01116 01117 01118 void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) 01119 { 01120 Clear(); 01121 copy.CopyTo( this ); 01122 } 01123 01124 01125 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const 01126 { 01127 fprintf (cfile, "<?xml "); 01128 01129 if ( !version.empty() ) 01130 fprintf (cfile, "version=\"%s\" ", version.c_str ()); 01131 if ( !encoding.empty() ) 01132 fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); 01133 if ( !standalone.empty() ) 01134 fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); 01135 fprintf (cfile, "?>"); 01136 } 01137 01138 void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const 01139 { 01140 (*stream) << "<?xml "; 01141 01142 if ( !version.empty() ) 01143 { 01144 (*stream) << "version=\""; 01145 PutString( version, stream ); 01146 (*stream) << "\" "; 01147 } 01148 if ( !encoding.empty() ) 01149 { 01150 (*stream) << "encoding=\""; 01151 PutString( encoding, stream ); 01152 (*stream ) << "\" "; 01153 } 01154 if ( !standalone.empty() ) 01155 { 01156 (*stream) << "standalone=\""; 01157 PutString( standalone, stream ); 01158 (*stream) << "\" "; 01159 } 01160 (*stream) << "?>"; 01161 } 01162 01163 01164 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const 01165 { 01166 TiXmlNode::CopyTo( target ); 01167 01168 target->version = version; 01169 target->encoding = encoding; 01170 target->standalone = standalone; 01171 } 01172 01173 01174 TiXmlNode* TiXmlDeclaration::Clone() const 01175 { 01176 TiXmlDeclaration* clone = new TiXmlDeclaration(); 01177 01178 if ( !clone ) 01179 return 0; 01180 01181 CopyTo( clone ); 01182 return clone; 01183 } 01184 01185 01186 void TiXmlUnknown::Print( FILE* cfile, int depth ) const 01187 { 01188 for ( int i=0; i<depth; i++ ) 01189 fprintf( cfile, " " ); 01190 fprintf( cfile, "<%s>", value.c_str() ); 01191 } 01192 01193 01194 void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const 01195 { 01196 (*stream) << "<" << value << ">"; // Don't use entities here! It is unknown. 01197 } 01198 01199 01200 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const 01201 { 01202 TiXmlNode::CopyTo( target ); 01203 } 01204 01205 01206 TiXmlNode* TiXmlUnknown::Clone() const 01207 { 01208 TiXmlUnknown* clone = new TiXmlUnknown(); 01209 01210 if ( !clone ) 01211 return 0; 01212 01213 CopyTo( clone ); 01214 return clone; 01215 } 01216 01217 01218 TiXmlAttributeSet::TiXmlAttributeSet() 01219 { 01220 sentinel.next = &sentinel; 01221 sentinel.prev = &sentinel; 01222 } 01223 01224 01225 TiXmlAttributeSet::~TiXmlAttributeSet() 01226 { 01227 assert( sentinel.next == &sentinel ); 01228 assert( sentinel.prev == &sentinel ); 01229 } 01230 01231 01232 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) 01233 { 01234 assert( !Find( addMe->strName() ) ); // Shouldn't be multiply adding to the set. 01235 01236 addMe->next = &sentinel; 01237 addMe->prev = sentinel.prev; 01238 01239 sentinel.prev->next = addMe; 01240 sentinel.prev = addMe; 01241 } 01242 01243 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) 01244 { 01245 TiXmlAttribute* node; 01246 01247 for( node = sentinel.next; node != &sentinel; node = node->next ) 01248 { 01249 if ( node == removeMe ) 01250 { 01251 node->prev->next = node->next; 01252 node->next->prev = node->prev; 01253 node->next = 0; 01254 node->prev = 0; 01255 return; 01256 } 01257 } 01258 assert( 0 ); // we tried to remove a non-linked attribute. 01259 } 01260 01261 TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const 01262 { 01263 TiXmlAttribute* node; 01264 01265 for( node = sentinel.next; node != &sentinel; node = node->next ) 01266 { 01267 if ( node->name == name ) 01268 return node; 01269 } 01270 return 0; 01271 } 01272 01273 01274 #ifdef TIXML_USE_STL 01275 TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base) 01276 { 01277 TIXML_STRING tag; 01278 tag.reserve( 8 * 1000 ); 01279 base.StreamIn( &in, &tag ); 01280 01281 base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); 01282 return in; 01283 } 01284 #endif 01285 01286 01287 TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base) 01288 { 01289 base.StreamOut (& out); 01290 return out; 01291 } 01292 01293 01294 #ifdef TIXML_USE_STL 01295 std::string & operator<< (std::string& out, const TiXmlNode& base ) 01296 { 01297 std::ostringstream os_stream( std::ostringstream::out ); 01298 base.StreamOut( &os_stream ); 01299 01300 out.Append( os_stream.str() ); 01301 return out; 01302 } 01303 #endif 01304 01305 01306 TiXmlHandle TiXmlHandle::FirstChild() const 01307 { 01308 if ( node ) 01309 { 01310 TiXmlNode* child = node->FirstChild(); 01311 if ( child ) 01312 return TiXmlHandle( child ); 01313 } 01314 return TiXmlHandle( 0 ); 01315 } 01316 01317 01318 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const 01319 { 01320 if ( node ) 01321 { 01322 TiXmlNode* child = node->FirstChild( value ); 01323 if ( child ) 01324 return TiXmlHandle( child ); 01325 } 01326 return TiXmlHandle( 0 ); 01327 } 01328 01329 01330 TiXmlHandle TiXmlHandle::FirstChildElement() const 01331 { 01332 if ( node ) 01333 { 01334 TiXmlElement* child = node->FirstChildElement(); 01335 if ( child ) 01336 return TiXmlHandle( child ); 01337 } 01338 return TiXmlHandle( 0 ); 01339 } 01340 01341 01342 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const 01343 { 01344 if ( node ) 01345 { 01346 TiXmlElement* child = node->FirstChildElement( value ); 01347 if ( child ) 01348 return TiXmlHandle( child ); 01349 } 01350 return TiXmlHandle( 0 ); 01351 } 01352 01353 01354 TiXmlHandle TiXmlHandle::Child( int count ) const 01355 { 01356 if ( node ) 01357 { 01358 int i; 01359 TiXmlNode* child = node->FirstChild(); 01360 for ( i=0; 01361 child && i<count; 01362 child = child->NextSibling(), ++i ) 01363 { 01364 // nothing 01365 } 01366 if ( child ) 01367 return TiXmlHandle( child ); 01368 } 01369 return TiXmlHandle( 0 ); 01370 } 01371 01372 01373 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const 01374 { 01375 if ( node ) 01376 { 01377 int i; 01378 TiXmlNode* child = node->FirstChild( value ); 01379 for ( i=0; 01380 child && i<count; 01381 child = child->NextSibling( value ), ++i ) 01382 { 01383 // nothing 01384 } 01385 if ( child ) 01386 return TiXmlHandle( child ); 01387 } 01388 return TiXmlHandle( 0 ); 01389 } 01390 01391 01392 TiXmlHandle TiXmlHandle::ChildElement( int count ) const 01393 { 01394 if ( node ) 01395 { 01396 int i; 01397 TiXmlElement* child = node->FirstChildElement(); 01398 for ( i=0; 01399 child && i<count; 01400 child = child->NextSiblingElement(), ++i ) 01401 { 01402 // nothing 01403 } 01404 if ( child ) 01405 return TiXmlHandle( child ); 01406 } 01407 return TiXmlHandle( 0 ); 01408 } 01409 01410 01411 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const 01412 { 01413 if ( node ) 01414 { 01415 int i; 01416 TiXmlElement* child = node->FirstChildElement( value ); 01417 for ( i=0; 01418 child && i<count; 01419 child = child->NextSiblingElement( value ), ++i ) 01420 { 01421 // nothing 01422 } 01423 if ( child ) 01424 return TiXmlHandle( child ); 01425 } 01426 return TiXmlHandle( 0 ); 01427 }

Generated on Sun Jul 17 21:34:28 2005 for OpenGL GUI by doxygen 1.3.8