org.jclarion.clarion.file.RingBufferedInputStreamClarionFile Maven / Gradle / Ivy
package org.jclarion.clarion.file;
import java.io.IOException;
import java.io.InputStream;
import org.jclarion.clarion.ClarionRandomAccessFile;
public abstract class RingBufferedInputStreamClarionFile extends ClarionRandomAccessFile
{
private byte buffer[]=new byte[16384]; // ring buffer
private int head;
private int tail;
private long pos;
private InputStream stream;
public RingBufferedInputStreamClarionFile()
{
}
@Override
public void close() throws IOException
{
closeStream();
}
private long lengthCache=-1;
@Override
public long length() throws IOException
{
if (lengthCache==-1) {
byte buffer[]=null;
InputStream is = createStream();
try {
lengthCache=0;
while (true) {
long len = is.skip(65536);
if (len>0) {
lengthCache+=len;
continue;
}
if (buffer==null) {
if (is.read()==-1) break;
lengthCache++;
buffer=new byte[1024];
} else {
len = is.read(buffer);
if (len<=0) break;
lengthCache+=len;
}
}
} finally {
is.close();
}
}
return lengthCache;
}
@Override
public int read(byte[] target, int ofs, int len) throws IOException
{
if (head==tail) fillBuffer();
if (head==tail) return 0;
int end=tail;
if (endend) {
len=end-head;
}
System.arraycopy(buffer,head,target,ofs,len);
head+=len;
if (head==buffer.length) head=0;
pos+=len;
return len;
}
@Override
public void seek(long ofs) throws IOException
{
// read backwards - into ring buffer
if (ofsbackbuffer) {
back=backbuffer;
}
head=head-(int)back;
if (head<0) head+=buffer.length;
pos=pos-back;
}
// read backwards - start all over
if (ofspos) {
if (head==tail) fillBuffer();
if (head==tail) break;
long len = ofs-pos;
int end=tail;
if (endend) {
len=end-head;
}
head+=(int)len;
if (head==buffer.length) head=0;
pos+=len;
}
}
@Override
public void write(byte[] arg0, int arg1, int arg2) throws IOException
{
throw new IOException("Not supported");
}
protected abstract InputStream createStream() throws IOException;
private void fillBuffer() throws IOException
{
if (stream==null) {
stream=createStream();
head=0;
tail=0;
pos=0;
}
int read=buffer.length-tail;
// only read half buffer at a time so that we have some backbuffer
if (read>buffer.length/2) read=buffer.length/2;
// do not allow tail to overrun head
if (tail=head) read = head-tail-1;
if (read==0) return;
read = stream.read(buffer,tail,read);
if (read<=0) return;
tail+=read;
if (tail==buffer.length) tail=0;
}
private void closeStream() throws IOException
{
try {
if (stream!=null) {
stream.close();
}
} finally {
stream=null;
head=0;
tail=0;
pos=0;
}
}
@Override
public long position() throws IOException {
return pos;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy