| /* 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; | |
| } | |
| } |