/* PushbackReader.java -- An character stream that can unread chars
   Copyright (C) 1998, 2000, 2001, 2003, 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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;

/**
 * This subclass of <code>FilterReader</code> provides the ability to 
 * unread data from a stream.  It maintains an internal buffer of unread
 * data that is supplied to the next read operation.  This is conceptually
 * similar to mark/reset functionality, except that in this case the 
 * position to reset the stream to does not need to be known in advance.
 * <p>
 * The default pushback buffer size one char, but this can be overridden
 * by the creator of the stream.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy (warrenl@cygnus.com)
 */
public class PushbackReader extends FilterReader
{
  /**
   * This is the default buffer size
   */
  private static final int DEFAULT_BUFFER_SIZE = 1;

  /**
   * This is the buffer that is used to store the pushed back data
   */
  private char[] buf;

  /**
   * This is the position in the buffer from which the next char will be
   * read.  Bytes are stored in reverse order in the buffer, starting from
   * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>.  Thus when 
   * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when 
   * it is empty
   */
  private int pos;

  /**
   * This method initializes a <code>PushbackReader</code> to read from the
   * specified subordinate <code>Reader</code> with a default pushback buffer 
   * size of 1.
   *
   * @param in The subordinate stream to read from
   */
  public PushbackReader(Reader in)
  {
    this(in, DEFAULT_BUFFER_SIZE);
  }

  /**
   * This method initializes a <code>PushbackReader</code> to read from the
   * specified subordinate <code>Reader</code> with the specified buffer
   * size
   *
   * @param in The subordinate <code>Reader</code> to read from
   * @param bufsize The pushback buffer size to use
   */
  public PushbackReader(Reader in, int bufsize)
  {
    super(in);

    if (bufsize < 0)
      throw new IllegalArgumentException("buffer size must be positive");

    buf = new char[bufsize];
    pos = bufsize;
  }

  /**
   * This method closes the stream and frees any associated resources.
   *
   * @exception IOException If an error occurs.
   */
  public void close() throws IOException
  {
    synchronized (lock)
      {
	buf = null;
	super.close();
      }
  }

  /**
   * This method throws an exception when called since this class does
   * not support mark/reset.
   *
   * @param read_limit Not used.
   *
   * @exception IOException Always thrown to indicate mark/reset not supported.
   */
  public void mark(int read_limit) throws IOException
  {
    throw new IOException("mark not supported in this class");
  }

  /**
   * This method returns <code>false</code> to indicate that it does not support
   * mark/reset functionality.
   *
   * @return This method returns <code>false</code> to indicate that this 
   * class does not support mark/reset functionality
   *
   */
  public boolean markSupported()
  {
    return(false);
  }

  /**
   * This method always throws an IOException in this class because
   * mark/reset functionality is not supported.
   *
   * @exception IOException Always thrown for this class
   */
  public void reset() throws IOException
  {
    throw new IOException("reset not supported in this class");
  }

  /**
   * This method determines whether or not this stream is ready to be read.
   * If it returns <code>false</code> to indicate that the stream is not
   * ready, any attempt to read from the stream could (but is not
   * guaranteed to) block.
   * <p>
   * This stream is ready to read if there are either chars waiting to be
   * read in the pushback buffer or if the underlying stream is ready to
   * be read.
   *
   * @return <code>true</code> if this stream is ready to be read, 
   * <code>false</code> otherwise
   *
   * @exception IOException If an error occurs
   */
  public boolean ready() throws IOException
  {
    synchronized (lock)
      {
	if (buf == null)
	  throw new IOException ("stream closed");

	if (((buf.length - pos) > 0) || super.ready())
	  return(true);
	else
	  return(false);
      }
  }

  // Don't delete this method just because the spec says it shouldn't be there!
  // See the CVS log for details.
  /**
    * This method skips the specified number of chars in the stream.  It
    * returns the actual number of chars skipped, which may be less than the
    * requested amount.
    * <p>
    * This method first discards chars from the buffer, then calls the
    * <code>skip</code> method on the underlying <code>Reader</code> to 
    * skip additional chars if necessary.
    *
    * @param num_chars The requested number of chars to skip
    *
    * @return The actual number of chars skipped.
    *
    * @exception IOException If an error occurs
    */
  public long skip(long num_chars) throws IOException
  {
    synchronized (lock)
      {
	if (num_chars <= 0)
	  return(0);

	if ((buf.length - pos) >= num_chars)
	  {
	    pos += num_chars;
	    return(num_chars);
	  }

	int chars_discarded = buf.length - pos;
	pos = buf.length;

	long chars_skipped = in.skip(num_chars - chars_discarded);

	return(chars_discarded + chars_skipped);
      }
  }

