Logo Search packages:      
Sourcecode: biosig4c++ version File versions  Download package

tinyxml.cpp

/*
www.sourceforge.net/projects/tinyxml
Original code by Lee Thomason (www.grinninglizard.com)

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.


Modified:  Copyright (C) 2009 Alois Schloegl <a.schloegl@ieee.org>
add support for zlib-compressed (gzipped) XML data

    $Id: tinyxml.h,v 1.5 2009/04/09 09:12:09 schloegl Exp $
    Copyright (C) 2009,2011 Alois Schloegl <a.schloegl@ieee.org>
    This file is part of the "BioSig for C/C++" repository
    (biosig4c++) at http://biosig.sf.net/

    BioSig is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 3
    of the License, or (at your option) any later version.

*/

#include <ctype.h>

#ifdef TIXML_USE_STL
#include <sstream>
#include <iostream>
#endif

#include "tinyxml.h"

FILE* TiXmlFOpen( const char* filename, const char* mode );

bool TiXmlBase::condenseWhiteSpace = true;

// Microsoft compiler security
FILE* TiXmlFOpen( const char* filename, const char* mode )
{
      #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
            FILE* fp = 0;
            errno_t err = fopen_s( &fp, filename, mode );
            if ( !err && fp )
                  return fp;
            return 0;
      #else
            return fopen( filename, mode );
      #endif
}

00067 void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
      int i=0;

      while( i<(int)str.length() )
      {
            unsigned char c = (unsigned char) str[i];

            if (    c == '&' 
                 && i < ( (int)str.length() - 2 )
                   && str[i+1] == '#'
                   && str[i+2] == 'x' )
            {
                  // Hexadecimal character reference.
                  // Pass through unchanged.
                  // &#xA9;   -- copyright symbol, for example.
                  //
                  // The -1 is a bug fix from Rob Laveaux. It keeps
                  // an overflow from happening if there is no ';'.
                  // There are actually 2 ways to exit this loop -
                  // while fails (error case) and break (semicolon found).
                  // However, there is no mechanism (currently) for
                  // this function to return an error.
                  while ( i<(int)str.length()-1 )
                  {
                        outString->append( str.c_str() + i, 1 );
                        ++i;
                        if ( str[i] == ';' )
                              break;
                  }
            }
            else if ( c == '&' )
            {
                  outString->append( entity[0].str, entity[0].strLength );
                  ++i;
            }
            else if ( c == '<' )
            {
                  outString->append( entity[1].str, entity[1].strLength );
                  ++i;
            }
            else if ( c == '>' )
            {
                  outString->append( entity[2].str, entity[2].strLength );
                  ++i;
            }
            else if ( c == '\"' )
            {
                  outString->append( entity[3].str, entity[3].strLength );
                  ++i;
            }
            else if ( c == '\'' )
            {
                  outString->append( entity[4].str, entity[4].strLength );
                  ++i;
            }
            else if ( c < 32 )
            {
                  // Easy pass at non-alpha/numeric/symbol
                  // Below 32 is symbolic.
                  char buf[ 32 ];
                  
                  #if defined(TIXML_SNPRINTF)         
                        TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
                  #else
                        sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
                  #endif            

                  //*ME:      warning C4267: convert 'size_t' to 'int'
                  //*ME:      Int-Cast to make compiler happy ...
                  outString->append( buf, (int)strlen( buf ) );
                  ++i;
            }
            else
            {
                  //char realc = (char) c;
                  //outString->append( &realc, 1 );
                  *outString += (char) c; // somewhat more efficient function call.
                  ++i;
            }
      }
}


TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
{
      parent = 0;
      type = _type;
      firstChild = 0;
      lastChild = 0;
      prev = 0;
      next = 0;
}


TiXmlNode::~TiXmlNode()
{
      TiXmlNode* node = firstChild;
      TiXmlNode* temp = 0;

      while ( node )
      {
            temp = node;
            node = node->next;
            delete temp;
      }     
}


void TiXmlNode::CopyTo( TiXmlNode* target ) const
{
      target->SetValue (value.c_str() );
      target->userData = userData; 
      target->location = location;
}


00184 void TiXmlNode::Clear()
{
      TiXmlNode* node = firstChild;
      TiXmlNode* temp = 0;

      while ( node )
      {
            temp = node;
            node = node->next;
            delete temp;
      }     

      firstChild = 0;
      lastChild = 0;
}


00201 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
{
      assert( node->parent == 0 || node->parent == this );
      assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );

      if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
      {
            delete node;
            if ( GetDocument() ) 
                  GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return 0;
      }

      node->parent = this;

      node->prev = lastChild;
      node->next = 0;

      if ( lastChild )
            lastChild->next = node;
      else
            firstChild = node;                  // it was an empty list.

      lastChild = node;
      return node;
}


00229 TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
{
      if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
      {
            if ( GetDocument() ) 
                  GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return 0;
      }
      TiXmlNode* node = addThis.Clone();
      if ( !node )
            return 0;

      return LinkEndChild( node );
}


