/* Copyright (C) 1998, 1999  Cygnus Solutions

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.io;
import gnu.gcj.convert.UnicodeToBytes;

/**
 * @author Per Bothner <bothner@cygnus.com>
 * @date April 17, 1998.  
 */
/* Written using "Java Class Libraries", 2nd edition, plus online
 * API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete and correct, but only supports 8859_1.
 */

public class OutputStreamWriter extends Writer
{
  BufferedOutputStream out;

  UnicodeToBytes converter;

  /* Temporary buffer. */
  private char[] work;
  private int wcount;

  public String getEncoding() { return converter.getName(); }

  private OutputStreamWriter(OutputStream out, UnicodeToBytes encoder)
  {
    super((this.out = (out instanceof BufferedOutputStream
		       ? (BufferedOutputStream) out
		       : new BufferedOutputStream(out, 250))));
    this.converter = encoder;
  } 

  public OutputStreamWriter(OutputStream out, String enc)
   throws UnsupportedEncodingException
  {
    this(out, UnicodeToBytes.getEncoder(enc));
  }

  public OutputStreamWriter(OutputStream out)
  {
    this(out, UnicodeToBytes.getDefaultEncoder());
  }

  public void close() throws IOException
  {
    synchronized (lock)
      {
	flush();
	if (out != null)
	  {
	    out.close();
	    out = null;
	  }
	work = null;
      }
  }

  public void flush() throws IOException
  {
    synchronized (lock)
      {
	if (wcount > 0)
	  {
	    writeChars(work, 0, wcount);
	    wcount = 0;
	  }
	out.flush();
      }
  }

  public void write(char[] buf, int offset, int count)
     throws IOException
  {
    synchronized (lock)
      {
	if (wcount > 0)
	  {
	    writeChars(work, 0, wcount);
	    wcount = 0;
	  }
	writeChars(buf, offset, count);
      }
  }

  /** Writes characters through to the inferior BufferedOutputStream.
   * Ignores wcount and the work buffer. */
  private void writeChars(char[] buf, int offset, int count)
    throws IOException
  {
    while (count > 0)
      {
	// We must flush if out.count == out.buf.length.
	// It is probably a good idea to flush if out.buf is almost full.
	// This test is an approximation for "almost full".
	if (out.count + count >= out.buf.length)
	  {
	    out.flush();
	    if (out.count != 0)
	      throw new IOException("unable to flush output byte buffer");
	  }
	converter.setOutput(out.buf, out.count);
	int converted = converter.write(buf, offset, count);
	offset += converted;
	count -= converted;
	out.count = converter.count;
      }
  }

  public void write(String str, int offset, int count)
     throws IOException
  {
    synchronized (lock)
      {
	if (work == null)
	  work = new char[100];
	int wlength = work.length;
	while (count > 0)
	  {
	    int size = count;
	    if (wcount + size > wlength)
	      {
		if (2*wcount > wlength)
		  {
		    writeChars(work, 0, wcount);
		    wcount = 0;
		  }
		if (wcount + size > wlength)
		  size = wlength - wcount;
	      }
	    str.getChars(offset, offset+size, work, wcount);
	    offset += size;
	    count -= size;
	    wcount += size;
	  }
      }
  }

  public void write(int ch) throws IOException
  {
    synchronized (lock)
      {
	if (work == null)
	  work = new char[100];
	if (wcount >= work.length)
	  {
	    writeChars(work, 0, wcount);
	    wcount = 0;
	  }
	work[wcount++] = (char) ch;
      }
  }
}
