/* PrintStream.java -- OutputStream for printing output
   Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006  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 java.util.Formatter;
import java.util.Locale;

import gnu.gcj.convert.UnicodeToBytes;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * Status:  Believed complete and correct to 1.3
 */

/**
 * This class prints Java primitive values and object to a stream as
 * text.  None of the methods in this class throw an exception.  However,
 * errors can be detected by calling the <code>checkError()</code> method.
 * Additionally, this stream can be designated as "autoflush" when 
 * created so that any writes are automatically flushed to the underlying
 * output sink when the current line is terminated.
 * <p>
 * This class converts char's into byte's using the system default encoding.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 */
public class PrintStream extends FilterOutputStream implements Appendable
{
  /* Notice the implementation is quite similar to OutputStreamWriter.
   * This leads to some minor duplication, because neither inherits
   * from the other, and we want to maximize performance. */

  // Line separator string.
  private static final char[] line_separator
    = System.getProperty("line.separator").toCharArray();
  
  UnicodeToBytes converter;

  // Work buffer of characters for converter.
  char[] work = new char[100];
  // Work buffer of bytes where we temporarily keep converter output.
  byte[] work_bytes = new byte[100];

  /**
   * This boolean indicates whether or not an error has ever occurred
   * on this stream.
   */
  private boolean error_occurred = false;

  /**
   * This is <code>true</code> if auto-flush is enabled, 
   * <code>false</code> otherwise
   */
  private boolean auto_flush;

  /**
   * This method intializes a new <code>PrintStream</code> object to write
   * to the specified output sink.
   *
   * @param out The <code>OutputStream</code> to write to.
   */
  public PrintStream (OutputStream out)
  {
    this (out, false);
  }

  /**
   * This method intializes a new <code>PrintStream</code> object to write
   * to the specified output sink.  This constructor also allows "auto-flush"
   * functionality to be specified where the stream will be flushed after
   * every <code>print</code> or <code>println</code> call, when the 
   * <code>write</code> methods with array arguments are called, or when a 
   * single new-line character is written.
   * <p>
   *
   * @param out The <code>OutputStream</code> to write to.
   * @param auto_flush <code>true</code> to flush the stream after every 
   * line, <code>false</code> otherwise
   */
  public PrintStream (OutputStream out, boolean auto_flush)
  {
    super (out);

    converter = UnicodeToBytes.getDefaultEncoder();
    this.auto_flush = auto_flush;
  }

  /**
   * This method initializes a new <code>PrintStream</code> object to write
   * to the specified output File. Doesn't autoflush.
   *
   * @param file The <code>File</code> to write to.
   * @throws FileNotFoundException if an error occurs while opening the file.
   *
   * @since 1.5
   */
  public PrintStream (File file)
    throws FileNotFoundException
  {
    this (new FileOutputStream(file), false);
  }

  /**
   * This method initializes a new <code>PrintStream</code> object to write
   * to the specified output File. Doesn't autoflush.
   *
   * @param file The <code>File</code> to write to.
   * @param encoding The name of the character encoding to use for this
   * object.
   * @throws FileNotFoundException If an error occurs while opening the file.
   * @throws UnsupportedEncodingException If the charset specified by
   * <code>encoding</code> is invalid.
   *
   * @since 1.5
   */
  public PrintStream (File file, String encoding)
    throws FileNotFoundException,UnsupportedEncodingException
  {
    this (new FileOutputStream(file), false, encoding);
  }

  /**
   * This method initializes a new <code>PrintStream</code> object to write
   * to the specified output File. Doesn't autoflush.
   *
   * @param fileName The name of the <code>File</code> to write to.
   * @throws FileNotFoundException if an error occurs while opening the file,
   *
   * @since 1.5
   */
  public PrintStream (String fileName)
    throws FileNotFoundException
  {
    this (new FileOutputStream(new File(fileName)), false);
  }

  /**
   * This method initializes a new <code>PrintStream</code> object to write
   * to the specified output File. Doesn't autoflush.
   *
   * @param fileName The name of the <code>File</code> to write to.
   * @param encoding The name of the character encoding to use for this
   * object.
   * @throws FileNotFoundException if an error occurs while opening the file.
   * @throws UnsupportedEncodingException If the charset specified by
   * <code>encoding</code> is invalid.
   *
   * @since 1.5
   */
  public PrintStream (String fileName, String encoding)
      throws FileNotFoundException,UnsupportedEncodingException
  {
    this (new FileOutputStream(new File(fileName)), false, encoding);
  }

