001: package org.python.parser;
002:
003: /**
004: * An implementation of interface CharStream, where the data is read from
005: * a Reader.
006: * This file started life as a copy of ASCII_CharStream.java.
007: */
008:
009: public final class ReaderCharStream implements CharStream {
010: public static final boolean staticFlag = false;
011: int bufsize;
012: int available;
013: int tokenBegin;
014: public int bufpos = -1;
015: private int bufline[];
016: private int bufcolumn[];
017:
018: private int column = 0;
019: private int line = 1;
020:
021: private boolean prevCharIsCR = false;
022: private boolean prevCharIsLF = false;
023:
024: private java.io.Reader inputStream;
025:
026: private char[] buffer;
027: private int maxNextCharInd = 0;
028: private int inBuf = 0;
029:
030: private final void ExpandBuff(boolean wrapAround) {
031: char[] newbuffer = new char[bufsize + 2048];
032: int newbufline[] = new int[bufsize + 2048];
033: int newbufcolumn[] = new int[bufsize + 2048];
034:
035: try {
036: if (wrapAround) {
037: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
038: bufsize - tokenBegin);
039: System.arraycopy(buffer, 0, newbuffer, bufsize
040: - tokenBegin, bufpos);
041: buffer = newbuffer;
042:
043: System.arraycopy(bufline, tokenBegin, newbufline, 0,
044: bufsize - tokenBegin);
045: System.arraycopy(bufline, 0, newbufline, bufsize
046: - tokenBegin, bufpos);
047: bufline = newbufline;
048:
049: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
050: 0, bufsize - tokenBegin);
051: System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize
052: - tokenBegin, bufpos);
053: bufcolumn = newbufcolumn;
054:
055: maxNextCharInd = (bufpos += (bufsize - tokenBegin));
056: } else {
057: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
058: bufsize - tokenBegin);
059: buffer = newbuffer;
060:
061: System.arraycopy(bufline, tokenBegin, newbufline, 0,
062: bufsize - tokenBegin);
063: bufline = newbufline;
064:
065: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
066: 0, bufsize - tokenBegin);
067: bufcolumn = newbufcolumn;
068:
069: maxNextCharInd = (bufpos -= tokenBegin);
070: }
071: } catch (Throwable t) {
072: throw new Error(t.getMessage());
073: }
074:
075: bufsize += 2048;
076: available = bufsize;
077: tokenBegin = 0;
078: }
079:
080: private final void FillBuff() throws java.io.IOException {
081: if (maxNextCharInd == available) {
082: if (available == bufsize) {
083: if (tokenBegin > 2048) {
084: bufpos = maxNextCharInd = 0;
085: available = tokenBegin;
086: } else if (tokenBegin < 0)
087: bufpos = maxNextCharInd = 0;
088: else
089: ExpandBuff(false);
090: } else if (available > tokenBegin)
091: available = bufsize;
092: else if ((tokenBegin - available) < 2048)
093: ExpandBuff(true);
094: else
095: available = tokenBegin;
096: }
097:
098: int i;
099: try {
100: if ((i = inputStream.read(buffer, maxNextCharInd, available
101: - maxNextCharInd)) == -1) {
102: inputStream.close();
103: throw new java.io.IOException();
104: } else
105: maxNextCharInd += i;
106: return;
107: } catch (java.io.IOException e) {
108: --bufpos;
109: backup(0);
110: if (tokenBegin == -1)
111: tokenBegin = bufpos;
112: throw e;
113: }
114: }
115:
116: public final char BeginToken() throws java.io.IOException {
117: tokenBegin = -1;
118: char c = readChar();
119: tokenBegin = bufpos;
120:
121: return c;
122: }
123:
124: private final void UpdateLineColumn(char c) {
125: column++;
126:
127: if (prevCharIsLF) {
128: prevCharIsLF = false;
129: line += (column = 1);
130: } else if (prevCharIsCR) {
131: prevCharIsCR = false;
132: if (c == '\n') {
133: prevCharIsLF = true;
134: } else
135: line += (column = 1);
136: }
137:
138: switch (c) {
139: case '\r':
140: prevCharIsCR = true;
141: break;
142: case '\n':
143: prevCharIsLF = true;
144: break;
145: case '\t':
146: column--;
147: column += (8 - (column & 07));
148: break;
149: default:
150: break;
151: }
152:
153: bufline[bufpos] = line;
154: bufcolumn[bufpos] = column;
155: }
156:
157: public final char readChar() throws java.io.IOException {
158: if (inBuf > 0) {
159: --inBuf;
160: return buffer[(bufpos == bufsize - 1) ? (bufpos = 0)
161: : ++bufpos];
162: }
163:
164: if (++bufpos >= maxNextCharInd)
165: FillBuff();
166:
167: char c = buffer[bufpos];
168:
169: UpdateLineColumn(c);
170: return (c);
171: }
172:
173: /**
174: * @deprecated
175: * @see #getEndColumn
176: */
177:
178: public final int getColumn() {
179: return bufcolumn[bufpos];
180: }
181:
182: /**
183: * @deprecated
184: * @see #getEndLine
185: */
186:
187: public final int getLine() {
188: return bufline[bufpos];
189: }
190:
191: public final int getEndColumn() {
192: return bufcolumn[bufpos];
193: }
194:
195: public final int getEndLine() {
196: return bufline[bufpos];
197: }
198:
199: public final int getBeginColumn() {
200: return bufcolumn[tokenBegin];
201: }
202:
203: public final int getBeginLine() {
204: return bufline[tokenBegin];
205: }
206:
207: public final void backup(int amount) {
208:
209: inBuf += amount;
210: if ((bufpos -= amount) < 0)
211: bufpos += bufsize;
212: }
213:
214: public ReaderCharStream(java.io.Reader dstream) {
215: inputStream = dstream;
216: line = 1;
217: column = 0;
218:
219: available = bufsize = 4096;
220: buffer = new char[bufsize];
221: bufline = new int[bufsize];
222: bufcolumn = new int[bufsize];
223: }
224:
225: public final String GetImage() {
226: if (bufpos >= tokenBegin)
227: return new String(buffer, tokenBegin, bufpos - tokenBegin
228: + 1);
229: else
230: return new String(buffer, tokenBegin, bufsize - tokenBegin)
231: + new String(buffer, 0, bufpos + 1);
232: }
233:
234: public final char[] GetSuffix(int len) {
235: char[] ret = new char[len];
236:
237: if ((bufpos + 1) >= len)
238: System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
239: else {
240: System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret,
241: 0, len - bufpos - 1);
242: System.arraycopy(buffer, 0, ret, len - bufpos - 1,
243: bufpos + 1);
244: }
245:
246: return ret;
247: }
248:
249: public void Done() {
250: buffer = null;
251: bufline = null;
252: bufcolumn = null;
253: }
254:
255: /**
256: * Method to adjust line and column numbers for the start of a token.<BR>
257: */
258: public void adjustBeginLineColumn(int newLine, int newCol) {
259: int start = tokenBegin;
260: int len;
261:
262: if (bufpos >= tokenBegin) {
263: len = bufpos - tokenBegin + inBuf + 1;
264: } else {
265: len = bufsize - tokenBegin + bufpos + 1 + inBuf;
266: }
267:
268: int i = 0, j = 0, k = 0;
269: int nextColDiff = 0, columnDiff = 0;
270:
271: while (i < len
272: && bufline[j = start % bufsize] == bufline[k = ++start
273: % bufsize]) {
274: bufline[j] = newLine;
275: nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
276: bufcolumn[j] = newCol + columnDiff;
277: columnDiff = nextColDiff;
278: i++;
279: }
280:
281: if (i < len) {
282: bufline[j] = newLine++;
283: bufcolumn[j] = newCol + columnDiff;
284:
285: while (i++ < len) {
286: if (bufline[j = start % bufsize] != bufline[++start
287: % bufsize])
288: bufline[j] = newLine++;
289: else
290: bufline[j] = newLine;
291: }
292: }
293:
294: line = bufline[j];
295: column = bufcolumn[j];
296: }
297:
298: }
|