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

/**
 * 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;
      }
  }
}
