1 | package org.apache.velocity.runtime.parser; |
2 | |
3 | /** |
4 | * NOTE : This class was originally an ASCII_CharStream autogenerated |
5 | * by Javacc. It was then modified via changing class name with appropriate |
6 | * fixes for CTORS, and mods to readChar(). |
7 | * |
8 | * This is safe because we *always* use Reader with this class, and never a |
9 | * InputStream. This guarantees that we have a correct stream of 16-bit |
10 | * chars - all encoding transformations have been done elsewhere, so we |
11 | * believe that there is no risk in doing this. Time will tell :) |
12 | */ |
13 | |
14 | /** |
15 | * An implementation of interface CharStream, where the stream is assumed to |
16 | * contain only ASCII characters (without unicode processing). |
17 | */ |
18 | |
19 | public final class VelocityCharStream |
20 | implements CharStream |
21 | { |
22 | public static final boolean staticFlag = false; |
23 | int bufsize; |
24 | int available; |
25 | int tokenBegin; |
26 | public int bufpos = -1; |
27 | private int bufline[]; |
28 | private int bufcolumn[]; |
29 | |
30 | private int column = 0; |
31 | private int line = 1; |
32 | |
33 | private boolean prevCharIsCR = false; |
34 | private boolean prevCharIsLF = false; |
35 | |
36 | private java.io.Reader inputStream; |
37 | |
38 | private char[] buffer; |
39 | private int maxNextCharInd = 0; |
40 | private int inBuf = 0; |
41 | |
42 | private final void ExpandBuff(boolean wrapAround) |
43 | { |
44 | char[] newbuffer = new char[bufsize + 2048]; |
45 | int newbufline[] = new int[bufsize + 2048]; |
46 | int newbufcolumn[] = new int[bufsize + 2048]; |
47 | |
48 | try |
49 | { |
50 | if (wrapAround) |
51 | { |
52 | System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); |
53 | System.arraycopy(buffer, 0, newbuffer, |
54 | bufsize - tokenBegin, bufpos); |
55 | buffer = newbuffer; |
56 | |
57 | System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); |
58 | System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); |
59 | bufline = newbufline; |
60 | |
61 | System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); |
62 | System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); |
63 | bufcolumn = newbufcolumn; |
64 | |
65 | maxNextCharInd = (bufpos += (bufsize - tokenBegin)); |
66 | } |
67 | else |
68 | { |
69 | System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); |
70 | buffer = newbuffer; |
71 | |
72 | System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); |
73 | bufline = newbufline; |
74 | |
75 | System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); |
76 | bufcolumn = newbufcolumn; |
77 | |
78 | maxNextCharInd = (bufpos -= tokenBegin); |
79 | } |
80 | } |
81 | catch (Throwable t) |
82 | { |
83 | throw new Error(t.getMessage()); |
84 | } |
85 | |
86 | |
87 | bufsize += 2048; |
88 | available = bufsize; |
89 | tokenBegin = 0; |
90 | } |
91 | |
92 | private final void FillBuff() throws java.io.IOException |
93 | { |
94 | if (maxNextCharInd == available) |
95 | { |
96 | if (available == bufsize) |
97 | { |
98 | if (tokenBegin > 2048) |
99 | { |
100 | bufpos = maxNextCharInd = 0; |
101 | available = tokenBegin; |
102 | } |
103 | else if (tokenBegin < 0) |
104 | bufpos = maxNextCharInd = 0; |
105 | else |
106 | ExpandBuff(false); |
107 | } |
108 | else if (available > tokenBegin) |
109 | available = bufsize; |
110 | else if ((tokenBegin - available) < 2048) |
111 | ExpandBuff(true); |
112 | else |
113 | available = tokenBegin; |
114 | } |
115 | |
116 | int i; |
117 | try { |
118 | if ((i = inputStream.read(buffer, maxNextCharInd, |
119 | available - maxNextCharInd)) == -1) |
120 | { |
121 | inputStream.close(); |
122 | throw new java.io.IOException(); |
123 | } |
124 | else |
125 | maxNextCharInd += i; |
126 | return; |
127 | } |
128 | catch(java.io.IOException e) { |
129 | --bufpos; |
130 | backup(0); |
131 | if (tokenBegin == -1) |
132 | tokenBegin = bufpos; |
133 | throw e; |
134 | } |
135 | } |
136 | |
137 | public final char BeginToken() throws java.io.IOException |
138 | { |
139 | tokenBegin = -1; |
140 | char c = readChar(); |
141 | tokenBegin = bufpos; |
142 | |
143 | return c; |
144 | } |
145 | |
146 | private final void UpdateLineColumn(char c) |
147 | { |
148 | column++; |
149 | |
150 | if (prevCharIsLF) |
151 | { |
152 | prevCharIsLF = false; |
153 | line += (column = 1); |
154 | } |
155 | else if (prevCharIsCR) |
156 | { |
157 | prevCharIsCR = false; |
158 | if (c == '\n') |
159 | { |
160 | prevCharIsLF = true; |
161 | } |
162 | else |
163 | line += (column = 1); |
164 | } |
165 | |
166 | switch (c) |
167 | { |
168 | case '\r' : |
169 | prevCharIsCR = true; |
170 | break; |
171 | case '\n' : |
172 | prevCharIsLF = true; |
173 | break; |
174 | case '\t' : |
175 | column--; |
176 | column += (8 - (column & 07)); |
177 | break; |
178 | default : |
179 | break; |
180 | } |
181 | |
182 | bufline[bufpos] = line; |
183 | bufcolumn[bufpos] = column; |
184 | } |
185 | |
186 | public final char readChar() throws java.io.IOException |
187 | { |
188 | if (inBuf > 0) |
189 | { |
190 | --inBuf; |
191 | |
192 | /* |
193 | * was : return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]); |
194 | */ |
195 | return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]; |
196 | } |
197 | |
198 | if (++bufpos >= maxNextCharInd) |
199 | FillBuff(); |
200 | |
201 | /* |
202 | * was : char c = (char)((char)0xff & buffer[bufpos]); |
203 | */ |
204 | char c = buffer[bufpos]; |
205 | |
206 | UpdateLineColumn(c); |
207 | return (c); |
208 | } |
209 | |
210 | /** |
211 | * @deprecated |
212 | * @see #getEndColumn |
213 | */ |
214 | |
215 | public final int getColumn() { |
216 | return bufcolumn[bufpos]; |
217 | } |
218 | |
219 | /** |
220 | * @deprecated |
221 | * @see #getEndLine |
222 | */ |
223 | |
224 | public final int getLine() { |
225 | return bufline[bufpos]; |
226 | } |
227 | |
228 | public final int getEndColumn() { |
229 | return bufcolumn[bufpos]; |
230 | } |
231 | |
232 | public final int getEndLine() { |
233 | return bufline[bufpos]; |
234 | } |
235 | |
236 | public final int getBeginColumn() { |
237 | return bufcolumn[tokenBegin]; |
238 | } |
239 | |
240 | public final int getBeginLine() { |
241 | return bufline[tokenBegin]; |
242 | } |
243 | |
244 | public final void backup(int amount) { |
245 | |
246 | inBuf += amount; |
247 | if ((bufpos -= amount) < 0) |
248 | bufpos += bufsize; |
249 | } |
250 | |
251 | public VelocityCharStream(java.io.Reader dstream, int startline, |
252 | int startcolumn, int buffersize) |
253 | { |
254 | inputStream = dstream; |
255 | line = startline; |
256 | column = startcolumn - 1; |
257 | |
258 | available = bufsize = buffersize; |
259 | buffer = new char[buffersize]; |
260 | bufline = new int[buffersize]; |
261 | bufcolumn = new int[buffersize]; |
262 | } |
263 | |
264 | public VelocityCharStream(java.io.Reader dstream, int startline, |
265 | int startcolumn) |
266 | { |
267 | this(dstream, startline, startcolumn, 4096); |
268 | } |
269 | public void ReInit(java.io.Reader dstream, int startline, |
270 | int startcolumn, int buffersize) |
271 | { |
272 | inputStream = dstream; |
273 | line = startline; |
274 | column = startcolumn - 1; |
275 | |
276 | if (buffer == null || buffersize != buffer.length) |
277 | { |
278 | available = bufsize = buffersize; |
279 | buffer = new char[buffersize]; |
280 | bufline = new int[buffersize]; |
281 | bufcolumn = new int[buffersize]; |
282 | } |
283 | prevCharIsLF = prevCharIsCR = false; |
284 | tokenBegin = inBuf = maxNextCharInd = 0; |
285 | bufpos = -1; |
286 | } |
287 | |
288 | public void ReInit(java.io.Reader dstream, int startline, |
289 | int startcolumn) |
290 | { |
291 | ReInit(dstream, startline, startcolumn, 4096); |
292 | } |
293 | public VelocityCharStream(java.io.InputStream dstream, int startline, |
294 | int startcolumn, int buffersize) |
295 | { |
296 | this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); |
297 | } |
298 | |
299 | public VelocityCharStream(java.io.InputStream dstream, int startline, |
300 | int startcolumn) |
301 | { |
302 | this(dstream, startline, startcolumn, 4096); |
303 | } |
304 | |
305 | public void ReInit(java.io.InputStream dstream, int startline, |
306 | int startcolumn, int buffersize) |
307 | { |
308 | ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); |
309 | } |
310 | public void ReInit(java.io.InputStream dstream, int startline, |
311 | int startcolumn) |
312 | { |
313 | ReInit(dstream, startline, startcolumn, 4096); |
314 | } |
315 | public final String GetImage() |
316 | { |
317 | if (bufpos >= tokenBegin) |
318 | return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); |
319 | else |
320 | return new String(buffer, tokenBegin, bufsize - tokenBegin) + |
321 | new String(buffer, 0, bufpos + 1); |
322 | } |
323 | |
324 | public final char[] GetSuffix(int len) |
325 | { |
326 | char[] ret = new char[len]; |
327 | |
328 | if ((bufpos + 1) >= len) |
329 | System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); |
330 | else |
331 | { |
332 | System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, |
333 | len - bufpos - 1); |
334 | System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); |
335 | } |
336 | |
337 | return ret; |
338 | } |
339 | |
340 | public void Done() |
341 | { |
342 | buffer = null; |
343 | bufline = null; |
344 | bufcolumn = null; |
345 | } |
346 | |
347 | /** |
348 | * Method to adjust line and column numbers for the start of a token.<BR> |
349 | */ |
350 | public void adjustBeginLineColumn(int newLine, int newCol) |
351 | { |
352 | int start = tokenBegin; |
353 | int len; |
354 | |
355 | if (bufpos >= tokenBegin) |
356 | { |
357 | len = bufpos - tokenBegin + inBuf + 1; |
358 | } |
359 | else |
360 | { |
361 | len = bufsize - tokenBegin + bufpos + 1 + inBuf; |
362 | } |
363 | |
364 | int i = 0, j = 0, k = 0; |
365 | int nextColDiff = 0, columnDiff = 0; |
366 | |
367 | while (i < len && |
368 | bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) |
369 | { |
370 | bufline[j] = newLine; |
371 | nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; |
372 | bufcolumn[j] = newCol + columnDiff; |
373 | columnDiff = nextColDiff; |
374 | i++; |
375 | } |
376 | |
377 | if (i < len) |
378 | { |
379 | bufline[j] = newLine++; |
380 | bufcolumn[j] = newCol + columnDiff; |
381 | |
382 | while (i++ < len) |
383 | { |
384 | if (bufline[j = start % bufsize] != bufline[++start % bufsize]) |
385 | bufline[j] = newLine++; |
386 | else |
387 | bufline[j] = newLine; |
388 | } |
389 | } |
390 | |
391 | line = bufline[j]; |
392 | column = bufcolumn[j]; |
393 | } |
394 | |
395 | } |