001: // FastCharStream.java
002: package org.apache.lucene.queryParser.surround.parser;
003:
004: /**
005: * Licensed to the Apache Software Foundation (ASF) under one or more
006: * contributor license agreements. See the NOTICE file distributed with
007: * this work for additional information regarding copyright ownership.
008: * The ASF licenses this file to You under the Apache License, Version 2.0
009: * (the "License"); you may not use this file except in compliance with
010: * the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: */
020:
021: import java.io.*;
022:
023: /** An efficient implementation of JavaCC's CharStream interface. <p>Note that
024: * this does not do line-number counting, but instead keeps track of the
025: * character position of the token in the input, as required by Lucene's {@link
026: * org.apache.lucene.analysis.Token} API. */
027: public final class FastCharStream implements CharStream {
028: char[] buffer = null;
029:
030: int bufferLength = 0; // end of valid chars
031: int bufferPosition = 0; // next char to read
032:
033: int tokenStart = 0; // offset in buffer
034: int bufferStart = 0; // position in file of buffer
035:
036: Reader input; // source of chars
037:
038: /** Constructs from a Reader. */
039: public FastCharStream(Reader r) {
040: input = r;
041: }
042:
043: public final char readChar() throws IOException {
044: if (bufferPosition >= bufferLength)
045: refill();
046: return buffer[bufferPosition++];
047: }
048:
049: private final void refill() throws IOException {
050: int newPosition = bufferLength - tokenStart;
051:
052: if (tokenStart == 0) { // token won't fit in buffer
053: if (buffer == null) { // first time: alloc buffer
054: buffer = new char[2048];
055: } else if (bufferLength == buffer.length) { // grow buffer
056: char[] newBuffer = new char[buffer.length * 2];
057: System.arraycopy(buffer, 0, newBuffer, 0, bufferLength);
058: buffer = newBuffer;
059: }
060: } else { // shift token to front
061: System
062: .arraycopy(buffer, tokenStart, buffer, 0,
063: newPosition);
064: }
065:
066: bufferLength = newPosition; // update state
067: bufferPosition = newPosition;
068: bufferStart += tokenStart;
069: tokenStart = 0;
070:
071: int charsRead = // fill space in buffer
072: input.read(buffer, newPosition, buffer.length - newPosition);
073: if (charsRead == -1)
074: throw new IOException("read past eof");
075: else
076: bufferLength += charsRead;
077: }
078:
079: public final char BeginToken() throws IOException {
080: tokenStart = bufferPosition;
081: return readChar();
082: }
083:
084: public final void backup(int amount) {
085: bufferPosition -= amount;
086: }
087:
088: public final String GetImage() {
089: return new String(buffer, tokenStart, bufferPosition
090: - tokenStart);
091: }
092:
093: public final char[] GetSuffix(int len) {
094: char[] value = new char[len];
095: System.arraycopy(buffer, bufferPosition - len, value, 0, len);
096: return value;
097: }
098:
099: public final void Done() {
100: try {
101: input.close();
102: } catch (IOException e) {
103: System.err.println("Caught: " + e + "; ignoring.");
104: }
105: }
106:
107: public final int getColumn() {
108: return bufferStart + bufferPosition;
109: }
110:
111: public final int getLine() {
112: return 1;
113: }
114:
115: public final int getEndColumn() {
116: return bufferStart + bufferPosition;
117: }
118:
119: public final int getEndLine() {
120: return 1;
121: }
122:
123: public final int getBeginColumn() {
124: return bufferStart + tokenStart;
125: }
126:
127: public final int getBeginLine() {
128: return 1;
129: }
130: }
|