]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/xml/xmlwriter.h
Merge branch 'NateEag-master-patch-12920' into 'master'
[xonotic/netradiant.git] / libs / xml / xmlwriter.h
index 8cf40bddf5b22e555674fe9b597355147057c705..f54662f7a58415b81a74fea12f4875530aa23728 100644 (file)
 /*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+   Copyright (C) 2001-2006, William Joseph.
+   All Rights Reserved.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant 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 2 of the License, or
-(at your option) any later version.
+   GtkRadiant 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 2 of the License, or
+   (at your option) any later version.
 
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
-#if !defined(INCLUDED_XML_XMLWRITER_H)
+#if !defined( INCLUDED_XML_XMLWRITER_H )
 #define INCLUDED_XML_XMLWRITER_H
 
 #include "convert.h"
 #include <vector>
 #include "xml/ixml.h"
 
-class BufferedTextOutputStream : public TextOutputStream
-{
-  static const int m_bufsize = 1024;
-  TextOutputStream& m_ostream;
-  char m_buffer[m_bufsize];
-  char* m_pos;
-  const char* m_end;
-
-  const char* end() const
-  {
-    return m_end;
-  }
-  void reset()
-  {
-    m_pos = m_buffer;
-  }
-  void flush()
-  {
-    m_ostream.write(m_buffer, m_pos - m_buffer);
-    reset();
-  }
-public:
-  BufferedTextOutputStream(TextOutputStream& ostream) : m_ostream(ostream), m_pos(m_buffer), m_end(m_buffer+m_bufsize)
-  {
-  }
-  ~BufferedTextOutputStream()
-  {
-    flush();
-  }
-  void write(const char c)
-  {
-    if(m_pos == end())
-    {
-      flush();
-    }
-    *m_pos++ = c;
-  }
-  std::size_t write(const char* buffer, std::size_t length)
-  {
-    const char*const end = buffer + length;
-    for(const char* p = buffer; p != end; ++p)
-    {
-      write(*p);
-    }
-    return length;
-  }
-};
-
 class XMLEntityOutputStream
 {
-  BufferedTextOutputStream m_ostream;
+SingleCharacterOutputStream m_ostream;
 public:
-  XMLEntityOutputStream(TextOutputStream& ostream)
-    : m_ostream(ostream)
-  {
-  }
-  void write(const char c)
-  {
-    m_ostream.write(c);
-  }
-  void writeEscaped(const char c)
-  {
-    switch(c)
-    {
-    case '<':
-      write('&');
-      write('l');
-      write('t');
-      write(';');
-      break;
-    case '>':
-      write('&');
-      write('g');
-      write('t');
-      write(';');
-      break;
-    case '"':
-      write('&');
-      write('q');
-      write('u');
-      write('o');
-      write('t');
-      write(';');
-      break;
-    case '&':
-      write('&');
-      write('a');
-      write('m');
-      write('p');
-      write(';');
-      break;
-    default:
-      write(c);
-      break;
-    }
-  }
-  std::size_t write(const char* buffer, std::size_t length)
-  {
-    const char*const end = buffer + length;
-    for(const char* p = buffer; p != end; ++p)
-    {
-      writeEscaped(*p);
-    }
-    return length;
-  }
+XMLEntityOutputStream( TextOutputStream& ostream )
+       : m_ostream( ostream ){
+}
+void write( const char c ){
+       m_ostream.write( c );
+}
+void writeEscaped( const char c ){
+       switch ( c )
+       {
+       case '<':
+               write( '&' );
+               write( 'l' );
+               write( 't' );
+               write( ';' );
+               break;
+       case '>':
+               write( '&' );
+               write( 'g' );
+               write( 't' );
+               write( ';' );
+               break;
+       case '"':
+               write( '&' );
+               write( 'q' );
+               write( 'u' );
+               write( 'o' );
+               write( 't' );
+               write( ';' );
+               break;
+       case '&':
+               write( '&' );
+               write( 'a' );
+               write( 'm' );
+               write( 'p' );
+               write( ';' );
+               break;
+       default:
+               write( c );
+               break;
+       }
+}
+std::size_t write( const char* buffer, std::size_t length ){
+       const char*const end = buffer + length;
+       for ( const char* p = buffer; p != end; ++p )
+       {
+               writeEscaped( *p );
+       }
+       return length;
+}
 };
 
 template<typename T>
-inline XMLEntityOutputStream& operator<<(XMLEntityOutputStream& ostream, const T& t)
-{
-  return ostream_write(ostream, t);
+inline XMLEntityOutputStream& operator<<( XMLEntityOutputStream& ostream, const T& t ){
+       return ostream_write( ostream, t );
 }
 
 
 class XMLStreamWriter : public XMLImporter, public XMLAttrVisitor
 {
-  class state_t
-  {
-  public:
-    enum EState
-    {
-      eStartElement,
-      eContent,
-    };
-    state_t()
-      : m_state(eStartElement)
-    {}
-    EState m_state;
-  };
-
-  XMLEntityOutputStream m_ostream;
-  std::vector<state_t> m_elements;
-
-  void write_cdata(const char* buffer, std::size_t length)
-  {
-    m_ostream << ConvertLocaleToUTF8(StringRange(buffer, buffer + length));
-  }
-  void write_string(const char* string)
-  {
-    m_ostream << string;
-  }
-  void write_quoted_string(const char* string)
-  {
-    m_ostream.write('"');
-    m_ostream << string;
-    m_ostream.write('"');
-  }
+class state_t
+{
+public:
+enum EState
+{
+       eStartElement,
+       eContent,
+};
+state_t()
+       : m_state( eStartElement )
+{}
+EState m_state;
+};
+
+XMLEntityOutputStream m_ostream;
+std::vector<state_t> m_elements;
+
+void write_cdata( const char* buffer, std::size_t length ){
+       m_ostream << StringRange( buffer, buffer + length );
+}
+void write_string( const char* string ){
+       m_ostream << string;
+}
+void write_quoted_string( const char* string ){
+       m_ostream.write( '"' );
+       m_ostream << string;
+       m_ostream.write( '"' );
+}
 public:
-  XMLStreamWriter(TextOutputStream& ostream)
-    : m_ostream(ostream)
-  {
-    m_elements.push_back(state_t());
-    m_elements.back().m_state = state_t::eContent;
-    m_ostream.write('<');
-    m_ostream.write('?');
-    write_string("xml");
-    visit("version", "1.0");
-    m_ostream.write('?');
-    m_ostream.write('>');
-  }
-
-  void pushElement(const XMLElement& element)
-  {
-    if(m_elements.back().m_state == state_t::eStartElement)
-    {
-      m_elements.back().m_state = state_t::eContent;
-      m_ostream.write('>');
-    }
-
-    m_elements.push_back(state_t());
-
-    m_ostream.write('<');
-    write_string(element.name());
-    element.forEachAttribute(*this);
-  }
-  void popElement(const char* name)
-  {
-    if(m_elements.back().m_state == state_t::eStartElement)
-    {
-      m_ostream.write('/');
-      m_ostream.write('>');
-    }
-    else
-    {
-      m_ostream.write('<');
-      m_ostream.write('/');
-      write_string(name);
-      m_ostream.write('>');
-    }
-  }
-  std::size_t write(const char* data, std::size_t length)
-  {
-    if(m_elements.back().m_state == state_t::eStartElement)
-    {
-      m_elements.back().m_state = state_t::eContent;
-      m_ostream.write('>');
-    }
-    write_cdata(data, length);
-    return length;
-  }
-
-  void visit(const char* name, const char* value)
-  {
-    m_ostream.write(' ');
-    write_string(name);
-    m_ostream.write('=');
-    write_quoted_string(value);
-  }
+XMLStreamWriter( TextOutputStream& ostream )
+       : m_ostream( ostream ){
+       m_elements.push_back( state_t() );
+       m_elements.back().m_state = state_t::eContent;
+       m_ostream.write( '<' );
+       m_ostream.write( '?' );
+       write_string( "xml" );
+       visit( "version", "1.0" );
+       m_ostream.write( '?' );
+       m_ostream.write( '>' );
+}
+
+void pushElement( const XMLElement& element ){
+       if ( m_elements.back().m_state == state_t::eStartElement ) {
+               m_elements.back().m_state = state_t::eContent;
+               m_ostream.write( '>' );
+       }
+
+       m_elements.push_back( state_t() );
+
+       m_ostream.write( '<' );
+       write_string( element.name() );
+       element.forEachAttribute( *this );
+}
+void popElement( const char* name ){
+       if ( m_elements.back().m_state == state_t::eStartElement ) {
+               m_ostream.write( '/' );
+               m_ostream.write( '>' );
+               m_elements.pop_back();
+       }
+       else
+       {
+               m_ostream.write( '<' );
+               m_ostream.write( '/' );
+               write_string( name );
+               m_ostream.write( '>' );
+               m_elements.pop_back();
+       }
+}
+std::size_t write( const char* data, std::size_t length ){
+       if ( m_elements.back().m_state == state_t::eStartElement ) {
+               m_elements.back().m_state = state_t::eContent;
+               m_ostream.write( '>' );
+       }
+       write_cdata( data, length );
+       return length;
+}
+
+void visit( const char* name, const char* value ){
+       m_ostream.write( ' ' );
+       write_string( name );
+       m_ostream.write( '=' );
+       write_quoted_string( value );
+}
 };