/* LineNumberInputStream.java -- An input stream which counts line numbers
   Copyright (C) 1998, 1999, 2002 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 class functions like a standard <code>InputStream</code>
 * except that it counts line numbers, and canonicalizes newline
 * characters.  As data is read, whenever the byte sequences "\r",
 * "\n", or "\r\n" are encountered, the running line count is
 * incremeted by one.  Additionally, the whatever line termination
 * sequence was encountered will be converted to a "\n" byte.  Note
 * that this class numbers lines from 0.  When the first line
 * terminator is encountered, the line number is incremented to 1, and
 * so on.
 * <p>
 * This class counts only line termination characters.  If the last line
 * read from the stream does not end in a line termination sequence, it
 * will not be counted as a line.
 * <p>
 * Note that since this class operates as a filter on an underlying
 * stream, it has the same mark/reset functionality as the underlying
 * stream.  The <code>mark()</code> and <code>reset()</code> methods
 * in this class handle line numbers correctly.  Calling
 * <code>reset()</code> resets the line number to the point at which
 * <code>mark()</code> was called if the subordinate stream supports
 * that functionality.
 * <p>
 * @deprecated This class is deprecated in favor if
 * <code>LineNumberReader</code> because it operates on ASCII bytes
 * instead of an encoded character stream.  This class is for backward
 * compatibility only and should not be used in new applications.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy <warrenl@cygnus.com>
 */
public class LineNumberInputStream extends FilterInputStream
{
  /** The current line number. */
  private int lineNumber = 0;

  /** The line number when the stream was marked. */
  private int markLineNumber = 0;

  /** Flag to indicate a '\r' was just read so that an immediately
   * subsequent '\n' can be ignored. */
  private boolean justReadReturnChar = false;

  /**
   * Create a new <code>LineNumberInputStream</code> that reads from the 
   * specified subordinate <code>InputStream</code>
   *
   * @param in The subordinate <code>InputStream</code> to read from
   */
  public LineNumberInputStream(InputStream in)
  {
    super(in);
  }

  /**
   * This method returns the number of bytes that can be read from the
   * stream before the stream can block.  This method is tricky
   * because the subordinate <code>InputStream</code> might return
   * only "\r\n" characters, which are replaced by a single "\n"
   * character by the <code>read()</code> method of this class.  So
   * this method can only guarantee that <code>in.available() /
   * 2</code> bytes can actually be read before blocking.  In
   * practice, considerably more bytes might be read before blocking
   * <p>
   * Note that the stream may not block if additional bytes beyond the count
   * returned by this method are read.
   *
   * @return The number of bytes that can be read before blocking could occur
   *
   * @exception IOException If an error occurs
   */
  public int available() throws IOException
  {
    // We can only guarantee half the characters that might be available
    // without blocking because "\r\n" is treated as a single character.
    return in.available() / 2;
  }

  /**
   * This method returns the current line number
   *
   * @return The current line number
   */
  public int getLineNumber()
  {
    return lineNumber;
  }

  /**
   * This method marks a position in the input to which the stream can
   * be "reset" byte calling the <code>reset()</code> method.  The
   * parameter <code>readlimit</code> is the number of bytes 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 bytes 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>
   * In this class, this method will remember the current line number
   * as well as the current position in the stream.  When the
   * <code>reset()</code> method is called, the line number will be
   * restored to the saved line number in addition to the stream
   * position.
   * <p>
   * This method only works if the subordinate stream supports mark/reset
   * functionality.
   *
   * @param readlimit The number of bytes that can be read before the
   * mark becomes invalid 
   */
  public void mark(int readlimit)
  {
    in.mark(readlimit);
    markLineNumber = lineNumber;
  }

