package edu.berkeley.cs.succinct.util.stream;
import org.apache.hadoop.fs.FSDataInputStream;
import java.io.IOException;
/**
* ByteBuffer like wrapper for FSDataInputStream
*/
public class RandomAccessByteStream {
private FSDataInputStream stream;
private long startPos;
private long limit;
public RandomAccessByteStream(FSDataInputStream stream, long startPos, long limit)
throws IOException {
this.stream = stream;
this.startPos = startPos;
this.limit = limit;
stream.seek(startPos);
}
public byte get() throws IOException {
if (stream.getPos() >= startPos + limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit);
}
return stream.readByte();
}
public byte get(int index) throws IOException {
if (index >= limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " index = " + index);
}
long currentPos = stream.getPos();
stream.seek(startPos + index);
byte returnValue = stream.readByte();
stream.seek(currentPos);
return returnValue;
}
public short getShort() throws IOException {
if (stream.getPos() >= startPos + limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit);
}
return stream.readShort();
}
public short getShort(int index) throws IOException {
if (index >= limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " index = " + index);
}
long currentPos = stream.getPos();
stream.seek(startPos + index);
short returnValue = stream.readShort();
stream.seek(currentPos);
return returnValue;
}
public int getInt() throws IOException {
if (stream.getPos() >= startPos + limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " currentPos = "
+ stream.getPos());
}
return stream.readInt();
}
public int getInt(int index) throws IOException {
if (index >= limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " index = " + index);
}
long currentPos = stream.getPos();
stream.seek(startPos + index);
int returnValue = stream.readInt();
stream.seek(currentPos);
return returnValue;
}
public long getLong() throws IOException {
if (stream.getPos() >= startPos + limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit);
}
return stream.readLong();
}
public long getLong(int index) throws IOException {
if (index >= limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " index = " + index);
}
long currentPos = stream.getPos();
stream.seek(startPos + index);
long returnValue = stream.readLong();
stream.seek(currentPos);
return returnValue;
}
public long position() throws IOException {
return stream.getPos() - startPos;
}
public RandomAccessByteStream position(long pos) throws IOException {
if (pos >= limit) {
throw new ArrayIndexOutOfBoundsException(
"Stream out of bounds: startPos = " + startPos + " limit = " + limit + " position = "
+ pos);
}
stream.seek(startPos + pos);
return this;
}
public RandomAccessIntStream asIntStream() throws IOException {
return new RandomAccessIntStream(stream, stream.getPos(),
(limit - (stream.getPos() - startPos)) / 4);
}
public RandomAccessLongStream asLongStream() throws IOException {
return new RandomAccessLongStream(stream, stream.getPos(),
(limit - (stream.getPos() - startPos)) / 8);
}
public RandomAccessByteStream rewind() throws IOException {
return position(0);
}
public void close() throws IOException {
stream.close();
}
}