/* Writer.java -- Base class for character output streams
   Copyright (C) 1998, 1999, 2001, 2003, 2004, 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;

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

/**
 * This abstract class forms the base of the hierarchy of classes that 
 * write output as a stream of chars.  It provides a common set of methods
 * for writing chars to stream.  Subclasses implement and/or extend these
 * methods to write chars in a particular manner or to a particular 
 * destination such as a file on disk or network connection.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner (bothner@cygnus.com)
 */
public abstract class Writer
{
  /**
   * This is the object used to synchronize criticial code sections for
   * thread safety.  Subclasses should use this field instead of using
   * synchronized methods or explicity synchronizations on <code>this</code>
   */
  protected Object lock;

  /**
   * This is the default no-argument constructor for this class.  This method
   * will set up the class to synchronize criticial sections on itself.
   */
  protected Writer()
  {
    lock = this;
  }

  /**
   * This method initializes a <code>Writer</code> that will synchronize
   * on the specified <code>Object</code>.
   *
   * @param lock The <code>Object</code> to use for synchronizing critical
   *             sections. Must not be null.
   */
  protected Writer(Object lock)
  {
    if (lock == null)
      throw new NullPointerException();

    this.lock = lock;
  }

  /**
   * This method forces any data that may have been buffered to be written
   * to the underlying output device.  Please note that the host environment
   * might perform its own buffering unbeknowst to Java.  In that case, a
   * write made (for example, to a disk drive) might be cached in OS
   * buffers instead of actually being written to disk.
   *
   * @exception IOException If an error occurs
   */
  public abstract void flush() throws IOException;

  /**
   * This method closes the stream.  Any internal or native resources 
   * associated
   * with this stream are freed.  Any subsequent attempt to access the stream
   * might throw an exception.
   * <p>
   * This method in this class does nothing.
   *
   * @exception IOException If an error occurs
   */
  public abstract void close() throws IOException;

  /**
   * This method writes a single char to the output stream. 
   *
   * @param b The char to be written to the output stream, passed as an int
   *
   * @exception IOException If an error occurs
   */
  public void write(int b) throws IOException
  {
    char[] buf = new char[1];

    buf[0] = (char)b;
    write(buf, 0, buf.length);
  }

  /**
   * This method all the writes char from the passed array to the output 
   * stream. This method is equivalent to 
   * <code>write(buf, 0, buf.length)</code> which
   * is exactly how it is implemented in this class.
   *
   * @param buf The array of char to write
   *
   * @exception IOException If an error occurs
   */
  public void write(char[] buf) throws IOException
  {
    write(buf, 0, buf.length);
  }

  /**
   * This method writes <code>len</code> char from the specified array
   * <code>buf</code> starting at index <code>offset</code> into the array.
   * <p>
   * Subclasses must provide an implementation of this abstract method.
   *
   * @param buf The array of char to write from
   * @param offset The index into the array to start writing from
   * @param len The number of char to write
   * 
   * @exception IOException If an error occurs
   */
  public abstract void write(char[] buf, int offset, int len) 
    throws IOException;

  /**
   * This method writes all the characters in a <code>String</code> to the
   * output.
   *
   * @param str The <code>String</code> whose chars are to be written.
   *
   * @exception IOException If an error occurs
   */
  public void write(String str) throws IOException
  {
    write(str, 0, str.length());
  } 

  /**
   * This method writes <code>len</code> chars from the <code>String</code>
   * starting at position <code>offset</code>.
   *
   * @param str The <code>String</code> that is to be written
   * @param offset The character offset into the <code>String</code> 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
  {
    // FIXME - for libgcj re-write using native code to not require 
    // copied buffer.
    char[] buf = new char[len];

    str.getChars(offset, offset + len, buf, 0);
    write(buf, 0, len);
  }

} // class Writer