  /**
   * This method intializes a new <code>PrintStream</code> object to write
   * to the specified output sink.  This constructor also allows "auto-flush"
   * functionality to be specified where the stream will be flushed after
   * every <code>print</code> or <code>println</code> call, when the 
   * <code>write</code> methods with array arguments are called, or when a 
   * single new-line character is written.
   * <p>
   *
   * @param out The <code>OutputStream</code> to write to.
   * @param auto_flush <code>true</code> to flush the stream after every 
   * line, <code>false</code> otherwise
   * @param encoding The name of the character encoding to use for this
   * object.
   */
  public PrintStream (OutputStream out, boolean auto_flush, String encoding)
    throws UnsupportedEncodingException
  {
    super (out);

    converter = UnicodeToBytes.getEncoder (encoding);
    this.auto_flush = auto_flush;
  }

  /**
   * This method checks to see if an error has occurred on this stream.  Note
   * that once an error has occurred, this method will continue to report
   * <code>true</code> forever for this stream.  Before checking for an
   * error condition, this method flushes the stream.
   *
   * @return <code>true</code> if an error has occurred, 
   * <code>false</code> otherwise
   */
  public boolean checkError ()
  {
    flush ();
    return error_occurred;
  }

  /**
   * This method can be called by subclasses to indicate that an error
   * has occurred and should be reported by <code>checkError</code>.
   */
  protected void setError ()
  {
    error_occurred = true;
  }

  /**
   * This method closes this stream and all underlying streams.
   */
  public void close ()
  {
    try
      {
	converter.setFinished();
	writeChars(new char[0], 0, 0);
	flush();
	out.close();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread().interrupt();
      }
    catch (IOException e)
      {
	setError ();
      }
  }

  /**
   * This method flushes any buffered bytes to the underlying stream and
   * then flushes that stream as well.
   */
  public void flush ()
  {
    try
      {
	out.flush();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread().interrupt();
      }
    catch (IOException e)
      {
	setError ();
      }
  }

  private synchronized void print (String str, boolean println)
  {
    try
      {
        writeChars(str, 0, str.length());
	if (println)
	  writeChars(line_separator, 0, line_separator.length);
	if (auto_flush)
	  flush();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread().interrupt();
      }
    catch (IOException e)
      {
	setError ();
      }
  }

  private synchronized void print (char[] chars, int pos, int len,
				   boolean println)
  {
    try
      {
        writeChars(chars, pos, len);
	if (println)
	  writeChars(line_separator, 0, line_separator.length);
	if (auto_flush)
	  flush();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread().interrupt();
      }
    catch (IOException e)
      {
	setError ();
      }
  }

  private void writeChars(char[] buf, int offset, int count)
    throws IOException
  {
    do
      {
	converter.setOutput(work_bytes, 0);
	int converted = converter.write(buf, offset, count);
	offset += converted;
	count -= converted;
	out.write(work_bytes, 0, converter.count);
      }
    while (count > 0 || converter.havePendingBytes());
  }

  private void writeChars(String str, int offset, int count)
    throws IOException
  {
    do
      {
	converter.setOutput(work_bytes, 0);
	int converted = converter.write(str, offset, count, work);
	offset += converted;
	count -= converted;
	out.write(work_bytes, 0, converter.count);
      }
    while (count > 0 || converter.havePendingBytes());
  }

  /**
   * This methods prints a boolean value to the stream.  <code>true</code>
   * values are printed as "true" and <code>false</code> values are printed
   * as "false".
   *
   * @param bool The <code>boolean</code> value to print
   */
  public void print (boolean bool)
  {
    print(String.valueOf(bool), false);
  }

  /**
   * This method prints an integer to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   *
   * @param inum The <code>int</code> value to be printed
   */
  public void print (int inum)
  {
    print(String.valueOf(inum), false);
  }

  /**
   * This method prints a long to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   *
   * @param lnum The <code>long</code> value to be printed
   */
  public void print (long lnum)
  {
    print(String.valueOf(lnum), false);
  }

  /**
   * This method prints a float to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   *
   * @param fnum The <code>float</code> value to be printed
   */
  public void print (float fnum)
  {
    print(String.valueOf(fnum), false);
  }

  /**
   * This method prints a double to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   *
   * @param dnum The <code>double</code> value to be printed
   */
  public void print (double dnum)
  {
    print(String.valueOf(dnum), false);
  }

  /**
   * This method prints an <code>Object</code> to the stream.  The actual
   * value printed is determined by calling the <code>String.valueOf()</code>
   * method.
   *
   * @param obj The <code>Object</code> to print.
   */
  public void print (Object obj)
  {
    print(obj == null ? "null" : obj.toString(), false);
  }

  /**
   * This method prints a <code>String</code> to the stream.  The actual
   * value printed depends on the system default encoding.
   *
   * @param str The <code>String</code> to print.
   */
  public void print (String str)
  {
    print(str == null ? "null" : str, false);
  }

  /**
   * This method prints a char to the stream.  The actual value printed is
   * determined by the character encoding in use.
   *
   * @param ch The <code>char</code> value to be printed
   */
  public synchronized void print (char ch)
  {
    work[0] = ch;
    print(work, 0, 1, false);
  }