  /**
   * This method reads an unsigned char from the input stream and returns it
   * as an int in the range of 0-65535.  This method also will return -1 if
   * the end of the stream has been reached.  The char returned will be read
   * from the pushback buffer, unless the buffer is empty, in which case
   * the char will be read from the underlying stream.
   * <p>
   * This method will block until the char can be read.
   *
   * @return The char read or -1 if end of stream
   *
   * @exception IOException If an error occurs
   */
  public int read() throws IOException
  {
    synchronized (lock)
      {
	if (buf == null)
          throw new IOException("stream closed");

	if (pos == buf.length)
	  return(super.read());

	++pos;
	return((buf[pos - 1] & 0xFFFF));
      }
  }

  /**
   * This method read chars from a stream and stores them into a caller
   * supplied buffer.  It starts storing the data at index <code>offset</code>
   * into
   * the buffer and attempts to read <code>len</code> chars.  This method can
   * return before reading the number of chars requested.  The actual number
   * of chars read is returned as an int.  A -1 is returned to indicate the
   * end of the stream.
   *  <p>
   * This method will block until some data can be read.
   * <p>
   * This method first reads chars from the pushback buffer in order to 
   * satisfy the read request.  If the pushback buffer cannot provide all
   * of the chars requested, the remaining chars are read from the 
   * underlying stream.
   *
   * @param buffer The array into which the chars read should be stored
   * @param offset The offset into the array to start storing chars
   * @param length The requested number of chars to read
   *
   * @return The actual number of chars read, or -1 if end of stream.
   *
   * @exception IOException If an error occurs.
   */
  public synchronized int read(char[] buffer, int offset, int length)
    throws IOException
  {
    synchronized (lock)
      {
	if (buf == null)
          throw new IOException("stream closed");

	if (offset < 0 || length < 0 || offset + length > buffer.length)
          throw new ArrayIndexOutOfBoundsException();

	int numBytes = Math.min(buf.length - pos, length);
	if (numBytes > 0)
	  {
	    System.arraycopy (buf, pos, buffer, offset, numBytes);
	    pos += numBytes;
	    return numBytes;
	  }

	return super.read(buffer, offset, length);
      }
  }

  /**
   * This method pushes a single char of data into the pushback buffer.
   * The char pushed back is the one that will be returned as the first char
   * of the next read.
   * <p>
   * If the pushback buffer is full, this method throws an exception.
   * <p>
   * The argument to this method is an <code>int</code>.  Only the low eight 
   * bits of this value are pushed back.
   *
   * @param b The char to be pushed back, passed as an int
   *
   * @exception IOException If the pushback buffer is full.
   */
  public void unread(int b) throws IOException
  {
    synchronized (lock)
      {
	if (buf == null)
	  throw new IOException("stream closed");
	if (pos == 0)
	  throw new IOException("Pushback buffer is full");

	--pos;
	buf[pos] = (char)(b & 0xFFFF);
      }
  }

  /**
   * This method pushes all of the chars in the passed char array into 
   * the pushback buffer.  These chars are pushed in reverse order so that
   * the next char read from the stream after this operation will be
   * <code>buf[0]</code> followed by <code>buf[1]</code>, etc.
   * <p>
   * If the pushback buffer cannot hold all of the requested chars, an
   * exception is thrown.
   *
   * @param buf The char array to be pushed back
   *
   * @exception IOException If the pushback buffer is full
   */
  public synchronized void unread(char[] buf) throws IOException
  {
    unread(buf, 0, buf.length);
  }

  /**
   * This method pushed back chars from the passed in array into the pushback
   * buffer.  The chars from <code>buf[offset]</code> to 
   * <code>buf[offset + len]</code>
   * are pushed in reverse order so that the next char read from the stream
   * after this operation will be <code>buf[offset]</code> followed by
   * <code>buf[offset + 1]</code>, etc.
   * <p>
   * If the pushback buffer cannot hold all of the requested chars, an
   * exception is thrown.
   *
   * @param buffer The char array to be pushed back
   * @param offset The index into the array where the chars to be push start
   * @param length The number of chars to be pushed.
   *
   * @exception IOException If the pushback buffer is full
   */
  public synchronized void unread(char[] buffer, int offset, int length)
    throws IOException
  {
    synchronized (lock)
      {
	if (buf == null)
          throw new IOException("stream closed");
	if (pos < length)
	  throw new IOException("Pushback buffer is full");

	// Note the order that these chars are being added is the opposite
	// of what would be done if they were added to the buffer one at a time.
	// See the Java Class Libraries book p. 1397.
	System.arraycopy(buffer, offset, buf, pos - length, length);

	// Don't put this into the arraycopy above, an exception might be thrown
	// and in that case we don't want to modify pos.
	pos -= length;
      }
  }
}

