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 STATIC_FLAG = 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 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 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 i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd);
154 if (i == -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 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 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 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 bufpos++;
247 if (bufpos >= maxNextCharInd)
248 {
249 FillBuff();
250 }
251
252
253
254
255 char c = buffer[bufpos];
256
257 UpdateLineColumn(c);
258 return c;
259 }
260
261
262
263
264
265 public int getColumn()
266 {
267 return bufcolumn[bufpos];
268 }
269
270
271
272
273
274 public int getLine()
275 {
276 return bufline[bufpos];
277 }
278
279
280
281
282 public int getEndColumn()
283 {
284 return bufcolumn[bufpos];
285 }
286
287
288
289
290 public int getEndLine()
291 {
292 return bufline[bufpos];
293 }
294
295
296
297
298 public int getBeginColumn()
299 {
300 return bufcolumn[tokenBegin];
301 }
302
303
304
305
306 public int getBeginLine()
307 {
308 return bufline[tokenBegin];
309 }
310
311
312
313
314 public void backup(int amount)
315 {
316
317 inBuf += amount;
318 bufpos -= amount;
319 if (bufpos < 0) {
320 bufpos += bufsize;
321 }
322 }
323
324
325
326
327
328
329
330 public VelocityCharStream(java.io.Reader dstream, int startline,
331 int startcolumn, int buffersize)
332 {
333 inputStream = dstream;
334 line = startline;
335 column = startcolumn - 1;
336
337 available = bufsize = nextBufExpand = buffersize;
338 buffer = new char[buffersize];
339 bufline = new int[buffersize];
340 bufcolumn = new int[buffersize];
341 }
342
343
344
345
346
347
348 public VelocityCharStream(java.io.Reader dstream, int startline,
349 int startcolumn)
350 {
351 this(dstream, startline, startcolumn, 4096);
352 }
353
354
355
356
357
358
359 public void ReInit(java.io.Reader dstream, int startline,
360 int startcolumn, int buffersize)
361 {
362 inputStream = dstream;
363 line = startline;
364 column = startcolumn - 1;
365
366 if (buffer == null || buffersize != buffer.length)
367 {
368 available = bufsize = nextBufExpand = buffersize;
369 buffer = new char[buffersize];
370 bufline = new int[buffersize];
371 bufcolumn = new int[buffersize];
372 }
373 prevCharIsLF = prevCharIsCR = false;
374 tokenBegin = inBuf = maxNextCharInd = 0;
375 bufpos = -1;
376 }
377
378
379
380
381
382
383 public void ReInit(java.io.Reader dstream, int startline,
384 int startcolumn)
385 {
386 ReInit(dstream, startline, startcolumn, 4096);
387 }
388
389
390
391
392
393
394 public VelocityCharStream(java.io.InputStream dstream, int startline,
395 int startcolumn, int buffersize)
396 {
397 this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
398 }
399
400
401
402
403
404
405 public VelocityCharStream(java.io.InputStream dstream, int startline,
406 int startcolumn)
407 {
408 this(dstream, startline, startcolumn, 4096);
409 }
410
411
412
413
414
415
416
417 public void ReInit(java.io.InputStream dstream, int startline,
418 int startcolumn, int buffersize)
419 {
420 ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
421 }
422
423
424
425
426
427 public void ReInit(java.io.InputStream dstream, int startline,
428 int startcolumn)
429 {
430 ReInit(dstream, startline, startcolumn, 4096);
431 }
432
433
434
435 public String GetImage()
436 {
437 if (bufpos >= tokenBegin)
438 {
439 return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
440 }
441 else
442 {
443 return new String(buffer, tokenBegin, bufsize - tokenBegin) +
444 new String(buffer, 0, bufpos + 1);
445 }
446 }
447
448
449
450
451 public char[] GetSuffix(int len)
452 {
453 char[] ret = new char[len];
454
455 if ((bufpos + 1) >= len)
456 {
457 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
458 }
459 else
460 {
461 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
462 len - bufpos - 1);
463 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
464 }
465
466 return ret;
467 }
468
469
470
471
472 public void Done()
473 {
474 buffer = null;
475 bufline = null;
476 bufcolumn = null;
477 }
478
479
480
481
482
483
484 public void adjustBeginLineColumn(int newLine, int newCol)
485 {
486 int start = tokenBegin;
487 int len;
488
489 if (bufpos >= tokenBegin)
490 {
491 len = bufpos - tokenBegin + inBuf + 1;
492 }
493 else
494 {
495 len = bufsize - tokenBegin + bufpos + 1 + inBuf;
496 }
497
498 int i = 0;
499 int j = 0;
500 int k = 0;
501 int nextColDiff = 0;
502 int columnDiff = 0;
503
504 while (i < len &&
505 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
506 {
507 bufline[j] = newLine;
508 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
509 bufcolumn[j] = newCol + columnDiff;
510 columnDiff = nextColDiff;
511 i++;
512 }
513
514 if (i < len)
515 {
516 bufline[j] = newLine++;
517 bufcolumn[j] = newCol + columnDiff;
518
519 while (i++ < len)
520 {
521 j = start % bufsize;
522 start++;
523 if (bufline[j] != bufline[start % bufsize]) {
524 bufline[j] = newLine++;
525 } else {
526 bufline[j] = newLine;
527 }
528 }
529 }
530
531 line = bufline[j];
532 column = bufcolumn[j];
533 }
534
535 }
536