00245 TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
{     
      if ( !beforeThis || beforeThis->parent != this ) {
            return 0;
      }
      if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
      {
            if ( GetDocument() ) 
                  GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return 0;
      }

      TiXmlNode* node = addThis.Clone();
      if ( !node )
            return 0;
      node->parent = this;

      node->next = beforeThis;
      node->prev = beforeThis->prev;
      if ( beforeThis->prev )
      {
            beforeThis->prev->next = node;
      }
      else
      {
            assert( firstChild == beforeThis );
            firstChild = node;
      }
      beforeThis->prev = node;
      return node;
}


00278 TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
{
      if ( !afterThis || afterThis->parent != this ) {
            return 0;
      }
      if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
      {
            if ( GetDocument() ) 
                  GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return 0;
      }

      TiXmlNode* node = addThis.Clone();
      if ( !node )
            return 0;
      node->parent = this;

      node->prev = afterThis;
      node->next = afterThis->next;
      if ( afterThis->next )
      {
            afterThis->next->prev = node;
      }
      else
      {
            assert( lastChild == afterThis );
            lastChild = node;
      }
      afterThis->next = node;
      return node;
}


00311 TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
{
      if ( !replaceThis )
            return 0;

      if ( replaceThis->parent != this )
            return 0;

      if ( withThis.ToDocument() ) {
            // A document can never be a child. Thanks to Noam.
            TiXmlDocument* document = GetDocument();
            if ( document ) 
                  document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return 0;
      }

      TiXmlNode* node = withThis.Clone();
      if ( !node )
            return 0;

      node->next = replaceThis->next;
      node->prev = replaceThis->prev;

      if ( replaceThis->next )
            replaceThis->next->prev = node;
      else
            lastChild = node;

      if ( replaceThis->prev )
            replaceThis->prev->next = node;
      else
            firstChild = node;

      delete replaceThis;
      node->parent = this;
      return node;
}


00350 bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
{
      if ( !removeThis ) {
            return false;
      }

      if ( removeThis->parent != this )
      {     
            assert( 0 );
            return false;
      }

      if ( removeThis->next )
            removeThis->next->prev = removeThis->prev;
      else
            lastChild = removeThis->prev;

      if ( removeThis->prev )
            removeThis->prev->next = removeThis->next;
      else
            firstChild = removeThis->next;

      delete removeThis;
      return true;
}

00376 const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
{
      const TiXmlNode* node;
      for ( node = firstChild; node; node = node->next )
      {
            if ( strcmp( node->Value(), _value ) == 0 )
                  return node;
      }
      return 0;
}


const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
{
      const TiXmlNode* node;
      for ( node = lastChild; node; node = node->prev )
      {
            if ( strcmp( node->Value(), _value ) == 0 )
                  return node;
      }
      return 0;
}


00400 const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
{
      if ( !previous )
      {
            return FirstChild();
      }
      else
      {
            assert( previous->parent == this );
            return previous->NextSibling();
      }
}


00414 const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
{
      if ( !previous )
      {
            return FirstChild( val );
      }
      else
      {
            assert( previous->parent == this );
            return previous->NextSibling( val );
      }
}


00428 const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
{
      const TiXmlNode* node;
      for ( node = next; node; node = node->next )
      {
            if ( strcmp( node->Value(), _value ) == 0 )
                  return node;
      }
      return 0;
}


00440 const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
{
      const TiXmlNode* node;
      for ( node = prev; node; node = node->prev )
      {
            if ( strcmp( node->Value(), _value ) == 0 )
                  return node;
      }
      return 0;
}


00452 void TiXmlElement::RemoveAttribute( const char * name )
{
    #ifdef TIXML_USE_STL
      TIXML_STRING str( name );
      TiXmlAttribute* node = attributeSet.Find( str );
      #else
      TiXmlAttribute* node = attributeSet.Find( name );
      #endif
      if ( node )
      {
            attributeSet.Remove( node );
            delete node;
      }
}

00467 const TiXmlElement* TiXmlNode::FirstChildElement() const
{
      const TiXmlNode* node;

      for ( node = FirstChild();
                  node;
                  node = node->NextSibling() )
      {
            if ( node->ToElement() )
                  return node->ToElement();
      }
      return 0;
}


00482 const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
{
      const TiXmlNode* node;

      for ( node = FirstChild( _value );
                  node;
                  node = node->NextSibling( _value ) )
      {
            if ( node->ToElement() )
                  return node->ToElement();
      }
      return 0;
}


00497 const TiXmlElement* TiXmlNode::NextSiblingElement() const
{
      const TiXmlNode* node;

      for ( node = NextSibling();
                  node;
                  node = node->NextSibling() )
      {
            if ( node->ToElement() )
                  return node->ToElement();
      }
      return 0;
}


00512 const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
{
      const TiXmlNode* node;

      for ( node = NextSibling( _value );
                  node;
                  node = node->NextSibling( _value ) )
      {
            if ( node->ToElement() )
                  return node->ToElement();
      }
      return 0;
}


00527 const TiXmlDocument* TiXmlNode::GetDocument() const
{
      const TiXmlNode* node;

      for( node = this; node; node = node->parent )
      {
            if ( node->ToDocument() )
                  return node->ToDocument();
      }
      return 0;
}


00540 TiXmlElement::TiXmlElement (const char * _value)
      : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
      firstChild = lastChild = 0;
      value = _value;
}


