1 package net.sourceforge.pmd.lang.vm.util;
2
3 import net.sourceforge.pmd.lang.ast.CharStream;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public final class VelocityCharStream
41 implements CharStream
42 {
43 public static final boolean staticFlag = false;
44 int bufsize;
45 private int nextBufExpand;
46 int available;
47 int tokenBegin;
48
49 public int bufpos = -1;
50 private int bufline[];
51 private int bufcolumn[];
52
53 private int column = 0;
54 private int line = 1;
55
56 private boolean prevCharIsCR = false;
57 private boolean prevCharIsLF = false;
58
59 private java.io.Reader inputStream;
60
61 private char[] buffer;
62 private int maxNextCharInd = 0;
63 private int inBuf = 0;
64
65 private final void ExpandBuff(boolean wrapAround)
66 {
67 char[] newbuffer = new char[bufsize + nextBufExpand];
68 int newbufline[] = new int[bufsize + nextBufExpand];
69 int newbufcolumn[] = new int[bufsize + nextBufExpand];
70
71 try
72 {
73 if (wrapAround)
74 {
75 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
76 System.arraycopy(buffer, 0, newbuffer,
77 bufsize - tokenBegin, bufpos);
78 buffer = newbuffer;
79
80 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
81 System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
82 bufline = newbufline;
83
84 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
85 System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
86 bufcolumn = newbufcolumn;
87
88 maxNextCharInd = (bufpos += (bufsize - tokenBegin));
89 }
90 else
91 {
92 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
93 buffer = newbuffer;
94
95 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
96 bufline = newbufline;
97
98 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
99 bufcolumn = newbufcolumn;
100
101 maxNextCharInd = (bufpos -= tokenBegin);
102 }
103 }
104 catch (Throwable t)
105 {
106 throw new Error(t.getMessage());
107 }
108
109
110 bufsize += nextBufExpand;
111 nextBufExpand = bufsize;
112 available = bufsize;
113 tokenBegin = 0;
114 }
115
116 private final void FillBuff() throws java.io.IOException
117 {
118 if (maxNextCharInd == available)
119 {
120 if (available == bufsize)
121 {
122 if (tokenBegin > nextBufExpand)
123 {
124 bufpos = maxNextCharInd = 0;
125 available = tokenBegin;
126 }
127 else if (tokenBegin < 0)
128 {
129 bufpos = maxNextCharInd = 0;
130 }
131 else
132 {
133 ExpandBuff(false);
134 }
135 }
136 else if (available > tokenBegin)
137 {
138 available = bufsize;
139 }
140 else if ((tokenBegin - available) < nextBufExpand)
141 {
142 ExpandBuff(true);
143 }
144 else
145 {
146 available = tokenBegin;
147 }
148 }
149
150 int i;
151 try
152 {
153 if ((i = inputStream.read(buffer, maxNextCharInd,
154 available - maxNextCharInd)) == -1)
155 {
156 inputStream.close();
157 throw new java.io.IOException();
158 }
159 else
160 {
161 maxNextCharInd += i;
162 }
163 return;
164 }
165 catch(java.io.IOException e)
166 {
167 --bufpos;
168 backup(0);
169 if (tokenBegin == -1)
170 {
171 tokenBegin = bufpos;
172 }
173 throw e;
174 }
175 }
176
177
178
179
180 public final char BeginToken() throws java.io.IOException
181 {
182 tokenBegin = -1;
183 char c = readChar();
184 tokenBegin = bufpos;
185
186 return c;
187 }
188
189 private final void UpdateLineColumn(char c)
190 {
191 column++;
192
193 if (prevCharIsLF)
194 {
195 prevCharIsLF = false;
196 line += (column = 1);
197 }
198 else if (prevCharIsCR)
199 {
200 prevCharIsCR = false;
201 if (c == '\n')
202 {
203 prevCharIsLF = true;
204 }
205 else
206 {
207 line += (column = 1);
208 }
209 }
210
211 switch (c)
212 {
213 case '\r' :
214 prevCharIsCR = true;
215 break;
216 case '\n' :
217 prevCharIsLF = true;
218 break;
219 case '\t' :
220 column--;
221 column += (8 - (column & 07));
222 break;
223 default :
224 break;
225 }
226
227 bufline[bufpos] = line;
228 bufcolumn[bufpos] = column;
229 }
230
231
232
233
234 public final char readChar() throws java.io.IOException
235 {
236 if (inBuf > 0)
237 {
238 --inBuf;
239
240
241
242
243 return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
244 }
245
246 if (++bufpos >= maxNextCharInd)
247 {
248 FillBuff();
249 }
250
251
252
253
254 char c = buffer[bufpos];
255
256 UpdateLineColumn(c);
257 return (c);
258 }
259
260
261
262
263
264 public final int getColumn()
265 {
266 return bufcolumn[bufpos];
267 }
268
269
270
271
272
273 public final int getLine()
274 {
275 return bufline[bufpos];
276 }
277
278
279
280
281 public final int getEndColumn()
282 {
283 return bufcolumn[bufpos];
284 }
285
286
287
288
289 public final int getEndLine()
290 {
291 return bufline[bufpos];
292 }
293
294
295
296
297 public final int getBeginColumn()
298 {
299 return bufcolumn[tokenBegin];
300 }
301
302
303
304
305 public final int getBeginLine()
306 {
307 return bufline[tokenBegin];
308 }
309
310
311
312
313 public final void backup(int amount)
314 {
315
316 inBuf += amount;
317 if ((bufpos -= amount) < 0)
318 bufpos += bufsize;
319 }
320
321
322
323
324
325
326
327 public VelocityCharStream(java.io.Reader dstream, int startline,
328 int startcolumn, int buffersize)
329 {
330 inputStream = dstream;
331 line = startline;
332 column = startcolumn - 1;
333
334 available = bufsize = nextBufExpand = buffersize;
335 buffer = new char[buffersize];
336 bufline = new int[buffersize];
337 bufcolumn = new int[buffersize];
338 }
339
340
341
342
343
344
345 public VelocityCharStream(java.io.Reader dstream, int startline,
346 int startcolumn)
347 {
348 this(dstream, startline, startcolumn, 4096);
349 }
350
351
352
353
354
355
356 public void ReInit(java.io.Reader dstream, int startline,
357 int startcolumn, int buffersize)
358 {
359 inputStream = dstream;
360 line = startline;
361 column = startcolumn - 1;
362
363 if (buffer == null || buffersize != buffer.length)
364 {
365 available = bufsize = nextBufExpand = buffersize;
366 buffer = new char[buffersize];
367 bufline = new int[buffersize];
368 bufcolumn = new int[buffersize];
369 }
370 prevCharIsLF = prevCharIsCR = false;
371 tokenBegin = inBuf = maxNextCharInd = 0;
372 bufpos = -1;
373 }
374
375
376
377
378
379
380 public void ReInit(java.io.Reader dstream, int startline,
381 int startcolumn)
382 {
383 ReInit(dstream, startline, startcolumn, 4096);
384 }
385
386
387
388
389
390
391 public VelocityCharStream(java.io.InputStream dstream, int startline,
392 int startcolumn, int buffersize)
393 {
394 this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
395 }
396
397
398
399
400
401
402 public VelocityCharStream(java.io.InputStream dstream, int startline,
403 int startcolumn)
404 {
405 this(dstream, startline, startcolumn, 4096);
406 }
407
408
409
410
411
412
413
414 public void ReInit(java.io.InputStream dstream, int startline,
415 int startcolumn, int buffersize)
416 {
417 ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
418 }
419
420
421
422
423
424 public void ReInit(java.io.InputStream dstream, int startline,
425 int startcolumn)
426 {
427 ReInit(dstream, startline, startcolumn, 4096);
428 }
429
430
431
432 public final String GetImage()
433 {
434 if (bufpos >= tokenBegin)
435 {
436 return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
437 }
438 else
439 {
440 return new String(buffer, tokenBegin, bufsize - tokenBegin) +
441 new String(buffer, 0, bufpos + 1);
442 }
443 }
444
445
446
447
448 public final char[] GetSuffix(int len)
449 {
450 char[] ret = new char[len];
451
452 if ((bufpos + 1) >= len)
453 {
454 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
455 }
456 else
457 {
458 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
459 len - bufpos - 1);
460 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
461 }
462
463 return ret;
464 }
465
466
467
468
469 public void Done()
470 {
471 buffer = null;
472 bufline = null;
473 bufcolumn = null;
474 }
475
476
477
478
479
480
481 public void adjustBeginLineColumn(int newLine, int newCol)
482 {
483 int start = tokenBegin;
484 int len;
485
486 if (bufpos >= tokenBegin)
487 {
488 len = bufpos - tokenBegin + inBuf + 1;
489 }
490 else
491 {
492 len = bufsize - tokenBegin + bufpos + 1 + inBuf;
493 }
494
495 int i = 0, j = 0, k = 0;
496 int nextColDiff = 0, columnDiff = 0;
497
498 while (i < len &&
499 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
500 {
501 bufline[j] = newLine;
502 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
503 bufcolumn[j] = newCol + columnDiff;
504 columnDiff = nextColDiff;
505 i++;
506 }
507
508 if (i < len)
509 {
510 bufline[j] = newLine++;
511 bufcolumn[j] = newCol + columnDiff;
512
513 while (i++ < len)
514 {
515 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
516 bufline[j] = newLine++;
517 else
518 bufline[j] = newLine;
519 }
520 }
521
522 line = bufline[j];
523 column = bufcolumn[j];
524 }
525
526 }
527