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