/* Copyright (C) 1998, 1999  Cygnus Solutions

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */
 
package java.io;

/**
 * @author Warren Levy <warrenl@cygnus.com>
 * @date October 16, 1998.  
 */
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * Status:  Believed complete and correct.
 */
 
public class PushbackReader extends FilterReader
{
  /* Internal buffer array for data. */
  private char[] buf;

  /* The current position in the buffer. */
  private int pos;

  public PushbackReader(Reader in)
  {
    this(in, 1);
  }

  public PushbackReader(Reader in, int size)
  {
    super(in);
    if (size < 0)
      throw new IllegalArgumentException();
    buf = new char[size];
    pos = buf.length;
  }

  public void close() throws IOException
  {
    synchronized (lock)
    {
      buf = null;
      super.close();
    }
  }

  public boolean markSupported()
  {
    return false;
  }

  public int read() throws IOException
  {
    synchronized (lock)
    {
      if (buf == null)
        throw new IOException();

      if (pos < buf.length)
        return ((int) buf[pos++]) & 0xFFFF;

      return super.read();
    }
  }

  public int read(char[] b, int off, int len) throws IOException
  {
    synchronized (lock)
    {
      if (buf == null)
        throw new IOException();

      if (off < 0 || len < 0 || off + len > b.length)
        throw new ArrayIndexOutOfBoundsException();

      int numBytes = Math.min(buf.length - pos, len);
      for (int i = 0; i < numBytes; i++)
        b[off++] = buf[pos++];

      return numBytes + super.read(b, off, len - numBytes);
    }
  }

  public boolean ready() throws IOException
  {
    synchronized (lock)
    {
      if (buf == null)
        throw new IOException();

      if (buf.length - pos > 0)
        return true;

      return super.ready();
    }
  }

  public void unread(int b) throws IOException
  {
    synchronized (lock)
    {
      if (buf == null || pos <= 0)
        throw new IOException();

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

  public void unread(char[] b) throws IOException
  {
    unread(b, 0, b.length);
  }

  public void unread(char[] b, int off, int len) throws IOException
  {
    synchronized (lock)
    {
      if (buf == null || pos < len)
        throw new IOException();

      // 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(b, off, buf, pos - len, len);

      // 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 -= len;
    }
  }
}
