blob: 9439bc08ba15c611e8f77fd5bbf8df41bb19363a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.queryparser.classic;
import java.io.*;
/** An efficient implementation of JavaCC's CharStream interface. <p>Note that
* this does not do line-number counting, but instead keeps track of the
* character position of the token in the input, as required by Lucene's {@link
* org.apache.lucene.analysis.tokenattributes.OffsetAttribute} API.
* */
public final class FastCharStream implements CharStream {
char[] buffer = null;
int bufferLength = 0; // end of valid chars
int bufferPosition = 0; // next char to read
int tokenStart = 0; // offset in buffer
int bufferStart = 0; // position in file of buffer
Reader input; // source of chars
/** Constructs from a Reader. */
public FastCharStream(Reader r) {
input = r;
}
@Override
public final char readChar() throws IOException {
if (bufferPosition >= bufferLength)
refill();
return buffer[bufferPosition++];
}
private final void refill() throws IOException {
int newPosition = bufferLength - tokenStart;
if (tokenStart == 0) { // token won't fit in buffer
if (buffer == null) { // first time: alloc buffer
buffer = new char[2048];
} else if (bufferLength == buffer.length) { // grow buffer
char[] newBuffer = new char[buffer.length*2];
System.arraycopy(buffer, 0, newBuffer, 0, bufferLength);
buffer = newBuffer;
}
} else { // shift token to front
System.arraycopy(buffer, tokenStart, buffer, 0, newPosition);
}
bufferLength = newPosition; // update state
bufferPosition = newPosition;
bufferStart += tokenStart;
tokenStart = 0;
int charsRead = // fill space in buffer
input.read(buffer, newPosition, buffer.length-newPosition);
if (charsRead == -1)
throw new IOException("read past eof");
else
bufferLength += charsRead;
}
@Override
public final char BeginToken() throws IOException {
tokenStart = bufferPosition;
return readChar();
}
@Override
public final void backup(int amount) {
bufferPosition -= amount;
}
@Override
public final String GetImage() {
return new String(buffer, tokenStart, bufferPosition - tokenStart);
}
@Override
public final char[] GetSuffix(int len) {
char[] value = new char[len];
System.arraycopy(buffer, bufferPosition - len, value, 0, len);
return value;
}
@Override
public final void Done() {
try {
input.close();
} catch (IOException e) {
}
}
/**
* Returns the column position of the character last read.
* @deprecated see: #getEndColumn
*/
@Deprecated
@Override
public final int getColumn() {
return bufferStart + bufferPosition;
}
/**
* @deprecated see #getEndLine
*/
@Override
@Deprecated
public final int getLine() {
return 1;
}
@Override
public final int getEndColumn() {
return bufferStart + bufferPosition;
}
@Override
public final int getEndLine() {
return 1;
}
@Override
public final int getBeginColumn() {
return bufferStart + tokenStart;
}
@Override
public final int getBeginLine() {
return 1;
}
}