package org.jboss.fresh.vfs.impl;
import org.jboss.fresh.vfs.FileInfo;
import org.jboss.fresh.vfs.FileName;
import org.jboss.fresh.vfs.FileOpInfo;
import org.jboss.fresh.vfs.FileReadInfo;
import org.jboss.fresh.vfs.VFSFileHandlerFactory;
import org.jboss.fresh.registry.RegistryContext;
import java.io.IOException;
import java.io.InputStream;
public class VFSInputStream extends InputStream {
private SecureVFS vfs;
private int pos = 0;
private byte[] buf;
private FileReadInfo rinf;
private FileOpInfo opinf;
private boolean closed = false;
private InputStream delegate;
public VFSInputStream(SecureVFS vfs, String filename) throws IOException {
this.vfs = vfs;
opinf = new FileOpInfo();
// check if file exists - if exists we get the resolved name
FileInfo info = vfs.getFileInfo(new FileName(filename), false);
if (info == null) throw new IOException("The specified file does not exist: " + filename);
String device = (String) info.getAttributes().get("file-handler");
if(device != null) {
try {
RegistryContext ctx = new RegistryContext();
VFSFileHandlerFactory f = (VFSFileHandlerFactory) ctx.lookup(device);
delegate = f.getInputStream(info);
} catch(IOException ex) {
throw ex;
} catch(Exception ex) {
IOException exout = new IOException("File handler initialization failed: ");
exout.initCause(ex);
throw exout;
}
return;
}
opinf.filename = info.getFileName();
//System.out.println("finfo: " + info);
rinf = new FileReadInfo();
rinf.more = true;
}
public int read() throws IOException {
if (delegate != null)
return delegate.read();
if (closed) return -1;
return 0;
}
public int read(byte[] buf) throws IOException {
if(delegate != null)
return delegate.read(buf);
if (closed) return -1;
return read(buf, 0, buf.length);
}
public int read(byte[] buf, int offs, int len) throws IOException {
if(delegate != null)
return delegate.read(buf, offs, len);
if (closed || !rinf.more) return -1;
// current position in the clients buffer
int cpos = offs;
// how much more can we write in the client's buffer
int togo = len;
//System.out.println(">>>>>>>********");
while (togo > 0 && rinf.more) {
//System.out.println("client buffer togo: " + togo);
// if we completely processed the last received buffer read a new one.
if (rinf.buf == null) {
//System.out.println("Reading: ");
//System.out.println("opinf: " + opinf + " offset: " + opinf.offset);
rinf = vfs.read(opinf);
if(rinf==null || rinf.buf==null) throw new IOException("Failed to read file from vfs: " + opinf.filename + " (offset:" + opinf.offset + ")");
//System.out.println("Read:");
//System.out.println("rinf: " + rinf);
//System.out.println("rinf buf: " + rinf.buf);
//System.out.println("rinf buf length: " + rinf.buf.length);
//System.out.println("========");
//System.out.println();
//System.out.println("opinf: " + opinf + " offset: " + opinf.offset);
//System.out.println("rinf: " + rinf);
//System.out.println("rinf buf: " + rinf.buf);
//System.out.println("rinf buf length: " + rinf.buf.length);
//System.out.println();
//System.out.println("========");
//System.out.println("opinf: " + opinf);
//System.out.println("opinf.offset: " + opinf.offset);
//System.out.println("rinf: " + rinf);
//System.out.println("rinf.buf: " + rinf.buf);
opinf.offset += rinf.buf.length;
opinf.tag = rinf.tag;
//System.out.println("opinf: " + opinf + " offset: " + opinf.offset);
pos = 0;
}
// how much still to process in the current buffer
int tlen = rinf.buf.length - pos;
//System.out.println("To process in the current buffer: " + tlen);
// can't write to client's buffer more than allowed
int tc = (tlen < togo ? tlen : togo);
//System.out.println("To write in the client buffer this pass: " + tc);
// copy
System.arraycopy(rinf.buf, pos, buf, cpos, tc);
// in the current buffer we have -tc to go
togo -= tc;
// in the client buffer current pos is +tc
cpos += tc;
// pos in the current buffer is +tc
pos += tc;
// if we completely processed the current buffer we need to nullify rinf.buf
if (pos >= rinf.buf.length) rinf.buf = null;
}
//System.out.println("Processed " + (len-togo) + " bytes");
return len - togo;
}
public void close() throws IOException {
if(delegate != null) {
delegate.close();
return;
}
closed = true;
}
}