/* 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., 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;

/* 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.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 * @date September 25, 1998 
 */
public class BufferedWriter extends Writer
{
  /**
   * This is the default buffer size
   */
  private static final int DEFAULT_BUFFER_SIZE = 8192;

  /**
   * 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 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 8192 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 out, int size)
  {
    super(out.lock);
    this.out = out;
    this.buffer = new char[size];
    this.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
   *
   * @exception IOException If an error occurs.
   */
  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 oneChar 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 void localFlush () throws IOException
  {
    if (count > 0)
      {
	out.write(buffer, 0, count);
	count = 0;
      }
  }
}
