diff --git a/core/src/main/java/org/jruby/util/IOOutputStream.java b/core/src/main/java/org/jruby/util/IOOutputStream.java index b9805280c6f..dd1507eb4a9 100644 --- a/core/src/main/java/org/jruby/util/IOOutputStream.java +++ b/core/src/main/java/org/jruby/util/IOOutputStream.java @@ -36,6 +36,7 @@ import org.jruby.RubyIO; import org.jruby.RubyString; import org.jruby.runtime.CallSite; +import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.MethodIndex; @@ -52,7 +53,8 @@ */ public class IOOutputStream extends OutputStream { private final IRubyObject io; - private final OutputStream out; + private final RubyIO realIO; + private final Ruby runtime; private final CallSite writeAdapter; private final CallSite closeAdapter = MethodIndex.getFunctionalCallSite("close"); private final Encoding encoding; @@ -64,10 +66,11 @@ public class IOOutputStream extends OutputStream { */ public IOOutputStream(final IRubyObject io, Encoding encoding, boolean checkAppend, boolean verifyCanWrite) { this.io = io; - this.out = ( io instanceof RubyIO && !((RubyIO) io).isClosed() && + this.runtime = io.getRuntime(); + this.realIO = ( io instanceof RubyIO && !((RubyIO) io).isClosed() && ((RubyIO) io).isBuiltin("write") ) ? - ((RubyIO) io).getOutStream() : null; - if (out == null || verifyCanWrite) { + ((RubyIO) io) : null; + if (realIO == null || verifyCanWrite) { final String site; if (io.respondsTo("write")) { site = "write"; @@ -106,12 +109,16 @@ public IOOutputStream(final IRubyObject io, Encoding encoding) { @Override public void write(final int bite) throws IOException { - if (out != null) { - out.write(bite); + ThreadContext context = runtime.getCurrentContext(); + + RubyString str = RubyString.newStringLight(runtime, new ByteList(new byte[]{(byte) bite}, encoding, false)); + + RubyIO realIO = this.realIO; + if (realIO != null) { + realIO.write(context, str); } else { - final Ruby runtime = io.getRuntime(); - writeAdapter.call(runtime.getCurrentContext(), io, io, - RubyString.newStringLight(runtime, new ByteList(new byte[] { (byte) bite }, encoding, false))); + IRubyObject io = this.io; + writeAdapter.call(context, io, io, str); } } @@ -122,21 +129,31 @@ public void write(final byte[] b) throws IOException { @Override public void write(final byte[] b,final int off, final int len) throws IOException { - if (out != null) { - out.write(b, off, len); + ThreadContext context = runtime.getCurrentContext(); + + RubyString str = RubyString.newStringLight(runtime, new ByteList(b, off, len, encoding, false)); + + RubyIO realIO = this.realIO; + if (realIO != null) { + realIO.write(context, str); } else { - final Ruby runtime = io.getRuntime(); - writeAdapter.call(runtime.getCurrentContext(), io, io, - RubyString.newStringLight(runtime, new ByteList(b, off, len, encoding, false))); + IRubyObject io = this.io; + writeAdapter.call(context, io, io, str); } } @Override public void close() throws IOException { - if (out != null) { - out.close(); - } else if (io.respondsTo("close")) { - closeAdapter.call(io.getRuntime().getCurrentContext(), io, io); + ThreadContext context = runtime.getCurrentContext(); + + RubyIO realIO = this.realIO; + if (realIO != null) { + realIO.close(context); + } else { + IRubyObject io = this.io; + if (io.respondsTo("close")) { + closeAdapter.call(context, io, io); + } } } }