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 }