Skip to content

Commit

Permalink
Avoid creating a Fixnum for the direct write
Browse files Browse the repository at this point in the history
None of the consumers use the return value, and this path is
intended to simulate OutputStream.write, which does not return the
number of bytes written, so skip the creation or retrieval of a
Fixnum and just return the int.
  • Loading branch information
headius committed Mar 2, 2021
1 parent b2b1e7b commit 241347d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
25 changes: 19 additions & 6 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,19 @@ public final IRubyObject write(ThreadContext context, int ch) {
return write(context, str, false);
}

/**
* Write a single byte to this IO's write target but do not return the number of bytes written (it will be 1).
*
* This version does not dig out any wrapped write IO (bytes will be written to this IO).
*
* @param context the current context
* @param ch the byte to write, as an int
*/
public final void write(ThreadContext context, byte ch) {
ByteList bytes = RubyInteger.singleCharByteList(ch);

write(context, bytes.unsafeBytes(), bytes.begin(), bytes.realSize(), bytes.getEncoding(), false);
}

/**
* Write the given range of bytes to this IO's write target.
Expand Down Expand Up @@ -1510,7 +1523,7 @@ public IRubyObject write(ThreadContext context, IRubyObject str, boolean nosync)
* Write the given range of bytes to this IO.
*
* Equivalent to io_write_m with source bytes and no digging out any wrapped write IO (bytes will be written to this
* IO.
* IO).
*
* @param context the current context
* @param bytes the bytes to write
Expand All @@ -1519,7 +1532,7 @@ public IRubyObject write(ThreadContext context, IRubyObject str, boolean nosync)
* @param encoding encoding of the bytes (will not be verified)
* @return the count of bytes written
*/
public IRubyObject write(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding) {
public int write(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding) {
return write(context, bytes, start, length, encoding, false);
}

Expand All @@ -1537,12 +1550,12 @@ public IRubyObject write(ThreadContext context, byte[] bytes, int start, int le
* @param nosync whether to write without syncing
* @return the count of bytes written
*/
public IRubyObject write(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding, boolean nosync) {
public int write(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding, boolean nosync) {
Ruby runtime = context.runtime;
OpenFile fptr;
long n;
int n;

if (length == 0) return RubyFixnum.zero(runtime);
if (length == 0) return 0;

fptr = getOpenFileChecked();

Expand All @@ -1557,7 +1570,7 @@ public IRubyObject write(ThreadContext context, byte[] bytes, int start, int len
if (locked) fptr.unlock();
}

return RubyFixnum.newFixnum(runtime, n);
return n;
}

/** rb_io_addstr
Expand Down
21 changes: 13 additions & 8 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -2092,11 +2092,11 @@ public long fwrite(ThreadContext context, RubyString str, boolean nosync) {

str = doWriteconv(context, str);
ByteList strByteList = str.getByteList();
return binwrite(context, strByteList.unsafeBytes(), strByteList.begin(), strByteList.length(), nosync);
return binwriteInt(context, strByteList.unsafeBytes(), strByteList.begin(), strByteList.length(), nosync);
}

// MRI: io_fwrite
public long fwrite(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding, boolean nosync) {
// MRI: io_fwrite with source bytes
public int fwrite(ThreadContext context, byte[] bytes, int start, int length, Encoding encoding, boolean nosync) {
// The System.console null check is our poor-man's isatty for Windows. See jruby/jruby#3292
if (Platform.IS_WINDOWS && isStdio() && System.console() != null) {
return rbW32WriteConsole(bytes, start, length, encoding);
Expand All @@ -2110,7 +2110,7 @@ public long fwrite(ThreadContext context, byte[] bytes, int start, int length, E
length = str.realSize();
}

return binwrite(context, bytes, start, length, nosync);
return binwriteInt(context, bytes, start, length, nosync);
}

// MRI: rb_w32_write_console
Expand All @@ -2120,7 +2120,7 @@ public static long rbW32WriteConsole(RubyString buffer) {
}

// MRI: rb_w32_write_console
public static long rbW32WriteConsole(byte[] bytes, int start, int length, Encoding encoding) {
public static int rbW32WriteConsole(byte[] bytes, int start, int length, Encoding encoding) {
// The actual port in MRI uses win32 APIs, but System.console seems to do what we want. See jruby/jruby#3292.
// FIXME: This assumes the System.console() is the right one to write to. Can you have multiple active?
System.console().printf("%s", RubyEncoding.decode(bytes, start, length, encoding.getCharset()));
Expand Down Expand Up @@ -2244,7 +2244,7 @@ private static class BinwriteArg {
}

// io_binwrite
public long binwrite(ThreadContext context, byte[] ptrBytes, int ptr, int len, boolean nosync) {
public int binwriteInt(ThreadContext context, byte[] ptrBytes, int ptr, int len, boolean nosync) {
int n, r, offset = 0;

/* don't write anything if current thread has a pending interrupt. */
Expand Down Expand Up @@ -2279,7 +2279,7 @@ public long binwrite(ThreadContext context, byte[] ptrBytes, int ptr, int len, b
n = 0;
}

if (io_fflush(context) < 0) return -1L;
if (io_fflush(context) < 0) return -1;
if (n == 0) return len;

checkClosed();
Expand Down Expand Up @@ -2314,7 +2314,7 @@ public long binwrite(ThreadContext context, byte[] ptrBytes, int ptr, int len, b
if (offset < len)
continue retry;
}
return -1L;
return -1;
}
}

Expand Down Expand Up @@ -2835,4 +2835,9 @@ public void unlock() {
public boolean lockedByMe() {
return lock.isHeldByCurrentThread();
}

@Deprecated
public long binwrite(ThreadContext context, byte[] ptrBytes, int ptr, int len, boolean nosync) {
return binwriteInt(context, ptrBytes, ptr, len, nosync);
}
}

0 comments on commit 241347d

Please sign in to comment.