/* * 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; final 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; } }