View Javadoc

1   package net.sourceforge.pmd.lang.vm.util;
2   
3   import net.sourceforge.pmd.lang.ast.CharStream;
4   
5   /*
6    * Licensed to the Apache Software Foundation (ASF) under one
7    * or more contributor license agreements.  See the NOTICE file
8    * distributed with this work for additional information
9    * regarding copyright ownership.  The ASF licenses this file
10   * to you under the Apache License, Version 2.0 (the
11   * "License"); you may not use this file except in compliance
12   * with the License.  You may obtain a copy of the License at
13   *
14   *   http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing,
17   * software distributed under the License is distributed on an
18   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19   * KIND, either express or implied.  See the License for the
20   * specific language governing permissions and limitations
21   * under the License.    
22   */
23  
24  /**
25   *  NOTE : This class was originally an ASCII_CharStream autogenerated
26   *  by Javacc.  It was then modified via changing class name with appropriate
27   *  fixes for CTORS, and mods to readChar().
28   *
29   *  This is safe because we *always* use Reader with this class, and never a
30   *  InputStream.  This guarantees that we have a correct stream of 16-bit
31   *  chars - all encoding transformations have been done elsewhere, so we
32   *  believe that there is no risk in doing this.  Time will tell :)
33   */
34  
35  /**
36   * An implementation of interface CharStream, where the stream is assumed to
37   * contain only ASCII characters (without unicode processing).
38   */
39  
40  public final class VelocityCharStream
41  implements CharStream
42  {
43      public static final boolean staticFlag = false;
44      int bufsize;
45      private int nextBufExpand;
46      int available;
47      int tokenBegin;
48  
49      public int bufpos = -1;
50      private int bufline[];
51      private int bufcolumn[];
52  
53      private int column = 0;
54      private int line = 1;
55  
56      private boolean prevCharIsCR = false;
57      private boolean prevCharIsLF = false;
58  
59      private java.io.Reader inputStream;
60  
61      private char[] buffer;
62      private int maxNextCharInd = 0;
63      private int inBuf = 0;
64  
65      private final void ExpandBuff(boolean wrapAround)
66      {
67          char[] newbuffer = new char[bufsize + nextBufExpand];
68          int newbufline[] = new int[bufsize + nextBufExpand];
69          int newbufcolumn[] = new int[bufsize + nextBufExpand];
70  
71          try
72          {
73              if (wrapAround)
74              {
75                  System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
76                  System.arraycopy(buffer, 0, newbuffer,
77                          bufsize - tokenBegin, bufpos);
78                  buffer = newbuffer;
79  
80                  System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
81                  System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
82                  bufline = newbufline;
83  
84                  System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
85                  System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
86                  bufcolumn = newbufcolumn;
87  
88                  maxNextCharInd = (bufpos += (bufsize - tokenBegin));
89              }
90              else
91              {
92                  System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
93                  buffer = newbuffer;
94  
95                  System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
96                  bufline = newbufline;
97  
98                  System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
99                  bufcolumn = newbufcolumn;
100 
101                 maxNextCharInd = (bufpos -= tokenBegin);
102             }
103         }
104         catch (Throwable t)
105         {
106             throw new Error(t.getMessage());
107         }
108 
109 
110         bufsize += nextBufExpand;
111         nextBufExpand = bufsize;
112         available = bufsize;
113         tokenBegin = 0;
114     }
115 
116     private final void FillBuff() throws java.io.IOException
117     {
118         if (maxNextCharInd == available)
119         {
120             if (available == bufsize)
121             {
122                 if (tokenBegin > nextBufExpand)
123                 {
124                     bufpos = maxNextCharInd = 0;
125                     available = tokenBegin;
126                 }
127                 else if (tokenBegin < 0)
128                 {
129                     bufpos = maxNextCharInd = 0;
130                 }
131                 else
132                 {
133                     ExpandBuff(false);
134                 }
135             }
136             else if (available > tokenBegin)
137             {
138                 available = bufsize;
139             }
140             else if ((tokenBegin - available) < nextBufExpand)
141             {
142                 ExpandBuff(true);
143             }
144             else
145             {
146                 available = tokenBegin;
147             }
148         }
149 
150         int i;
151         try 
152         {
153             if ((i = inputStream.read(buffer, maxNextCharInd,
154                     available - maxNextCharInd)) == -1)
155             {
156                 inputStream.close();
157                 throw new java.io.IOException();
158             }
159             else
160             {
161                 maxNextCharInd += i;
162             }
163             return;
164         }
165         catch(java.io.IOException e) 
166         {
167             --bufpos;
168             backup(0);
169             if (tokenBegin == -1)
170             {
171                 tokenBegin = bufpos;
172             }
173             throw e;
174         }
175     }
176 
177     /**
178      * @see org.apache.velocity.runtime.parser.CharStream#BeginToken()
179      */
180     public final char BeginToken() throws java.io.IOException
181     {
182         tokenBegin = -1;
183         char c = readChar();
184         tokenBegin = bufpos;
185 
186         return c;
187     }
188 
189     private final void UpdateLineColumn(char c)
190     {
191         column++;
192 
193         if (prevCharIsLF)
194         {
195             prevCharIsLF = false;
196             line += (column = 1);
197         }
198         else if (prevCharIsCR)
199         {
200             prevCharIsCR = false;
201             if (c == '\n')
202             {
203                 prevCharIsLF = true;
204             }
205             else
206             {
207                 line += (column = 1);
208             }
209         }
210 
211         switch (c)
212         {
213         case '\r' :
214             prevCharIsCR = true;
215             break;
216         case '\n' :
217             prevCharIsLF = true;
218             break;
219         case '\t' :
220             column--;
221             column += (8 - (column & 07));
222             break;
223         default :
224             break;
225         }
226 
227         bufline[bufpos] = line;
228         bufcolumn[bufpos] = column;
229     }
230 
231     /**
232      * @see org.apache.velocity.runtime.parser.CharStream#readChar()
233      */
234     public final char readChar() throws java.io.IOException
235     {
236         if (inBuf > 0)
237         {
238             --inBuf;
239 
240             /*
241              *  was : return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]);
242              */
243             return  buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
244         }
245 
246         if (++bufpos >= maxNextCharInd)
247         {
248             FillBuff();
249         }
250 
251         /*
252          *  was : char c = (char)((char)0xff & buffer[bufpos]);
253          */
254         char c = buffer[bufpos];
255 
256         UpdateLineColumn(c);
257         return (c);
258     }
259 
260     /**
261      * @see org.apache.velocity.runtime.parser.CharStream#getColumn()
262      * @deprecated
263      */
264     public final int getColumn() 
265     {
266         return bufcolumn[bufpos];
267     }
268 
269     /**
270      * @see org.apache.velocity.runtime.parser.CharStream#getLine()
271      * @deprecated
272      */
273     public final int getLine() 
274     {
275         return bufline[bufpos];
276     }
277 
278     /**
279      * @see org.apache.velocity.runtime.parser.CharStream#getEndColumn()
280      */
281     public final int getEndColumn() 
282     {
283         return bufcolumn[bufpos];
284     }
285 
286     /**
287      * @see org.apache.velocity.runtime.parser.CharStream#getEndLine()
288      */
289     public final int getEndLine() 
290     {
291         return bufline[bufpos];
292     }
293 
294     /**
295      * @see org.apache.velocity.runtime.parser.CharStream#getBeginColumn()
296      */
297     public final int getBeginColumn() 
298     {
299         return bufcolumn[tokenBegin];
300     }
301 
302     /**
303      * @see org.apache.velocity.runtime.parser.CharStream#getBeginLine()
304      */
305     public final int getBeginLine() 
306     {
307         return bufline[tokenBegin];
308     }
309 
310     /**
311      * @see org.apache.velocity.runtime.parser.CharStream#backup(int)
312      */
313     public final void backup(int amount) 
314     {
315 
316         inBuf += amount;
317         if ((bufpos -= amount) < 0)
318             bufpos += bufsize;
319     }
320 
321     /**
322      * @param dstream
323      * @param startline
324      * @param startcolumn
325      * @param buffersize
326      */
327     public VelocityCharStream(java.io.Reader dstream, int startline,
328             int startcolumn, int buffersize)
329     {
330         inputStream = dstream;
331         line = startline;
332         column = startcolumn - 1;
333 
334         available = bufsize = nextBufExpand = buffersize;
335         buffer = new char[buffersize];
336         bufline = new int[buffersize];
337         bufcolumn = new int[buffersize];
338     }
339 
340     /**
341      * @param dstream
342      * @param startline
343      * @param startcolumn
344      */
345     public VelocityCharStream(java.io.Reader dstream, int startline,
346             int startcolumn)
347     {
348         this(dstream, startline, startcolumn, 4096);
349     }
350     /**
351      * @param dstream
352      * @param startline
353      * @param startcolumn
354      * @param buffersize
355      */
356     public void ReInit(java.io.Reader dstream, int startline,
357             int startcolumn, int buffersize)
358     {
359         inputStream = dstream;
360         line = startline;
361         column = startcolumn - 1;
362 
363         if (buffer == null || buffersize != buffer.length)
364         {
365             available = bufsize = nextBufExpand = buffersize;
366             buffer = new char[buffersize];
367             bufline = new int[buffersize];
368             bufcolumn = new int[buffersize];
369         }
370         prevCharIsLF = prevCharIsCR = false;
371         tokenBegin = inBuf = maxNextCharInd = 0;
372         bufpos = -1;
373     }
374 
375     /**
376      * @param dstream
377      * @param startline
378      * @param startcolumn
379      */
380     public void ReInit(java.io.Reader dstream, int startline,
381             int startcolumn)
382     {
383         ReInit(dstream, startline, startcolumn, 4096);
384     }
385     /**
386      * @param dstream
387      * @param startline
388      * @param startcolumn
389      * @param buffersize
390      */
391     public VelocityCharStream(java.io.InputStream dstream, int startline,
392             int startcolumn, int buffersize)
393     {
394         this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
395     }
396 
397     /**
398      * @param dstream
399      * @param startline
400      * @param startcolumn
401      */
402     public VelocityCharStream(java.io.InputStream dstream, int startline,
403             int startcolumn)
404     {
405         this(dstream, startline, startcolumn, 4096);
406     }
407 
408     /**
409      * @param dstream
410      * @param startline
411      * @param startcolumn
412      * @param buffersize
413      */
414     public void ReInit(java.io.InputStream dstream, int startline,
415             int startcolumn, int buffersize)
416     {
417         ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
418     }
419     /**
420      * @param dstream
421      * @param startline
422      * @param startcolumn
423      */
424     public void ReInit(java.io.InputStream dstream, int startline,
425             int startcolumn)
426     {
427         ReInit(dstream, startline, startcolumn, 4096);
428     }
429     /**
430      * @see org.apache.velocity.runtime.parser.CharStream#GetImage()
431      */
432     public final String GetImage()
433     {
434         if (bufpos >= tokenBegin)
435         {
436             return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
437         }
438         else
439         {
440             return new String(buffer, tokenBegin, bufsize - tokenBegin) +
441             new String(buffer, 0, bufpos + 1);
442         }
443     }
444 
445     /**
446      * @see org.apache.velocity.runtime.parser.CharStream#GetSuffix(int)
447      */
448     public final char[] GetSuffix(int len)
449     {
450         char[] ret = new char[len];
451 
452         if ((bufpos + 1) >= len)
453         {
454             System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
455         }
456         else
457         {
458             System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
459                     len - bufpos - 1);
460             System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
461         }
462 
463         return ret;
464     }
465 
466     /**
467      * @see org.apache.velocity.runtime.parser.CharStream#Done()
468      */
469     public void Done()
470     {
471         buffer = null;
472         bufline = null;
473         bufcolumn = null;
474     }
475 
476     /**
477      * Method to adjust line and column numbers for the start of a token.<BR>
478      * @param newLine
479      * @param newCol
480      */
481     public void adjustBeginLineColumn(int newLine, int newCol)
482     {
483         int start = tokenBegin;
484         int len;
485 
486         if (bufpos >= tokenBegin)
487         {
488             len = bufpos - tokenBegin + inBuf + 1;
489         }
490         else
491         {
492             len = bufsize - tokenBegin + bufpos + 1 + inBuf;
493         }
494 
495         int i = 0, j = 0, k = 0;
496         int nextColDiff = 0, columnDiff = 0;
497 
498         while (i < len &&
499                 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
500         {
501             bufline[j] = newLine;
502             nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
503             bufcolumn[j] = newCol + columnDiff;
504             columnDiff = nextColDiff;
505             i++;
506         }
507 
508         if (i < len)
509         {
510             bufline[j] = newLine++;
511             bufcolumn[j] = newCol + columnDiff;
512 
513             while (i++ < len)
514             {
515                 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
516                     bufline[j] = newLine++;
517                 else
518                     bufline[j] = newLine;
519             }
520         }
521 
522         line = bufline[j];
523         column = bufcolumn[j];
524     }
525 
526 }
527