View Javadoc

1   /* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 3.0 */
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 (with java-like unicode escape processing).
7    */
8   
9   public class JavaCharStream implements CharStream {
10      public static final boolean staticFlag = false;
11  
12      static final int hexval(char c) throws java.io.IOException {
13          switch (c) {
14              case '0':
15                  return 0;
16              case '1':
17                  return 1;
18              case '2':
19                  return 2;
20              case '3':
21                  return 3;
22              case '4':
23                  return 4;
24              case '5':
25                  return 5;
26              case '6':
27                  return 6;
28              case '7':
29                  return 7;
30              case '8':
31                  return 8;
32              case '9':
33                  return 9;
34  
35              case 'a':
36              case 'A':
37                  return 10;
38              case 'b':
39              case 'B':
40                  return 11;
41              case 'c':
42              case 'C':
43                  return 12;
44              case 'd':
45              case 'D':
46                  return 13;
47              case 'e':
48              case 'E':
49                  return 14;
50              case 'f':
51              case 'F':
52                  return 15;
53          }
54  
55          throw new java.io.IOException(); // Should never come here
56      }
57  
58      public int bufpos = -1;
59      int bufsize;
60      int available;
61      int tokenBegin;
62      protected int bufline[];
63      protected int bufcolumn[];
64  
65      protected int column = 0;
66      protected int line = 1;
67  
68      protected boolean prevCharIsCR = false;
69      protected boolean prevCharIsLF = false;
70  
71      protected java.io.Reader inputStream;
72  
73      protected char[] nextCharBuf;
74      protected char[] buffer;
75      protected int maxNextCharInd = 0;
76      protected int nextCharInd = -1;
77      protected int inBuf = 0;
78  
79      protected void ExpandBuff(boolean wrapAround) {
80          char[] newbuffer = new char[bufsize + 2048];
81          int newbufline[] = new int[bufsize + 2048];
82          int newbufcolumn[] = new int[bufsize + 2048];
83  
84          try {
85              if (wrapAround) {
86                  System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
87                  System.arraycopy(buffer, 0, newbuffer,
88                          bufsize - tokenBegin, bufpos);
89                  buffer = newbuffer;
90  
91                  System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
92                  System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
93                  bufline = newbufline;
94  
95                  System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
96                  System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
97                  bufcolumn = newbufcolumn;
98  
99                  bufpos += (bufsize - tokenBegin);
100             } else {
101                 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
102                 buffer = newbuffer;
103 
104                 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
105                 bufline = newbufline;
106 
107                 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
108                 bufcolumn = newbufcolumn;
109 
110                 bufpos -= tokenBegin;
111             }
112         } catch (Throwable t) {
113             throw new RuntimeException(t.getMessage());
114         }
115 
116         available = (bufsize += 2048);
117         tokenBegin = 0;
118     }
119 
120     protected void FillBuff() throws java.io.IOException {
121         int i;
122         if (maxNextCharInd == 4096)
123             maxNextCharInd = nextCharInd = 0;
124 
125         try {
126             if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
127                     4096 - maxNextCharInd)) == -1) {
128                 inputStream.close();
129                 throw new java.io.IOException();
130             } else
131                 maxNextCharInd += i;
132             return;
133         } catch (java.io.IOException e) {
134             if (bufpos != 0) {
135                 --bufpos;
136                 backup(0);
137             } else {
138                 bufline[bufpos] = line;
139                 bufcolumn[bufpos] = column;
140             }
141             throw e;
142         }
143     }
144 
145     protected char ReadByte() throws java.io.IOException {
146         if (++nextCharInd >= maxNextCharInd)
147             FillBuff();
148 
149         return nextCharBuf[nextCharInd];
150     }
151 
152     public char BeginToken() throws java.io.IOException {
153         if (inBuf > 0) {
154             --inBuf;
155 
156             if (++bufpos == bufsize)
157                 bufpos = 0;
158 
159             tokenBegin = bufpos;
160             return buffer[bufpos];
161         }
162 
163         tokenBegin = 0;
164         bufpos = -1;
165 
166         return readChar();
167     }
168 
169     protected void AdjustBuffSize() {
170         if (available == bufsize) {
171             if (tokenBegin > 2048) {
172                 bufpos = 0;
173                 available = tokenBegin;
174             } else
175                 ExpandBuff(false);
176         } else if (available > tokenBegin)
177             available = bufsize;
178         else if ((tokenBegin - available) < 2048)
179             ExpandBuff(true);
180         else
181             available = tokenBegin;
182     }
183 
184     protected void UpdateLineColumn(char c) {
185         column++;
186 
187         if (prevCharIsLF) {
188             prevCharIsLF = false;
189             line += (column = 1);
190         } else if (prevCharIsCR) {
191             prevCharIsCR = false;
192             if (c == '\n') {
193                 prevCharIsLF = true;
194             } else
195                 line += (column = 1);
196         }
197 
198         switch (c) {
199             case '\r':
200                 prevCharIsCR = true;
201                 break;
202             case '\n':
203                 prevCharIsLF = true;
204                 break;
205             case '\t':
206                 column--;
207                 column += (8 - (column & 07));
208                 break;
209             default :
210                 break;
211         }
212 
213         bufline[bufpos] = line;
214         bufcolumn[bufpos] = column;
215     }
216 
217     public char readChar() throws java.io.IOException {
218         if (inBuf > 0) {
219             --inBuf;
220 
221             if (++bufpos == bufsize)
222                 bufpos = 0;
223 
224             return buffer[bufpos];
225         }
226 
227         char c;
228 
229         if (++bufpos == available)
230             AdjustBuffSize();
231 
232         if ((buffer[bufpos] = c = ReadByte()) == '//') {
233             UpdateLineColumn(c);
234 
235             int backSlashCnt = 1;
236 
237             for (; ;) // Read all the backslashes
238             {
239                 if (++bufpos == available)
240                     AdjustBuffSize();
241 
242                 try {
243                     if ((buffer[bufpos] = c = ReadByte()) != '//') {
244                         UpdateLineColumn(c);
245                         // found a non-backslash char.
246                         if ((c == 'u') && ((backSlashCnt & 1) == 1)) {
247                             if (--bufpos < 0)
248                                 bufpos = bufsize - 1;
249 
250                             break;
251                         }
252 
253                         backup(backSlashCnt);
254                         return '//';
255                     }
256                 } catch (java.io.IOException e) {
257                     if (backSlashCnt > 1)
258                         backup(backSlashCnt);
259 
260                     return '//';
261                 }
262 
263                 UpdateLineColumn(c);
264                 backSlashCnt++;
265             }
266 
267             // Here, we have seen an odd number of backslash's followed by a 'u'
268             try {
269                 while ((c = ReadByte()) == 'u')
270                     ++column;
271 
272                 buffer[bufpos] = c = (char) (hexval(c) << 12 |
273                         hexval(ReadByte()) << 8 |
274                         hexval(ReadByte()) << 4 |
275                         hexval(ReadByte()));
276 
277                 column += 4;
278             } catch (java.io.IOException e) {
279                 throw new RuntimeException("Invalid escape character at line " + line +
280                         " column " + column + ".");
281             }
282 
283             if (backSlashCnt == 1)
284                 return c;
285             else {
286                 backup(backSlashCnt - 1);
287                 return '//';
288             }
289         } else {
290             UpdateLineColumn(c);
291             return (c);
292         }
293     }
294 
295     /***
296      * @see #getEndColumn
297      * @deprecated
298      */
299 
300     public int getColumn() {
301         return bufcolumn[bufpos];
302     }
303 
304     /***
305      * @see #getEndLine
306      * @deprecated
307      */
308 
309     public int getLine() {
310         return bufline[bufpos];
311     }
312 
313     public int getEndColumn() {
314         return bufcolumn[bufpos];
315     }
316 
317     public int getEndLine() {
318         return bufline[bufpos];
319     }
320 
321     public int getBeginColumn() {
322         return bufcolumn[tokenBegin];
323     }
324 
325     public int getBeginLine() {
326         return bufline[tokenBegin];
327     }
328 
329     public void backup(int amount) {
330 
331         inBuf += amount;
332         if ((bufpos -= amount) < 0)
333             bufpos += bufsize;
334     }
335 
336     public JavaCharStream(java.io.Reader dstream,
337                           int startline, int startcolumn, int buffersize) {
338         inputStream = dstream;
339         line = startline;
340         column = startcolumn - 1;
341 
342         available = bufsize = buffersize;
343         buffer = new char[buffersize];
344         bufline = new int[buffersize];
345         bufcolumn = new int[buffersize];
346         nextCharBuf = new char[4096];
347     }
348 
349     public JavaCharStream(java.io.Reader dstream,
350                           int startline, int startcolumn) {
351         this(dstream, startline, startcolumn, 4096);
352     }
353 
354     public JavaCharStream(java.io.Reader dstream) {
355         this(dstream, 1, 1, 4096);
356     }
357 
358     public void ReInit(java.io.Reader dstream,
359                        int startline, int startcolumn, int buffersize) {
360         inputStream = dstream;
361         line = startline;
362         column = startcolumn - 1;
363 
364         if (buffer == null || buffersize != buffer.length) {
365             available = bufsize = buffersize;
366             buffer = new char[buffersize];
367             bufline = new int[buffersize];
368             bufcolumn = new int[buffersize];
369             nextCharBuf = new char[4096];
370         }
371         prevCharIsLF = prevCharIsCR = false;
372         tokenBegin = inBuf = maxNextCharInd = 0;
373         nextCharInd = bufpos = -1;
374     }
375 
376     public void ReInit(java.io.Reader dstream,
377                        int startline, int startcolumn) {
378         ReInit(dstream, startline, startcolumn, 4096);
379     }
380 
381     public void ReInit(java.io.Reader dstream) {
382         ReInit(dstream, 1, 1, 4096);
383     }
384 
385     public JavaCharStream(java.io.InputStream dstream, int startline,
386                           int startcolumn, int buffersize) {
387         this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
388     }
389 
390     public JavaCharStream(java.io.InputStream dstream, int startline,
391                           int startcolumn) {
392         this(dstream, startline, startcolumn, 4096);
393     }
394 
395     public JavaCharStream(java.io.InputStream dstream) {
396         this(dstream, 1, 1, 4096);
397     }
398 
399     public void ReInit(java.io.InputStream dstream, int startline,
400                        int startcolumn, int buffersize) {
401         ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
402     }
403 
404     public void ReInit(java.io.InputStream dstream, int startline,
405                        int startcolumn) {
406         ReInit(dstream, startline, startcolumn, 4096);
407     }
408 
409     public void ReInit(java.io.InputStream dstream) {
410         ReInit(dstream, 1, 1, 4096);
411     }
412 
413     public String GetImage() {
414         if (bufpos >= tokenBegin)
415             return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
416         else
417             return new String(buffer, tokenBegin, bufsize - tokenBegin) +
418                     new String(buffer, 0, bufpos + 1);
419     }
420 
421     public char[] GetSuffix(int len) {
422         char[] ret = new char[len];
423 
424         if ((bufpos + 1) >= len)
425             System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
426         else {
427             System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
428                     len - bufpos - 1);
429             System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
430         }
431 
432         return ret;
433     }
434 
435     public void Done() {
436         nextCharBuf = null;
437         buffer = null;
438         bufline = null;
439         bufcolumn = null;
440     }
441 
442     /***
443      * Method to adjust line and column numbers for the start of a token.<BR>
444      */
445     public void adjustBeginLineColumn(int newLine, int newCol) {
446         int start = tokenBegin;
447         int len;
448 
449         if (bufpos >= tokenBegin) {
450             len = bufpos - tokenBegin + inBuf + 1;
451         } else {
452             len = bufsize - tokenBegin + bufpos + 1 + inBuf;
453         }
454 
455         int i = 0, j = 0, k = 0;
456         int nextColDiff = 0, columnDiff = 0;
457 
458         while (i < len &&
459                 bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
460             bufline[j] = newLine;
461             nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
462             bufcolumn[j] = newCol + columnDiff;
463             columnDiff = nextColDiff;
464             i++;
465         }
466 
467         if (i < len) {
468             bufline[j] = newLine++;
469             bufcolumn[j] = newCol + columnDiff;
470 
471             while (i++ < len) {
472                 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
473                     bufline[j] = newLine++;
474                 else
475                     bufline[j] = newLine;
476             }
477         }
478 
479         line = bufline[j];
480         column = bufcolumn[j];
481     }
482 
483 }