001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.xpointer.parser;
018:
019: /**
020: * An implementation of interface CharStream, where the stream is assumed to
021: * contain only ASCII characters (without unicode processing).
022: *
023: * @version CVS $Id: SimpleCharStream.java 433543 2006-08-22 06:22:54Z crossley $
024: */
025:
026: public class SimpleCharStream {
027: public static final boolean staticFlag = false;
028: int bufsize;
029: int available;
030: int tokenBegin;
031: public int bufpos = -1;
032: protected int bufline[];
033: protected int bufcolumn[];
034:
035: protected int column = 0;
036: protected int line = 1;
037:
038: protected boolean prevCharIsCR = false;
039: protected boolean prevCharIsLF = false;
040:
041: protected java.io.Reader inputStream;
042:
043: protected char[] buffer;
044: protected int maxNextCharInd = 0;
045: protected int inBuf = 0;
046:
047: protected void expandBuff(boolean wrapAround) {
048: char[] newbuffer = new char[bufsize + 2048];
049: int newbufline[] = new int[bufsize + 2048];
050: int newbufcolumn[] = new int[bufsize + 2048];
051:
052: try {
053: if (wrapAround) {
054: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
055: bufsize - tokenBegin);
056: System.arraycopy(buffer, 0, newbuffer, bufsize
057: - tokenBegin, bufpos);
058: buffer = newbuffer;
059:
060: System.arraycopy(bufline, tokenBegin, newbufline, 0,
061: bufsize - tokenBegin);
062: System.arraycopy(bufline, 0, newbufline, bufsize
063: - tokenBegin, bufpos);
064: bufline = newbufline;
065:
066: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
067: 0, bufsize - tokenBegin);
068: System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize
069: - tokenBegin, bufpos);
070: bufcolumn = newbufcolumn;
071:
072: maxNextCharInd = (bufpos += (bufsize - tokenBegin));
073: } else {
074: System.arraycopy(buffer, tokenBegin, newbuffer, 0,
075: bufsize - tokenBegin);
076: buffer = newbuffer;
077:
078: System.arraycopy(bufline, tokenBegin, newbufline, 0,
079: bufsize - tokenBegin);
080: bufline = newbufline;
081:
082: System.arraycopy(bufcolumn, tokenBegin, newbufcolumn,
083: 0, bufsize - tokenBegin);
084: bufcolumn = newbufcolumn;
085:
086: maxNextCharInd = (bufpos -= tokenBegin);
087: }
088: } catch (Throwable t) {
089: throw new Error(t.getMessage());
090: }
091:
092: bufsize += 2048;
093: available = bufsize;
094: tokenBegin = 0;
095: }
096:
097: protected void fillBuff() throws java.io.IOException {
098: if (maxNextCharInd == available) {
099: if (available == bufsize) {
100: if (tokenBegin > 2048) {
101: bufpos = maxNextCharInd = 0;
102: available = tokenBegin;
103: } else if (tokenBegin < 0)
104: bufpos = maxNextCharInd = 0;
105: else
106: expandBuff(false);
107: } else if (available > tokenBegin)
108: available = bufsize;
109: else if ((tokenBegin - available) < 2048)
110: expandBuff(true);
111: else
112: available = tokenBegin;
113: }
114:
115: int i;
116: try {
117: if ((i = inputStream.read(buffer, maxNextCharInd, available
118: - maxNextCharInd)) == -1) {
119: inputStream.close();
120: throw new java.io.IOException();
121: } else
122: maxNextCharInd += i;
123: return;
124: } catch (java.io.IOException e) {
125: --bufpos;
126: backup(0);
127: if (tokenBegin == -1)
128: tokenBegin = bufpos;
129: throw e;
130: }
131: }
132:
133: public char beginToken() throws java.io.IOException {
134: tokenBegin = -1;
135: char c = readChar();
136: tokenBegin = bufpos;
137:
138: return c;
139: }
140:
141: protected void updateLineColumn(char c) {
142: column++;
143:
144: if (prevCharIsLF) {
145: prevCharIsLF = false;
146: line += (column = 1);
147: } else if (prevCharIsCR) {
148: prevCharIsCR = false;
149: if (c == '\n') {
150: prevCharIsLF = true;
151: } else
152: line += (column = 1);
153: }
154:
155: switch (c) {
156: case '\r':
157: prevCharIsCR = true;
158: break;
159: case '\n':
160: prevCharIsLF = true;
161: break;
162: case '\t':
163: column--;
164: column += (8 - (column & 07));
165: break;
166: default:
167: break;
168: }
169:
170: bufline[bufpos] = line;
171: bufcolumn[bufpos] = column;
172: }
173:
174: public char readChar() throws java.io.IOException {
175: if (inBuf > 0) {
176: --inBuf;
177:
178: if (++bufpos == bufsize)
179: bufpos = 0;
180:
181: return buffer[bufpos];
182: }
183:
184: if (++bufpos >= maxNextCharInd)
185: fillBuff();
186:
187: char c = buffer[bufpos];
188:
189: updateLineColumn(c);
190: return (c);
191: }
192:
193: /**
194: * @deprecated
195: * @see #getEndColumn()
196: */
197:
198: public int getColumn() {
199: return bufcolumn[bufpos];
200: }
201:
202: /**
203: * @deprecated
204: * @see #getEndLine()
205: */
206:
207: public int getLine() {
208: return bufline[bufpos];
209: }
210:
211: public int getEndColumn() {
212: return bufcolumn[bufpos];
213: }
214:
215: public int getEndLine() {
216: return bufline[bufpos];
217: }
218:
219: public int getBeginColumn() {
220: return bufcolumn[tokenBegin];
221: }
222:
223: public int getBeginLine() {
224: return bufline[tokenBegin];
225: }
226:
227: public void backup(int amount) {
228:
229: inBuf += amount;
230: if ((bufpos -= amount) < 0)
231: bufpos += bufsize;
232: }
233:
234: public SimpleCharStream(java.io.Reader dstream, int startline,
235: int startcolumn, int buffersize) {
236: inputStream = dstream;
237: line = startline;
238: column = startcolumn - 1;
239:
240: available = bufsize = buffersize;
241: buffer = new char[buffersize];
242: bufline = new int[buffersize];
243: bufcolumn = new int[buffersize];
244: }
245:
246: public SimpleCharStream(java.io.Reader dstream, int startline,
247: int startcolumn) {
248: this (dstream, startline, startcolumn, 4096);
249: }
250:
251: public SimpleCharStream(java.io.Reader dstream) {
252: this (dstream, 1, 1, 4096);
253: }
254:
255: public void reInit(java.io.Reader dstream, int startline,
256: int startcolumn, int buffersize) {
257: inputStream = dstream;
258: line = startline;
259: column = startcolumn - 1;
260:
261: if (buffer == null || buffersize != buffer.length) {
262: available = bufsize = buffersize;
263: buffer = new char[buffersize];
264: bufline = new int[buffersize];
265: bufcolumn = new int[buffersize];
266: }
267: prevCharIsLF = prevCharIsCR = false;
268: tokenBegin = inBuf = maxNextCharInd = 0;
269: bufpos = -1;
270: }
271:
272: public void reInit(java.io.Reader dstream, int startline,
273: int startcolumn) {
274: reInit(dstream, startline, startcolumn, 4096);
275: }
276:
277: public void reInit(java.io.Reader dstream) {
278: reInit(dstream, 1, 1, 4096);
279: }
280:
281: public SimpleCharStream(java.io.InputStream dstream, int startline,
282: int startcolumn, int buffersize) {
283: this (new java.io.InputStreamReader(dstream), startline,
284: startcolumn, buffersize);
285: }
286:
287: public SimpleCharStream(java.io.InputStream dstream, int startline,
288: int startcolumn) {
289: this (dstream, startline, startcolumn, 4096);
290: }
291:
292: public SimpleCharStream(java.io.InputStream dstream) {
293: this (dstream, 1, 1, 4096);
294: }
295:
296: public void reInit(java.io.InputStream dstream, int startline,
297: int startcolumn, int buffersize) {
298: reInit(new java.io.InputStreamReader(dstream), startline,
299: startcolumn, buffersize);
300: }
301:
302: public void reInit(java.io.InputStream dstream) {
303: reInit(dstream, 1, 1, 4096);
304: }
305:
306: public void reInit(java.io.InputStream dstream, int startline,
307: int startcolumn) {
308: reInit(dstream, startline, startcolumn, 4096);
309: }
310:
311: public String getImage() {
312: if (bufpos >= tokenBegin)
313: return new String(buffer, tokenBegin, bufpos - tokenBegin
314: + 1);
315: else
316: return new String(buffer, tokenBegin, bufsize - tokenBegin)
317: + new String(buffer, 0, bufpos + 1);
318: }
319:
320: public char[] getSuffix(int len) {
321: char[] ret = new char[len];
322:
323: if ((bufpos + 1) >= len)
324: System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
325: else {
326: System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret,
327: 0, len - bufpos - 1);
328: System.arraycopy(buffer, 0, ret, len - bufpos - 1,
329: bufpos + 1);
330: }
331:
332: return ret;
333: }
334:
335: public void done() {
336: buffer = null;
337: bufline = null;
338: bufcolumn = null;
339: }
340:
341: /**
342: * Method to adjust line and column numbers for the start of a token.<BR>
343: */
344: public void adjustBeginLineColumn(int newLine, int newCol) {
345: int start = tokenBegin;
346: int len;
347:
348: if (bufpos >= tokenBegin) {
349: len = bufpos - tokenBegin + inBuf + 1;
350: } else {
351: len = bufsize - tokenBegin + bufpos + 1 + inBuf;
352: }
353:
354: int i = 0, j = 0, k = 0;
355: int nextColDiff = 0, columnDiff = 0;
356:
357: while (i < len
358: && bufline[j = start % bufsize] == bufline[k = ++start
359: % bufsize]) {
360: bufline[j] = newLine;
361: nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
362: bufcolumn[j] = newCol + columnDiff;
363: columnDiff = nextColDiff;
364: i++;
365: }
366:
367: if (i < len) {
368: bufline[j] = newLine++;
369: bufcolumn[j] = newCol + columnDiff;
370:
371: while (i++ < len) {
372: if (bufline[j = start % bufsize] != bufline[++start
373: % bufsize])
374: bufline[j] = newLine++;
375: else
376: bufline[j] = newLine;
377: }
378: }
379:
380: line = bufline[j];
381: column = bufcolumn[j];
382: }
383:
384: }
|