blob: 1f37a98e92809f45f0c84e5549bc0504dad1bcc5 [file] [log] [blame]
Rahul Ravikumar05336002019-10-14 15:04:32 -07001/*
2 * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.io;
27
28/**
29 * This class is an input stream filter that provides the added
30 * functionality of keeping track of the current line number.
31 * <p>
32 * A line is a sequence of bytes ending with a carriage return
33 * character ({@code '\u005Cr'}), a newline character
34 * ({@code '\u005Cn'}), or a carriage return character followed
35 * immediately by a linefeed character. In all three cases, the line
36 * terminating character(s) are returned as a single newline character.
37 * <p>
38 * The line number begins at {@code 0}, and is incremented by
39 * {@code 1} when a {@code read} returns a newline character.
40 *
41 * @author Arthur van Hoff
42 * @see java.io.LineNumberReader
43 * @since JDK1.0
44 * @deprecated This class incorrectly assumes that bytes adequately represent
45 * characters. As of JDK&nbsp;1.1, the preferred way to operate on
46 * character streams is via the new character-stream classes, which
47 * include a class for counting line numbers.
48 */
49@Deprecated
50public
51class LineNumberInputStream extends FilterInputStream {
52 int pushBack = -1;
53 int lineNumber;
54 int markLineNumber;
55 int markPushBack = -1;
56
57 /**
58 * Constructs a newline number input stream that reads its input
59 * from the specified input stream.
60 *
61 * @param in the underlying input stream.
62 */
63 public LineNumberInputStream(InputStream in) {
64 super(in);
65 }
66
67 /**
68 * Reads the next byte of data from this input stream. The value
69 * byte is returned as an {@code int} in the range
70 * {@code 0} to {@code 255}. If no byte is available
71 * because the end of the stream has been reached, the value
72 * {@code -1} is returned. This method blocks until input data
73 * is available, the end of the stream is detected, or an exception
74 * is thrown.
75 * <p>
76 * The {@code read} method of
77 * {@code LineNumberInputStream} calls the {@code read}
78 * method of the underlying input stream. It checks for carriage
79 * returns and newline characters in the input, and modifies the
80 * current line number as appropriate. A carriage-return character or
81 * a carriage return followed by a newline character are both
82 * converted into a single newline character.
83 *
84 * @return the next byte of data, or {@code -1} if the end of this
85 * stream is reached.
86 * @exception IOException if an I/O error occurs.
87 * @see java.io.FilterInputStream#in
88 * @see java.io.LineNumberInputStream#getLineNumber()
89 */
90 @SuppressWarnings("fallthrough")
91 public int read() throws IOException {
92 int c = pushBack;
93
94 if (c != -1) {
95 pushBack = -1;
96 } else {
97 c = in.read();
98 }
99
100 switch (c) {
101 case '\r':
102 pushBack = in.read();
103 if (pushBack == '\n') {
104 pushBack = -1;
105 }
106 case '\n':
107 lineNumber++;
108 return '\n';
109 }
110 return c;
111 }
112
113 /**
114 * Reads up to {@code len} bytes of data from this input stream
115 * into an array of bytes. This method blocks until some input is available.
116 * <p>
117 * The {@code read} method of
118 * {@code LineNumberInputStream} repeatedly calls the
119 * {@code read} method of zero arguments to fill in the byte array.
120 *
121 * @param b the buffer into which the data is read.
122 * @param off the start offset of the data.
123 * @param len the maximum number of bytes read.
124 * @return the total number of bytes read into the buffer, or
125 * {@code -1} if there is no more data because the end of
126 * this stream has been reached.
127 * @exception IOException if an I/O error occurs.
128 * @see java.io.LineNumberInputStream#read()
129 */
130 public int read(byte b[], int off, int len) throws IOException {
131 if (b == null) {
132 throw new NullPointerException();
133 } else if ((off < 0) || (off > b.length) || (len < 0) ||
134 ((off + len) > b.length) || ((off + len) < 0)) {
135 throw new IndexOutOfBoundsException();
136 } else if (len == 0) {
137 return 0;
138 }
139
140 int c = read();
141 if (c == -1) {
142 return -1;
143 }
144 b[off] = (byte)c;
145
146 int i = 1;
147 try {
148 for (; i < len ; i++) {
149 c = read();
150 if (c == -1) {
151 break;
152 }
153 if (b != null) {
154 b[off + i] = (byte)c;
155 }
156 }
157 } catch (IOException ee) {
158 }
159 return i;
160 }
161
162 /**
163 * Skips over and discards {@code n} bytes of data from this
164 * input stream. The {@code skip} method may, for a variety of
165 * reasons, end up skipping over some smaller number of bytes,
166 * possibly {@code 0}. The actual number of bytes skipped is
167 * returned. If {@code n} is negative, no bytes are skipped.
168 * <p>
169 * The {@code skip} method of {@code LineNumberInputStream} creates
170 * a byte array and then repeatedly reads into it until
171 * {@code n} bytes have been read or the end of the stream has
172 * been reached.
173 *
174 * @param n the number of bytes to be skipped.
175 * @return the actual number of bytes skipped.
176 * @exception IOException if an I/O error occurs.
177 * @see java.io.FilterInputStream#in
178 */
179 public long skip(long n) throws IOException {
180 int chunk = 2048;
181 long remaining = n;
182 byte data[];
183 int nr;
184
185 if (n <= 0) {
186 return 0;
187 }
188
189 data = new byte[chunk];
190 while (remaining > 0) {
191 nr = read(data, 0, (int) Math.min(chunk, remaining));
192 if (nr < 0) {
193 break;
194 }
195 remaining -= nr;
196 }
197
198 return n - remaining;
199 }
200
201 /**
202 * Sets the line number to the specified argument.
203 *
204 * @param lineNumber the new line number.
205 * @see #getLineNumber
206 */
207 public void setLineNumber(int lineNumber) {
208 this.lineNumber = lineNumber;
209 }
210
211 /**
212 * Returns the current line number.
213 *
214 * @return the current line number.
215 * @see #setLineNumber
216 */
217 public int getLineNumber() {
218 return lineNumber;
219 }
220
221
222 /**
223 * Returns the number of bytes that can be read from this input
224 * stream without blocking.
225 * <p>
226 * Note that if the underlying input stream is able to supply
227 * <i>k</i> input characters without blocking, the
228 * {@code LineNumberInputStream} can guarantee only to provide
229 * <i>k</i>/2 characters without blocking, because the
230 * <i>k</i> characters from the underlying input stream might
231 * consist of <i>k</i>/2 pairs of {@code '\u005Cr'} and
232 * {@code '\u005Cn'}, which are converted to just
233 * <i>k</i>/2 {@code '\u005Cn'} characters.
234 *
235 * @return the number of bytes that can be read from this input stream
236 * without blocking.
237 * @exception IOException if an I/O error occurs.
238 * @see java.io.FilterInputStream#in
239 */
240 public int available() throws IOException {
241 return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
242 }
243
244 /**
245 * Marks the current position in this input stream. A subsequent
246 * call to the {@code reset} method repositions this stream at
247 * the last marked position so that subsequent reads re-read the same bytes.
248 * <p>
249 * The {@code mark} method of
250 * {@code LineNumberInputStream} remembers the current line
251 * number in a private variable, and then calls the {@code mark}
252 * method of the underlying input stream.
253 *
254 * @param readlimit the maximum limit of bytes that can be read before
255 * the mark position becomes invalid.
256 * @see java.io.FilterInputStream#in
257 * @see java.io.LineNumberInputStream#reset()
258 */
259 public void mark(int readlimit) {
260 markLineNumber = lineNumber;
261 markPushBack = pushBack;
262 in.mark(readlimit);
263 }
264
265 /**
266 * Repositions this stream to the position at the time the
267 * {@code mark} method was last called on this input stream.
268 * <p>
269 * The {@code reset} method of
270 * {@code LineNumberInputStream} resets the line number to be
271 * the line number at the time the {@code mark} method was
272 * called, and then calls the {@code reset} method of the
273 * underlying input stream.
274 * <p>
275 * Stream marks are intended to be used in
276 * situations where you need to read ahead a little to see what's in
277 * the stream. Often this is most easily done by invoking some
278 * general parser. If the stream is of the type handled by the
279 * parser, it just chugs along happily. If the stream is not of
280 * that type, the parser should toss an exception when it fails,
281 * which, if it happens within readlimit bytes, allows the outer
282 * code to reset the stream and try another parser.
283 *
284 * @exception IOException if an I/O error occurs.
285 * @see java.io.FilterInputStream#in
286 * @see java.io.LineNumberInputStream#mark(int)
287 */
288 public void reset() throws IOException {
289 lineNumber = markLineNumber;
290 pushBack = markPushBack;
291 in.reset();
292 }
293}