forked from I2P_Developers/i2p.i2p
Checking in MessageChannel, nothing to see here moving on...
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.channels.spi.AbstractSelectionKey;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class MessageChannel extends SelectableChannel implements ReadableByteChannel, WritableByteChannel {
|
||||
|
||||
final MessageInputStream in;
|
||||
final MessageOutputStream out;
|
||||
boolean _isRegistered = false;
|
||||
SelectionKey whichKey = null;
|
||||
SelectorProvider provider = null;
|
||||
Selector sel = null;
|
||||
Object lock = null;
|
||||
I2PSocket socket;
|
||||
|
||||
MessageChannel(I2PSocket socket) {
|
||||
try {
|
||||
this.socket = socket;
|
||||
in = (MessageInputStream) socket.getInputStream();
|
||||
out = (MessageOutputStream) socket.getOutputStream();
|
||||
in.setReadTimeout(0);
|
||||
out.setWriteTimeout(0);
|
||||
out.setBufferSize(0x1000);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MessageChannel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
// dunno what to do with this for now
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectorProvider provider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int validOps() {
|
||||
return SelectionKey.OP_READ | SelectionKey.OP_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistered() {
|
||||
return _isRegistered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey keyFor(Selector arg0) {
|
||||
return whichKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey register(final Selector sel, final int ops, Object lock) throws ClosedChannelException {
|
||||
this.sel = sel;
|
||||
this.provider = sel.provider();
|
||||
this.lock = lock;
|
||||
this._isRegistered = true;
|
||||
final MessageChannel that = this; // lol java
|
||||
SelectionKey key = new AbstractSelectionKey() {
|
||||
int operations = ops;
|
||||
@Override
|
||||
public SelectableChannel channel() {
|
||||
return that;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Selector selector() {
|
||||
return sel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int interestOps() {
|
||||
return this.operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey interestOps(int ops) {
|
||||
this.operations = ops;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readyOps() {
|
||||
int readyOps = 0;
|
||||
if((operations & OP_READ) != 0) {
|
||||
try {
|
||||
// check the input stream
|
||||
if (in.available() > 0) {
|
||||
readyOps |= OP_READ;
|
||||
}
|
||||
} catch (IOException ex) {}
|
||||
}
|
||||
if((operations & OP_WRITE) != 0) {
|
||||
if(!out.getClosed())
|
||||
readyOps |= OP_WRITE;
|
||||
}
|
||||
return readyOps;
|
||||
}
|
||||
};
|
||||
key.attach(lock);
|
||||
// I... THINK this is right?
|
||||
sel.keys().add(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectableChannel configureBlocking(boolean blocking) throws IOException {
|
||||
if (blocking == false) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object blockingLock() {
|
||||
return this.lock;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implCloseChannel() throws IOException {
|
||||
this.socket.close();
|
||||
}
|
||||
|
||||
/* Read no more than buf.remaining()
|
||||
* Continue to read until that, or in.read
|
||||
* returns 0, which happens when there's
|
||||
* no more data available.
|
||||
*/
|
||||
|
||||
public int read(ByteBuffer buf) throws IOException {
|
||||
int amount = 0;
|
||||
for (;;) {
|
||||
byte[] lbuf = new byte[buf.remaining()];
|
||||
int samount = in.read(lbuf);
|
||||
if (samount <= 0) {
|
||||
this.close();
|
||||
}
|
||||
if (samount == 0) {
|
||||
break;
|
||||
}
|
||||
amount += samount;
|
||||
buf.put(lbuf, 0, samount);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
/* Write in 0x1000 increments, the MessageOutputStream's
|
||||
* already set buffer size. Once it starts to fail
|
||||
* (wait timeout is 0) then put the bytes back and return.
|
||||
*/
|
||||
|
||||
public int write(ByteBuffer buf) throws IOException {
|
||||
int written = 0;
|
||||
for (;;) {
|
||||
if(buf.remaining()==0)
|
||||
return written;
|
||||
byte[] lbuf = new byte[Math.min(buf.remaining(), 0x1000)];
|
||||
buf.get(lbuf);
|
||||
try {
|
||||
out.write(lbuf, 0, lbuf.length);
|
||||
written += lbuf.length;
|
||||
} catch(InterruptedIOException ex) {
|
||||
buf.put(lbuf);
|
||||
return written;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user