  /**
   * This method prints an array of characters to the stream.  The actual
   * value printed depends on the system default encoding.
   *
   * @param charArray The array of characters to print.
   */
  public void print (char[] charArray)
  {
    print(charArray, 0, charArray.length, false);
  }

  /**
   * This method prints a line separator sequence to the stream.  The value
   * printed is determined by the system property <xmp>line.separator</xmp>
   * and is not necessarily the Unix '\n' newline character.
   */
  public void println ()
  {
    print(line_separator, 0, line_separator.length, false);
  }

  /**
   * This methods prints a boolean value to the stream.  <code>true</code>
   * values are printed as "true" and <code>false</code> values are printed
   * as "false".
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param bool The <code>boolean</code> value to print
   */
  public void println (boolean bool)
  {
    print(String.valueOf(bool), true);
  }

  /**
   * This method prints an integer to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param inum The <code>int</code> value to be printed
   */
  public void println (int inum)
  {
    print(String.valueOf(inum), true);
  }

  /**
   * This method prints a long to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param lnum The <code>long</code> value to be printed
   */
  public void println (long lnum)
  {
    print(String.valueOf(lnum), true);
  }

  /**
   * This method prints a float to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param fnum The <code>float</code> value to be printed
   */
  public void println (float fnum)
  {
    print(String.valueOf(fnum), true);
  }

  /**
   * This method prints a double to the stream.  The value printed is
   * determined using the <code>String.valueOf()</code> method.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param dnum The <code>double</code> value to be printed
   */
  public void println (double dnum)
  {
    print(String.valueOf(dnum), true);
  }

  /**
   * This method prints an <code>Object</code> to the stream.  The actual
   * value printed is determined by calling the <code>String.valueOf()</code>
   * method.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param obj The <code>Object</code> to print.
   */
  public void println (Object obj)
  {
    print(obj == null ? "null" : obj.toString(), true);
  }

  /**
   * This method prints a <code>String</code> to the stream.  The actual
   * value printed depends on the system default encoding.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param str The <code>String</code> to print.
   */
  public void println (String str)
  {
    print (str == null ? "null" : str, true);
  }

  /**
   * This method prints a char to the stream.  The actual value printed is
   * determined by the character encoding in use.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param ch The <code>char</code> value to be printed
   */
  public synchronized void println (char ch)
  {
    work[0] = ch;
    print(work, 0, 1, true);
  }

  /**
   * This method prints an array of characters to the stream.  The actual
   * value printed depends on the system default encoding.
   * <p>
   * This method prints a line termination sequence after printing the value.
   *
   * @param charArray The array of characters to print.
   */
  public void println (char[] charArray)
  {
    print(charArray, 0, charArray.length, true);
  }

  /**
   * This method writes a byte of data to the stream.  If auto-flush is
   * enabled, printing a newline character will cause the stream to be
   * flushed after the character is written.
   * 
   * @param oneByte The byte to be written
   */
  public void write (int oneByte)
  {
    try
      {
        out.write (oneByte & 0xff);
        
        if (auto_flush && (oneByte == '\n'))
          flush ();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread ().interrupt ();
      }
    catch (IOException e)
      {
        setError ();
      }
  }

  /**
   * This method writes <code>len</code> bytes from the specified array
   * starting at index <code>offset</code> into the array.
   *
   * @param buffer The array of bytes to write
   * @param offset The index into the array to start writing from
   * @param len The number of bytes to write
   */
  public void write (byte[] buffer, int offset, int len)
  {
    try
      {
        out.write (buffer, offset, len);
        
        if (auto_flush)
          flush ();
      }
    catch (InterruptedIOException iioe)
      {
	Thread.currentThread ().interrupt ();
      }
    catch (IOException e)
      {
        setError ();
      }
  }

  /** @since 1.5 */
  public PrintStream append(char c)
  {
    print(c);
    return this;
  }

  /** @since 1.5 */
  public PrintStream append(CharSequence cs)
  {
    print(cs == null ? "null" : cs.toString());
    return this;
  }

  /** @since 1.5 */
  public PrintStream append(CharSequence cs, int start, int end)
  {
    print(cs == null ? "null" : cs.subSequence(start, end).toString());
    return this;
  }

  /** @since 1.5 */
  public PrintStream printf(String format, Object... args)
  {
    return format(format, args);
  }

  /** @since 1.5 */
  public PrintStream printf(Locale locale, String format, Object... args)
  {
    return format(locale, format, args);
  }

  /** @since 1.5 */
  public PrintStream format(String format, Object... args)
  {
    return format(Locale.getDefault(), format, args);
  }

  /** @since 1.5 */
  public PrintStream format(Locale locale, String format, Object... args)
  {
    Formatter f = new Formatter(this, locale);
    f.format(format, args);
    return this;
  }
} // class PrintStream

