package mp4.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileInputStream extends RandomAccessInputStream {
public static int DEFAULT_BUFFER_SIZE = 16 * 1024;
byte[] buf = null;
long filePos = 0;
int bufp;
int curBufSize = 0;
RandomAccessFile fp;
long markPos;
long fileLength = -1;
byte[] singlebyteb = new byte[1];
public RandomAccessFileInputStream(File file, int bufferSize)
throws FileNotFoundException {
fp = new RandomAccessFile(file, "r");
try {
fileLength = fp.length();
} catch(IOException e) { }
buf = new byte[bufferSize];
resetBuffer();
}
public int available() {
return (int)(fileLength == -1 ? -1 : fileLength - filePos);
}
public RandomAccessFileInputStream(File file)
throws FileNotFoundException {
this(file, DEFAULT_BUFFER_SIZE);
}
public RandomAccessFileInputStream(String filename)
throws FileNotFoundException {
this(new File(filename), DEFAULT_BUFFER_SIZE);
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#read()
*/
@Override
public int read() throws IOException {
int len = read(singlebyteb);
if (len == 0)
return -1;
else
return ((int)singlebyteb[0])&0xff;
// return fp.read();
}
public void fillBuffer() throws IOException {
if (bufp >= curBufSize) {
if (filePos != fp.getFilePointer())
fp.seek(filePos);
int len = fp.read(buf, 0, buf.length);
curBufSize = Math.max(len, 0);
bufp = 0;
}
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#read(byte[], int, int)
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
int cnt = 0;
while(len > 0) {
fillBuffer();
if (curBufSize == 0)
return cnt;
for (int i=0;i<len && bufp < curBufSize;i++) {
b[off+cnt] = buf[bufp];
cnt++;
bufp++;
len--;
filePos++;
}
//return fp.read(b, off, len);
}
return cnt;
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#read(byte[])
*/
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#close()
*/
public void close() throws IOException {
fp.close();
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#getFilePointer()
*/
public long getFilePointer() throws IOException {
return filePos;
}
/*
public int skip(int n) throws IOException {
return fp.skipBytes(n);
}
*/
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#seek(long)
*/
public void seek(long pos) throws IOException {
long offset = pos - filePos;
fp.seek(pos);
filePos = pos;
long newbufp = bufp + offset;
if (newbufp < 0 || newbufp > buf.length)
resetBuffer();
else
bufp = (int)newbufp;
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#length()
*/
public long length() throws IOException {
return fp.length();
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#markSupported()
*/
public boolean markSupported() {
return true;
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#mark(int)
*/
public void mark(int readLimit) {
try {
markPos = getFilePointer();
} catch (IOException e) {
}
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#reset()
*/
public void reset() throws IOException {
seek(markPos);
}
private void resetBuffer() {
bufp = buf.length;
}
/* (non-Javadoc)
* @see com.unwiredappeal.tivo.utils.RandomAccessInputStream#skip(long)
*/
public long skip(long n) throws IOException {
long cpos = getFilePointer();
long left = length() - cpos;
n = Math.min(n, left);
seek(cpos+n);
return n;
}
}