@Override public int read(byte[] bytes, int off, int len) throws IOException { if (bytes == null) { throw new NullPointerException("null destination buffer"); } if ((len | off | (off + len) | (bytes.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } if (len == 0) { return 0; } try { synchronized (stream) { final int available = stream.bufferedInputBytesRemaining(); if (available >= len) { return stream.copyBufferedBytes(bytes, off, len); } else if (stream.getDescriptor().getChannel() instanceof SelectableChannel) { SelectableChannel ch = (SelectableChannel) stream.getDescriptor().getChannel(); synchronized (ch.blockingLock()) { boolean oldBlocking = ch.isBlocking(); try { if (!oldBlocking) { ch.configureBlocking(true); } return stream.bufferedRead(ByteBuffer.wrap(bytes, off, len), true); } finally { if (!oldBlocking) { ch.configureBlocking(oldBlocking); } } } } else { return stream.bufferedRead(ByteBuffer.wrap(bytes, off, len), true); } } } catch (BadDescriptorException ex) { throw new IOException(ex.getMessage()); } catch (EOFException ex) { return -1; } }
@Override public void write(byte[] bytes, int off, int len) throws IOException { if (bytes == null) { throw new NullPointerException("null source buffer"); } if ((len | off | (off + len) | (bytes.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } try { synchronized (stream) { if (!stream.isSync() && stream.bufferedOutputSpaceRemaining() >= len) { stream.buffer.put(bytes, off, len); } else if (stream.getDescriptor().getChannel() instanceof SelectableChannel) { SelectableChannel ch = (SelectableChannel) stream.getDescriptor().getChannel(); synchronized (ch.blockingLock()) { boolean oldBlocking = ch.isBlocking(); try { if (!oldBlocking) { ch.configureBlocking(true); } stream.bufferedWrite(ByteBuffer.wrap(bytes, off, len)); } finally { if (!oldBlocking) { ch.configureBlocking(oldBlocking); } } } } else { stream.bufferedWrite(ByteBuffer.wrap(bytes, off, len)); } } } catch (BadDescriptorException ex) { throw new IOException(ex.getMessage()); } }
@JRubyMethod(required = 1, visibility = Visibility.PRIVATE) public static IRubyObject initialize(IRubyObject recv, IRubyObject io) { try { if (io instanceof RubyIO) { RubyIO rubyIO = (RubyIO) io; OpenFile of = rubyIO.getOpenFile(); Stream stream = of.getMainStreamSafe(); if (stream instanceof ChannelStream) { ChannelStream cStream = (ChannelStream) stream; if (cStream.getDescriptor().getChannel() instanceof SelectableChannel) { SelectableChannel selChannel = (SelectableChannel) cStream.getDescriptor().getChannel(); ((RubyObject) recv) .extend( new IRubyObject[] { ((RubyModule) recv.getRuntime().getModule("Net").getConstant("BufferedIO")) .getConstant("NativeImplementation") }); SelectableChannel sc = (SelectableChannel) (selChannel); recv.dataWrapStruct(new NativeImpl(sc)); } } } recv.getInstanceVariables().setInstanceVariable("@io", io); recv.getInstanceVariables() .setInstanceVariable("@read_timeout", recv.getRuntime().newFixnum(60)); recv.getInstanceVariables().setInstanceVariable("@debug_output", recv.getRuntime().getNil()); recv.getInstanceVariables() .setInstanceVariable("@rbuf", RubyString.newEmptyString(recv.getRuntime())); return recv; } catch (BadDescriptorException e) { throw recv.getRuntime().newErrnoEBADFError(); } }