/* OutputStreamWriter.java -- Writer that converts chars to bytes
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.io;

import gnu.java.nio.charset.EncodingHelper;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.MalformedInputException;

/**
 * This class writes characters to an output stream that is byte oriented
 * It converts the chars that are written to bytes using an encoding layer,
 * which is specific to a particular encoding standard.  The desired
 * encoding can either be specified by name, or if no encoding is specified,
 * the system default encoding will be used.  The system default encoding
 * name is determined from the system property <code>file.encoding</code>.
 * The only encodings that are guaranteed to be available are "8859_1"
 * (the Latin-1 character set) and "UTF8".  Unfortunately, Java does not
 * provide a mechanism for listing the encodings that are supported in
 * a given implementation.
 * <p>
 * Here is a list of standard encoding names that may be available:
 * <p>
 * <ul>
 * <li>8859_1 (ISO-8859-1/Latin-1)
 * <li>8859_2 (ISO-8859-2/Latin-2)
 * <li>8859_3 (ISO-8859-3/Latin-3)
 * <li>8859_4 (ISO-8859-4/Latin-4)
 * <li>8859_5 (ISO-8859-5/Latin-5)
 * <li>8859_6 (ISO-8859-6/Latin-6)
 * <li>8859_7 (ISO-8859-7/Latin-7)
 * <li>8859_8 (ISO-8859-8/Latin-8)
 * <li>8859_9 (ISO-8859-9/Latin-9)
 * <li>ASCII (7-bit ASCII)
 * <li>UTF8 (UCS Transformation Format-8)
 * <li>More Later
 * </ul>
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner (bothner@cygnus.com)
 * @date April 17, 1998.
 */
public class OutputStreamWriter extends Writer
{
  /**
   * The output stream.
   */
  private OutputStream out;

  /**
   * The charset encoder.
   */
  private final CharsetEncoder encoder;

  /**
   * java.io canonical name of the encoding.
   */
  private final String encodingName;

  /**
   * Buffer output before character conversion as it has costly overhead.
   */
  private final CharBuffer outputBuffer;
  private final static int BUFFER_SIZE = 1024;

  /**
   * This method initializes a new instance of <code>OutputStreamWriter</code>
   * to write to the specified stream using a caller supplied character
   * encoding scheme.  Note that due to a deficiency in the Java language
   * design, there is no way to determine which encodings are supported.
   *
   * @param out The <code>OutputStream</code> to write to
   * @param encoding_scheme The name of the encoding scheme to use for
   * character to byte translation
   *
   * @exception UnsupportedEncodingException If the named encoding is
   * not available.
   */
  public OutputStreamWriter (OutputStream out, String encoding_scheme)
    throws UnsupportedEncodingException
  {
    CharsetEncoder encoder;
    String encodingName;
    this.out = out;
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);