#ifdef TIXML_USE_STL
TiXmlElement::TiXmlElement( const std::string& _value ) 
      : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
      firstChild = lastChild = 0;
      value = _value;
}
#endif


TiXmlElement::TiXmlElement( const TiXmlElement& copy)
      : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
      firstChild = lastChild = 0;
      copy.CopyTo( this );    
}


TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
{
      ClearThis();
      base.CopyTo( this );
      return *this;
}


TiXmlElement::~TiXmlElement()
{
      ClearThis();
}


void TiXmlElement::ClearThis()
{
      Clear();
      while( attributeSet.First() )
      {
            TiXmlAttribute* node = attributeSet.First();
            attributeSet.Remove( node );
            delete node;
      }
}


00592 const char* TiXmlElement::Attribute( const char* name ) const
{
      const TiXmlAttribute* node = attributeSet.Find( name );
      if ( node )
            return node->Value();
      return 0;
}


#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      if ( attrib )
            return &attrib->ValueStr();
      return 0;
}
#endif


00612 const char* TiXmlElement::Attribute( const char* name, int* i ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      const char* result = 0;

      if ( attrib ) {
            result = attrib->Value();
            if ( i ) {
                  attrib->QueryIntValue( i );
            }
      }
      return result;
}


#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      const std::string* result = 0;

      if ( attrib ) {
            result = &attrib->ValueStr();
            if ( i ) {
                  attrib->QueryIntValue( i );
            }
      }
      return result;
}
#endif


00644 const char* TiXmlElement::Attribute( const char* name, double* d ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      const char* result = 0;

      if ( attrib ) {
            result = attrib->Value();
            if ( d ) {
                  attrib->QueryDoubleValue( d );
            }
      }
      return result;
}


#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      const std::string* result = 0;

      if ( attrib ) {
            result = &attrib->ValueStr();
            if ( d ) {
                  attrib->QueryDoubleValue( d );
            }
      }
      return result;
}
#endif


00676 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      if ( !attrib )
            return TIXML_NO_ATTRIBUTE;
      return attrib->QueryIntValue( ival );
}


#ifdef TIXML_USE_STL
int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      if ( !attrib )
            return TIXML_NO_ATTRIBUTE;
      return attrib->QueryIntValue( ival );
}
#endif


00696 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      if ( !attrib )
            return TIXML_NO_ATTRIBUTE;
      return attrib->QueryDoubleValue( dval );
}


#ifdef TIXML_USE_STL
int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
{
      const TiXmlAttribute* attrib = attributeSet.Find( name );
      if ( !attrib )
            return TIXML_NO_ATTRIBUTE;
      return attrib->QueryDoubleValue( dval );
}
#endif


00716 void TiXmlElement::SetAttribute( const char * name, int val )
{     
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
      if ( attrib ) {
            attrib->SetIntValue( val );
      }
}


#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, int val )
{     
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
      if ( attrib ) {
            attrib->SetIntValue( val );
      }
}
#endif


00736 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
{     
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
      if ( attrib ) {
            attrib->SetDoubleValue( val );
      }
}


#ifdef TIXML_USE_STL
void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
{     
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
      if ( attrib ) {
            attrib->SetDoubleValue( val );
      }
}
#endif 


00756 void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
{
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
      if ( attrib ) {
            attrib->SetValue( cvalue );
      }
}


#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
{
      TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
      if ( attrib ) {
            attrib->SetValue( _value );
      }
}
#endif


00776 void TiXmlElement::Print( FILE* cfile, int depth ) const
{
      int i;
      assert( cfile );
      for ( i=0; i<depth; i++ ) {
            fprintf( cfile, "    " );
      }

      fprintf( cfile, "<%s", value.c_str() );

      const TiXmlAttribute* attrib;
      for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
      {
            fprintf( cfile, " " );
            attrib->Print( cfile, depth );
      }

      // There are 3 different formatting approaches:
      // 1) An element without children is printed as a <foo /> node
      // 2) An element with only a text child is printed as <foo> text </foo>
      // 3) An element with children is printed on multiple lines.
      TiXmlNode* node;
      if ( !firstChild )
      {
            fprintf( cfile, " />" );
      }
      else if ( firstChild == lastChild && firstChild->ToText() )
      {
            fprintf( cfile, ">" );
            firstChild->Print( cfile, depth + 1 );
            fprintf( cfile, "</%s>", value.c_str() );
      }
      else
      {
            fprintf( cfile, ">" );

            for ( node = firstChild; node; node=node->NextSibling() )
            {
                  if ( !node->ToText() )
                  {
                        fprintf( cfile, "\n" );
                  }
                  node->Print( cfile, depth+1 );
            }
            fprintf( cfile, "\n" );
            for( i=0; i<depth; ++i ) {
                  fprintf( cfile, "    " );
            }
            fprintf( cfile, "</%s>", value.c_str() );
      }
}

