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