| /* Copyright (C) 1998, 1999 Free Software Foundation |
| |
| 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 November 11, 1998. |
| * @deprecated |
| */ |
| /* 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. Deprecated in JDK 1.1. |
| */ |
| |
| 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; |
| |
| public LineNumberInputStream(InputStream in) |
| { |
| super(in); |
| } |
| |
| 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; |
| } |
| |
| public int getLineNumber() |
| { |
| return lineNumber; |
| } |
| |
| public void mark(int readlimit) |
| { |
| in.mark(readlimit); |
| markLineNumber = lineNumber; |
| } |
| |
| 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; |
| } |
| |
| 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; |
| } |
| |
| public void reset() throws IOException |
| { |
| in.reset(); |
| lineNumber = markLineNumber; |
| justReadReturnChar = false; |
| } |
| |
| public void setLineNumber(int lineNumber) |
| { |
| this.lineNumber = lineNumber; |
| } |
| |
| 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; |
| } |
| } |