#ifdef ZLIB_H 
void TiXmlElement::gzPrint( gzFile cfile, int depth ) const
{
      assert( cfile );
      int i;
      assert( cfile );
      for ( i=0; i<depth; i++ ) {
            gzprintf( cfile, "    " );
      }

      gzprintf( cfile, "<%s", value.c_str() );

      const TiXmlAttribute* attrib;
      for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
      {
            gzprintf( cfile, " " );
            attrib->gzPrint( cfile, depth );
      }

      // There are 3 different formatting approaches:
      // 1) An element without children is printed as a <foo /> node
      // 2) An element with only a text child is printed as <foo> text </foo>
      // 3) An element with children is printed on multiple lines.
      TiXmlNode* node;
      if ( !firstChild )
      {
            gzprintf( cfile, " />" );
      }
      else if ( firstChild == lastChild && firstChild->ToText() )
      {
            gzprintf( cfile, ">" );
            firstChild->gzPrint( cfile, depth + 1 );
            gzprintf( cfile, "</%s>", value.c_str() );
      }
      else
      {
            gzprintf( cfile, ">" );

            for ( node = firstChild; node; node=node->NextSibling() )
            {
                  if ( !node->ToText() )
                  {
                        gzprintf( cfile, "\n" );
                  }
                  node->gzPrint( cfile, depth+1 );
            }
            gzprintf( cfile, "\n" );
            for( i=0; i<depth; ++i ) {
                  gzprintf( cfile, "    " );
            }
            gzprintf( cfile, "</%s>", value.c_str() );
      }
}
#endif


void TiXmlElement::CopyTo( TiXmlElement* target ) const
{
      // superclass:
      TiXmlNode::CopyTo( target );

      // Element class: 
      // Clone the attributes, then clone the children.
      const TiXmlAttribute* attribute = 0;
      for(  attribute = attributeSet.First();
      attribute;
      attribute = attribute->Next() )
      {
            target->SetAttribute( attribute->Name(), attribute->Value() );
      }

      TiXmlNode* node = 0;
      for ( node = firstChild; node; node = node->NextSibling() )
      {
            target->LinkEndChild( node->Clone() );
      }
}

00906 bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
{
      if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
      {
            for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
            {
                  if ( !node->Accept( visitor ) )
                        break;
            }
      }
      return visitor->VisitExit( *this );
}


00920 TiXmlNode* TiXmlElement::Clone() const
{
      TiXmlElement* clone = new TiXmlElement( Value() );
      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


00931 const char* TiXmlElement::GetText() const
{
      const TiXmlNode* child = this->FirstChild();
      if ( child ) {
            const TiXmlText* childText = child->ToText();
            if ( childText ) {
                  return childText->Value();
            }
      }
      return 0;
}


00944 TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
      tabsize = 4;
      useMicrosoftBOM = false;
      ClearError();
}

00951 TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
      tabsize = 4;
      useMicrosoftBOM = false;
      value = documentName;
      ClearError();
}


#ifdef TIXML_USE_STL
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
      tabsize = 4;
      useMicrosoftBOM = false;
    value = documentName;
      ClearError();
}
#endif


TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
      copy.CopyTo( this );
}


TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
{
      Clear();
      copy.CopyTo( this );
      return *this;
}


00985 bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
{
      return LoadFile( Value(), encoding );
}


00991 bool TiXmlDocument::SaveFile() const
{
      return SaveFile( Value() );
}

00996 bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
{
      TIXML_STRING filename( _filename );
      value = filename;

      // reading in binary mode so that tinyxml can normalize the EOL
#ifdef ZLIB_H
      gzFile file;
      file = gzopen( value.c_str(), "rb" );     
      if ( file )
      {
            bool result = LoadFile( file, encoding );
            gzclose( file );
            return result;
      }
#else
      FILE* file = TiXmlFOpen( value.c_str (), "rb" );      

      if ( file )
      {
            bool result = LoadFile( file, encoding );
            fclose( file );
            return result;
      }
#endif 
      else
      {
            SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
            return false;
      }
}

01028 bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
{
      if ( !file ) 
      {
            SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
            return false;
      }

      // Delete the existing data:
      Clear();
      location.Clear();

      // Get the file size, so we can pre-allocate the string. HUGE speed impact.
      long length = 0;
      fseek( file, 0, SEEK_END );
      length = ftell( file );
      fseek( file, 0, SEEK_SET );

      // Strange case, but good to handle up front.
      if ( length <= 0 )
      {
            SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
            return false;
      }

      // Subtle bug here. TinyXml did use fgets. But from the XML spec:
      // 2.11 End-of-Line Handling
      // <snip>
      // <quote>
      // ...the XML processor MUST behave as if it normalized all line breaks in external 
      // parsed entities (including the document entity) on input, before parsing, by translating 
      // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
      // a single #xA character.
      // </quote>
      //
      // It is not clear fgets does that, and certainly isn't clear it works cross platform. 
      // Generally, you expect fgets to translate from the convention of the OS to the c/unix
      // convention, and not work generally.

      /*
      while( fgets( buf, sizeof(buf), file ) )
      {
            data += buf;
      }
      */

      char* buf = new char[ length+1 ];
      buf[0] = 0;

      if ( fread( buf, length, 1, file ) != 1 ) {
            delete [] buf;
            SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
            return false;
      }

      // Process the buffer in place to normalize new lines. (See comment above.)
      // Copies from the 'p' to 'q' pointer, where p can advance faster if
      // a newline-carriage return is hit.
      //
      // Wikipedia:
      // Systems based on ASCII or a compatible character set use either LF  (Line feed, '\n', 0x0A, 10 in decimal) or 
      // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
      //          * LF:    Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
    //            * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
    //            * CR:    Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9

      const char* p = buf;    // the read head
      char* q = buf;                // the write head
      const char CR = 0x0d;
      const char LF = 0x0a;

      buf[length] = 0;
      while( *p ) {
            assert( p < (buf+length) );
            assert( q <= (buf+length) );
            assert( q <= p );

            if ( *p == CR ) {
                  *q++ = LF;
                  p++;
                  if ( *p == LF ) {       // check for CR+LF (and skip LF)
                        p++;
                  }
            }
            else {
                  *q++ = *p++;
            }
      }
      assert( q <= (buf+length) );
      *q = 0;

      Parse( buf, 0, encoding );

      delete [] buf;
      return !Error();
}


