@Override public void write(int i) throws IOException { synchronized (stream) { if (!stream.isSync() && stream.hasBufferedOutputSpace()) { stream.buffer.put((byte) i); return; } } byte[] b = {(byte) i}; write(b, 0, 1); }
protected void initSocket(Ruby runtime, ChannelDescriptor descriptor) { // continue with normal initialization openFile = new OpenFile(); try { openFile.setMainStream( ChannelStream.fdopen(runtime, descriptor, new ModeFlags(ModeFlags.RDONLY))); openFile.setPipeStream( ChannelStream.fdopen(runtime, descriptor, new ModeFlags(ModeFlags.WRONLY))); openFile.getPipeStream().setSync(true); } catch (org.jruby.util.io.InvalidValueException ex) { throw runtime.newErrnoEINVALError(); } openFile.setMode(OpenFile.READWRITE | OpenFile.SYNC); }
@Override public int read() throws IOException { synchronized (stream) { // If it can be pulled direct from the buffer, don't go via the slow path if (stream.hasBufferedInputBytes()) { try { return stream.read(); } catch (BadDescriptorException ex) { throw new IOException(ex.getMessage()); } } } byte[] b = new byte[1]; // java.io.InputStream#read must return an unsigned value; return read(b, 0, 1) == 1 ? b[0] & 0xff : -1; }
@Override public void flush() throws IOException { try { synchronized (stream) { stream.flushWrite(true); } } catch (BadDescriptorException ex) { throw new IOException(ex.getMessage()); } }
@Override public void close() throws IOException { try { synchronized (stream) { stream.fclose(); } } catch (BadDescriptorException ex) { throw new IOException(ex.getMessage()); } }
protected void initSocket(Ruby runtime, ChannelDescriptor descriptor) { // continue with normal initialization MakeOpenFile(); try { openFile.setMainStream( ChannelStream.fdopen(runtime, descriptor, newModeFlags(runtime, ModeFlags.RDONLY))); openFile.setPipeStream( ChannelStream.fdopen(runtime, descriptor, newModeFlags(runtime, ModeFlags.WRONLY))); openFile.getPipeStream().setSync(true); } catch (org.jruby.util.io.InvalidValueException ex) { throw runtime.newErrnoEINVALError(); } openFile.setMode(OpenFile.READWRITE | OpenFile.SYNC); // see rsock_init_sock in MRI; sockets are initialized to binary setAscii8bitBinmode(); }
@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(); } }
@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()); } }
@Override public int available() throws IOException { synchronized (stream) { return !stream.eof ? stream.bufferedInputBytesRemaining() : 0; } }