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      public static final boolean staticFlag = false;
42      int bufsize;
43      private int nextBufExpand;
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 + nextBufExpand];
66          int newbufline[] = new int[bufsize + nextBufExpand];
67          int newbufcolumn[] = new int[bufsize + nextBufExpand];
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 += nextBufExpand;
109         nextBufExpand = bufsize;
110         available = bufsize;
111         tokenBegin = 0;
112     }
113 
114     private final void FillBuff() throws java.io.IOException
115     {
116         if (maxNextCharInd == available)
117         {
118             if (available == bufsize)
119             {
120                 if (tokenBegin > nextBufExpand)
121                 {
122                     bufpos = maxNextCharInd = 0;
123                     available = tokenBegin;
124                 }
125                 else if (tokenBegin < 0)
126                 {
127                     bufpos = maxNextCharInd = 0;
128                 }
129                 else
130                 {
131                     ExpandBuff(false);
132                 }
133             }
134             else if (available > tokenBegin)
135             {
136                 available = bufsize;
137             }
138             else if ((tokenBegin - available) < nextBufExpand)
139             {
140                 ExpandBuff(true);
141             }
142             else
143             {
144                 available = tokenBegin;
145             }
146         }
147 
148         int i;
149         try 
150         {
151             if ((i = inputStream.read(buffer, maxNextCharInd,
152                     available - maxNextCharInd)) == -1)
153             {
154                 inputStream.close();
155                 throw new java.io.IOException();
156             }
157             else
158             {
159                 maxNextCharInd += i;
160             }
161             return;
162         }
163         catch(java.io.IOException e) 
164         {
165             --bufpos;
166             backup(0);
167             if (tokenBegin == -1)
168             {
169                 tokenBegin = bufpos;
170             }
171             throw e;
172         }
173     }
174 
175     /**
176      * @see org.apache.velocity.runtime.parser.CharStream#BeginToken()
177      */
178     public final char BeginToken() throws java.io.IOException
179     {
180         tokenBegin = -1;
181         char c = readChar();
182         tokenBegin = bufpos;
183 
184         return c;
185     }
186 
187     private final void UpdateLineColumn(char c)
188     {
189         column++;
190 
191         if (prevCharIsLF)
192         {
193             prevCharIsLF = false;
194             line += (column = 1);
195         }
196         else if (prevCharIsCR)
197         {
198             prevCharIsCR = false;
199             if (c == '\n')
200             {
201                 prevCharIsLF = true;
202             }
203             else
204             {
205                 line += (column = 1);
206             }
207         }
208 
209         switch (c)
210         {
211         case '\r' :
212             prevCharIsCR = true;
213             break;
214         case '\n' :
215             prevCharIsLF = true;
216             break;
217         case '\t' :
218             column--;
219             column += (8 - (column & 07));
220             break;
221         default :
222             break;
223         }
224 
225         bufline[bufpos] = line;
226         bufcolumn[bufpos] = column;
227     }
228 
229     /**
230      * @see org.apache.velocity.runtime.parser.CharStream#readChar()
231      */
232     public final char readChar() throws java.io.IOException
233     {
234         if (inBuf > 0)
235         {
236             --inBuf;
237 
238             /*
239              *  was : return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]);
240              */
241             return  buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
242         }
243 
244         if (++bufpos >= maxNextCharInd)
245         {
246             FillBuff();
247         }
248 
249         /*
250          *  was : char c = (char)((char)0xff & buffer[bufpos]);
251          */
252         char c = buffer[bufpos];
253 
254         UpdateLineColumn(c);
255         return (c);
256     }
257 
258     /**
259      * @see org.apache.velocity.runtime.parser.CharStream#getColumn()
260      * @deprecated
261      */
262     public final int getColumn() 
263     {
264         return bufcolumn[bufpos];
265     }
266 
267     /**
268      * @see org.apache.velocity.runtime.parser.CharStream#getLine()
269      * @deprecated
270      */
271     public final int getLine() 
272     {
273         return bufline[bufpos];
274     }
275 
276     /**
277      * @see org.apache.velocity.runtime.parser.CharStream#getEndColumn()
278      */
279     public final int getEndColumn() 
280     {
281         return bufcolumn[bufpos];
282     }
283 
284     /**
285      * @see org.apache.velocity.runtime.parser.CharStream#getEndLine()
286      */
287     public final int getEndLine() 
288     {
289         return bufline[bufpos];
290     }
291 
292     /**
293      * @see org.apache.velocity.runtime.parser.CharStream#getBeginColumn()
294      */
295     public final int getBeginColumn() 
296     {
297         return bufcolumn[tokenBegin];
298     }
299 
300     /**
301      * @see org.apache.velocity.runtime.parser.CharStream#getBeginLine()
302      */
303     public final int getBeginLine() 
304     {
305         return bufline[tokenBegin];
306     }
307 
308     /**
309      * @see org.apache.velocity.runtime.parser.CharStream#backup(int)
310      */
311     public final void backup(int amount) 
312     {
313 
314         inBuf += amount;
315         if ((bufpos -= amount) < 0)
316             bufpos += bufsize;
317     }
318 
319     /**
320      * @param dstream
321      * @param startline
322      * @param startcolumn
323      * @param buffersize
324      */
325     public VelocityCharStream(java.io.Reader dstream, int startline,
326             int startcolumn, int buffersize)
327     {
328         inputStream = dstream;
329         line = startline;
330         column = startcolumn - 1;
331 
332         available = bufsize = nextBufExpand = buffersize;
333         buffer = new char[buffersize];
334         bufline = new int[buffersize];
335         bufcolumn = new int[buffersize];
336     }
337 
338     /**
339      * @param dstream
340      * @param startline
341      * @param startcolumn
342      */
343     public VelocityCharStream(java.io.Reader dstream, int startline,
344             int startcolumn)
345     {
346         this(dstream, startline, startcolumn, 4096);
347     }
348     /**
349      * @param dstream
350      * @param startline
351      * @param startcolumn
352      * @param buffersize
353      */
354     public void ReInit(java.io.Reader dstream, int startline,
355             int startcolumn, int buffersize)
356     {
357         inputStream = dstream;
358         line = startline;
359         column = startcolumn - 1;
360 
361         if (buffer == null || buffersize != buffer.length)
362         {
363             available = bufsize = nextBufExpand = buffersize;
364             buffer = new char[buffersize];
365             bufline = new int[buffersize];
366             bufcolumn = new int[buffersize];
367         }
368         prevCharIsLF = prevCharIsCR = false;
369         tokenBegin = inBuf = maxNextCharInd = 0;
370         bufpos = -1;
371     }
372 
373     /**
374      * @param dstream
375      * @param startline
376      * @param startcolumn
377      */
378     public void ReInit(java.io.Reader dstream, int startline,
379             int startcolumn)
380     {
381         ReInit(dstream, startline, startcolumn, 4096);
382     }
383     /**
384      * @param dstream
385      * @param startline
386      * @param startcolumn
387      * @param buffersize
388      */
389     public VelocityCharStream(java.io.InputStream dstream, int startline,
390             int startcolumn, int buffersize)
391     {
392         this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
393     }
394 
395     /**
396      * @param dstream
397      * @param startline
398      * @param startcolumn
399      */
400     public VelocityCharStream(java.io.InputStream dstream, int startline,
401             int startcolumn)
402     {
403         this(dstream, startline, startcolumn, 4096);
404     }
405 
406     /**
407      * @param dstream
408      * @param startline
409      * @param startcolumn
410      * @param buffersize
411      */
412     public void ReInit(java.io.InputStream dstream, int startline,
413             int startcolumn, int buffersize)
414     {
415         ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
416     }
417     /**
418      * @param dstream
419      * @param startline
420      * @param startcolumn
421      */
422     public void ReInit(java.io.InputStream dstream, int startline,
423             int startcolumn)
424     {
425         ReInit(dstream, startline, startcolumn, 4096);
426     }
427     /**
428      * @see org.apache.velocity.runtime.parser.CharStream#GetImage()
429      */
430     public final String GetImage()
431     {
432         if (bufpos >= tokenBegin)
433         {
434             return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
435         }
436         else
437         {
438             return new String(buffer, tokenBegin, bufsize - tokenBegin) +
439             new String(buffer, 0, bufpos + 1);
440         }
441     }
442 
443     /**
444      * @see org.apache.velocity.runtime.parser.CharStream#GetSuffix(int)
445      */
446     public final char[] GetSuffix(int len)
447     {
448         char[] ret = new char[len];
449 
450         if ((bufpos + 1) >= len)
451         {
452             System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
453         }
454         else
455         {
456             System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
457                     len - bufpos - 1);
458             System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
459         }
460 
461         return ret;
462     }
463 
464     /**
465      * @see org.apache.velocity.runtime.parser.CharStream#Done()
466      */
467     public void Done()
468     {
469         buffer = null;
470         bufline = null;
471         bufcolumn = null;
472     }
473 
474     /**
475      * Method to adjust line and column numbers for the start of a token.<BR>
476      * @param newLine
477      * @param newCol
478      */
479     public void adjustBeginLineColumn(int newLine, int newCol)
480     {
481         int start = tokenBegin;
482         int len;
483 
484         if (bufpos >= tokenBegin)
485         {
486             len = bufpos - tokenBegin + inBuf + 1;
487         }
488         else
489         {
490             len = bufsize - tokenBegin + bufpos + 1 + inBuf;
491         }
492 
493         int i = 0, j = 0, k = 0;
494         int nextColDiff = 0, columnDiff = 0;
495 
496         while (i < len &&
497                 bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
498         {
499             bufline[j] = newLine;
500             nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
501             bufcolumn[j] = newCol + columnDiff;
502             columnDiff = nextColDiff;
503             i++;
504         }
505 
506         if (i < len)
507         {
508             bufline[j] = newLine++;
509             bufcolumn[j] = newCol + columnDiff;
510 
511             while (i++ < len)
512             {
513                 if (bufline[j = start % bufsize] != bufline[++start % bufsize])
514                     bufline[j] = newLine++;
515                 else
516                     bufline[j] = newLine;
517             }
518         }
519 
520         line = bufline[j];
521         column = bufcolumn[j];
522     }
523 
524 }