/* BufferedWriter.java -- Buffer output into large blocks before writing
   Copyright (C) 1998, 1999, 2000, 2001 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */


package java.io;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * Status:  Complete to version 1.1.
 */

/**
  * This class accumulates chars written in a buffer instead of immediately
  * writing the data to the underlying output sink. The chars are instead
  * as one large block when the buffer is filled, or when the stream is
  * closed or explicitly flushed. This mode operation can provide a more
  * efficient mechanism for writing versus doing numerous small unbuffered
  * writes.
  *
  * @version 0.0
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Tom Tromey <tromey@cygnus.com>
  * @date September 25, 1998 
  */

public class BufferedWriter extends Writer
{
  /**
   * This method initializes a new <code>BufferedWriter</code> instance
   * that will write to the specified subordinate <code>Writer</code>
   * and which will use a default buffer size of 512 chars.
   *
   * @param out The underlying <code>Writer</code> to write data to
   */
  public BufferedWriter (Writer out)
  {
    this (out, DEFAULT_BUFFER_SIZE);
  }

  /**
   * This method initializes a new <code>BufferedWriter</code> instance
   * that will write to the specified subordinate <code>Writer</code>
   * and which will use the specified buffer size
   *
   * @param out The underlying <code>Writer</code> to write data to
   * @param size The size of the internal buffer
   */
  public BufferedWriter (Writer ox, int size)
  {
    super (ox);
    out = ox;
    buffer = new char[size];
    count = 0;
  }

  /**
   * This method flushes any remaining buffered chars then closes the 
   * underlying output stream.  Any further attempts to write to this stream
   * may throw an exception
   */
  public void close () throws IOException
  {
    synchronized (lock)
      {
	// It is safe to call localFlush even if the stream is already
	// closed.
	localFlush ();
	out.close();
	buffer = null;
      }
  }

  /**
   * This method causes any currently buffered chars to be immediately
   * written to the underlying output stream.
   *
   * @exception IOException If an error occurs
   */
  public void flush () throws IOException
  {
    synchronized (lock)
      {
	if (buffer == null)
	  throw new IOException ("Stream closed");
	localFlush ();
	out.flush();
      }
  }

  /**
   * This method writes out a system depedent line separator sequence.  The
   * actual value written is detemined from the <xmp>line.separator</xmp>
   * system property.
   *
   * @exception IOException If an error occurs
   */
  public void newLine () throws IOException
  {
    write (System.getProperty("line.separator"));
  }

  /**
   * This method writes a single char of data.  This will be written to the
   * buffer instead of the underlying data source.  However, if the buffer
   * is filled as a result of this write request, it will be flushed to the
   * underlying output stream.
   *
   * @param b The char of data to be written, passed as an int
   *
   * @exception IOException If an error occurs
   */
  public void write (int oneChar) throws IOException
  {
    synchronized (lock)
      {
	if (buffer == null)
	  throw new IOException ("Stream closed");
	buffer[count++] = (char) oneChar;
	if (count == buffer.length)
	  localFlush ();
      }
  }

  /**
   * This method writes <code>len</code> chars from the char array 
   * <code>buf</code> starting at position <code>offset</code> in the buffer. 
   * These chars will be written to the internal buffer.  However, if this
   * write operation fills the buffer, the buffer will be flushed to the
   * underlying output stream.
   *
   * @param buf The array of chars to write.
   * @param offset The index into the char array to start writing from.
   * @param len The number of chars to write.
   *
   * @exception IOException If an error occurs
   */
  public void write (char[] buf, int offset, int len) throws IOException
  {
    synchronized (lock)
      {
	if (buffer == null)
	  throw new IOException ("Stream closed");

	// Bypass buffering if there is too much incoming data.
	if (count + len > buffer.length)
	  {
	    localFlush ();
	    out.write(buf, offset, len);
	  }
	else
	  {
	    System.arraycopy(buf, offset, buffer, count, len);
	    count += len;
	    if (count == buffer.length)
	      localFlush ();
	  }
      }
  }

  /**
   * This method writes <code>len</code> chars from the <code>String</code>
   * <code>str</code> starting at position <code>offset</code> in the string. 
   * These chars will be written to the internal buffer.  However, if this
   * write operation fills the buffer, the buffer will be flushed to the
   * underlying output stream.
   *
   * @param str The <code>String</code> to write.
   * @param offset The index into the string to start writing from.
   * @param len The number of chars to write.
   *
   * @exception IOException If an error occurs
   */
  public void write (String str, int offset, int len) throws IOException
  {
    synchronized (lock)
      {
	if (buffer == null)
	  throw new IOException ("Stream closed");

	if (count + len > buffer.length)
	  {
	    localFlush ();
	    out.write(str, offset, len);
	  }
	else
	  {
	    str.getChars(offset, offset + len, buffer, count);
	    count += len;
	    if (count == buffer.length)
	      localFlush ();
	  }
      }
  }

  // This should only be called with the lock held.
  private final void localFlush () throws IOException
  {
    if (count > 0)
      {
	out.write(buffer, 0, count);
	count = 0;
      }
  }

  /**
   * This is the underlying <code>Writer</code> to which this object
   * sends its output.
   */
  private Writer out;

  /**
   * This is the internal char array used for buffering output before
   * writing it.
   */
  char[] buffer;

  /**
   * This is the number of chars that are currently in the buffer and
   * are waiting to be written to the underlying stream.  It always points to
   * the index into the buffer where the next char of data will be stored
   */
  int count;

  /**
   * This is the default buffer size
   */
  private static final int DEFAULT_BUFFER_SIZE = 8192;
}
