summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2002-06-17 03:49:21 +0000
committerTom Tromey <tromey@redhat.com>2002-06-17 03:49:21 +0000
commita573067d5873f17e8c55aad84ff19b08fd179a5a (patch)
treeb28d70432f01da22d85d8bc76672b3b64079c79c
parentb6cd625a41ceee88a761449bd275c62727cd78b3 (diff)
downloadclasspath-a573067d5873f17e8c55aad84ff19b08fd179a5a.tar.gz
* java/io/LineNumberInputStream.java: Merged with libgcj version.
-rw-r--r--ChangeLog4
-rw-r--r--java/io/LineNumberInputStream.java576
2 files changed, 276 insertions, 304 deletions
diff --git a/ChangeLog b/ChangeLog
index 67c5fa7b4..53c708377 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2002-06-16 Tom Tromey <tromey@redhat.com>
+
+ * java/io/LineNumberInputStream.java: Merged with libgcj version.
+
2002-06-13 Tom Tromey <tromey@redhat.com>
Fix for Mauve regressions:
diff --git a/java/io/LineNumberInputStream.java b/java/io/LineNumberInputStream.java
index 3f819e72d..4a4d68a3d 100644
--- a/java/io/LineNumberInputStream.java
+++ b/java/io/LineNumberInputStream.java
@@ -1,5 +1,5 @@
/* LineNumberInputStream.java -- An input stream which counts line numbers
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,309 +39,277 @@ 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()} resets the line number to the point
- * at which <code>mark()</code> was called if the subordinate stream supports
- * that functionality.
- * <p>
- * 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.
- *
- * @deprecated
- *
- * @version 0.0
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
-public class LineNumberInputStream extends FilterInputStream
-{
-
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
- * This variable is used to keep track of the current line number
- */
-private int line_number;
-
-/**
- * This variable is used to keep track of the line number that was
- * current when the <code>mark()</code> method was called.
- */
-private int marked_line_number;
-
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
- * 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);
-
- // Override this.in with another filter
- this.in = new PushbackInputStream(in);
-}
-
-/*************************************************************************/
-
-/*
- * Instance Methods
+ * 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()} 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>
*/
-
-/**
- * This method returns the current line number
- *
- * @returns The current line number
- */
-public int
-getLineNumber()
-{
- return(line_number);
-}
-
-/*************************************************************************/
-
-/**
- * This method sets the current line number to the specified value.
- *
- * @param line_number The new line number
- */
-public void
-setLineNumber(int line_number)
-{
- this.line_number = line_number;
-}
-
-/*************************************************************************/
-
-/**
- * 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
-{
- return(in.available() / 2);
-}
-
-/*************************************************************************/
-
-/**
- * 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 synchronized void
-mark(int readlimit)
-{
- in.mark(readlimit);
-
- marked_line_number = line_number;
-}
-
-/*************************************************************************/
-
-/**
- * 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 synchronized void
-reset() throws IOException
-{
- in.reset();
-
- line_number = marked_line_number;
-}
-
-/*************************************************************************/
-
-/**
- * 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 synchronized int
-read() throws IOException
-{
- int byte_read = in.read();
-
- if (byte_read == '\n')
- ++line_number;
-
- if (byte_read == '\r')
- {
- int extra_byte_read = in.read();
-
- if ((extra_byte_read != '\n') && (extra_byte_read != -1))
- ((PushbackInputStream)in).unread(extra_byte_read);
-
- byte_read = '\n';
- ++line_number;
- }
-
- return(byte_read);
-}
-
-/*************************************************************************/
-
-/**
- * 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 synchronized int
-read(byte[] buf, int offset, int len) throws IOException
-{
- if (len == 0)
- return(0);
-
- // Read the first byte here in order to allow IOException's to
- // propagate up
- int byte_read = read();
- if (byte_read == -1)
- return(-1);
- buf[offset] = (byte)byte_read;
-
- int total_read = 1;
-
- // Read the rest of the bytes. We do this in a single read() loop
- // like a raw InputStream. That's ok in my book since this class is
- // deprecated anyway.
- try
- {
- for (int i = 1; i < len; i++)
- {
- byte_read = read();
- if (byte_read == -1)
- return(total_read);
-
- buf[offset + i] = (byte)byte_read;
-
- ++total_read;
- }
- }
- catch (IOException e)
- {
- return(total_read);
- }
-
- return(total_read);
-}
-
-/*************************************************************************/
-
-/**
- * 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 num_byte The requested number of bytes to skip.
- *
- * @return The actual number of bytes skipped.
- *
- * @exception IOException If an error occurs.
- */
-public long
-skip(long num_bytes) throws IOException
+public class LineNumberInputStream extends FilterInputStream
{
- return(super.skip(num_bytes));
+ /** 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
+ *
+ * @returns 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;
+ }
}
-
-} // class LineNumberInputStream
-