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 STATIC_FLAG = 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 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 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             i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd);
154             if (i == -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 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 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 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         bufpos++;
247         if (bufpos >= maxNextCharInd)
248         {
249             FillBuff();
250         }
251 
252         /*
253          *  was : char c = (char)((char)0xff & buffer[bufpos]);
254          */
255         char c = buffer[bufpos];
256 
257         UpdateLineColumn(c);
258         return c;
259     }
260 
261     /**
262      * @see org.apache.velocity.runtime.parser.CharStream#getColumn()
263      * @deprecated
264      */
265     public int getColumn() 
266     {
267         return bufcolumn[bufpos];
268     }
269 
270     /**
271      * @see org.apache.velocity.runtime.parser.CharStream#getLine()
272      * @deprecated
273      */
274     public int getLine() 
275     {
276         return bufline[bufpos];
277     }
278 
279     /**
280      * @see org.apache.velocity.runtime.parser.CharStream#getEndColumn()
281      */
282     public int getEndColumn() 
283     {
284         return bufcolumn[bufpos];
285     }
286 
287     /**
288      * @see org.apache.velocity.runtime.parser.CharStream#getEndLine()
289      */
290     public int getEndLine() 
291     {
292         return bufline[bufpos];
293     }
294 
295     /**
296      * @see org.apache.velocity.runtime.parser.CharStream#getBeginColumn()
297      */
298     public int getBeginColumn() 
299     {
300         return bufcolumn[tokenBegin];
301     }
302 
303     /**
304      * @see org.apache.velocity.runtime.parser.CharStream#getBeginLine()
305      */
306     public int getBeginLine() 
307     {
308         return bufline[tokenBegin];
309     }
310 
311     /**
312      * @see org.apache.velocity.runtime.parser.CharStream#backup(int)
313      */
314     public void backup(int amount) 
315     {
316 
317         inBuf += amount;
318         bufpos -= amount;
319         if (bufpos < 0) {
320             bufpos += bufsize;
321         }
322     }
323 
324     /**
325      * @param dstream
326      * @param startline
327      * @param startcolumn
328      * @param buffersize
329      */
330     public VelocityCharStream(java.io.Reader dstream, int startline,
331             int startcolumn, int buffersize)
332     {
333         inputStream = dstream;
334         line = startline;
335         column = startcolumn - 1;
336 
337         available = bufsize = nextBufExpand = buffersize;
338         buffer = new char[buffersize];
339         bufline = new int[buffersize];
340         bufcolumn = new int[buffersize];
341     }
342 
343     /**
344      * @param dstream
345      * @param startline
346      * @param startcolumn
347      */
348     public VelocityCharStream(java.io.Reader dstream, int startline,
349             int startcolumn)
350     {
351         this(dstream, startline, startcolumn, 4096);
352     }
353     /**
354      * @param dstream
355      * @param startline
356      * @param startcolumn
357      * @param buffersize
358      */
359     public void ReInit(java.io.Reader dstream, int startline,
360             int startcolumn, int buffersize)
361     {
362         inputStream = dstream;
363         line = startline;
364         column = startcolumn - 1;
365 
366         if (buffer == null || buffersize != buffer.length)
367         {
368             available = bufsize = nextBufExpand = buffersize;
369             buffer = new char[buffersize];
370             bufline = new int[buffersize];
371             bufcolumn = new int[buffersize];
372         }
373         prevCharIsLF = prevCharIsCR = false;
374         tokenBegin = inBuf = maxNextCharInd = 0;
375         bufpos = -1;
376     }
377 
378     /**
379      * @param dstream
380      * @param startline
381      * @param startcolumn
382      */
383     public void ReInit(java.io.Reader dstream, int startline,
384             int startcolumn)
385     {
386         ReInit(dstream, startline, startcolumn, 4096);
387     }
388     /**
389      * @param dstream
390      * @param startline
391      * @param startcolumn
392      * @param buffersize
393      */
394     public VelocityCharStream(java.io.InputStream dstream, int startline,
395             int startcolumn, int buffersize)
396     {
397         this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
398     }
399 
400     /**
401      * @param dstream
402      * @param startline
403      * @param startcolumn
404      */
405     public VelocityCharStream(java.io.InputStream dstream, int startline,
406             int startcolumn)
407     {
408         this(dstream, startline, startcolumn, 4096);
409     }
410 
411     /**
412      * @param dstream
413      * @param startline
414      * @param startcolumn
415      * @param buffersize
416      */
417     public void ReInit(java.io.InputStream dstream, int startline,
418             int startcolumn, int buffersize)
419     {
420         ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
421     }
422     /**
423      * @param dstream
424      * @param startline
425      * @param startcolumn
426      */
427     public void ReInit(java.io.InputStream dstream, int startline,
428             int startcolumn)
429     {
430         ReInit(dstream, startline, startcolumn, 4096);
431     }
432     /**
433      * @see org.apache.velocity.runtime.parser.CharStream#GetImage()
434      */
435     public String GetImage()
436     {
437         if (bufpos >= tokenBegin)
438         {
439             return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
440         }
441         else
442         {
443             return new String(buffer, tokenBegin, bufsize - tokenBegin) +
444             new String(buffer, 0, bufpos + 1);
445         }
446     }
447 
448     /**
449      * @see org.apache.velocity.runtime.parser.CharStream#GetSuffix(int)
450      */
451     public char[] GetSuffix(int len)
452     {
453         char[] ret = new char[len];
454 
455         if ((bufpos + 1) >= len)
456         {
457             System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
458         }
459         else
460         {
461             System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
462                     len - bufpos - 1);
463             System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
464         }
465 
466         return ret;
467     }
468 
469     /**
470      * @see org.apache.velocity.runtime.parser.CharStream#Done()
471      */
472     public void Done()
473     {
474         buffer = null;
475         bufline = null;
476         bufcolumn = null;
477     }
478 
479     /**
480      * Method to adjust line and column numbers for the start of a token.<BR>
481      * @param newLine
482      * @param newCol
483      */
484     public void adjustBeginLineColumn(int newLine, int newCol)
485     {
486         int start = tokenBegin;
487         int len;
488 
489         if (bufpos >= tokenBegin)
490         {
491             len = bufpos - tokenBegin + inBuf + 1;
492         }
493         else
494         {
495             len = bufsize - tokenBegin + bufpos + 1 + inBuf;
496         }
497 
498         int i = 0;
499         int j = 0;
500         int k = 0;
501         int nextColDiff = 0;
502         int columnDiff = 0;
503 
504         while (i < len &&
505                 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
506         {
507             bufline[j] = newLine;
508             nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
509             bufcolumn[j] = newCol + columnDiff;
510             columnDiff = nextColDiff;
511             i++;
512         }
513 
514         if (i < len)
515         {
516             bufline[j] = newLine++;
517             bufcolumn[j] = newCol + columnDiff;
518 
519             while (i++ < len)
520             {
521                 j = start % bufsize;
522                 start++;
523                 if (bufline[j] != bufline[start % bufsize]) {
524                     bufline[j] = newLine++;
525                 } else {
526                     bufline[j] = newLine;
527                 }
528             }
529         }
530 
531         line = bufline[j];
532         column = bufcolumn[j];
533     }
534 
535 }
536