blob: 9da026b39eeb8e85db6808e0567991bfc4e99f3c [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.geode.cache.lucene.internal.directory;
import java.io.EOFException;
import java.io.IOException;
import org.apache.lucene.store.IndexInput;
import org.apache.geode.cache.lucene.internal.filesystem.File;
import org.apache.geode.cache.lucene.internal.filesystem.SeekableInputStream;
class FileIndexInput extends IndexInput {
private final File file;
SeekableInputStream in;
private long position;
// Used for slice operations
private long sliceOffset;
private long sliceLength;
FileIndexInput(String resourceDesc, File file) {
this(resourceDesc, file, 0L, file.getLength());
}
/**
* Constructor for a slice.
*/
private FileIndexInput(String resourceDesc, File file, long offset, long length) {
super(resourceDesc);
this.file = file;
in = file.getInputStream();
this.sliceOffset = offset;
this.sliceLength = length;
}
@Override
public long length() {
return sliceLength;
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public FileIndexInput clone() {
FileIndexInput clone = (FileIndexInput) super.clone();
clone.in = in.clone();
return clone;
}
@Override
public long getFilePointer() {
return position;
}
@Override
public void seek(long pos) throws IOException {
in.seek(pos + sliceOffset);
this.position = pos;
}
@Override
public IndexInput slice(String sliceDescription, long offset, long length) throws IOException {
if (length > (this.sliceLength - offset)) {
throw new IllegalArgumentException("Slice length is to large. Asked for " + length
+ " file length is " + sliceLength + ": " + this.file.getName());
}
if (offset < 0 || offset >= this.sliceLength) {
throw new IllegalArgumentException("Slice offset is invalid: " + this.file.getName());
}
FileIndexInput result =
new FileIndexInput(sliceDescription, file, sliceOffset + offset, length);
result.seek(0);
return result;
}
@Override
public byte readByte() throws IOException {
if (++position > sliceLength) {
throw new EOFException("Read past end of file " + file.getName());
}
int result = in.read();
if (result == -1) {
throw new EOFException("Read past end of file " + file.getName());
} else {
return (byte) result;
}
}
@Override
public void readBytes(byte[] b, int offset, int len) throws IOException {
if (len == 0) {
return;
}
if (position + len > sliceLength) {
throw new EOFException("Read past end of file " + file.getName());
}
// For the FileSystemInputStream, it will always read all bytes, up
// until the end of the file. So if we didn't get enough bytes, it's
// because we reached the end of the file.
int numRead = in.read(b, offset, len);
if (numRead < len) {
throw new EOFException("Read past end of file " + file.getName());
}
position += len;
}
}