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    
036            public static final boolean staticFlag = false;
037    
038            private static final int hexval(char c) throws java.io.IOException
039            {
040                    switch (c)
041                    {
042                            case '0':
043                                    return 0;
044                            case '1':
045                                    return 1;
046                            case '2':
047                                    return 2;
048                            case '3':
049                                    return 3;
050                            case '4':
051                                    return 4;
052                            case '5':
053                                    return 5;
054                            case '6':
055                                    return 6;
056                            case '7':
057                                    return 7;
058                            case '8':
059                                    return 8;
060                            case '9':
061                                    return 9;
062    
063                            case 'a':
064                            case 'A':
065                                    return 10;
066                            case 'b':
067                            case 'B':
068                                    return 11;
069                            case 'c':
070                            case 'C':
071                                    return 12;
072                            case 'd':
073                            case 'D':
074                                    return 13;
075                            case 'e':
076                            case 'E':
077                                    return 14;
078                            case 'f':
079                            case 'F':
080                                    return 15;
081                    }
082    
083                    throw new java.io.IOException(); // Should never come here
084            }
085    
086            private int bufpos = -1;
087            private int bufsize;
088            private int available;
089            private int tokenBegin;
090            private int bufline[];
091            private int bufcolumn[];
092    
093            private int column = 0;
094            private int line = 1;
095    
096            private java.io.Reader inputStream;
097    
098            private boolean prevCharIsCR = false;
099            private boolean prevCharIsLF = false;
100    
101            private char[] nextCharBuf;
102            private char[] buffer;
103            private int maxNextCharInd = 0;
104            private int nextCharInd = -1;
105            private int inBuf = 0;
106    
107            private final void expandBuff(boolean wrapAround)
108            {
109                    char[] newbuffer = new char[bufsize + 2048];
110                    int newbufline[] = new int[bufsize + 2048];
111                    int newbufcolumn[] = new int[bufsize + 2048];
112    
113                    try
114                    {
115                            if (wrapAround)
116                            {
117                                    System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
118                                    System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
119                                    buffer = newbuffer;
120    
121                                    System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
122                                    System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
123                                    bufline = newbufline;
124    
125                                    System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
126                                    System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
127                                    bufcolumn = newbufcolumn;
128    
129                                    bufpos += (bufsize - tokenBegin);
130                            }
131                            else
132                            {
133                                    System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
134                                    buffer = newbuffer;
135    
136                                    System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
137                                    bufline = newbufline;
138    
139                                    System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
140                                    bufcolumn = newbufcolumn;
141    
142                                    bufpos -= tokenBegin;
143                            }
144                    }
145                    catch (Throwable t)
146                    {
147                            throw new Error(t.getMessage());
148                    }
149    
150                    available = (bufsize += 2048);
151                    tokenBegin = 0;
152            }
153    
154            private final void fillBuff() throws java.io.IOException
155            {
156                    int i;
157                    if (maxNextCharInd == 4096)
158                            maxNextCharInd = nextCharInd = 0;
159    
160                    try
161                    {
162                            if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 4096 - maxNextCharInd)) == -1)
163                            {
164                                    inputStream.close();
165                                    throw new java.io.IOException();
166                            }
167                            maxNextCharInd += i;
168                            return;
169                    }
170                    catch (java.io.IOException e)
171                    {
172                            if (bufpos != 0)
173                            {
174                                    --bufpos;
175                                    backup(0);
176                            }
177                            else
178                            {
179                                    bufline[bufpos] = line;
180                                    bufcolumn[bufpos] = column;
181                            }
182                            throw e;
183                    }
184            }
185    
186            private final char readByte() throws java.io.IOException
187            {
188                    if (++nextCharInd >= maxNextCharInd)
189                            fillBuff();
190    
191                    return nextCharBuf[nextCharInd];
192            }
193    
194            public final char beginToken() throws java.io.IOException
195            {
196                    if (inBuf > 0)
197                    {
198                            --inBuf;
199                            return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
200                    }
201    
202                    tokenBegin = 0;
203                    bufpos = -1;
204    
205                    return readChar();
206            }
207    
208            private final void adjustBuffSize()
209            {
210                    if (available == bufsize)
211                    {
212                            if (tokenBegin > 2048)
213                            {
214                                    bufpos = 0;
215                                    available = tokenBegin;
216                            }
217                            else
218                                    expandBuff(false);
219                    }
220                    else if (available > tokenBegin)
221                            available = bufsize;
222                    else if ((tokenBegin - available) < 2048)
223                            expandBuff(true);
224                    else
225                            available = tokenBegin;
226            }
227    
228            private final void updateLineColumn(char c)
229            {
230                    column++;
231    
232                    if (prevCharIsLF)
233                    {
234                            prevCharIsLF = false;
235                            line += (column = 1);
236                    }
237                    else if (prevCharIsCR)
238                    {
239                            prevCharIsCR = false;
240                            if (c == '\n')
241                            {
242                                    prevCharIsLF = true;
243                            }
244                            else
245                                    line += (column = 1);
246                    }
247    
248                    switch (c)
249                    {
250                            case '\r':
251                                    prevCharIsCR = true;
252                                    break;
253                            case '\n':
254                                    prevCharIsLF = true;
255                                    break;
256                            case '\t':
257                                    column--;
258                                    column += (8 - (column & 07));
259                                    break;
260                            default:
261                                    break;
262                    }
263    
264                    bufline[bufpos] = line;
265                    bufcolumn[bufpos] = column;
266            }
267    
268            public final char readChar() throws java.io.IOException
269            {
270                    if (inBuf > 0)
271                    {
272                            --inBuf;
273                            return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
274                    }
275    
276                    char c;
277    
278                    if (++bufpos == available)
279                            adjustBuffSize();
280    
281                    if (((buffer[bufpos] = c = (char)((char)0xff & readByte())) == '\\'))
282                    {
283                            updateLineColumn(c);
284    
285                            int backSlashCnt = 1;
286    
287                            for (;;) // Read all the backslashes
288                            {
289                                    if (++bufpos == available)
290                                            adjustBuffSize();
291    
292                                    try
293                                    {
294                                            if ((buffer[bufpos] = c = (char)((char)0xff & readByte())) != '\\')
295                                            {
296                                                    updateLineColumn(c);
297                                                    // found a non-backslash char.
298                                                    if ((c == 'u') && ((backSlashCnt & 1) == 1))
299                                                    {
300                                                            if (--bufpos < 0)
301                                                                    bufpos = bufsize - 1;
302    
303                                                            break;
304                                                    }
305    
306                                                    backup(backSlashCnt);
307                                                    return '\\';
308                                            }
309                                    }
310                                    catch (java.io.IOException e)
311                                    {
312                                            if (backSlashCnt > 1)
313                                                    backup(backSlashCnt);
314    
315                                            return '\\';
316                                    }
317    
318                                    updateLineColumn(c);
319                                    backSlashCnt++;
320                            }
321    
322                            // Here, we have seen an odd number of backslash's followed by a 'u'
323                            try
324                            {
325                                    while ((c = (char)((char)0xff & readByte())) == 'u')
326                                            ++column;
327    
328                                    buffer[bufpos] = c = (char)(hexval(c) << 12
329                                                    | hexval((char)((char)0xff & readByte())) << 8
330                                                    | hexval((char)((char)0xff & readByte())) << 4 | 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 + " column " + column
337                                                    + ".");
338                            }
339    
340                            if (backSlashCnt == 1)
341                                    return c;
342    
343                            backup(backSlashCnt - 1);
344                            return '\\';
345                    }
346    
347                    updateLineColumn(c);
348                    return (c);
349            }
350    
351            public final int getEndColumn()
352            {
353                    return bufcolumn[bufpos];
354            }
355    
356            public final int getEndLine()
357            {
358                    return bufline[bufpos];
359            }
360    
361            public final int getBeginColumn()
362            {
363                    return bufcolumn[tokenBegin];
364            }
365    
366            public final int getBeginLine()
367            {
368                    return bufline[tokenBegin];
369            }
370    
371            public final void backup(int amount)
372            {
373    
374                    inBuf += amount;
375                    if ((bufpos -= amount) < 0)
376                            bufpos += bufsize;
377            }
378    
379            private ASCII_UCodeESC_CharStream(java.io.Reader dstream, int startline, int startcolumn,
380                            int buffersize)
381            {
382                    inputStream = dstream;
383                    line = startline;
384                    column = startcolumn - 1;
385    
386                    available = bufsize = buffersize;
387                    buffer = new char[buffersize];
388                    bufline = new int[buffersize];
389                    bufcolumn = new int[buffersize];
390                    nextCharBuf = new char[4096];
391            }
392    
393            public ASCII_UCodeESC_CharStream(java.io.InputStream dstream, int startline, int startcolumn)
394            {
395                    this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
396            }
397    
398            public final String getImage()
399            {
400                    if (bufpos >= tokenBegin)
401                            return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
402                    return new String(buffer, tokenBegin, bufsize - tokenBegin)
403                                    + new String(buffer, 0, bufpos + 1);
404            }
405    
406            public final char[] getSuffix(int len)
407            {
408                    char[] ret = new char[len];
409    
410                    if ((bufpos + 1) >= len)
411                            System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
412                    else
413                    {
414                            System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, len - bufpos - 1);
415                            System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
416                    }
417    
418                    return ret;
419            }
420    
421    }