    try
      {
        // Don't use NIO if avoidable
        if(EncodingHelper.isISOLatin1(encoding_scheme))
          {
            encodingName = "ISO8859_1";
            encoder = null;
          }
       else
         {
           /*
            * Workaround for encodings with a byte-order-mark.
            * We only want to write it once per stream.
            */
           try
             {
               if(encoding_scheme.equalsIgnoreCase("UnicodeBig") ||
                  encoding_scheme.equalsIgnoreCase("UTF-16") ||
                  encoding_scheme.equalsIgnoreCase("UTF16"))
                 {
                   encoding_scheme = "UTF-16BE";
                   out.write((byte)0xFE);
                   out.write((byte)0xFF);
                 }
               else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle"))
                 {
                   encoding_scheme = "UTF-16LE";
                   out.write((byte)0xFF);
                   out.write((byte)0xFE);
                 }
             }
           catch(IOException ioe)
             {
             }

           Charset cs = EncodingHelper.getCharset(encoding_scheme);
           if(cs == null)
             throw new UnsupportedEncodingException("Encoding "+encoding_scheme+
                                                    " unknown");
           encoder = cs.newEncoder();
           encodingName = EncodingHelper.getOldCanonical(cs.name());

           encoder.onMalformedInput(CodingErrorAction.REPLACE);
           encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
         }
      }
    catch(RuntimeException e)
      {
        // Default to ISO Latin-1, will happen if this is called, for instance,
        //  before the NIO provider is loadable.
        encoder = null;
        encodingName = "ISO8859_1";
      }
    this.encoder = encoder;
    this.encodingName = encodingName;
  }

  /**
   * This method initializes a new instance of <code>OutputStreamWriter</code>
   * to write to the specified stream using the default encoding.
   *
   * @param out The <code>OutputStream</code> to write to
   */
  public OutputStreamWriter (OutputStream out)
  {
    CharsetEncoder encoder;
    String encodingName;
    this.out = out;
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
    try
      {
        String encoding = System.getProperty("file.encoding");
        Charset cs = Charset.forName(encoding);
        encoder = cs.newEncoder();
        encodingName =  EncodingHelper.getOldCanonical(cs.name());
      }
    catch(RuntimeException e)
      {
        encoder = null;
        encodingName = "ISO8859_1";
      }

    if(encoder != null)
      {
        encoder.onMalformedInput(CodingErrorAction.REPLACE);
        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
      }
    this.encoder = encoder;
    this.encodingName = encodingName;
  }

  /**
   * This method initializes a new instance of <code>OutputStreamWriter</code>
   * to write to the specified stream using a given <code>Charset</code>.
   *
   * @param out The <code>OutputStream</code> to write to
   * @param cs The <code>Charset</code> of the encoding to use
   *
   * @since 1.5
   */
  public OutputStreamWriter(OutputStream out, Charset cs)
  {
    this.out = out;
    encoder = cs.newEncoder();
    encoder.onMalformedInput(CodingErrorAction.REPLACE);
    encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
    encodingName = EncodingHelper.getOldCanonical(cs.name());
  }

  /**
   * This method initializes a new instance of <code>OutputStreamWriter</code>
   * to write to the specified stream using a given
   * <code>CharsetEncoder</code>.
   *
   * @param out The <code>OutputStream</code> to write to
   * @param enc The <code>CharsetEncoder</code> to encode the output with
   *
   * @since 1.5
   */
  public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
  {
    this.out = out;
    encoder = enc;
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
    Charset cs = enc.charset();
    if (cs == null)
      encodingName = "US-ASCII";
    else
      encodingName = EncodingHelper.getOldCanonical(cs.name());
  }

  /**
   * This method closes this stream, and the underlying
   * <code>OutputStream</code>
   *
   * @exception IOException If an error occurs
   */
  public void close () throws IOException
  {
    if(out == null)
      return;
    flush();
    out.close ();
    out = null;
  }

  /**
   * This method returns the name of the character encoding scheme currently
   * in use by this stream.  If the stream has been closed, then this method
   * may return <code>null</code>.
   *
   * @return The encoding scheme name
   */
  public String getEncoding ()
  {
    return out != null ? encodingName : null;
  }

  /**
   * This method flushes any buffered bytes to the underlying output sink.
   *
   * @exception IOException If an error occurs
   */
  public void flush () throws IOException
  {
      if(out != null){
          if(outputBuffer != null){
              char[] buf = new char[outputBuffer.position()];
              if(buf.length > 0){
                  outputBuffer.flip();
                  outputBuffer.get(buf);
                  writeConvert(buf, 0, buf.length);
                  outputBuffer.clear();
              }
          }
          out.flush ();
      }
  }

  /**
   * This method writes <code>count</code> characters from the specified
   * array to the output stream starting at position <code>offset</code>
   * into the array.
   *
   * @param buf The array of character to write from
   * @param offset The offset into the array to start writing chars from
   * @param count The number of chars to write.
   *
   * @exception IOException If an error occurs
   */
  public void write (char[] buf, int offset, int count) throws IOException
  {
    if(out == null)
      throw new IOException("Stream is closed.");
    if(buf == null)
      throw new IOException("Buffer is null.");

    if(outputBuffer != null)
        {
            if(count >= outputBuffer.remaining())
                {
                    int r = outputBuffer.remaining();
                    outputBuffer.put(buf, offset, r);
                    writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
                    outputBuffer.clear();
                    offset += r;
                    count -= r;
                    // if the remaining bytes is larger than the whole buffer,
                    // just don't buffer.
                    if(count >= outputBuffer.remaining()){
                      writeConvert(buf, offset, count);
                      return;
                    }
                }
            outputBuffer.put(buf, offset, count);
        } else writeConvert(buf, offset, count);
  }

 /**
  * Converts and writes characters.
  */
  private void writeConvert (char[] buf, int offset, int count)
      throws IOException
  {
    if(encoder == null)
    {
      byte[] b = new byte[count];
      for(int i=0;i<count;i++)
        b[i] = nullConversion(buf[offset+i]);
      out.write(b);
    } else {
      try  {
        ByteBuffer output = encoder.encode(CharBuffer.wrap(buf,offset,count));
        encoder.reset();
        if(output.hasArray())
          out.write(output.array());
        else
          {
            byte[] outbytes = new byte[output.remaining()];
            output.get(outbytes);
            out.write(outbytes);
          }
      } catch(IllegalStateException e) {
        throw new IOException("Internal error.");
      } catch(MalformedInputException e) {
        throw new IOException("Invalid character sequence.");
      } catch(CharacterCodingException e) {
        throw new IOException("Unmappable character.");
      }
    }
  }

  private byte nullConversion(char c) {
          return (byte)((c <= 0xFF)?c:'?');
  }

  /**
   * This method writes <code>count</code> bytes from the specified
   * <code>String</code> starting at position <code>offset</code> into the
   * <code>String</code>.
   *
   * @param str The <code>String</code> to write chars from
   * @param offset The position in the <code>String</code> to start
   * writing chars from
   * @param count The number of chars to write
   *
   * @exception IOException If an error occurs
   */
  public void write (String str, int offset, int count) throws IOException
  {
    if(str == null)
      throw new IOException("String is null.");

    write(str.toCharArray(), offset, count);
  }

  /**
   * This method writes a single character to the output stream.
   *
   * @param ch The char to write, passed as an int.
   *
   * @exception IOException If an error occurs
   */
  public void write (int ch) throws IOException
  {
          // No buffering, no encoding ... just pass through
          if (encoder == null && outputBuffer == null) {
                  out.write(nullConversion((char)ch));
          } else {
                  if (outputBuffer != null) {
                          if (outputBuffer.remaining() == 0) {
                                  writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
                                  outputBuffer.clear();
                          }
                          outputBuffer.put((char)ch);
                  } else {
                      writeConvert(new char[]{ (char)ch }, 0, 1);
                  }
          }
  }
} // class OutputStreamWriter
