Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/io/LineNumberReader.java
38829 views
1
/*
2
* Copyright (c) 1996, 2019, 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
26
package java.io;
27
28
29
/**
30
* A buffered character-input stream that keeps track of line numbers. This
31
* class defines methods {@link #setLineNumber(int)} and {@link
32
* #getLineNumber()} for setting and getting the current line number
33
* respectively.
34
*
35
* <p> By default, line numbering begins at 0. This number increments at every
36
* <a href="#lt">line terminator</a> as the data is read, and can be changed
37
* with a call to <tt>setLineNumber(int)</tt>. Note however, that
38
* <tt>setLineNumber(int)</tt> does not actually change the current position in
39
* the stream; it only changes the value that will be returned by
40
* <tt>getLineNumber()</tt>.
41
*
42
* <p> A line is considered to be <a name="lt">terminated</a> by any one of a
43
* line feed ('\n'), a carriage return ('\r'), or a carriage return followed
44
* immediately by a linefeed.
45
*
46
* @author Mark Reinhold
47
* @since JDK1.1
48
*/
49
50
public class LineNumberReader extends BufferedReader {
51
52
/** The current line number */
53
private int lineNumber = 0;
54
55
/** The line number of the mark, if any */
56
private int markedLineNumber; // Defaults to 0
57
58
/** If the next character is a line feed, skip it */
59
private boolean skipLF;
60
61
/** The skipLF flag when the mark was set */
62
private boolean markedSkipLF;
63
64
/**
65
* Create a new line-numbering reader, using the default input-buffer
66
* size.
67
*
68
* @param in
69
* A Reader object to provide the underlying stream
70
*/
71
public LineNumberReader(Reader in) {
72
super(in);
73
}
74
75
/**
76
* Create a new line-numbering reader, reading characters into a buffer of
77
* the given size.
78
*
79
* @param in
80
* A Reader object to provide the underlying stream
81
*
82
* @param sz
83
* An int specifying the size of the buffer
84
*/
85
public LineNumberReader(Reader in, int sz) {
86
super(in, sz);
87
}
88
89
/**
90
* Set the current line number.
91
*
92
* @param lineNumber
93
* An int specifying the line number
94
*
95
* @see #getLineNumber
96
*/
97
public void setLineNumber(int lineNumber) {
98
this.lineNumber = lineNumber;
99
}
100
101
/**
102
* Get the current line number.
103
*
104
* @return The current line number
105
*
106
* @see #setLineNumber
107
*/
108
public int getLineNumber() {
109
return lineNumber;
110
}
111
112
/**
113
* Read a single character. <a href="#lt">Line terminators</a> are
114
* compressed into single newline ('\n') characters. Whenever a line
115
* terminator is read the current line number is incremented.
116
*
117
* @return The character read, or -1 if the end of the stream has been
118
* reached
119
*
120
* @throws IOException
121
* If an I/O error occurs
122
*/
123
@SuppressWarnings("fallthrough")
124
public int read() throws IOException {
125
synchronized (lock) {
126
int c = super.read();
127
if (skipLF) {
128
if (c == '\n')
129
c = super.read();
130
skipLF = false;
131
}
132
switch (c) {
133
case '\r':
134
skipLF = true;
135
case '\n': /* Fall through */
136
lineNumber++;
137
return '\n';
138
}
139
return c;
140
}
141
}
142
143
/**
144
* Read characters into a portion of an array. Whenever a <a
145
* href="#lt">line terminator</a> is read the current line number is
146
* incremented.
147
*
148
* @param cbuf
149
* Destination buffer
150
*
151
* @param off
152
* Offset at which to start storing characters
153
*
154
* @param len
155
* Maximum number of characters to read
156
*
157
* @return The number of bytes read, or -1 if the end of the stream has
158
* already been reached
159
*
160
* @throws IOException
161
* If an I/O error occurs
162
*/
163
@SuppressWarnings("fallthrough")
164
public int read(char cbuf[], int off, int len) throws IOException {
165
synchronized (lock) {
166
int n = super.read(cbuf, off, len);
167
168
for (int i = off; i < off + n; i++) {
169
int c = cbuf[i];
170
if (skipLF) {
171
skipLF = false;
172
if (c == '\n')
173
continue;
174
}
175
switch (c) {
176
case '\r':
177
skipLF = true;
178
case '\n': /* Fall through */
179
lineNumber++;
180
break;
181
}
182
}
183
184
return n;
185
}
186
}
187
188
/**
189
* Read a line of text. Whenever a <a href="#lt">line terminator</a> is
190
* read the current line number is incremented.
191
*
192
* @return A String containing the contents of the line, not including
193
* any <a href="#lt">line termination characters</a>, or
194
* <tt>null</tt> if the end of the stream has been reached
195
*
196
* @throws IOException
197
* If an I/O error occurs
198
*/
199
public String readLine() throws IOException {
200
synchronized (lock) {
201
String l = super.readLine(skipLF);
202
skipLF = false;
203
if (l != null)
204
lineNumber++;
205
return l;
206
}
207
}
208
209
/** Maximum skip-buffer size */
210
private static final int maxSkipBufferSize = 8192;
211
212
/** Skip buffer, null until allocated */
213
private char skipBuffer[] = null;
214
215
/**
216
* Skip characters.
217
*
218
* @param n
219
* The number of characters to skip
220
*
221
* @return The number of characters actually skipped
222
*
223
* @throws IOException
224
* If an I/O error occurs
225
*
226
* @throws IllegalArgumentException
227
* If <tt>n</tt> is negative
228
*/
229
public long skip(long n) throws IOException {
230
if (n < 0)
231
throw new IllegalArgumentException("skip() value is negative");
232
int nn = (int) Math.min(n, maxSkipBufferSize);
233
synchronized (lock) {
234
if ((skipBuffer == null) || (skipBuffer.length < nn))
235
skipBuffer = new char[nn];
236
long r = n;
237
while (r > 0) {
238
int nc = read(skipBuffer, 0, (int) Math.min(r, nn));
239
if (nc == -1)
240
break;
241
r -= nc;
242
}
243
return n - r;
244
}
245
}
246
247
/**
248
* Mark the present position in the stream. Subsequent calls to reset()
249
* will attempt to reposition the stream to this point, and will also reset
250
* the line number appropriately.
251
*
252
* @param readAheadLimit
253
* Limit on the number of characters that may be read while still
254
* preserving the mark. After reading this many characters,
255
* attempting to reset the stream may fail.
256
*
257
* @throws IOException
258
* If an I/O error occurs
259
*/
260
public void mark(int readAheadLimit) throws IOException {
261
synchronized (lock) {
262
// If the most recently read character is '\r', then increment the
263
// read ahead limit as in this case if the next character is '\n',
264
// two characters would actually be read by the next read().
265
if (skipLF)
266
readAheadLimit++;
267
super.mark(readAheadLimit);
268
markedLineNumber = lineNumber;
269
markedSkipLF = skipLF;
270
}
271
}
272
273
/**
274
* Reset the stream to the most recent mark.
275
*
276
* @throws IOException
277
* If the stream has not been marked, or if the mark has been
278
* invalidated
279
*/
280
public void reset() throws IOException {
281
synchronized (lock) {
282
super.reset();
283
lineNumber = markedLineNumber;
284
skipLF = markedSkipLF;
285
}
286
}
287
288
}
289
290