1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.jrst.legacy;
24
25 import org.apache.commons.collections.primitives.ArrayCharList;
26 import org.apache.commons.collections.primitives.CharList;
27
28 import java.io.BufferedReader;
29 import java.io.IOException;
30 import java.io.LineNumberReader;
31 import java.io.PushbackReader;
32 import java.io.Reader;
33 import java.util.ArrayList;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class AdvancedReader {
74
75
76 protected static final String TAB = " ";
77
78 protected static final int READ_AHEAD = 80;
79
80 protected Reader in;
81 protected CharList buffer;
82
83 protected int charNumber;
84 protected int charNumberMark;
85 protected int lineNumber;
86 protected int lineNumberMark;
87
88 protected int nextChar;
89 protected int markChar;
90
91 protected int readInMark;
92
93 protected boolean nlTwoCtrlChars = false;
94 protected boolean noNlAtEOF = false;
95
96
97
98
99
100 public AdvancedReader(Reader in) {
101 this.in = new LineNumberReader(in);
102 buffer = new ArrayCharList();
103 }
104
105 public void mark() throws IOException {
106 markChar = nextChar;
107 charNumberMark = charNumber;
108 lineNumberMark = lineNumber;
109
110 free(markChar);
111 }
112
113 public void reset() throws IOException {
114 nextChar = markChar;
115 charNumber = charNumberMark;
116 lineNumber = lineNumberMark;
117
118 }
119
120 public int readSinceMark() {
121 return nextChar - markChar;
122 }
123
124
125
126
127 public int getCharNumber() {
128 return charNumber;
129 }
130
131
132
133
134 public int getLineNumber() {
135 return lineNumber;
136 }
137
138
139
140
141
142
143
144
145 private int free(int number) throws IOException {
146
147 int result = Math.min(buffer.size(), number);
148 buffer.subList(0, result).clear();
149
150 nextChar -= result;
151 markChar -= result;
152
153 return result;
154 }
155
156
157
158
159
160
161
162 private void fill(int number) throws IOException {
163 int needed = nextChar + number - buffer.size();
164 if (needed > 0) {
165 char[] cbuf = new char[needed + READ_AHEAD];
166 int read = in.read(cbuf);
167 if (read != -1) {
168 for (int i = 0; i < read; i++) {
169 buffer.add(cbuf[i]);
170 }
171 }
172 }
173 }
174
175 public boolean eof() throws IOException {
176 boolean result = -1 == read();
177 if (!result) {
178 unread(1);
179 }
180 return result;
181 }
182
183 public int skip(int number) throws IOException {
184 int result = 0;
185 while (result < number && read() != -1) {
186 result++;
187 }
188 return result;
189 }
190
191
192
193
194
195 public void add(char character) {
196 buffer.add(nextChar,character);
197 }
198
199
200
201
202
203
204
205
206 public int unread(int number) {
207 int result = Math.min(number, nextChar);
208
209 nextChar -= result;
210 charNumber -= result;
211 for (int i = nextChar; i < nextChar + result; i++) {
212 if (buffer.get(i) == '\n' || (buffer.get(i) == '\r' && i + 1 < nextChar + result && buffer.get(i + 1) != '\n')) {
213 lineNumber--;
214 }
215 }
216
217 return result;
218 }
219
220
221
222
223
224
225
226
227
228
229 public int unread(String line, boolean addNewLine) {
230 int result = unread(line.length() + (addNewLine ? (nlTwoCtrlChars ? 2 : 1) : 0));
231 return result;
232 }
233
234
235
236
237
238
239
240
241
242
243
244 public int unread(String[] lines, boolean addNewLine) {
245 int result = 0;
246 for (String line : lines) {
247 result += unread(line, addNewLine);
248 }
249 return result;
250 }
251
252
253
254
255
256
257
258 public int read() throws IOException {
259 fill(1);
260 int result = -1;
261 if (nextChar < buffer.size()) {
262 result = buffer.get(nextChar++);
263 charNumber++;
264 if ((char)result == '\n' || ((char)result == '\r' && nextChar < buffer.size() && buffer.get(nextChar) != '\n')) {
265 lineNumber++;
266 }
267 }
268 return result;
269 }
270
271
272
273
274
275
276
277 public String readLine() throws IOException {
278 StringBuffer result = new StringBuffer(READ_AHEAD);
279 int c = read();
280 while (c != -1 && c != '\n' && c != '\r') {
281 result.append((char) c);
282 c = read();
283 }
284 nlTwoCtrlChars = false;
285 if (c == '\r') {
286 c = read();
287 if (c != '\n' && c != -1) {
288 unread(1);
289 } else {
290 nlTwoCtrlChars = true;
291 }
292 }
293 noNlAtEOF = false;
294 if (c == -1 && result.length() >= 0) {
295 if (c == -1 && result.length() == 0) {
296 return null;
297 } else {
298 noNlAtEOF = true;
299 return result.toString();
300 }
301 } else {
302 return result.toString();
303 }
304 }
305
306
307
308
309
310
311
312
313
314 public void skipBlankLines() throws IOException {
315 readUntil("^\\s*\\S+.*");
316 }
317
318
319
320
321
322
323
324 String[] readAll() throws IOException {
325 String[] result = readLines(-1);
326 return result;
327 }
328
329
330
331
332
333
334
335
336
337 public String[] readLines(int count) throws IOException {
338 ArrayList<String> result = new ArrayList<String>();
339
340 String tmp = "";
341 for (int i = count; tmp != null && i != 0; i--) {
342 tmp = readLine();
343 if (tmp != null) {
344 result.add(tmp);
345 }
346 }
347 return result.toArray(new String[result.size()]);
348 }
349
350
351
352
353
354
355
356 public String[] readUntilBlank() throws IOException {
357 String[] result = readUntil("\\s*");
358 return result;
359 }
360
361
362
363
364
365
366
367
368
369
370 public String[] readUntil(String pattern) throws IOException {
371 ArrayList<String> result = new ArrayList<String>();
372 String tmp = readLine();
373 while (tmp != null && !tmp.matches(pattern)) {
374 result.add(tmp);
375 tmp = readLine();
376 }
377 if (tmp != null) {
378 unread(tmp.length() + (!noNlAtEOF ? (nlTwoCtrlChars ? 2 : 1) : 0));
379 }
380 return result.toArray(new String[result.size()]);
381 }
382
383
384
385
386
387
388
389
390 public String[] readWhile(String pattern) throws IOException {
391 ArrayList<String> result = new ArrayList<String>();
392 String tmp = readLine();
393 while (tmp != null && tmp.matches(pattern)) {
394 result.add(tmp);
395 tmp = readLine();
396 }
397 if (tmp != null) {
398 unread(tmp.length() + (!noNlAtEOF ? (nlTwoCtrlChars ? 2 : 1) : 0));
399 }
400 return result.toArray(new String[result.size()]);
401 }
402
403 }