/* BufferedReader.java
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 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;

import gnu.java.lang.CPStringBuilder;

/* 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 subclass of <code>FilterReader</code> buffers input from an
 * underlying implementation to provide a possibly more efficient read
 * mechanism.  It maintains the buffer and buffer state in instance
 * variables that are available to subclasses.  The default buffer size
 * of 8192 chars can be overridden by the creator of the stream.
 * <p>
 * This class also implements mark/reset functionality.  It is capable
 * of remembering any number of input chars, to the limits of
 * system memory or the size of <code>Integer.MAX_VALUE</code>
 *
 * @author Per Bothner (bothner@cygnus.com)
 * @author Aaron M. Renn (arenn@urbanophile.com)
 */
public class BufferedReader extends Reader
{
  Reader in;
  char[] buffer;
  /* Index of current read position.  Must be >= 0 and <= limit. */
  /* There is a special case where pos may be equal to limit+1; this
   * is used as an indicator that a readLine was done with a '\r' was
   * the very last char in the buffer.  Since we don't want to read-ahead
   * and potentially block, we set pos this way to indicate the situation
   * and deal with it later.  Doing it this way rather than having a
   * separate boolean field to indicate the condition has the advantage
   * that it is self-clearing on things like mark/reset.
   */
  int pos;
  /* Limit of valid data in buffer.  Must be >= pos and <= buffer.length. */
  /* This can be < pos in the one special case described above. */
  int limit;

  /* The value -1 means there is no mark, or the mark has been invalidated.
     Otherwise, markPos is the index in the buffer of the marked position.
     Must be >= 0 and <= pos.
     Note we do not explicitly store the read-limit.
     The implicit read-limit is (buffer.length - markPos), which is
     guaranteed to be >= the read-limit requested in the call to mark. */
  int markPos = -1;

  // The JCL book specifies the default buffer size as 8K characters.
  // This is package-private because it is used by LineNumberReader.
  static final int DEFAULT_BUFFER_SIZE = 8192;

  /**
    * Create a new <code>BufferedReader</code> that will read from the
    * specified subordinate stream with a default buffer size of 8192 chars.
    *
    * @param in The subordinate stream to read from
    */
  public BufferedReader(Reader in)
  {
    this(in, DEFAULT_BUFFER_SIZE);
  }

  /**
   * Create a new <code>BufferedReader</code> that will read from the
   * specified subordinate stream with a buffer size that is specified by the
   * caller.
   *
   * @param in The subordinate stream to read from
   * @param size The buffer size to use
   *
   * @exception IllegalArgumentException if size &lt;= 0
   */
  public BufferedReader(Reader in, int size)
  {
    super(in.lock);
    if (size <= 0)
      throw new IllegalArgumentException("Illegal buffer size: " + size);
    this.in = in;
    buffer = new char[size];
  }

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

  /**
   * Returns <code>true</code> to indicate that this class supports mark/reset
   * functionality.
   *
   * @return <code>true</code>
   */
  public boolean markSupported()
  {
    return true;
  }

  /**
   * Mark a position in the input to which the stream can be
   * "reset" by calling the <code>reset()</code> method.  The parameter
   * <code>readLimit</code> is the number of chars that can be read from the
   * stream after setting the mark before the mark becomes invalid.  For
   * example, if <code>mark()</code> is called with a read limit of 10, then
   * when 11 chars of data are read from the stream before the
   * <code>reset()</code> method is called, then the mark is invalid and the
   * stream object instance is not required to remember the mark.
   * <p>
   * Note that the number of chars that can be remembered by this method
   * can be greater than the size of the internal read buffer.  It is also
   * not dependent on the subordinate stream supporting mark/reset
   * functionality.
   *
   * @param readLimit The number of chars that can be read before the mark
   *        becomes invalid
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException if readLimit is negative.
   */
  public void mark(int readLimit) throws IOException
  {
    if (readLimit < 0)
      throw new IllegalArgumentException("Read-ahead limit is negative");

    synchronized (lock)
      {
        checkStatus();
        // In this method we need to be aware of the special case where
        // pos + 1 == limit.  This indicates that a '\r' was the last char
        // in the buffer during a readLine.  We'll want to maintain that
        // condition after we shift things around and if a larger buffer is
        // needed to track readLimit, we'll have to make it one element
        // larger to ensure we don't invalidate the mark too early, if the
        // char following the '\r' is NOT a '\n'.  This is ok because, per
        // the spec, we are not required to invalidate when passing readLimit.
        //
        // Note that if 'pos > limit', then doing 'limit -= pos' will cause
        // limit to be negative.  This is the only way limit will be < 0.

        if (pos + readLimit > limit)
          {
            char[] old_buffer = buffer;
            int extraBuffSpace = 0;
            if (pos > limit)
              extraBuffSpace = 1;
            if (readLimit + extraBuffSpace > limit)
              buffer = new char[readLimit + extraBuffSpace];
            limit -= pos;
            if (limit >= 0)
              {
                System.arraycopy(old_buffer, pos, buffer, 0, limit);
                pos = 0;
              }
          }

        if (limit < 0)
          {
            // Maintain the relationship of 'pos > limit'.
            pos = 1;
            limit = markPos = 0;
          }
        else
          markPos = pos;
        // Now pos + readLimit <= buffer.length. thus if we need to read
        // beyond buffer.length, then we are allowed to invalidate markPos.
      }
  }

