View Javadoc

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