  /**
   * This method reads an unsigned byte from the input stream and returns it
   * as an int in the range of 0-255.  This method will return -1 if the
   * end of the stream has been reached.
   * <p>
   * Note that if a line termination sequence is encountered (ie, "\r",
   * "\n", or "\r\n") then that line termination sequence is converted to
   * a single "\n" value which is returned from this method.  This means
   * that it is possible this method reads two bytes from the subordinate
   * stream instead of just one.
   * <p>
   * Note that this method will block until a byte of data is available
   * to be read.
   *
   * @return The byte read or -1 if end of stream
   * 
   * @exception IOException If an error occurs
   */
  public int read() throws IOException
  {
    // Treat "\r\n" as a single character.  A '\r' may have been read by
    // a previous call to read so we keep an internal flag to avoid having
    // to read ahead.

    int ch = in.read();

    if (ch == '\n')
      if (justReadReturnChar)
	{
	  ch = in.read();
          justReadReturnChar = false;
	}
      else
	lineNumber++;
    else if (ch == '\r')
      {
	ch = '\n';
	justReadReturnChar = true;
	lineNumber++;
      }
    else
      justReadReturnChar = false;

    return ch;
  }

  /**
   * This method reads bytes from a stream and stores them into a caller
   * supplied buffer.  It starts storing data at index <code>offset</code> into
   * the buffer and attemps to read <code>len</code> bytes.  This method can
   * return before reading the number of bytes requested.  The actual number
   * of bytes read is returned as an int.  A -1 is returned to indicated the
   * end of the stream.
   * <p>
   * This method will block until some data can be read.
   * <p>
   * Note that if a line termination sequence is encountered (ie, "\r",
   * "\n", or "\r\n") then that line termination sequence is converted to
   * a single "\n" value which is stored in the buffer.  Only a single
   * byte is counted towards the number of bytes read in this case.
   *
   * @param buf The array into which the bytes read should be stored
   * @param offset The offset into the array to start storing bytes
   * @param len The requested number of bytes to read
   *
   * @return The actual number of bytes read, or -1 if end of stream
   *
   * @exception IOException If an error occurs.
   */
  public int read(byte[] b, int off, int len) throws IOException
  {
    if (off < 0 || len < 0 || off + len > b.length)
      throw new ArrayIndexOutOfBoundsException();

    // This case always succeeds.
    if (len == 0)
      return 0;

    // The simplest, though not necessarily the most time efficient thing
    // to do is simply call read(void) len times.  Since this is a deprecated
    // class, that should be ok.
    final int origOff = off;
    while (len-- > 0)
      {
	int ch = read();
	if (ch < 0)
	  break;

	b[off++] = (byte) ch;
      }

    // This is safe since we already know that some bytes were
    // actually requested.
    return off == origOff ? -1 : off - origOff;
  }

  /**
   * This method resets a stream to the point where the
   * <code>mark()</code> method was called.  Any bytes that were read
   * after the mark point was set will be re-read during subsequent
   * reads.
   * <p>
   * In this class, this method will also restore the line number that was
   * current when the <code>mark()</code> method was called.
   *  <p>
   * This method only works if the subordinate stream supports mark/reset
   * functionality.
   *
   * @exception IOException If an error occurs
   */
  public void reset() throws IOException
  {
    in.reset();
    lineNumber = markLineNumber;
    justReadReturnChar = false;
  }

  /**
   * This method sets the current line number to the specified value.
   * 
   * @param lineNumber The new line number
   */
  public void setLineNumber(int lineNumber)
  {
    this.lineNumber = lineNumber;
  }

  /**
   * This method skips up to the requested number of bytes in the 
   * input stream.  The actual number of bytes skipped is returned.  If the
   * desired number of bytes to skip is negative, no bytes are skipped.
   *
   * @param n requested number of bytes to skip.
   *
   * @return The actual number of bytes skipped.
   *
   * @exception IOException If an error occurs.
   */
  public long skip(long n) throws IOException
  {
    if (n <= 0)
      return 0L;

    final long origN = n;

    do
      {
	int ch = read();
	if (ch < 0)
	  break;
	if (ch == '\n' || ch == '\r')
	  lineNumber++;
      }
    while (--n > 0);

    return origN - n;
  }
}