  /**
   * Reset the stream to the point where the <code>mark()</code> method
   * was called.  Any chars that were read after the mark point was set will
   * be re-read during subsequent reads.
   * <p>
   * This method will throw an IOException if the number of chars read from
   * the stream since the call to <code>mark()</code> exceeds the mark limit
   * passed when establishing the mark.
   *
   * @exception IOException If an error occurs;
   */
  public void reset() throws IOException
  {
    synchronized (lock)
      {
        checkStatus();
        if (markPos < 0)
          throw new IOException("mark never set or invalidated");

        // Need to handle the extremely unlikely case where a readLine was
        // done with a '\r' as the last char in the buffer; which was then
        // immediately followed by a mark and a reset with NO intervening
        // read of any sort.  In that case, setting pos to markPos would
        // lose that info and a subsequent read would thus not skip a '\n'
        // (if one exists).  The value of limit in this rare case is zero.
        // We can assume that if limit is zero for other reasons, then
        // pos is already set to zero and doesn't need to be readjusted.
        if (limit > 0)
          pos = markPos;
      }
  }

  /**
   * This method determines whether or not a stream is ready to be read.  If
   * this method returns <code>false</code> then this stream could (but is
   * not guaranteed to) block on the next read attempt.
   *
   * @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)
      {
        checkStatus();
        return pos < limit || in.ready();
      }
  }

  /**
   * 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.
   *
   * @param buf The array into which the chars read should be stored
   * @param offset The offset into the array to start storing chars
   * @param count 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.
   * @exception IndexOutOfBoundsException If offset and count are not
   * valid regarding buf.
   */
  public int read(char[] buf, int offset, int count) throws IOException
  {
    if (offset < 0 || offset + count > buf.length || count < 0)
      throw new IndexOutOfBoundsException();

    synchronized (lock)
      {
        checkStatus();
        // Once again, we need to handle the special case of a readLine
        // that has a '\r' at the end of the buffer.  In this case, we'll
        // need to skip a '\n' if it is the next char to be read.
        // This special case is indicated by 'pos > limit'.
        boolean retAtEndOfBuffer = false;

        int avail = limit - pos;
        if (count > avail)
          {
            if (avail > 0)
              count = avail;
            else // pos >= limit
              {
                if (limit == buffer.length)
                  markPos = -1; // read too far - invalidate the mark.
                if (pos > limit)
                  {
                    // Set a boolean and make pos == limit to simplify things.
                    retAtEndOfBuffer = true;
                    --pos;
                  }
                if (markPos < 0)
                  {
                    // Optimization:  can read directly into buf.
                    if (count >= buffer.length && !retAtEndOfBuffer)
                      return in.read(buf, offset, count);
                    pos = limit = 0;
                  }
                avail = in.read(buffer, limit, buffer.length - limit);
                if (retAtEndOfBuffer && avail > 0 && buffer[limit] == '\n')
                  {
                    --avail;
                    limit++;
                  }
                if (avail < count)
                  {
                    if (avail <= 0)
                      return avail;
                    count = avail;
                  }
                limit += avail;
              }
          }
        System.arraycopy(buffer, pos, buf, offset, count);
        pos += count;
        return count;
      }
  }

  /* Read more data into the buffer.  Update pos and limit appropriately.
     Assumes pos==limit initially.  May invalidate the mark if read too much.
     Return number of chars read (never 0), or -1 on eof. */
  private int fill() throws IOException
  {
    checkStatus();
    // Handle the special case of a readLine that has a '\r' at the end of
    // the buffer.  In this case, we'll need to skip a '\n' if it is the
    // next char to be read.  This special case is indicated by 'pos > limit'.
    boolean retAtEndOfBuffer = false;
    if (pos > limit)
      {
        retAtEndOfBuffer = true;
        --pos;
      }

    if (markPos >= 0 && limit == buffer.length)
      markPos = -1;
    if (markPos < 0)
      pos = limit = 0;
    int count = in.read(buffer, limit, buffer.length - limit);
    if (count > 0)
      limit += count;

    if (retAtEndOfBuffer && buffer[pos] == '\n')
      {
        --count;
        // If the mark was set to the location of the \n, then we
        // must change it to fully pretend that the \n does not
        // exist.
        if (markPos == pos)
          ++markPos;
        ++pos;
      }

    return count;
  }

