001: /*
002: * Author: Mike Atkinson
003: *
004: * This software has been developed under the copyleft
005: * rules of the GNU General Public License. Please
006: * consult the GNU General Public License for more
007: * details about use and distribution of this software.
008: */
009: package net.sourceforge.jrefactory.io;
010:
011: /* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 3.0 */
012: /**
013: * An implementation of interface CharStream, where the stream is assumed to
014: * contain only ASCII characters (with java-like unicode escape processing).
015: *@author <a href="JRefactory@ladyshot.demon.co.uk">Mike Atkinson</a>
016: *@version $Id: JavaCharStream.java,v 1.1 2003/10/23 14:19:20 mikeatkinson Exp $
017: *@since 2.8.00
018: */
019:
020: public class JavaCharStream extends CharStream {
021: final int hexval(char c) throws java.io.IOException {
022: switch (c) {
023: case '0':
024: return 0;
025: case '1':
026: return 1;
027: case '2':
028: return 2;
029: case '3':
030: return 3;
031: case '4':
032: return 4;
033: case '5':
034: return 5;
035: case '6':
036: return 6;
037: case '7':
038: return 7;
039: case '8':
040: return 8;
041: case '9':
042: return 9;
043:
044: case 'a':
045: case 'A':
046: return 10;
047: case 'b':
048: case 'B':
049: return 11;
050: case 'c':
051: case 'C':
052: return 12;
053: case 'd':
054: case 'D':
055: return 13;
056: case 'e':
057: case 'E':
058: return 14;
059: case 'f':
060: case 'F':
061: return 15;
062: }
063:
064: throw new java.io.IOException(); // Should never come here
065: }
066:
067: protected char[] nextCharBuf;
068: protected int nextCharInd = -1;
069:
070: protected void ExpandBuff(boolean wrapAround) {
071: char[] newbuffer = new char[bufsize + 2048];
072: int newbufline[] = new int[bufsize + 2048];
073: int newbufcolumn[] = new int[bufsize + 2048];
074:
075: try {
076: if (wrapAround) {
077: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
078: bufsize - tokenBegin);
079: System.arraycopy(buffer, 0, newbuffer, bufsize
080: - tokenBegin, bufpos);
081: buffer = newbuffer;
082:
083: System.arraycopy(bufline, tokenBegin, newbufline, 0,
084: bufsize - tokenBegin);
085: System.arraycopy(bufline, 0, newbufline, bufsize
086: - tokenBegin, bufpos);
087: bufline = newbufline;
088:
089: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
090: 0, bufsize - tokenBegin);
091: System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize
092: - tokenBegin, bufpos);
093: bufcolumn = newbufcolumn;
094:
095: bufpos += (bufsize - tokenBegin);
096: } else {
097: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
098: bufsize - tokenBegin);
099: buffer = newbuffer;
100:
101: System.arraycopy(bufline, tokenBegin, newbufline, 0,
102: bufsize - tokenBegin);
103: bufline = newbufline;
104:
105: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
106: 0, bufsize - tokenBegin);
107: bufcolumn = newbufcolumn;
108:
109: bufpos -= tokenBegin;
110: }
111: } catch (Throwable t) {
112: throw new Error(t.getMessage());
113: }
114:
115: available = (bufsize += 2048);
116: tokenBegin = 0;
117: }
118:
119: protected void FillBuff() throws java.io.IOException {
120: int i;
121: if (maxNextCharInd == 4096)
122: maxNextCharInd = nextCharInd = 0;
123:
124: try {
125: if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
126: 4096 - maxNextCharInd)) == -1) {
127: inputStream.close();
128: throw new java.io.IOException();
129: } else
130: maxNextCharInd += i;
131: return;
132: } catch (java.io.IOException e) {
133: if (bufpos != 0) {
134: --bufpos;
135: backup(0);
136: } else {
137: bufline[bufpos] = line;
138: bufcolumn[bufpos] = column;
139: }
140: throw e;
141: }
142: }
143:
144: protected char ReadChar() throws java.io.IOException {
145: if (++nextCharInd >= maxNextCharInd)
146: FillBuff();
147:
148: return nextCharBuf[nextCharInd];
149: }
150:
151: public char BeginToken() throws java.io.IOException {
152: if (inBuf > 0) {
153: --inBuf;
154:
155: if (++bufpos == bufsize)
156: bufpos = 0;
157:
158: tokenBegin = bufpos;
159: return buffer[bufpos];
160: }
161:
162: tokenBegin = 0;
163: bufpos = -1;
164:
165: return readChar();
166: }
167:
168: protected void AdjustBuffSize() {
169: if (available == bufsize) {
170: if (tokenBegin > 2048) {
171: bufpos = 0;
172: available = tokenBegin;
173: } else
174: ExpandBuff(false);
175: } else if (available > tokenBegin)
176: available = bufsize;
177: else if ((tokenBegin - available) < 2048)
178: ExpandBuff(true);
179: else
180: available = tokenBegin;
181: }
182:
183: protected void UpdateLineColumn(char c) {
184: column++;
185:
186: if (prevCharIsLF) {
187: prevCharIsLF = false;
188: line += (column = 1);
189: } else if (prevCharIsCR) {
190: prevCharIsCR = false;
191: if (c == '\n') {
192: prevCharIsLF = true;
193: } else
194: line += (column = 1);
195: }
196:
197: switch (c) {
198: case '\r':
199: prevCharIsCR = true;
200: break;
201: case '\n':
202: prevCharIsLF = true;
203: break;
204: case '\t':
205: column--;
206: column += (8 - (column & 07));
207: break;
208: default:
209: break;
210: }
211:
212: bufline[bufpos] = line;
213: bufcolumn[bufpos] = column;
214: }
215:
216: public char readChar() throws java.io.IOException {
217: if (inBuf > 0) {
218: --inBuf;
219:
220: if (++bufpos == bufsize)
221: bufpos = 0;
222:
223: return buffer[bufpos];
224: }
225:
226: char c;
227:
228: if (++bufpos == available)
229: AdjustBuffSize();
230:
231: if ((buffer[bufpos] = c = ReadChar()) == '\\') {
232: UpdateLineColumn(c);
233:
234: int backSlashCnt = 1;
235:
236: for (;;) // Read all the backslashes
237: {
238: if (++bufpos == available)
239: AdjustBuffSize();
240:
241: try {
242: if ((buffer[bufpos] = c = ReadChar()) != '\\') {
243: UpdateLineColumn(c);
244: // found a non-backslash char.
245: if ((c == 'u') && ((backSlashCnt & 1) == 1)) {
246: if (--bufpos < 0)
247: bufpos = bufsize - 1;
248:
249: break;
250: }
251:
252: backup(backSlashCnt);
253: return '\\';
254: }
255: } catch (java.io.IOException e) {
256: if (backSlashCnt > 1)
257: backup(backSlashCnt);
258:
259: return '\\';
260: }
261:
262: UpdateLineColumn(c);
263: backSlashCnt++;
264: }
265:
266: // Here, we have seen an odd number of backslash's followed by a 'u'
267: try {
268: while ((c = ReadChar()) == 'u')
269: ++column;
270:
271: buffer[bufpos] = c = (char) (hexval(c) << 12
272: | hexval(ReadChar()) << 8
273: | hexval(ReadChar()) << 4 | hexval(ReadChar()));
274:
275: column += 4;
276: } catch (java.io.IOException e) {
277: throw new Error("Invalid escape character at line "
278: + line + " column " + column + ".");
279: }
280:
281: if (backSlashCnt == 1)
282: return c;
283: else {
284: backup(backSlashCnt - 1);
285: return '\\';
286: }
287: } else {
288: if (c > 127) {
289: System.out
290: .println("JavaCharStream: reading character='"
291: + c + "'=" + ((int) c));
292: }
293: UpdateLineColumn(c);
294: return (c);
295: }
296: }
297:
298: public void backup(int amount) {
299:
300: inBuf += amount;
301: if ((bufpos -= amount) < 0)
302: bufpos += bufsize;
303: }
304:
305: public JavaCharStream(java.io.Reader dstream) {
306: this (dstream, 1, 1, 4096);
307: }
308:
309: public JavaCharStream(java.io.Reader dstream, int startline,
310: int startcolumn, int buffersize) {
311: if (inputStream != null)
312: throw new Error(
313: "\n ERROR: Second call to the constructor of a JavaCharStream. You must\n"
314: + " either use ReInit() or set the JavaCC option STATIC to false\n"
315: + " during the generation of this class.");
316: inputStream = dstream;
317: line = startline;
318: column = startcolumn - 1;
319:
320: available = bufsize = buffersize;
321: buffer = new char[buffersize];
322: bufline = new int[buffersize];
323: bufcolumn = new int[buffersize];
324: nextCharBuf = new char[4096];
325: }
326:
327: public void ReInit(java.io.Reader dstream, int startline,
328: int startcolumn, int buffersize) {
329: inputStream = dstream;
330: line = startline;
331: column = startcolumn - 1;
332:
333: if (buffer == null || buffersize != buffer.length) {
334: available = bufsize = buffersize;
335: buffer = new char[buffersize];
336: bufline = new int[buffersize];
337: bufcolumn = new int[buffersize];
338: nextCharBuf = new char[4096];
339: }
340: prevCharIsLF = prevCharIsCR = false;
341: tokenBegin = inBuf = maxNextCharInd = 0;
342: nextCharInd = bufpos = -1;
343: }
344:
345: public String GetImage() {
346: if (bufpos >= tokenBegin)
347: return new String(buffer, tokenBegin, bufpos - tokenBegin
348: + 1);
349: else
350: return new String(buffer, tokenBegin, bufsize - tokenBegin)
351: + new String(buffer, 0, bufpos + 1);
352: }
353:
354: public char[] GetSuffix(int len) {
355: char[] ret = new char[len];
356:
357: if ((bufpos + 1) >= len)
358: System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
359: else {
360: System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret,
361: 0, len - bufpos - 1);
362: System.arraycopy(buffer, 0, ret, len - bufpos - 1,
363: bufpos + 1);
364: }
365:
366: return ret;
367: }
368:
369: public void Done() {
370: nextCharBuf = null;
371: buffer = null;
372: bufline = null;
373: bufcolumn = null;
374: }
375:
376: /**
377: * Method to adjust line and column numbers for the start of a token.<BR>
378: */
379: public void adjustBeginLineColumn(int newLine, int newCol) {
380: int start = tokenBegin;
381: int len;
382:
383: if (bufpos >= tokenBegin) {
384: len = bufpos - tokenBegin + inBuf + 1;
385: } else {
386: len = bufsize - tokenBegin + bufpos + 1 + inBuf;
387: }
388:
389: int i = 0, j = 0, k = 0;
390: int nextColDiff = 0, columnDiff = 0;
391:
392: while (i < len
393: && bufline[j = start % bufsize] == bufline[k = ++start
394: % bufsize]) {
395: bufline[j] = newLine;
396: nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
397: bufcolumn[j] = newCol + columnDiff;
398: columnDiff = nextColDiff;
399: i++;
400: }
401:
402: if (i < len) {
403: bufline[j] = newLine++;
404: bufcolumn[j] = newCol + columnDiff;
405:
406: while (i++ < len) {
407: if (bufline[j = start % bufsize] != bufline[++start
408: % bufsize])
409: bufline[j] = newLine++;
410: else
411: bufline[j] = newLine;
412: }
413: }
414:
415: line = bufline[j];
416: column = bufcolumn[j];
417: }
418:
419: }
|