
org.infinispan.io.GridInputStream Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2010 Red Hat Inc. and/or its affiliates and other
* contributors as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.infinispan.io;
import org.infinispan.Cache;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Bela Ban
* @author Marko Luksa
*/
public class GridInputStream extends InputStream {
private int index = 0; // index into the file for writing
private int localIndex = 0;
private byte[] currentBuffer = null;
private boolean endReached = false;
private boolean closed = false;
private FileChunkMapper fileChunkMapper;
GridInputStream(GridFile file, Cache cache) {
fileChunkMapper = new FileChunkMapper(file, cache);
}
@Override
public int read() throws IOException {
checkClosed();
int remaining = getBytesRemainingInChunk();
if (remaining == 0) {
if (endReached)
return -1;
fetchNextChunk();
if (currentBuffer == null)
return -1;
else if (isLastChunk())
endReached = true;
}
int retval = 0x0ff¤tBuffer[localIndex++];
index++;
return retval;
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
checkClosed();
int totalBytesRead = 0;
while (len > 0) {
int bytesRead = readFromChunk(b, off, len);
if (bytesRead == -1)
return totalBytesRead > 0 ? totalBytesRead : -1;
off += bytesRead;
len -= bytesRead;
totalBytesRead += bytesRead;
}
return totalBytesRead;
}
private int readFromChunk(byte[] b, int off, int len) {
int remaining = getBytesRemainingInChunk();
if (remaining == 0) {
if (endReached)
return -1;
fetchNextChunk();
if (currentBuffer == null)
return -1;
else if (isLastChunk())
endReached = true;
remaining = getBytesRemainingInChunk();
}
int bytesToRead = Math.min(len, remaining);
System.arraycopy(currentBuffer, localIndex, b, off, bytesToRead);
localIndex += bytesToRead;
index += bytesToRead;
return bytesToRead;
}
private boolean isLastChunk() {
return currentBuffer.length < getChunkSize();
}
@Override
public long skip(long len) throws IOException {
checkClosed();
//naive and inefficient, but working
long count = 0;
while(len!=count && read()!=-1){
count++;
}
return count;
}
@Override
public int available() throws IOException {
checkClosed();
return getBytesRemainingInChunk();
}
@Override
public void close() throws IOException {
localIndex = index = 0;
endReached = false;
closed = true;
}
private void checkClosed() throws IOException{
if(closed){
throw new IOException("Stream is closed");
}
}
private int getBytesRemainingInChunk() {
return currentBuffer == null ? 0 : currentBuffer.length - localIndex;
}
private void fetchNextChunk() {
currentBuffer = fileChunkMapper.fetchChunk(getChunkNumber());
localIndex = 0;
}
private int getChunkNumber() {
return index / getChunkSize();
}
private int getChunkSize() {
return fileChunkMapper.getChunkSize();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy