Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-09 07:52:00

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