#ifdef ZLIB_H
bool TiXmlDocument::LoadFile(gzFile file, TiXmlEncoding encoding )
{

      char *buf = NULL;
      long length = 0; 

      // file is loaded in hdr->AS.Header; 
      size_t buflen = 1l<<18; 
      while (!gzeof(file)) {
            buf = (char*)realloc(buf, buflen);
            length += gzread(file, buf+length, buflen-1);
            buflen *= 2;
      }
      buf[length] = 0;
      buf = (char*)realloc(buf,length+1);

      // Process the buffer in place to normalize new lines. (See comment above.)
      // Copies from the 'p' to 'q' pointer, where p can advance faster if
      // a newline-carriage return is hit.
      //
      // Wikipedia:
      // Systems based on ASCII or a compatible character set use either LF  (Line feed, '\n', 0x0A, 10 in decimal) or 
      // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
      //          * LF:    Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
    //            * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
    //            * CR:    Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9

      const char* p = buf;    // the read head
      char* q = buf;                // the write head
      const char CR = 0x0d;
      const char LF = 0x0a;

      buf[length] = 0;
      while( *p ) {
            assert( p < (buf+length) );
            assert( q <= (buf+length) );
            assert( q <= p );

            if ( *p == CR ) {
                  *q++ = LF;
                  p++;
                  if ( *p == LF ) {       // check for CR+LF (and skip LF)
                        p++;
                  }
            }
            else {
                  *q++ = *p++;
            }
      }
      assert( q <= (buf+length) );
      *q = 0;

      Parse( buf, 0, encoding );

      delete [] buf;
      return !Error();
}
#endif 


bool TiXmlDocument::SaveFile( const char * filename, char compression ) const
{
      // The old c stuff lives on...

      if (compression) {
#ifdef ZLIB_H 
            gzFile fid = gzopen(filename, "wb" );
            if (fid) {
                  bool result = SaveFile(fid);
                  gzclose(fid);
                  return result;
            }     
#else
            fprintf(stdout,"warning: zlib compression not supported\n"); 
#endif
      } 
      else {
            FILE *fid = fopen(filename, "wb" );
            if (fid) {
                  bool result = SaveFile(fid);
                  fclose(fid);
                  return result;
            }     
      }
      return false;
}


01215 bool TiXmlDocument::SaveFile( const char * filename ) const
{
      // The old c stuff lives on...
      FILE* fp = TiXmlFOpen( filename, "w" );
      if ( fp )
      {
            bool result = SaveFile( fp );
            fclose( fp );
            return result;
      }
      return false;
}


01229 bool TiXmlDocument::SaveFile( FILE* fp ) const
{
      if ( useMicrosoftBOM ) 
      {
            const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
            const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
            const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;

            fputc( TIXML_UTF_LEAD_0, fp );
            fputc( TIXML_UTF_LEAD_1, fp );
            fputc( TIXML_UTF_LEAD_2, fp );
      }
      Print( fp, 0 );
      return (ferror(fp) == 0);
}

#ifdef ZLIB_H 
bool TiXmlDocument::SaveFile( gzFile fp ) const
{
      if ( useMicrosoftBOM ) 
      {
            const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
            const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
            const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;

            gzputc( fp, TIXML_UTF_LEAD_0 );
            gzputc( fp, TIXML_UTF_LEAD_1 );
            gzputc( fp, TIXML_UTF_LEAD_2 );
      }
      gzPrint( fp, 0 ); 
      int err;
      gzerror(fp,&err);
      return (err!=0);
}
#endif 



void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
{
      TiXmlNode::CopyTo( target );

      target->error = error;
      target->errorId = errorId;
      target->errorDesc = errorDesc;
      target->tabsize = tabsize;
      target->errorLocation = errorLocation;
      target->useMicrosoftBOM = useMicrosoftBOM;

      TiXmlNode* node = 0;
      for ( node = firstChild; node; node = node->NextSibling() )
      {
            target->LinkEndChild( node->Clone() );
      }     
}