  public int read() throws IOException
  {
    synchronized (lock)
      {
        checkStatus();
        if (pos >= limit && fill () <= 0)
          return -1;
        return buffer[pos++];
      }
  }

  /* Return the end of the line starting at this.pos and ending at limit.
   * The index returns is *before* any line terminators, or limit
   * if no line terminators were found.
   */
  private int lineEnd(int limit)
  {
    int i = pos;
    for (; i < limit; i++)
      {
        char ch = buffer[i];
        if (ch == '\n' || ch == '\r')
          break;
      }
    return i;
  }

  /**
   * This method reads a single line of text from the input stream, returning
   * it as a <code>String</code>.  A line is terminated by "\n", a "\r", or
   * an "\r\n" sequence.  The system dependent line separator is not used.
   * The line termination characters are not returned in the resulting
   * <code>String</code>.
   *
   * @return The line of text read, or <code>null</code> if end of stream.
   *
   * @exception IOException If an error occurs
   */
  public String readLine() throws IOException
  {
    checkStatus();
    // Handle the special case where a previous readLine (with no intervening
    // reads/skips) had a '\r' at the end of the buffer.
    // In this case, we'll need to skip a '\n' if it's the next char to be read.
    // This special case is indicated by 'pos > limit'.
    if (pos > limit)
      {
        int ch = read();
        if (ch < 0)
          return null;
        if (ch != '\n')
          --pos;
      }
    int i = lineEnd(limit);
    if (i < limit)
      {
        String str = String.valueOf(buffer, pos, i - pos);
        pos = i + 1;
        // If the last char in the buffer is a '\r', we must remember
        // to check if the next char to be read after the buffer is refilled
        // is a '\n'.  If so, skip it.  To indicate this condition, we set pos
        // to be limit + 1, which normally is never possible.
        if (buffer[i] == '\r')
          if (pos == limit || buffer[pos] == '\n')
            pos++;
        return str;
      }
    CPStringBuilder sbuf = new CPStringBuilder(200);
    sbuf.append(buffer, pos, i - pos);
    pos = i;
    // We only want to return null when no characters were read before
    // EOF.  So we must keep track of this separately.  Otherwise we
    // would treat an empty `sbuf' as an EOF condition, which is wrong
    // when there is just a newline.
    boolean eof = false;
    for (;;)
      {
        // readLine should block. So we must not return until a -1 is reached.
        if (pos >= limit)
          {
            // here count == 0 isn't sufficient to give a failure.
            int count = fill();
            if (count < 0)
              {
                eof = true;
                break;
              }
            continue;
          }
        int ch = buffer[pos++];
        if (ch == '\n' || ch == '\r')
          {
            // Check here if a '\r' was the last char in the buffer; if so,
            // mark it as in the comment above to indicate future reads
            // should skip a newline that is the next char read after
            // refilling the buffer.
            if (ch == '\r')
              if (pos == limit || buffer[pos] == '\n')
                pos++;
            break;
          }
        i = lineEnd(limit);
        sbuf.append(buffer, pos - 1, i - (pos - 1));
        pos = i;
      }
    return (sbuf.length() == 0 && eof) ? null : sbuf.toString();
  }

  /**
   * 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 in the buffer, then calls the
   * <code>skip</code> method on the underlying stream to skip the
   * remaining chars.
   *
   * @param count The requested number of chars to skip
   *
   * @return The actual number of chars skipped.
   *
   * @exception IOException If an error occurs.
   * @exception IllegalArgumentException If count is negative.
   */
  public long skip(long count) throws IOException
  {
    synchronized (lock)
      {
        checkStatus();
        if (count < 0)
          throw new IllegalArgumentException("skip value is negative");
        if (count == 0)
          return 0;
        // Yet again, we need to handle the special case of a readLine
        // that has a '\r' at the end of the buffer.  In this case, we need
        // to ignore a '\n' if it is the next char to be read.
        // This special case is indicated by 'pos > limit' (i.e. avail < 0).
        // To simplify things, if we're dealing with the special case for
        // readLine, just read the next char (since the fill method will
        // skip the '\n' for us).  By doing this, we'll have to back up pos.
        // That's easier than trying to keep track of whether we've skipped
        // one element or not.
        if (pos > limit)
          {
            if (read() < 0)
              return 0;
            else
              --pos;
          }

        int avail = limit - pos;

        if (count < avail)
          {
            pos += count;
            return count;
          }

        pos = limit;
        long todo = count - avail;
        if (todo > buffer.length)
          {
            markPos = -1;
            todo -= in.skip(todo);
          }
        else
          {
            while (todo > 0)
              {
                avail = fill();
                if (avail <= 0)
                  break;
                if (avail > todo)
                  avail = (int) todo;
                pos += avail;
                todo -= avail;
              }
          }
        return count - todo;
      }
  }

  private void checkStatus() throws IOException
  {
    if (in == null)
      throw new IOException("Stream closed");
  }
}
