001: // FastCharStream.java
002: package org.apache.lucene.queryParser.precedence;
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 org.apache.lucene.queryParser.*;
022:
023: import java.io.*;
024:
025: /** An efficient implementation of JavaCC's CharStream interface. <p>Note that
026: * this does not do line-number counting, but instead keeps track of the
027: * character position of the token in the input, as required by Lucene's {@link
028: * org.apache.lucene.analysis.Token} API. */
029: public final class FastCharStream implements CharStream {
030: char[] buffer = null;
031:
032: int bufferLength = 0; // end of valid chars
033: int bufferPosition = 0; // next char to read
034:
035: int tokenStart = 0; // offset in buffer
036: int bufferStart = 0; // position in file of buffer
037:
038: Reader input; // source of chars
039:
040: /** Constructs from a Reader. */
041: public FastCharStream(Reader r) {
042: input = r;
043: }
044:
045: public final char readChar() throws IOException {
046: if (bufferPosition >= bufferLength)
047: refill();
048: return buffer[bufferPosition++];
049: }
050:
051: private final void refill() throws IOException {
052: int newPosition = bufferLength - tokenStart;
053:
054: if (tokenStart == 0) { // token won't fit in buffer
055: if (buffer == null) { // first time: alloc buffer
056: buffer = new char[2048];
057: } else if (bufferLength == buffer.length) { // grow buffer
058: char[] newBuffer = new char[buffer.length * 2];
059: System.arraycopy(buffer, 0, newBuffer, 0, bufferLength);
060: buffer = newBuffer;
061: }
062: } else { // shift token to front
063: System
064: .arraycopy(buffer, tokenStart, buffer, 0,
065: newPosition);
066: }
067:
068: bufferLength = newPosition; // update state
069: bufferPosition = newPosition;
070: bufferStart += tokenStart;
071: tokenStart = 0;
072:
073: int charsRead = // fill space in buffer
074: input.read(buffer, newPosition, buffer.length - newPosition);
075: if (charsRead == -1)
076: throw new IOException("read past eof");
077: else
078: bufferLength += charsRead;
079: }
080:
081: public final char BeginToken() throws IOException {
082: tokenStart = bufferPosition;
083: return readChar();
084: }
085:
086: public final void backup(int amount) {
087: bufferPosition -= amount;
088: }
089:
090: public final String GetImage() {
091: return new String(buffer, tokenStart, bufferPosition
092: - tokenStart);
093: }
094:
095: public final char[] GetSuffix(int len) {
096: char[] value = new char[len];
097: System.arraycopy(buffer, bufferPosition - len, value, 0, len);
098: return value;
099: }
100:
101: public final void Done() {
102: try {
103: input.close();
104: } catch (IOException e) {
105: System.err.println("Caught: " + e + "; ignoring.");
106: }
107: }
108:
109: public final int getColumn() {
110: return bufferStart + bufferPosition;
111: }
112:
113: public final int getLine() {
114: return 1;
115: }
116:
117: public final int getEndColumn() {
118: return bufferStart + bufferPosition;
119: }
120:
121: public final int getEndLine() {
122: return 1;
123: }
124:
125: public final int getBeginColumn() {
126: return bufferStart + tokenStart;
127: }
128:
129: public final int getBeginLine() {
130: return 1;
131: }
132: }
|