FDIOStreamFactory.java
package eu.javaexperience.io.fd;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import eu.javaexperience.io.CloseSensitiveInputStream;
import eu.javaexperience.io.CloseSensitiveOutputStream;
import eu.javaexperience.reflect.FdMirror;
import eu.javaexperience.reflect.Mirror;
public class FDIOStreamFactory
{
public static FDIOStream fromSocket(final Socket s) throws IOException
{
return new CloseRegFDIO()
{
private FileDescriptor fd = FdMirror.getFileDescriptorFromSocket(s);
@Override
public OutputStream getOutputStream()
{
try
{
return s.getOutputStream();
}
catch (IOException e)
{
}
return null;
}
@Override
public InputStream getInputStream()
{
try
{
return s.getInputStream();
}
catch (IOException e)
{
}
return null;
}
@Override
public void close()
{
try
{
s.close();
}
catch (IOException e)
{}
}
@Override
public int getFD()
{
return FdMirror.getFD(fd);
}
private boolean closed = false;
@Override
public boolean isClosed()
{
return closed;
}
@Override
public void setClosed(boolean b)
{
closed = b;
}
@Override
public FileDescriptor getFileDescriptor()
{
return fd;
}
@Override
public void flush() throws IOException
{
s.getOutputStream().flush();
}
@Override
public String localAddress()
{
return s.getLocalAddress().toString();
}
@Override
public String remoteAddress()
{
return s.getRemoteSocketAddress().toString();
}
};
}
public static FDIOStream closeOnFinalize(final FDIOStream sock)
{
return new FDIOStream()
{
@Override
public boolean isClosed()
{
return sock.isClosed();
}
@Override
public OutputStream getOutputStream()
{
return sock.getOutputStream();
}
@Override
public InputStream getInputStream()
{
return sock.getInputStream();
}
@Override
public void close()
{
sock.close();
}
@Override
public int getFD()
{
return sock.getFD();
}
protected void finalize()
{
close();
}
@Override
public FileDescriptor getFileDescriptor()
{
return sock.getFileDescriptor();
}
@Override
public void flush() throws IOException
{
sock.flush();
}
@Override
public String localAddress()
{
return sock.localAddress();
}
@Override
public String remoteAddress()
{
return sock.remoteAddress();
}
};
}
public static interface CloseRegFDIO extends FDIOStream
{
public void setClosed(boolean b);
}
public static FDIOStream fromFD(final FileDescriptor _fd)
{
return fromFD(FdMirror.getFD(_fd));
}
public static FDIOStream fromFD(final int _fd)
{
return new FDIOStream()
{
private final int fd = _fd;
private final FileDescriptor ofd = new FileDescriptor();
{
FdMirror.setFd(ofd, _fd);
}
CloseSensitiveInputStream is = new CloseSensitiveInputStream( new FileInputStream(ofd));
CloseSensitiveOutputStream os = new CloseSensitiveOutputStream( new FileOutputStream(ofd));
@Override
public InputStream getInputStream()
{
return is;
}
@Override
public OutputStream getOutputStream()
{
return os;
}
@Override
public void close()
{
try{os.close();}catch(Exception e){}
try{is.close();}catch(Exception e){}
}
@Override
public int getFD()
{
return fd;
}
@Override
public boolean isClosed()
{
return is.isClosed() || os.isClosed();
}
@Override
public FileDescriptor getFileDescriptor()
{
return ofd;
}
@Override
public void flush() throws IOException
{
os.flush();
}
@Override
public String localAddress()
{
return String.valueOf(fd);
}
@Override
public String remoteAddress()
{
return String.valueOf(fd);
}
};
}
public static FDIOStreamServer fromServerSocket(final ServerSocket ss)
{
return new FDIOStreamServer()
{
@Override
public void close()
{
try
{
ss.close();
}
catch (IOException e)
{
}
}
@Override
public FDIOStream accept() throws IOException
{
try
{
return fromSocket(ss.accept());
}
catch(Exception e)
{
throw new IOException(e);
}
}
@Override
public int getFD()
{
return 0;
}
@Override
public FileDescriptor getFileDescriptor()
{
return null;
}
};
}
}