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