File: //usr/local/rvm/gems/ruby-2.5.9/gems/nio4r-2.5.8/ext/nio4r/org/nio4r/Nio4r.java
package org.nio4r;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.load.Library;
import org.jruby.runtime.builtin.IRubyObject;
import org.nio4r.ByteBuffer;
import org.nio4r.Monitor;
import org.nio4r.Selector;
public class Nio4r implements Library {
private Ruby ruby;
public void load(final Ruby ruby, boolean bln) {
this.ruby = ruby;
RubyModule nio = ruby.defineModule("NIO");
RubyClass selector = ruby.defineClassUnder("Selector", ruby.getObject(), new ObjectAllocator() {
public IRubyObject allocate(Ruby ruby, RubyClass rc) {
return new Selector(ruby, rc);
}
}, nio);
selector.defineAnnotatedMethods(Selector.class);
RubyClass monitor = ruby.defineClassUnder("Monitor", ruby.getObject(), new ObjectAllocator() {
public IRubyObject allocate(Ruby ruby, RubyClass rc) {
return new Monitor(ruby, rc);
}
}, nio);
monitor.defineAnnotatedMethods(Monitor.class);
RubyClass byteBuffer = ruby.defineClassUnder("ByteBuffer", ruby.getObject(), new ObjectAllocator() {
public IRubyObject allocate(Ruby ruby, RubyClass rc) {
return new ByteBuffer(ruby, rc);
}
}, nio);
byteBuffer.defineAnnotatedMethods(ByteBuffer.class);
byteBuffer.includeModule(ruby.getEnumerable());
ruby.defineClassUnder("OverflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
ruby.defineClassUnder("UnderflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
ruby.defineClassUnder("MarkUnsetError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer);
}
public static int symbolToInterestOps(Ruby ruby, SelectableChannel channel, IRubyObject interest) {
if(interest == ruby.newSymbol("r")) {
if((channel.validOps() & SelectionKey.OP_ACCEPT) != 0) {
return SelectionKey.OP_ACCEPT;
} else {
return SelectionKey.OP_READ;
}
} else if(interest == ruby.newSymbol("w")) {
if(channel instanceof SocketChannel && !((SocketChannel)channel).isConnected()) {
return SelectionKey.OP_CONNECT;
} else {
return SelectionKey.OP_WRITE;
}
} else if(interest == ruby.newSymbol("rw")) {
int interestOps = 0;
/* nio4r emulates the POSIX behavior, which is sloppy about allowed modes */
if((channel.validOps() & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0) {
interestOps |= symbolToInterestOps(ruby, channel, ruby.newSymbol("r"));
}
if((channel.validOps() & (SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT)) != 0) {
interestOps |= symbolToInterestOps(ruby, channel, ruby.newSymbol("w"));
}
return interestOps;
} else {
throw ruby.newArgumentError("invalid interest type: " + interest);
}
}
public static IRubyObject interestOpsToSymbol(Ruby ruby, int interestOps) {
switch(interestOps) {
case SelectionKey.OP_READ:
case SelectionKey.OP_ACCEPT:
return ruby.newSymbol("r");
case SelectionKey.OP_WRITE:
case SelectionKey.OP_CONNECT:
return ruby.newSymbol("w");
case SelectionKey.OP_READ | SelectionKey.OP_CONNECT:
case SelectionKey.OP_READ | SelectionKey.OP_WRITE:
return ruby.newSymbol("rw");
case 0:
return ruby.getNil();
default:
throw ruby.newArgumentError("unknown interest op combination");
}
}
}