Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-14 08:15:01

0001 #ifndef DDCORE_SRC_XML_TINYXML_INL_H
0002 #define DDCORE_SRC_XML_TINYXML_INL_H
0003 
0004 /*
0005   www.sourceforge.net/projects/tinyxml
0006   Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
0007 
0008   This software is provided 'as-is', without any express or implied
0009   warranty. In no event will the authors be held liable for any
0010   damages arising from the use of this software.
0011 
0012   Permission is granted to anyone to use this software for any
0013   purpose, including commercial applications, and to alter it and
0014   redistribute it freely, subject to the following restrictions:
0015 
0016   1. The origin of this software must not be misrepresented; you must
0017   not claim that you wrote the original software. If you use this
0018   software in a product, an acknowledgment in the product documentation
0019   would be appreciated but is not required.
0020 
0021   2. Altered source versions must be plainly marked as such, and
0022   must not be misrepresented as being the original software.
0023 
0024   3. This notice may not be removed or altered from any source
0025   distribution.
0026 
0027 
0028   F.Gaede, DESY : changed extension to .cc  for use with marlin
0029   and include from "marlin/tinyxml.h"
0030 */
0031 
0032 
0033 #include <ctype.h>
0034 
0035 #ifdef TIXML_USE_STL
0036 #include <sstream>
0037 #include <iostream>
0038 #endif
0039 
0040 #include <XML/tinyxml.h>
0041 
0042 
0043 bool TiXmlBase::condenseWhiteSpace = true;
0044 
0045 void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
0046 {
0047   int i=0;
0048 
0049   while( i<(int)str.length() )
0050   {
0051     unsigned char c = (unsigned char) str[i];
0052 
0053     if (    c == '&'
0054             && i < ( (int)str.length() - 2 )
0055             && str[i+1] == '#'
0056             && str[i+2] == 'x' )
0057     {
0058       // Hexadecimal character reference.
0059       // Pass through unchanged.
0060       // &#xA9;     -- copyright symbol, for example.
0061       //
0062       // The -1 is a bug fix from Rob Laveaux. It keeps
0063       // an overflow from happening if there is no ';'.
0064       // There are actually 2 ways to exit this loop -
0065       // while fails (error case) and break (semicolon found).
0066       // However, there is no mechanism (currently) for
0067       // this function to return an error.
0068       while ( i<(int)str.length()-1 )
0069       {
0070         outString->append( str.c_str() + i, 1 );
0071         ++i;
0072         if ( str[i] == ';' )
0073           break;
0074       }
0075     }
0076     else if ( c == '&' )
0077     {
0078       outString->append( entity[0].str, entity[0].strLength );
0079       ++i;
0080     }
0081     else if ( c == '<' )
0082     {
0083       outString->append( entity[1].str, entity[1].strLength );
0084       ++i;
0085     }
0086     else if ( c == '>' )
0087     {
0088       outString->append( entity[2].str, entity[2].strLength );
0089       ++i;
0090     }
0091     else if ( c == '\"' )
0092     {
0093       outString->append( entity[3].str, entity[3].strLength );
0094       ++i;
0095     }
0096     else if ( c == '\'' )
0097     {
0098       outString->append( entity[4].str, entity[4].strLength );
0099       ++i;
0100     }
0101     else if ( c < 32 )
0102     {
0103       // Easy pass at non-alpha/numeric/symbol
0104       // Below 32 is symbolic.
0105       char buf[ 32 ];
0106 
0107 #if defined(TIXML_SNPRINTF)
0108       TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
0109 #else
0110       sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
0111 #endif
0112 
0113       //*ME:        warning C4267: convert 'size_t' to 'int'
0114       //*ME:        Int-Cast to make compiler happy ...
0115       outString->append( buf, (int)strlen( buf ) );
0116       ++i;
0117     }
0118     else
0119     {
0120       //char realc = (char) c;
0121       //outString->append( &realc, 1 );
0122       *outString += (char) c;       // somewhat more efficient function call.
0123       ++i;
0124     }
0125   }
0126 }
0127 
0128 
0129 TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
0130 {
0131   parent = 0;
0132   type = _type;
0133   firstChild = 0;
0134   lastChild = 0;
0135   prev = 0;
0136   next = 0;
0137 }
0138 
0139 
0140 TiXmlNode::~TiXmlNode()
0141 {
0142   TiXmlNode* node = firstChild;
0143   while ( node )
0144   {
0145     TiXmlNode* temp = node;
0146     node = node->next;
0147     delete temp;
0148   }
0149 }
0150 
0151 
0152 void TiXmlNode::CopyTo( TiXmlNode* target ) const
0153 {
0154   target->SetValue (value.c_str() );
0155   target->userData = userData;
0156 }
0157 
0158 
0159 void TiXmlNode::Clear()
0160 {
0161   TiXmlNode* node = firstChild;
0162   while ( node )
0163   {
0164     TiXmlNode* temp = node;
0165     node = node->next;
0166     delete temp;
0167   }
0168 
0169   firstChild = 0;
0170   lastChild = 0;
0171 }
0172 
0173 
0174 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
0175 {
0176   assert( node->parent == 0 || node->parent == this );
0177   assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
0178 
0179   if ( node->Type() == TiXmlNode::DOCUMENT )
0180   {
0181     delete node;
0182     if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
0183     return 0;
0184   }
0185 
0186   node->parent = this;
0187 
0188   node->prev = lastChild;
0189   node->next = 0;
0190 
0191   if ( lastChild )
0192     lastChild->next = node;
0193   else
0194     firstChild = node;                  // it was an empty list.
0195 
0196   lastChild = node;
0197   return node;
0198 }
0199 
0200 
0201 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
0202 {
0203   if ( addThis.Type() == TiXmlNode::DOCUMENT )
0204   {
0205     if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
0206     return 0;
0207   }
0208   TiXmlNode* node = addThis.Clone();
0209   if ( !node )
0210     return 0;
0211 
0212   return LinkEndChild( node );
0213 }
0214 
0215 
0216 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
0217 {
0218   if ( !beforeThis || beforeThis->parent != this ) {
0219     return 0;
0220   }
0221   if ( addThis.Type() == TiXmlNode::DOCUMENT )
0222   {
0223     if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
0224     return 0;
0225   }
0226 
0227   TiXmlNode* node = addThis.Clone();
0228   if ( !node )
0229     return 0;
0230   node->parent = this;
0231 
0232   node->next = beforeThis;
0233   node->prev = beforeThis->prev;
0234   if ( beforeThis->prev )
0235   {
0236     beforeThis->prev->next = node;
0237   }
0238   else
0239   {
0240     assert( firstChild == beforeThis );
0241     firstChild = node;
0242   }
0243   beforeThis->prev = node;
0244   return node;
0245 }
0246 
0247 
0248 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
0249 {
0250   if ( !afterThis || afterThis->parent != this ) {
0251     return 0;
0252   }
0253   if ( addThis.Type() == TiXmlNode::DOCUMENT )
0254   {
0255     if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
0256     return 0;
0257   }
0258 
0259   TiXmlNode* node = addThis.Clone();
0260   if ( !node )
0261     return 0;
0262   node->parent = this;
0263 
0264   node->prev = afterThis;
0265   node->next = afterThis->next;
0266   if ( afterThis->next )
0267   {
0268     afterThis->next->prev = node;
0269   }
0270   else
0271   {
0272     assert( lastChild == afterThis );
0273     lastChild = node;
0274   }
0275   afterThis->next = node;
0276   return node;
0277 }
0278 
0279 
0280 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
0281 {
0282   if ( replaceThis->parent != this )
0283     return 0;
0284 
0285   TiXmlNode* node = withThis.Clone();
0286   if ( !node )
0287     return 0;
0288 
0289   node->next = replaceThis->next;
0290   node->prev = replaceThis->prev;
0291 
0292   if ( replaceThis->next )
0293     replaceThis->next->prev = node;
0294   else
0295     lastChild = node;
0296 
0297   if ( replaceThis->prev )
0298     replaceThis->prev->next = node;
0299   else
0300     firstChild = node;
0301 
0302   delete replaceThis;
0303   node->parent = this;
0304   return node;
0305 }
0306 
0307 
0308 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
0309 {
0310   if ( removeThis->parent != this )
0311   {
0312     assert( 0 );
0313     return false;
0314   }
0315 
0316   if ( removeThis->next )
0317     removeThis->next->prev = removeThis->prev;
0318   else
0319     lastChild = removeThis->prev;
0320 
0321   if ( removeThis->prev )
0322     removeThis->prev->next = removeThis->next;
0323   else
0324     firstChild = removeThis->next;
0325 
0326   delete removeThis;
0327   return true;
0328 }
0329 
0330 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
0331 {
0332   const TiXmlNode* node;
0333   for ( node = firstChild; node; node = node->next )
0334   {
0335     if ( strcmp( node->Value(), _value ) == 0 )
0336       return node;
0337   }
0338   return 0;
0339 }
0340 
0341 
0342 const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
0343 {
0344   const TiXmlNode* node;
0345   for ( node = lastChild; node; node = node->prev )
0346   {
0347     if ( strcmp( node->Value(), _value ) == 0 )
0348       return node;
0349   }
0350   return 0;
0351 }
0352 
0353 
0354 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
0355 {
0356   if ( !previous )
0357   {
0358     return FirstChild();
0359   }
0360   else
0361   {
0362     assert( previous->parent == this );
0363     return previous->NextSibling();
0364   }
0365 }
0366 
0367 
0368 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
0369 {
0370   if ( !previous )
0371   {
0372     return FirstChild( val );
0373   }
0374   else
0375   {
0376     assert( previous->parent == this );
0377     return previous->NextSibling( val );
0378   }
0379 }
0380 
0381 
0382 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
0383 {
0384   const TiXmlNode* node;
0385   for ( node = next; node; node = node->next )
0386   {
0387     if ( strcmp( node->Value(), _value ) == 0 )
0388       return node;
0389   }
0390   return 0;
0391 }
0392 
0393 
0394 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
0395 {
0396   const TiXmlNode* node;
0397   for ( node = prev; node; node = node->prev )
0398   {
0399     if ( strcmp( node->Value(), _value ) == 0 )
0400       return node;
0401   }
0402   return 0;
0403 }
0404 
0405 
0406 void TiXmlElement::RemoveAttribute( const char * name )
0407 {
0408 #ifdef TIXML_USE_STL
0409   TIXML_STRING str( name );
0410   TiXmlAttribute* node = attributeSet.Find( str );
0411 #else
0412   TiXmlAttribute* node = attributeSet.Find( name );
0413 #endif
0414   if ( node )
0415   {
0416     attributeSet.Remove( node );
0417     delete node;
0418   }
0419 }
0420 
0421 const TiXmlElement* TiXmlNode::FirstChildElement() const
0422 {
0423   const TiXmlNode* node;
0424 
0425   for ( node = FirstChild();
0426         node;
0427         node = node->NextSibling() )
0428   {
0429     if ( node->ToElement() )
0430       return node->ToElement();
0431   }
0432   return 0;
0433 }
0434 
0435 
0436 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
0437 {
0438   const TiXmlNode* node;
0439 
0440   for ( node = FirstChild( _value );
0441         node;
0442         node = node->NextSibling( _value ) )
0443   {
0444     if ( node->ToElement() )
0445       return node->ToElement();
0446   }
0447   return 0;
0448 }
0449 
0450 
0451 const TiXmlElement* TiXmlNode::NextSiblingElement() const
0452 {
0453   const TiXmlNode* node;
0454 
0455   for ( node = NextSibling();
0456         node;
0457         node = node->NextSibling() )
0458   {
0459     if ( node->ToElement() )
0460       return node->ToElement();
0461   }
0462   return 0;
0463 }
0464 
0465 
0466 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
0467 {
0468   const TiXmlNode* node;
0469 
0470   for ( node = NextSibling( _value );
0471         node;
0472         node = node->NextSibling( _value ) )
0473   {
0474     if ( node->ToElement() )
0475       return node->ToElement();
0476   }
0477   return 0;
0478 }
0479 
0480 
0481 const TiXmlElement* TiXmlNode::PreviousSiblingElement() const
0482 {
0483   const TiXmlNode* node;
0484 
0485   for ( node = PreviousSibling();
0486         node;
0487         node = node->PreviousSibling() )
0488   {
0489     if ( node->ToElement() )
0490       return node->ToElement();
0491   }
0492   return 0;
0493 }
0494 
0495 const TiXmlElement* TiXmlNode::PreviousSiblingElement( const char * _value ) const
0496 {
0497   const TiXmlNode* node;
0498 
0499   for ( node = PreviousSibling( _value );
0500         node;
0501         node = node->PreviousSibling( _value ) )
0502   {
0503     if ( node->ToElement() )
0504       return node->ToElement();
0505   }
0506   return 0;
0507 }
0508 
0509 
0510 const TiXmlDocument* TiXmlNode::GetDocument() const
0511 {
0512   const TiXmlNode* node;
0513 
0514   for( node = this; node; node = node->parent )
0515   {
0516     if ( node->ToDocument() )
0517       return node->ToDocument();
0518   }
0519   return 0;
0520 }
0521 
0522 
0523 TiXmlElement::TiXmlElement (const char * _value)
0524   : TiXmlNode( TiXmlNode::ELEMENT )
0525 {
0526   firstChild = lastChild = 0;
0527   value = _value;
0528 }
0529 
0530 
0531 #ifdef TIXML_USE_STL
0532 TiXmlElement::TiXmlElement( const std::string& _value )
0533   : TiXmlNode( TiXmlNode::ELEMENT )
0534 {
0535   firstChild = lastChild = 0;
0536   value = _value;
0537 }
0538 #endif
0539 
0540 
0541 TiXmlElement::TiXmlElement( const TiXmlElement& copy)
0542   : TiXmlNode( TiXmlNode::ELEMENT )
0543 {
0544   firstChild = lastChild = 0;
0545   copy.CopyTo( this );
0546 }
0547 
0548 
0549 void TiXmlElement::operator=( const TiXmlElement& base )
0550 {
0551   ClearThis();
0552   base.CopyTo( this );
0553 }
0554 
0555 
0556 TiXmlElement::~TiXmlElement()
0557 {
0558   ClearThis();
0559 }
0560 
0561 
0562 void TiXmlElement::ClearThis()
0563 {
0564   Clear();
0565   while( attributeSet.First() )
0566   {
0567     TiXmlAttribute* node = attributeSet.First();
0568     attributeSet.Remove( node );
0569     delete node;
0570   }
0571 }
0572 
0573 void TiXmlElement::ClearAttributes()
0574 {
0575   while( attributeSet.First() )
0576   {
0577     TiXmlAttribute* node = attributeSet.First();
0578     attributeSet.Remove( node );
0579     delete node;
0580   }
0581 }
0582 
0583 
0584 const char* TiXmlElement::Attribute( const char* name ) const
0585 {
0586   const TiXmlAttribute* node = attributeSet.Find( name );
0587   if ( node )
0588     return node->Value();
0589   return 0;
0590 }
0591 
0592 
0593 #ifdef TIXML_USE_STL
0594 const std::string* TiXmlElement::Attribute( const std::string& name ) const
0595 {
0596   const TiXmlAttribute* node = attributeSet.Find( name );
0597   if ( node )
0598     return &node->ValueStr();
0599   return 0;
0600 }
0601 #endif
0602 
0603 
0604 const char* TiXmlElement::Attribute( const char* name, int* i ) const
0605 {
0606   const char* s = Attribute( name );
0607   if ( i )
0608   {
0609     if ( s ) {
0610       *i = atoi( s );
0611     }
0612     else {
0613       *i = 0;
0614     }
0615   }
0616   return s;
0617 }
0618 
0619 
0620 #ifdef TIXML_USE_STL
0621 const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
0622 {
0623   const std::string* s = Attribute( name );
0624   if ( i )
0625   {
0626     if ( s ) {
0627       *i = atoi( s->c_str() );
0628     }
0629     else {
0630       *i = 0;
0631     }
0632   }
0633   return s;
0634 }
0635 #endif
0636 
0637 
0638 const char* TiXmlElement::Attribute( const char* name, double* d ) const
0639 {
0640   const char* s = Attribute( name );
0641   if ( d )
0642   {
0643     if ( s ) {
0644       *d = atof( s );
0645     }
0646     else {
0647       *d = 0;
0648     }
0649   }
0650   return s;
0651 }
0652 
0653 
0654 #ifdef TIXML_USE_STL
0655 const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
0656 {
0657   const std::string* s = Attribute( name );
0658   if ( d )
0659   {
0660     if ( s ) {
0661       *d = atof( s->c_str() );
0662     }
0663     else {
0664       *d = 0;
0665     }
0666   }
0667   return s;
0668 }
0669 #endif
0670 
0671 
0672 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
0673 {
0674   const TiXmlAttribute* node = attributeSet.Find( name );
0675   if ( !node )
0676     return TIXML_NO_ATTRIBUTE;
0677   return node->QueryIntValue( ival );
0678 }
0679 
0680 
0681 #ifdef TIXML_USE_STL
0682 int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
0683 {
0684   const TiXmlAttribute* node = attributeSet.Find( name );
0685   if ( !node )
0686     return TIXML_NO_ATTRIBUTE;
0687   return node->QueryIntValue( ival );
0688 }
0689 #endif
0690 
0691 
0692 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
0693 {
0694   const TiXmlAttribute* node = attributeSet.Find( name );
0695   if ( !node )
0696     return TIXML_NO_ATTRIBUTE;
0697   return node->QueryDoubleValue( dval );
0698 }
0699 
0700 
0701 #ifdef TIXML_USE_STL
0702 int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
0703 {
0704   const TiXmlAttribute* node = attributeSet.Find( name );
0705   if ( !node )
0706     return TIXML_NO_ATTRIBUTE;
0707   return node->QueryDoubleValue( dval );
0708 }
0709 #endif
0710 
0711 
0712 void TiXmlElement::SetAttribute( const char * name, int val )
0713 {
0714   char buf[64];
0715 #if defined(TIXML_SNPRINTF)
0716   TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
0717 #else
0718   sprintf( buf, "%d", val );
0719 #endif
0720   SetAttribute( name, buf );
0721 }
0722 
0723 
0724 #ifdef TIXML_USE_STL
0725 void TiXmlElement::SetAttribute( const std::string& name, int val )
0726 {
0727   std::ostringstream oss;
0728   oss << val;
0729   SetAttribute( name, oss.str() );
0730 }
0731 #endif
0732 
0733 
0734 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
0735 {
0736   char buf[256];
0737 #if defined(TIXML_SNPRINTF)
0738   TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
0739 #else
0740   sprintf( buf, "%f", val );
0741 #endif
0742   SetAttribute( name, buf );
0743 }
0744 
0745 
0746 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
0747 {
0748 #ifdef TIXML_USE_STL
0749   TIXML_STRING _name( cname );
0750   TIXML_STRING _value( cvalue );
0751 #else
0752   const char* _name = cname;
0753   const char* _value = cvalue;
0754 #endif
0755 
0756   TiXmlAttribute* node = attributeSet.Find( _name );
0757   if ( node )
0758   {
0759     node->SetValue( _value );
0760     return;
0761   }
0762 
0763   TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
0764   if ( attrib )
0765   {
0766     attributeSet.Add( attrib );
0767   }
0768   else
0769   {
0770     TiXmlDocument* document = GetDocument();
0771     if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
0772   }
0773 }
0774 
0775 
0776 #ifdef TIXML_USE_STL
0777 void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
0778 {
0779   TiXmlAttribute* node = attributeSet.Find( name );
0780   if ( node )
0781   {
0782     node->SetValue( _value );
0783     return;
0784   }
0785 
0786   TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
0787   if ( attrib )
0788   {
0789     attributeSet.Add( attrib );
0790   }
0791   else
0792   {
0793     TiXmlDocument* document = GetDocument();
0794     if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
0795   }
0796 }
0797 #endif
0798 
0799 
0800 void TiXmlElement::Print( FILE* cfile, int depth ) const
0801 {
0802   int i;
0803   assert( cfile );
0804   for ( i=0; i<depth; i++ ) {
0805     fprintf( cfile, "    " );
0806   }
0807 
0808   fprintf( cfile, "<%s", value.c_str() );
0809 
0810   const TiXmlAttribute* attrib;
0811   for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
0812   {
0813     fprintf( cfile, " " );
0814     attrib->Print( cfile, depth );
0815   }
0816 
0817   // There are 3 different formatting approaches:
0818   // 1) An element without children is printed as a <foo /> node
0819   // 2) An element with only a text child is printed as <foo> text </foo>
0820   // 3) An element with children is printed on multiple lines.
0821   TiXmlNode* node;
0822   if ( !firstChild )
0823   {
0824     fprintf( cfile, " />" );
0825   }
0826   else if ( firstChild == lastChild && firstChild->ToText() )
0827   {
0828     fprintf( cfile, ">" );
0829     firstChild->Print( cfile, depth + 1 );
0830     fprintf( cfile, "</%s>", value.c_str() );
0831   }
0832   else
0833   {
0834     fprintf( cfile, ">" );
0835 
0836     for ( node = firstChild; node; node=node->NextSibling() )
0837     {
0838       if ( !node->ToText() )
0839       {
0840         fprintf( cfile, "\n" );
0841       }
0842       node->Print( cfile, depth+1 );
0843     }
0844     fprintf( cfile, "\n" );
0845     for( i=0; i<depth; ++i ) {
0846       fprintf( cfile, "    " );
0847     }
0848     fprintf( cfile, "</%s>", value.c_str() );
0849   }
0850 }
0851 
0852 
0853 void TiXmlElement::CopyTo( TiXmlElement* target ) const
0854 {
0855   // superclass:
0856   TiXmlNode::CopyTo( target );
0857 
0858   // Element class:
0859   // Clone the attributes, then clone the children.
0860   const TiXmlAttribute* attribute = 0;
0861   for(  attribute = attributeSet.First();
0862         attribute;
0863         attribute = attribute->Next() )
0864   {
0865     target->SetAttribute( attribute->Name(), attribute->Value() );
0866   }
0867 
0868   TiXmlNode* node = 0;
0869   for ( node = firstChild; node; node = node->NextSibling() )
0870   {
0871     target->LinkEndChild( node->Clone() );
0872   }
0873 }
0874 
0875 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
0876 {
0877   if ( visitor->VisitEnter( *this, attributeSet.First() ) )
0878   {
0879     for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
0880     {
0881       if ( !node->Accept( visitor ) )
0882         break;
0883     }
0884   }
0885   return visitor->VisitExit( *this );
0886 }
0887 
0888 
0889 TiXmlNode* TiXmlElement::Clone() const
0890 {
0891   TiXmlElement* clone = new TiXmlElement( Value() );
0892   if ( !clone )
0893     return 0;
0894 
0895   CopyTo( clone );
0896   return clone;
0897 }
0898 
0899 
0900 const char* TiXmlElement::GetText() const
0901 {
0902   const TiXmlNode* child = this->FirstChild();
0903   if ( child ) {
0904     const TiXmlText* childText = child->ToText();
0905     if ( childText ) {
0906       return childText->Value();
0907     }
0908   }
0909   return 0;
0910 }
0911 
0912 
0913 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
0914 {
0915   tabsize = 4;
0916   useMicrosoftBOM = false;
0917   ClearError();
0918 }
0919 
0920 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
0921 {
0922   tabsize = 4;
0923   useMicrosoftBOM = false;
0924   value = documentName;
0925   ClearError();
0926 }
0927 
0928 
0929 #ifdef TIXML_USE_STL
0930 TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
0931 {
0932   tabsize = 4;
0933   useMicrosoftBOM = false;
0934   value = documentName;
0935   ClearError();
0936 }
0937 #endif
0938 
0939 
0940 TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
0941 {
0942   copy.CopyTo( this );
0943 }
0944 
0945 
0946 void TiXmlDocument::operator=( const TiXmlDocument& copy )
0947 {
0948   Clear();
0949   copy.CopyTo( this );
0950 }
0951 
0952 
0953 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
0954 {
0955   // See STL_STRING_BUG below.
0956   //StringToBuffer buf( value );
0957 
0958   return LoadFile( Value(), encoding );
0959 }
0960 
0961 
0962 bool TiXmlDocument::SaveFile() const
0963 {
0964   // See STL_STRING_BUG below.
0965   //    StringToBuffer buf( value );
0966   //
0967   //    if ( buf.buffer && SaveFile( buf.buffer ) )
0968   //            return true;
0969   //
0970   //    return false;
0971   return SaveFile( Value() );
0972 }
0973 
0974 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
0975 {
0976   // There was a really terrifying little bug here. The code:
0977   //            value = filename
0978   // in the STL case, cause the assignment method of the std::string to
0979   // be called. What is strange, is that the std::string had the same
0980   // address as its c_str() method, and so bad things happen. Looks
0981   // like a bug in the Microsoft STL implementation.
0982   // Add an extra string to avoid the crash.
0983   TIXML_STRING filename( _filename );
0984   value = filename;
0985 
0986   // reading in binary mode so that tinyxml can normalize the EOL
0987   FILE* file = fopen( value.c_str (), "rb" );
0988 
0989   if ( file )
0990   {
0991     bool result = LoadFile( file, encoding );
0992     fclose( file );
0993     return result;
0994   }
0995   else
0996   {
0997     SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
0998     return false;
0999   }
1000 }
1001 
1002 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
1003 {
1004   if ( !file )
1005   {
1006     SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
1007     return false;
1008   }
1009 
1010   // Delete the existing data:
1011   Clear();
1012   location.Clear();
1013 
1014   // Get the file size, so we can pre-allocate the string. HUGE speed impact.
1015   long length = 0;
1016   fseek( file, 0, SEEK_END );
1017   length = ftell( file );
1018   fseek( file, 0, SEEK_SET );
1019 
1020   // Strange case, but good to handle up front.
1021   if ( length == 0 )
1022   {
1023     SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
1024     return false;
1025   }
1026 
1027   // If we have a file, assume it is all one big XML file, and read it in.
1028   // The document parser may decide the document ends sooner than the entire file, however.
1029   TIXML_STRING data;
1030   data.reserve( length );
1031 
1032   // Subtle bug here. TinyXml did use fgets. But from the XML spec:
1033   // 2.11 End-of-Line Handling
1034   // <snip>
1035   // <quote>
1036   // ...the XML processor MUST behave as if it normalized all line breaks in external
1037   // parsed entities (including the document entity) on input, before parsing, by translating
1038   // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
1039   // a single #xA character.
1040   // </quote>
1041   //
1042   // It is not clear fgets does that, and certainly isn't clear it works cross platform.
1043   // Generally, you expect fgets to translate from the convention of the OS to the c/unix
1044   // convention, and not work generally.
1045 
1046   /*
1047     while( fgets( buf, sizeof(buf), file ) )
1048     {
1049     data += buf;
1050     }
1051   */
1052 
1053   char* buf = new char[ length+1 ];
1054   buf[0] = 0;
1055 
1056   if ( fread( buf, length, 1, file ) != 1 ) {
1057     delete [] buf;
1058     SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
1059     return false;
1060   }
1061 
1062   const char* lastPos = buf;
1063   const char* p = buf;
1064 
1065   buf[length] = 0;
1066   while( *p ) {
1067     assert( p < (buf+length) );
1068     if ( *p == 0xa ) {
1069       // Newline character. No special rules for this. Append all the characters
1070       // since the last string, and include the newline.
1071       data.append( lastPos, (p-lastPos+1) );    // append, include the newline
1072       ++p;                                                                      // move past the newline
1073       lastPos = p;                                                      // and point to the new buffer (may be 0)
1074       assert( p <= (buf+length) );
1075     }
1076     else if ( *p == 0xd ) {
1077       // Carriage return. Append what we have so far, then
1078       // handle moving forward in the buffer.
1079       if ( (p-lastPos) > 0 ) {
1080         data.append( lastPos, p-lastPos );      // do not add the CR
1081       }
1082       data += (char)0xa;                                                // a proper newline
1083 
1084       if ( *(p+1) == 0xa ) {
1085         // Carriage return - new line sequence
1086         p += 2;
1087         lastPos = p;
1088         assert( p <= (buf+length) );
1089       }
1090       else {
1091         // it was followed by something else...that is presumably characters again.
1092         ++p;
1093         lastPos = p;
1094         assert( p <= (buf+length) );
1095       }
1096     }
1097     else {
1098       ++p;
1099     }
1100   }
1101   // Handle_t any left over characters.
1102   if ( p-lastPos ) {
1103     data.append( lastPos, p-lastPos );
1104   }
1105   delete [] buf;
1106   buf = 0;
1107 
1108   Parse( data.c_str(), 0, encoding );
1109 
1110   if (  Error() )
1111     return false;
1112   else
1113     return true;
1114 }
1115 
1116 
1117 bool TiXmlDocument::SaveFile( const char * filename ) const
1118 {
1119   // The old c stuff lives on...
1120   FILE* fp = fopen( filename, "w" );
1121   if ( fp )
1122   {
1123     bool result = SaveFile( fp );
1124     fclose( fp );
1125     return result;
1126   }
1127   return false;
1128 }
1129 
1130 
1131 bool TiXmlDocument::SaveFile( FILE* fp ) const
1132 {
1133   if ( useMicrosoftBOM )
1134   {
1135     const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
1136     const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
1137     const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
1138 
1139     fputc( TIXML_UTF_LEAD_0, fp );
1140     fputc( TIXML_UTF_LEAD_1, fp );
1141     fputc( TIXML_UTF_LEAD_2, fp );
1142   }
1143   Print( fp, 0 );
1144   return (ferror(fp) == 0);
1145 }
1146 
1147 
1148 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
1149 {
1150   TiXmlNode::CopyTo( target );
1151 
1152   target->error = error;
1153   target->errorDesc = errorDesc.c_str ();
1154 
1155   TiXmlNode* node = 0;
1156   for ( node = firstChild; node; node = node->NextSibling() )
1157   {
1158     target->LinkEndChild( node->Clone() );
1159   }
1160 }
1161 
1162 
1163 TiXmlNode* TiXmlDocument::Clone() const
1164 {
1165   TiXmlDocument* clone = new TiXmlDocument();
1166   if ( !clone )
1167     return 0;
1168 
1169   CopyTo( clone );
1170   return clone;
1171 }
1172 
1173 
1174 void TiXmlDocument::Print( FILE* cfile, int depth ) const
1175 {
1176   assert( cfile );
1177   for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1178   {
1179     node->Print( cfile, depth );
1180     fprintf( cfile, "\n" );
1181   }
1182 }
1183 
1184 
1185 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
1186 {
1187   if ( visitor->VisitEnter( *this ) )
1188   {
1189     for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
1190     {
1191       if ( !node->Accept( visitor ) )
1192         break;
1193     }
1194   }
1195   return visitor->VisitExit( *this );
1196 }
1197 
1198 
1199 const TiXmlAttribute* TiXmlAttribute::Next() const
1200 {
1201   // We are using knowledge of the sentinel. The sentinel
1202   // have a value or name.
1203   if ( next->value.empty() && next->name.empty() )
1204     return 0;
1205   return next;
1206 }
1207 
1208 /*
1209   TiXmlAttribute* TiXmlAttribute::Next()
1210   {
1211   // We are using knowledge of the sentinel. The sentinel
1212   // have a value or name.
1213   if ( next->value.empty() && next->name.empty() )
1214   return 0;
1215   return next;
1216   }
1217 */
1218 
1219 const TiXmlAttribute* TiXmlAttribute::Previous() const
1220 {
1221   // We are using knowledge of the sentinel. The sentinel
1222   // have a value or name.
1223   if ( prev->value.empty() && prev->name.empty() )
1224     return 0;
1225   return prev;
1226 }
1227 
1228 /*
1229   TiXmlAttribute* TiXmlAttribute::Previous()
1230   {
1231   // We are using knowledge of the sentinel. The sentinel
1232   // have a value or name.
1233   if ( prev->value.empty() && prev->name.empty() )
1234   return 0;
1235   return prev;
1236   }
1237 */
1238 
1239 void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1240 {
1241   TIXML_STRING n, v;
1242 
1243   PutString( name, &n );
1244   PutString( value, &v );
1245 
1246   if (value.find ('\"') == TIXML_STRING::npos) {
1247     if ( cfile ) {
1248       fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
1249     }
1250     if ( str ) {
1251       (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
1252     }
1253   }
1254   else {
1255     if ( cfile ) {
1256       fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
1257     }
1258     if ( str ) {
1259       (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
1260     }
1261   }
1262 }
1263 
1264 
1265 int TiXmlAttribute::QueryIntValue( int* ival ) const
1266 {
1267   if ( sscanf( value.c_str(), "%d", ival ) == 1 )
1268     return TIXML_SUCCESS;
1269   return TIXML_WRONG_TYPE;
1270 }
1271 
1272 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
1273 {
1274   if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
1275     return TIXML_SUCCESS;
1276   return TIXML_WRONG_TYPE;
1277 }
1278 
1279 void TiXmlAttribute::SetIntValue( int _value )
1280 {
1281   char buf [64];
1282 #if defined(TIXML_SNPRINTF)
1283   TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
1284 #else
1285   sprintf (buf, "%d", _value);
1286 #endif
1287   SetValue (buf);
1288 }
1289 
1290 void TiXmlAttribute::SetDoubleValue( double _value )
1291 {
1292   char buf [256];
1293 #if defined(TIXML_SNPRINTF)
1294   TIXML_SNPRINTF( buf, sizeof(buf), "%f", _value);
1295 #else
1296   sprintf (buf, "%f", _value);
1297 #endif
1298   SetValue (buf);
1299 }
1300 
1301 int TiXmlAttribute::IntValue() const
1302 {
1303   return atoi (value.c_str ());
1304 }
1305 
1306 double  TiXmlAttribute::DoubleValue() const
1307 {
1308   return atof (value.c_str ());
1309 }
1310 
1311 
1312 TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
1313 {
1314   copy.CopyTo( this );
1315 }
1316 
1317 
1318 void TiXmlComment::operator=( const TiXmlComment& base )
1319 {
1320   Clear();
1321   base.CopyTo( this );
1322 }
1323 
1324 
1325 void TiXmlComment::Print( FILE* cfile, int depth ) const
1326 {
1327   assert( cfile );
1328   for ( int i=0; i<depth; i++ )
1329   {
1330     fprintf( cfile,  "    " );
1331   }
1332   fprintf( cfile, "<!--%s-->", value.c_str() );
1333 }
1334 
1335 
1336 void TiXmlComment::CopyTo( TiXmlComment* target ) const
1337 {
1338   TiXmlNode::CopyTo( target );
1339 }
1340 
1341 
1342 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
1343 {
1344   return visitor->Visit( *this );
1345 }
1346 
1347 
1348 TiXmlNode* TiXmlComment::Clone() const
1349 {
1350   TiXmlComment* clone = new TiXmlComment();
1351 
1352   if ( !clone )
1353     return 0;
1354 
1355   CopyTo( clone );
1356   return clone;
1357 }
1358 
1359 
1360 void TiXmlText::Print( FILE* cfile, int depth ) const
1361 {
1362   assert( cfile );
1363   if ( cdata )
1364   {
1365     int i;
1366     fprintf( cfile, "\n" );
1367     for ( i=0; i<depth; i++ ) {
1368       fprintf( cfile, "    " );
1369     }
1370     fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );      // unformatted output
1371   }
1372   else
1373   {
1374     TIXML_STRING buffer;
1375     PutString( value, &buffer );
1376     fprintf( cfile, "%s", buffer.c_str() );
1377   }
1378 }
1379 
1380 
1381 void TiXmlText::CopyTo( TiXmlText* target ) const
1382 {
1383   TiXmlNode::CopyTo( target );
1384   target->cdata = cdata;
1385 }
1386 
1387 
1388 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
1389 {
1390   return visitor->Visit( *this );
1391 }
1392 
1393 
1394 TiXmlNode* TiXmlText::Clone() const
1395 {
1396   TiXmlText* clone = 0;
1397   clone = new TiXmlText( "" );
1398 
1399   if ( !clone )
1400     return 0;
1401 
1402   CopyTo( clone );
1403   return clone;
1404 }
1405 
1406 
1407 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
1408                                     const char * _encoding,
1409                                     const char * _standalone )
1410   : TiXmlNode( TiXmlNode::DECLARATION )
1411 {
1412   version = _version;
1413   encoding = _encoding;
1414   standalone = _standalone;
1415 }
1416 
1417 
1418 #ifdef TIXML_USE_STL
1419 TiXmlDeclaration::TiXmlDeclaration(     const std::string& _version,
1420                                         const std::string& _encoding,
1421                                         const std::string& _standalone )
1422   : TiXmlNode( TiXmlNode::DECLARATION )
1423 {
1424   version = _version;
1425   encoding = _encoding;
1426   standalone = _standalone;
1427 }
1428 #endif
1429 
1430 
1431 TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
1432   : TiXmlNode( TiXmlNode::DECLARATION )
1433 {
1434   copy.CopyTo( this );
1435 }
1436 
1437 
1438 void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
1439 {
1440   Clear();
1441   copy.CopyTo( this );
1442 }
1443 
1444 
1445 void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
1446 {
1447   if ( cfile ) fprintf( cfile, "<?xml " );
1448   if ( str )   (*str) += "<?xml ";
1449 
1450   if ( !version.empty() ) {
1451     if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
1452     if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
1453   }
1454   if ( !encoding.empty() ) {
1455     if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
1456     if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
1457   }
1458   if ( !standalone.empty() ) {
1459     if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
1460     if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
1461   }
1462   if ( cfile ) fprintf( cfile, "?>" );
1463   if ( str )   (*str) += "?>";
1464 }
1465 
1466 
1467 void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
1468 {
1469   TiXmlNode::CopyTo( target );
1470 
1471   target->version = version;
1472   target->encoding = encoding;
1473   target->standalone = standalone;
1474 }
1475 
1476 
1477 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
1478 {
1479   return visitor->Visit( *this );
1480 }
1481 
1482 
1483 TiXmlNode* TiXmlDeclaration::Clone() const
1484 {
1485   TiXmlDeclaration* clone = new TiXmlDeclaration();
1486 
1487   if ( !clone )
1488     return 0;
1489 
1490   CopyTo( clone );
1491   return clone;
1492 }
1493 
1494 
1495 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
1496 {
1497   for ( int i=0; i<depth; i++ )
1498     fprintf( cfile, "    " );
1499   fprintf( cfile, "<%s>", value.c_str() );
1500 }
1501 
1502 
1503 void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
1504 {
1505   TiXmlNode::CopyTo( target );
1506 }
1507 
1508 
1509 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
1510 {
1511   return visitor->Visit( *this );
1512 }
1513 
1514 
1515 TiXmlNode* TiXmlUnknown::Clone() const
1516 {
1517   TiXmlUnknown* clone = new TiXmlUnknown();
1518 
1519   if ( !clone )
1520     return 0;
1521 
1522   CopyTo( clone );
1523   return clone;
1524 }
1525 
1526 
1527 TiXmlAttributeSet::TiXmlAttributeSet()
1528 {
1529   sentinel.next = &sentinel;
1530   sentinel.prev = &sentinel;
1531 }
1532 
1533 
1534 TiXmlAttributeSet::~TiXmlAttributeSet()
1535 {
1536   assert( sentinel.next == &sentinel );
1537   assert( sentinel.prev == &sentinel );
1538 }
1539 
1540 
1541 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
1542 {
1543 #ifdef TIXML_USE_STL
1544   assert( !Find( TIXML_STRING( addMe->Name() ) ) );     // Shouldn't be multiply adding to the set.
1545 #else
1546   assert( !Find( addMe->Name() ) );     // Shouldn't be multiply adding to the set.
1547 #endif
1548 
1549   addMe->next = &sentinel;
1550   addMe->prev = sentinel.prev;
1551 
1552   sentinel.prev->next = addMe;
1553   sentinel.prev      = addMe;
1554 }
1555 
1556 void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
1557 {
1558   TiXmlAttribute* node;
1559 
1560   for( node = sentinel.next; node != &sentinel; node = node->next )
1561   {
1562     if ( node == removeMe )
1563     {
1564       node->prev->next = node->next;
1565       node->next->prev = node->prev;
1566       node->next = 0;
1567       node->prev = 0;
1568       return;
1569     }
1570   }
1571   assert( 0 );          // we tried to remove a non-linked attribute.
1572 }
1573 
1574 
1575 #ifdef TIXML_USE_STL
1576 const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
1577 {
1578   for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1579   {
1580     if ( node->name == name )
1581       return node;
1582   }
1583   return 0;
1584 }
1585 
1586 /*
1587   TiXmlAttribute*       TiXmlAttributeSet::Find( const std::string& name )
1588   {
1589   for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1590   {
1591   if ( node->name == name )
1592   return node;
1593   }
1594   return 0;
1595   }
1596 */
1597 #endif
1598 
1599 
1600 const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
1601 {
1602   for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1603   {
1604     if ( strcmp( node->name.c_str(), name ) == 0 )
1605       return node;
1606   }
1607   return 0;
1608 }
1609 
1610 /*
1611   TiXmlAttribute*       TiXmlAttributeSet::Find( const char* name )
1612   {
1613   for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
1614   {
1615   if ( strcmp( node->name.c_str(), name ) == 0 )
1616   return node;
1617   }
1618   return 0;
1619   }
1620 */
1621 
1622 #ifdef TIXML_USE_STL
1623 std::istream& operator>> (std::istream & in, TiXmlNode & base)
1624 {
1625   TIXML_STRING tag;
1626   tag.reserve( 8 * 1000 );
1627   base.StreamIn( &in, &tag );
1628 
1629   base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
1630   return in;
1631 }
1632 #endif
1633 
1634 
1635 #ifdef TIXML_USE_STL
1636 std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
1637 {
1638   TiXmlPrinter printer;
1639   printer.SetStreamPrinting();
1640   base.Accept( &printer );
1641   out << printer.Str();
1642 
1643   return out;
1644 }
1645 
1646 
1647 std::string& operator<< (std::string& out, const TiXmlNode& base )
1648 {
1649   TiXmlPrinter printer;
1650   printer.SetStreamPrinting();
1651   base.Accept( &printer );
1652   out.append( printer.Str() );
1653 
1654   return out;
1655 }
1656 #endif
1657 
1658 
1659 TiXmlHandle_t TiXmlHandle_t::FirstChild() const
1660 {
1661   if ( node )
1662   {
1663     TiXmlNode* child = node->FirstChild();
1664     if ( child )
1665       return TiXmlHandle_t( child );
1666   }
1667   return TiXmlHandle_t( 0 );
1668 }
1669 
1670 
1671 TiXmlHandle_t TiXmlHandle_t::FirstChild( const char * value ) const
1672 {
1673   if ( node )
1674   {
1675     TiXmlNode* child = node->FirstChild( value );
1676     if ( child )
1677       return TiXmlHandle_t( child );
1678   }
1679   return TiXmlHandle_t( 0 );
1680 }
1681 
1682 
1683 TiXmlHandle_t TiXmlHandle_t::FirstChildElement() const
1684 {
1685   if ( node )
1686   {
1687     TiXmlElement* child = node->FirstChildElement();
1688     if ( child )
1689       return TiXmlHandle_t( child );
1690   }
1691   return TiXmlHandle_t( 0 );
1692 }
1693 
1694 
1695 TiXmlHandle_t TiXmlHandle_t::FirstChildElement( const char * value ) const
1696 {
1697   if ( node )
1698   {
1699     TiXmlElement* child = node->FirstChildElement( value );
1700     if ( child )
1701       return TiXmlHandle_t( child );
1702   }
1703   return TiXmlHandle_t( 0 );
1704 }
1705 
1706 
1707 TiXmlHandle_t TiXmlHandle_t::Child( int count ) const
1708 {
1709   if ( node )
1710   {
1711     int i;
1712     TiXmlNode* child = node->FirstChild();
1713     for (     i=0;
1714               child && i<count;
1715               child = child->NextSibling(), ++i )
1716     {
1717       // nothing
1718     }
1719     if ( child )
1720       return TiXmlHandle_t( child );
1721   }
1722   return TiXmlHandle_t( 0 );
1723 }
1724 
1725 
1726 TiXmlHandle_t TiXmlHandle_t::Child( const char* value, int count ) const
1727 {
1728   if ( node )
1729   {
1730     int i;
1731     TiXmlNode* child = node->FirstChild( value );
1732     for (     i=0;
1733               child && i<count;
1734               child = child->NextSibling( value ), ++i )
1735     {
1736       // nothing
1737     }
1738     if ( child )
1739       return TiXmlHandle_t( child );
1740   }
1741   return TiXmlHandle_t( 0 );
1742 }
1743 
1744 
1745 TiXmlHandle_t TiXmlHandle_t::ChildElement( int count ) const
1746 {
1747   if ( node )
1748   {
1749     int i;
1750     TiXmlElement* child = node->FirstChildElement();
1751     for (     i=0;
1752               child && i<count;
1753               child = child->NextSiblingElement(), ++i )
1754     {
1755       // nothing
1756     }
1757     if ( child )
1758       return TiXmlHandle_t( child );
1759   }
1760   return TiXmlHandle_t( 0 );
1761 }
1762 
1763 
1764 TiXmlHandle_t TiXmlHandle_t::ChildElement( const char* value, int count ) const
1765 {
1766   if ( node )
1767   {
1768     int i;
1769     TiXmlElement* child = node->FirstChildElement( value );
1770     for (     i=0;
1771               child && i<count;
1772               child = child->NextSiblingElement( value ), ++i )
1773     {
1774       // nothing
1775     }
1776     if ( child )
1777       return TiXmlHandle_t( child );
1778   }
1779   return TiXmlHandle_t( 0 );
1780 }
1781 
1782 
1783 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
1784 {
1785   return true;
1786 }
1787 
1788 bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
1789 {
1790   return true;
1791 }
1792 
1793 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
1794 {
1795   DoIndent();
1796   buffer += "<";
1797   buffer += element.Value();
1798 
1799   for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
1800   {
1801     buffer += " ";
1802     attrib->Print( 0, 0, &buffer );
1803   }
1804 
1805   if ( !element.FirstChild() )
1806   {
1807     buffer += " />";
1808     DoLineBreak();
1809   }
1810   else
1811   {
1812     buffer += ">";
1813     if (    element.FirstChild()->ToText()
1814             && element.LastChild() == element.FirstChild()
1815             && element.FirstChild()->ToText()->CDATA() == false )
1816     {
1817       simpleTextPrint = true;
1818       // no DoLineBreak()!
1819     }
1820     else
1821     {
1822       DoLineBreak();
1823     }
1824   }
1825   ++depth;
1826   return true;
1827 }
1828 
1829 
1830 bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
1831 {
1832   --depth;
1833   if ( !element.FirstChild() )
1834   {
1835     // nothing.
1836   }
1837   else
1838   {
1839     if ( simpleTextPrint )
1840     {
1841       simpleTextPrint = false;
1842     }
1843     else
1844     {
1845       DoIndent();
1846     }
1847     buffer += "</";
1848     buffer += element.Value();
1849     buffer += ">";
1850     DoLineBreak();
1851   }
1852   return true;
1853 }
1854 
1855 
1856 bool TiXmlPrinter::Visit( const TiXmlText& text )
1857 {
1858   if ( text.CDATA() )
1859   {
1860     DoIndent();
1861     buffer += "<![CDATA[";
1862     buffer += text.Value();
1863     buffer += "]]>";
1864     DoLineBreak();
1865   }
1866   else if ( simpleTextPrint )
1867   {
1868     buffer += text.Value();
1869   }
1870   else
1871   {
1872     DoIndent();
1873     buffer += text.Value();
1874     DoLineBreak();
1875   }
1876   return true;
1877 }
1878 
1879 
1880 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
1881 {
1882   DoIndent();
1883   declaration.Print( 0, 0, &buffer );
1884   DoLineBreak();
1885   return true;
1886 }
1887 
1888 
1889 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
1890 {
1891   DoIndent();
1892   buffer += "<!--";
1893   buffer += comment.Value();
1894   buffer += "-->";
1895   DoLineBreak();
1896   return true;
1897 }
1898 
1899 
1900 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
1901 {
1902   DoIndent();
1903   buffer += "<";
1904   buffer += unknown.Value();
1905   buffer += ">";
1906   DoLineBreak();
1907   return true;
1908 }
1909 
1910 
1911 #endif