001    /* Generated By:JavaCC: Do not edit this line. ASCII_UCodeESC_CharStream.java Version 0.7pre6 */
002    
003    /*
004     * Cobertura - http://cobertura.sourceforge.net/
005     *
006     * This file was taken from JavaNCSS
007     * http://www.kclee.com/clemens/java/javancss/
008     * Copyright (C) 2000 Chr. Clemens Lee <clemens a.t kclee d.o.t com>
009     *
010     * Cobertura is free software; you can redistribute it and/or modify
011     * it under the terms of the GNU General Public License as published
012     * by the Free Software Foundation; either version 2 of the License,
013     * or (at your option) any later version.
014     *
015     * Cobertura is distributed in the hope that it will be useful, but
016     * WITHOUT ANY WARRANTY; without even the implied warranty of
017     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018     * General Public License for more details.
019     *
020     * You should have received a copy of the GNU General Public License
021     * along with Cobertura; if not, write to the Free Software
022     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
023     * USA
024     */
025    
026    package net.sourceforge.cobertura.javancss;
027    
028    /**
029     * An implementation of interface CharStream, where the stream is assumed to
030     * contain only ASCII characters (with java-like unicode escape processing).
031     */
032    
033    public final class ASCII_UCodeESC_CharStream
034    {
035      public static final boolean staticFlag = false;
036      static final int hexval(char c) throws java.io.IOException {
037        switch(c)
038        {
039           case '0' :
040              return 0;
041           case '1' :
042              return 1;
043           case '2' :
044              return 2;
045           case '3' :
046              return 3;
047           case '4' :
048              return 4;
049           case '5' :
050              return 5;
051           case '6' :
052              return 6;
053           case '7' :
054              return 7;
055           case '8' :
056              return 8;
057           case '9' :
058              return 9;
059    
060           case 'a' :
061           case 'A' :
062              return 10;
063           case 'b' :
064           case 'B' :
065              return 11;
066           case 'c' :
067           case 'C' :
068              return 12;
069           case 'd' :
070           case 'D' :
071              return 13;
072           case 'e' :
073           case 'E' :
074              return 14;
075           case 'f' :
076           case 'F' :
077              return 15;
078        }
079    
080        throw new java.io.IOException(); // Should never come here
081      }
082    
083      public int bufpos = -1;
084      int bufsize;
085      int available;
086      int tokenBegin;
087      private int bufline[];
088      private int bufcolumn[];
089    
090      private int column = 0;
091      private int line = 1;
092    
093      private java.io.Reader inputStream;
094    
095      private boolean prevCharIsCR = false;
096      private boolean prevCharIsLF = false;
097    
098      private char[] nextCharBuf;
099      private char[] buffer;
100      private int maxNextCharInd = 0;
101      private int nextCharInd = -1;
102      private int inBuf = 0;
103    
104      private final void ExpandBuff(boolean wrapAround)
105      {
106         char[] newbuffer = new char[bufsize + 2048];
107         int newbufline[] = new int[bufsize + 2048];
108         int newbufcolumn[] = new int[bufsize + 2048];
109    
110         try
111         {
112            if (wrapAround)
113            {
114               System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
115               System.arraycopy(buffer, 0, newbuffer,
116                                                 bufsize - tokenBegin, bufpos);
117               buffer = newbuffer;
118    
119               System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
120               System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
121               bufline = newbufline;
122    
123               System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
124               System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
125               bufcolumn = newbufcolumn;
126    
127               bufpos += (bufsize - tokenBegin);
128            }
129            else
130            {
131               System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
132               buffer = newbuffer;
133    
134               System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
135               bufline = newbufline;
136    
137               System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
138               bufcolumn = newbufcolumn;
139    
140               bufpos -= tokenBegin;
141            }
142         }
143         catch (Throwable t)
144         {
145            throw new Error(t.getMessage());
146         }
147    
148         available = (bufsize += 2048);
149         tokenBegin = 0;
150      }
151    
152      private final void FillBuff() throws java.io.IOException
153      {
154         int i;
155         if (maxNextCharInd == 4096)
156            maxNextCharInd = nextCharInd = 0;
157    
158         try {
159            if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
160                                                4096 - maxNextCharInd)) == -1)
161            {
162               inputStream.close();
163               throw new java.io.IOException();
164            }
165            else
166               maxNextCharInd += i;
167            return;
168         }
169         catch(java.io.IOException e) {
170            if (bufpos != 0)
171            {
172               --bufpos;
173               backup(0);
174            }
175            else
176            {
177               bufline[bufpos] = line;
178               bufcolumn[bufpos] = column;
179            }
180            throw e;
181         }
182      }
183    
184      private final char ReadByte() throws java.io.IOException
185      {
186         if (++nextCharInd >= maxNextCharInd)
187            FillBuff();
188    
189         return nextCharBuf[nextCharInd];
190      }
191    
192      public final char BeginToken() throws java.io.IOException
193      {     
194         if (inBuf > 0)
195         {
196            --inBuf;
197            return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
198                                                               : ++bufpos];
199         }
200    
201         tokenBegin = 0;
202         bufpos = -1;
203    
204         return readChar();
205      }     
206    
207      private final void AdjustBuffSize()
208      {
209         if (available == bufsize)
210         {
211            if (tokenBegin > 2048)
212            {
213               bufpos = 0;
214               available = tokenBegin;
215            }
216            else
217               ExpandBuff(false);
218         }
219         else if (available > tokenBegin)
220            available = bufsize;
221         else if ((tokenBegin - available) < 2048)
222            ExpandBuff(true);
223         else
224            available = tokenBegin;
225      }
226    
227      private final void UpdateLineColumn(char c)
228      {
229         column++;
230    
231         if (prevCharIsLF)
232         {
233            prevCharIsLF = false;
234            line += (column = 1);
235         }
236         else if (prevCharIsCR)
237         {
238            prevCharIsCR = false;
239            if (c == '\n')
240            {
241               prevCharIsLF = true;
242            }
243            else
244               line += (column = 1);
245         }
246    
247         switch (c)
248         {
249            case '\r' :
250               prevCharIsCR = true;
251               break;
252            case '\n' :
253               prevCharIsLF = true;
254               break;
255            case '\t' :
256               column--;
257               column += (8 - (column & 07));
258               break;
259            default :
260               break;
261         }
262    
263         bufline[bufpos] = line;
264         bufcolumn[bufpos] = column;
265      }
266    
267      public final char readChar() throws java.io.IOException
268      {
269         if (inBuf > 0)
270         {
271            --inBuf;
272            return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
273         }
274    
275         char c;
276    
277         if (++bufpos == available)
278            AdjustBuffSize();
279    
280         if (((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) == '\\'))
281         {
282            UpdateLineColumn(c);
283    
284            int backSlashCnt = 1;
285    
286            for (;;) // Read all the backslashes
287            {
288               if (++bufpos == available)
289                  AdjustBuffSize();
290    
291               try
292               {
293                  if ((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) != '\\')
294                  {
295                     UpdateLineColumn(c);
296                     // found a non-backslash char.
297                     if ((c == 'u') && ((backSlashCnt & 1) == 1))
298                     {
299                        if (--bufpos < 0)
300                           bufpos = bufsize - 1;
301    
302                        break;
303                     }
304    
305                     backup(backSlashCnt);
306                     return '\\';
307                  }
308               }
309               catch(java.io.IOException e)
310               {
311                  if (backSlashCnt > 1)
312                     backup(backSlashCnt);
313    
314                  return '\\';
315               }
316    
317               UpdateLineColumn(c);
318               backSlashCnt++;
319            }
320    
321            // Here, we have seen an odd number of backslash's followed by a 'u'
322            try
323            {
324               while ((c = (char)((char)0xff & ReadByte())) == 'u')
325                  ++column;
326    
327               buffer[bufpos] = c = (char)(hexval(c) << 12 |
328                                           hexval((char)((char)0xff & ReadByte())) << 8 |
329                                           hexval((char)((char)0xff & ReadByte())) << 4 |
330                                           hexval((char)((char)0xff & ReadByte())));
331    
332               column += 4;
333            }
334            catch(java.io.IOException e)
335            {
336               throw new Error("Invalid escape character at line " + line +
337                                             " column " + column + ".");
338            }
339    
340            if (backSlashCnt == 1)
341               return c;
342            else
343            {
344               backup(backSlashCnt - 1);
345               return '\\';
346            }
347         }
348         else
349         {
350            UpdateLineColumn(c);
351            return (c);
352         }
353      }
354    
355      /**
356       * @deprecated 
357       * @see #getEndColumn
358       */
359    
360      public final int getColumn() {
361         return bufcolumn[bufpos];
362      }
363    
364      /**
365       * @deprecated 
366       * @see #getEndLine
367       */
368    
369      public final int getLine() {
370         return bufline[bufpos];
371      }
372    
373      public final int getEndColumn() {
374         return bufcolumn[bufpos];
375      }
376    
377      public final int getEndLine() {
378         return bufline[bufpos];
379      }
380    
381      public final int getBeginColumn() {
382         return bufcolumn[tokenBegin];
383      }
384    
385      public final int getBeginLine() {
386         return bufline[tokenBegin];
387      }
388    
389      public final void backup(int amount) {
390    
391        inBuf += amount;
392        if ((bufpos -= amount) < 0)
393           bufpos += bufsize;
394      }
395    
396      public ASCII_UCodeESC_CharStream(java.io.Reader dstream,
397                     int startline, int startcolumn, int buffersize)
398      {
399        inputStream = dstream;
400        line = startline;
401        column = startcolumn - 1;
402    
403        available = bufsize = buffersize;
404        buffer = new char[buffersize];
405        bufline = new int[buffersize];
406        bufcolumn = new int[buffersize];
407        nextCharBuf = new char[4096];
408      }
409    
410      public ASCII_UCodeESC_CharStream(java.io.Reader dstream,
411                                            int startline, int startcolumn)
412      {
413         this(dstream, startline, startcolumn, 4096);
414      }
415      public void ReInit(java.io.Reader dstream,
416                     int startline, int startcolumn, int buffersize)
417      {
418        inputStream = dstream;
419        line = startline;
420        column = startcolumn - 1;
421    
422        if (buffer == null || buffersize != buffer.length)
423        {
424          available = bufsize = buffersize;
425          buffer = new char[buffersize];
426          bufline = new int[buffersize];
427          bufcolumn = new int[buffersize];
428          nextCharBuf = new char[4096];
429        }
430        prevCharIsLF = prevCharIsCR = false;
431        tokenBegin = inBuf = maxNextCharInd = 0;
432        nextCharInd = bufpos = -1;
433      }
434    
435      public void ReInit(java.io.Reader dstream,
436                                            int startline, int startcolumn)
437      {
438         ReInit(dstream, startline, startcolumn, 4096);
439      }
440      public ASCII_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
441      int startcolumn, int buffersize)
442      {
443         this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
444      }
445    
446      public ASCII_UCodeESC_CharStream(java.io.InputStream dstream, int startline,
447                                                               int startcolumn)
448      {
449         this(dstream, startline, startcolumn, 4096);
450      }
451    
452      public void ReInit(java.io.InputStream dstream, int startline,
453      int startcolumn, int buffersize)
454      {
455         ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
456      }
457      public void ReInit(java.io.InputStream dstream, int startline,
458                                                               int startcolumn)
459      {
460         ReInit(dstream, startline, startcolumn, 4096);
461      }
462    
463      public final String GetImage()
464      {
465         if (bufpos >= tokenBegin)
466            return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
467         else
468            return new String(buffer, tokenBegin, bufsize - tokenBegin) +
469                                  new String(buffer, 0, bufpos + 1);
470      }
471    
472      public final char[] GetSuffix(int len)
473      {
474         char[] ret = new char[len];
475    
476         if ((bufpos + 1) >= len)
477            System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
478         else
479         {
480            System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
481                                                              len - bufpos - 1);
482            System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
483         }
484    
485         return ret;
486      }
487    
488      public void Done()
489      {
490         nextCharBuf = null;
491         buffer = null;
492         bufline = null;
493         bufcolumn = null;
494      }
495    
496      /**
497       * Method to adjust line and column numbers for the start of a token.<BR>
498       */
499      public void adjustBeginLineColumn(int newLine, int newCol)
500      {
501         int start = tokenBegin;
502         int len;
503    
504         if (bufpos >= tokenBegin)
505         {
506            len = bufpos - tokenBegin + inBuf + 1;
507         }
508         else
509         {
510            len = bufsize - tokenBegin + bufpos + 1 + inBuf;
511         }
512    
513         int i = 0, j = 0, k = 0;
514         int nextColDiff = 0, columnDiff = 0;
515    
516         while (i < len &&
517                bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
518         {
519            bufline[j] = newLine;
520            nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
521            bufcolumn[j] = newCol + columnDiff;
522            columnDiff = nextColDiff;
523            i++;
524         } 
525    
526         if (i < len)
527         {
528            bufline[j] = newLine++;
529            bufcolumn[j] = newCol + columnDiff;
530    
531            while (i++ < len)
532            {
533               if (bufline[j = start % bufsize] != bufline[++start % bufsize])
534                  bufline[j] = newLine++;
535               else
536                  bufline[j] = newLine;
537            }
538         }
539    
540         line = bufline[j];
541         column = bufcolumn[j];
542      }
543    
544    }