01286 TiXmlNode* TiXmlDocument::Clone() const
{
      TiXmlDocument* clone = new TiXmlDocument();
      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


01297 void TiXmlDocument::Print( FILE* cfile, int depth ) const
{
      assert( cfile );
      for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
      {
            node->Print( cfile, depth );
            fprintf( cfile, "\n" );
      }
}

#ifdef ZLIB_H 
void TiXmlDocument::gzPrint( gzFile cfile, int depth ) const
{
      assert( cfile );
      for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
      {
            node->gzPrint( cfile, depth );
            gzprintf( cfile, "\n" );
      }
}
#endif

01319 bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
{
      if ( visitor->VisitEnter( *this ) )
      {
            for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
            {
                  if ( !node->Accept( visitor ) )
                        break;
            }
      }
      return visitor->VisitExit( *this );
}


01333 const TiXmlAttribute* TiXmlAttribute::Next() const
{
      // We are using knowledge of the sentinel. The sentinel
      // have a value or name.
      if ( next->value.empty() && next->name.empty() )
            return 0;
      return next;
}

/*
TiXmlAttribute* TiXmlAttribute::Next()
{
      // We are using knowledge of the sentinel. The sentinel
      // have a value or name.
      if ( next->value.empty() && next->name.empty() )
            return 0;
      return next;
}
*/

01353 const TiXmlAttribute* TiXmlAttribute::Previous() const
{
      // We are using knowledge of the sentinel. The sentinel
      // have a value or name.
      if ( prev->value.empty() && prev->name.empty() )
            return 0;
      return prev;
}

/*
TiXmlAttribute* TiXmlAttribute::Previous()
{
      // We are using knowledge of the sentinel. The sentinel
      // have a value or name.
      if ( prev->value.empty() && prev->name.empty() )
            return 0;
      return prev;
}
*/

void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
{
      TIXML_STRING n, v;

      EncodeString( name, &n );
      EncodeString( value, &v );

      if (value.find ('\"') == TIXML_STRING::npos) {
            if ( cfile ) {
            fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
            }
            if ( str ) {
                  (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
            }
      }
      else {
            if ( cfile ) {
            fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
            }
            if ( str ) {
                  (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
            }
      }
}

#ifdef ZLIB_H 
void TiXmlAttribute::gzPrint( gzFile cfile, int /*depth*/, TIXML_STRING* str ) const
{
      TIXML_STRING n, v;

      EncodeString( name, &n );
      EncodeString( value, &v );

      if (value.find ('\"') == TIXML_STRING::npos) {
            if ( cfile ) {
            gzprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
            }
            if ( str ) {
                  (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
            }
      }
      else {
            if ( cfile ) {
            gzprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
            }
            if ( str ) {
                  (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
            }
      }
}
#endif


01426 int TiXmlAttribute::QueryIntValue( int* ival ) const
{
      if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
            return TIXML_SUCCESS;
      return TIXML_WRONG_TYPE;
}

01433 int TiXmlAttribute::QueryDoubleValue( double* dval ) const
{
      if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
            return TIXML_SUCCESS;
      return TIXML_WRONG_TYPE;
}

01440 void TiXmlAttribute::SetIntValue( int _value )
{
      char buf [64];
      #if defined(TIXML_SNPRINTF)         
            TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
      #else
            sprintf (buf, "%d", _value);
      #endif
      SetValue (buf);
}

01451 void TiXmlAttribute::SetDoubleValue( double _value )
{
      char buf [256];
      #if defined(TIXML_SNPRINTF)         
            TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
      #else
            sprintf (buf, "%g", _value);
      #endif
      SetValue (buf);
}

01462 int TiXmlAttribute::IntValue() const
{
      return atoi (value.c_str ());
}

01467 double  TiXmlAttribute::DoubleValue() const
{
      return atof (value.c_str ());
}


TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
{
      copy.CopyTo( this );
}


TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
{
      Clear();
      base.CopyTo( this );
      return *this;
}


01487 void TiXmlComment::Print( FILE* cfile, int depth ) const
{
      assert( cfile );
      for ( int i=0; i<depth; i++ )
      {
            fprintf( cfile,  "    " );
      }
      fprintf( cfile, "<!--%s-->", value.c_str() );
}

#ifdef ZLIB_H
void TiXmlComment::gzPrint( gzFile cfile, int depth ) const
{
      assert( cfile );
      for ( int i=0; i<depth; i++ )
      {
            gzprintf( cfile,  "    " );
      }
      gzprintf( cfile, "<!--%s-->", value.c_str() );
}
#endif

void TiXmlComment::CopyTo( TiXmlComment* target ) const
{
      TiXmlNode::CopyTo( target );
}


01515 bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
{
      return visitor->Visit( *this );
}


01521 TiXmlNode* TiXmlComment::Clone() const
{
      TiXmlComment* clone = new TiXmlComment();

      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


01533 void TiXmlText::Print( FILE* cfile, int depth ) const
{
      assert( cfile );
      if ( cdata )
      {
            int i;
            fprintf( cfile, "\n" );
            for ( i=0; i<depth; i++ ) {
                  fprintf( cfile, "    " );
            }
            fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );  // unformatted output
      }
      else
      {
            TIXML_STRING buffer;
            EncodeString( value, &buffer );
            fprintf( cfile, "%s", buffer.c_str() );
      }
}

#ifdef ZLIB_H
void TiXmlText::gzPrint( gzFile cfile, int depth ) const
{
      assert( cfile );
      if ( cdata )
      {
            int i;
            gzprintf( cfile, "\n" );
            for ( i=0; i<depth; i++ ) {
                  gzprintf( cfile, "    " );
            }
            gzprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output
      }
      else
      {
            TIXML_STRING buffer;
            EncodeString( value, &buffer );
            gzprintf( cfile, "%s", buffer.c_str() );
      }
}
#endif


void TiXmlText::CopyTo( TiXmlText* target ) const
{
      TiXmlNode::CopyTo( target );
      target->cdata = cdata;
}


01583 bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
{
      return visitor->Visit( *this );
}


01589 TiXmlNode* TiXmlText::Clone() const
{     
      TiXmlText* clone = 0;
      clone = new TiXmlText( "" );

      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


01602 TiXmlDeclaration::TiXmlDeclaration( const char * _version,
                                                      const char * _encoding,
                                                      const char * _standalone )
      : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
      version = _version;
      encoding = _encoding;
      standalone = _standalone;
}


#ifdef TIXML_USE_STL
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
                                                      const std::string& _encoding,
                                                      const std::string& _standalone )
      : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
      version = _version;
      encoding = _encoding;
      standalone = _standalone;
}
#endif


TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
      : TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
      copy.CopyTo( this );    
}


TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
{
      Clear();
      copy.CopyTo( this );
      return *this;
}


void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
{
      if ( cfile ) fprintf( cfile, "<?xml " );
      if ( str )   (*str) += "<?xml ";

      if ( !version.empty() ) {
            if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
            if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
      }
      if ( !encoding.empty() ) {
            if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
            if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
      }
      if ( !standalone.empty() ) {
            if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
            if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
      }
      if ( cfile ) fprintf( cfile, "?>" );
      if ( str )   (*str) += "?>";
}

#ifdef ZLIB_H
void TiXmlDeclaration::gzPrint( gzFile cfile, int /*depth*/, TIXML_STRING* str ) const
{
      if ( cfile ) gzprintf( cfile, "<?xml " );
      if ( str )   (*str) += "<?xml ";

      if ( !version.empty() ) {
            if ( cfile ) gzprintf (cfile, "version=\"%s\" ", version.c_str ());
            if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
      }
      if ( !encoding.empty() ) {
            if ( cfile ) gzprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
            if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
      }
      if ( !standalone.empty() ) {
            if ( cfile ) gzprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
            if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
      }
      if ( cfile ) gzprintf( cfile, "?>" );
      if ( str )   (*str) += "?>";
}
#endif


void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
{
      TiXmlNode::CopyTo( target );

      target->version = version;
      target->encoding = encoding;
      target->standalone = standalone;
}


01696 bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
{
      return visitor->Visit( *this );
}


01702 TiXmlNode* TiXmlDeclaration::Clone() const
{     
      TiXmlDeclaration* clone = new TiXmlDeclaration();

      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


01714 void TiXmlUnknown::Print( FILE* cfile, int depth ) const
{
      for ( int i=0; i<depth; i++ )
            fprintf( cfile, "    " );
      fprintf( cfile, "<%s>", value.c_str() );
}

#ifdef ZLIB_H
void TiXmlUnknown::gzPrint( gzFile cfile, int depth ) const
{
      for ( int i=0; i<depth; i++ )
            gzprintf( cfile, "    " );
      gzprintf( cfile, "<%s>", value.c_str() );
}
#endif

void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
{
      TiXmlNode::CopyTo( target );
}


01736 bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
{
      return visitor->Visit( *this );
}


01742 TiXmlNode* TiXmlUnknown::Clone() const
{
      TiXmlUnknown* clone = new TiXmlUnknown();

      if ( !clone )
            return 0;

      CopyTo( clone );
      return clone;
}


TiXmlAttributeSet::TiXmlAttributeSet()
{
      sentinel.next = &sentinel;
      sentinel.prev = &sentinel;
}


TiXmlAttributeSet::~TiXmlAttributeSet()
{
      assert( sentinel.next == &sentinel );
      assert( sentinel.prev == &sentinel );
}


void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
{
    #ifdef TIXML_USE_STL
      assert( !Find( TIXML_STRING( addMe->Name() ) ) );     // Shouldn't be multiply adding to the set.
      #else
      assert( !Find( addMe->Name() ) );   // Shouldn't be multiply adding to the set.
      #endif

      addMe->next = &sentinel;
      addMe->prev = sentinel.prev;

      sentinel.prev->next = addMe;
      sentinel.prev      = addMe;
}

void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
{
      TiXmlAttribute* node;

      for( node = sentinel.next; node != &sentinel; node = node->next )
      {
            if ( node == removeMe )
            {
                  node->prev->next = node->next;
                  node->next->prev = node->prev;
                  node->next = 0;
                  node->prev = 0;
                  return;
            }
      }
      assert( 0 );            // we tried to remove a non-linked attribute.
}


#ifdef TIXML_USE_STL
TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
{
      for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
      {
            if ( node->name == name )
                  return node;
      }
      return 0;
}

TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
{
      TiXmlAttribute* attrib = Find( _name );
      if ( !attrib ) {
            attrib = new TiXmlAttribute();
            Add( attrib );
            attrib->SetName( _name );
      }
      return attrib;
}
#endif


TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
{
      for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
      {
            if ( strcmp( node->name.c_str(), name ) == 0 )
                  return node;
      }
      return 0;
}


TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
{
      TiXmlAttribute* attrib = Find( _name );
      if ( !attrib ) {
            attrib = new TiXmlAttribute();
            Add( attrib );
            attrib->SetName( _name );
      }
      return attrib;
}


#ifdef TIXML_USE_STL    
std::istream& operator>> (std::istream & in, TiXmlNode & base)
{
      TIXML_STRING tag;
      tag.reserve( 8 * 1000 );
      base.StreamIn( &in, &tag );

      base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
      return in;
}
#endif


#ifdef TIXML_USE_STL    
std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
{
      TiXmlPrinter printer;
      printer.SetStreamPrinting();
      base.Accept( &printer );
      out << printer.Str();

      return out;
}


std::string& operator<< (std::string& out, const TiXmlNode& base )
{
      TiXmlPrinter printer;
      printer.SetStreamPrinting();
      base.Accept( &printer );
      out.append( printer.Str() );

      return out;
}
#endif


01886 TiXmlHandle TiXmlHandle::FirstChild() const
{
      if ( node )
      {
            TiXmlNode* child = node->FirstChild();
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01898 TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
{
      if ( node )
      {
            TiXmlNode* child = node->FirstChild( value );
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01910 TiXmlHandle TiXmlHandle::FirstChildElement() const
{
      if ( node )
      {
            TiXmlElement* child = node->FirstChildElement();
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01922 TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
{
      if ( node )
      {
            TiXmlElement* child = node->FirstChildElement( value );
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01934 TiXmlHandle TiXmlHandle::Child( int count ) const
{
      if ( node )
      {
            int i;
            TiXmlNode* child = node->FirstChild();
            for ( i=0;
                        child && i<count;
                        child = child->NextSibling(), ++i )
            {
                  // nothing
            }
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01953 TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
{
      if ( node )
      {
            int i;
            TiXmlNode* child = node->FirstChild( value );
            for ( i=0;
                        child && i<count;
                        child = child->NextSibling( value ), ++i )
            {
                  // nothing
            }
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01972 TiXmlHandle TiXmlHandle::ChildElement( int count ) const
{
      if ( node )
      {
            int i;
            TiXmlElement* child = node->FirstChildElement();
            for ( i=0;
                        child && i<count;
                        child = child->NextSiblingElement(), ++i )
            {
                  // nothing
            }
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


01991 TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
{
      if ( node )
      {
            int i;
            TiXmlElement* child = node->FirstChildElement( value );
            for ( i=0;
                        child && i<count;
                        child = child->NextSiblingElement( value ), ++i )
            {
                  // nothing
            }
            if ( child )
                  return TiXmlHandle( child );
      }
      return TiXmlHandle( 0 );
}


02010 bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
{
      return true;
}

02015 bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
{
      return true;
}

02020 bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
{
      DoIndent();
      buffer += "<";
      buffer += element.Value();

      for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
      {
            buffer += " ";
            attrib->Print( 0, 0, &buffer );
      }

      if ( !element.FirstChild() ) 
      {
            buffer += " />";
            DoLineBreak();
      }
      else 
      {
            buffer += ">";
            if (    element.FirstChild()->ToText()
                    && element.LastChild() == element.FirstChild()
                    && element.FirstChild()->ToText()->CDATA() == false )
            {
                  simpleTextPrint = true;
                  // no DoLineBreak()!
            }
            else
            {
                  DoLineBreak();
            }
      }
      ++depth;    
      return true;
}


02057 bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
{
      --depth;
      if ( !element.FirstChild() ) 
      {
            // nothing.
      }
      else 
      {
            if ( simpleTextPrint )
            {
                  simpleTextPrint = false;
            }
            else
            {
                  DoIndent();
            }
            buffer += "</";
            buffer += element.Value();
            buffer += ">";
            DoLineBreak();
      }
      return true;
}


02083 bool TiXmlPrinter::Visit( const TiXmlText& text )
{
      if ( text.CDATA() )
      {
            DoIndent();
            buffer += "<![CDATA[";
            buffer += text.Value();
            buffer += "]]>";
            DoLineBreak();
      }
      else if ( simpleTextPrint )
      {
            TIXML_STRING str;
            TiXmlBase::EncodeString( text.ValueTStr(), &str );
            buffer += str;
      }
      else
      {
            DoIndent();
            TIXML_STRING str;
            TiXmlBase::EncodeString( text.ValueTStr(), &str );
            buffer += str;
            DoLineBreak();
      }
      return true;
}


02111 bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
{
      DoIndent();
      declaration.Print( 0, 0, &buffer );
      DoLineBreak();
      return true;
}


02120 bool TiXmlPrinter::Visit( const TiXmlComment& comment )
{
      DoIndent();
      buffer += "<!--";
      buffer += comment.Value();
      buffer += "-->";
      DoLineBreak();
      return true;
}


02131 bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
{
      DoIndent();
      buffer += "<";
      buffer += unknown.Value();
      buffer += ">";
      DoLineBreak();
      return true;
}


Generated by  Doxygen 1.6.0   Back to index