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