Skip to content

Commit

Permalink
Some conversion of obvious FileChannel which can be made into more sp…
Browse files Browse the repository at this point in the history
…ecific Channel interfaces
enebo committed Dec 9, 2016

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent d26784d commit 125315f
Showing 2 changed files with 29 additions and 30 deletions.
26 changes: 13 additions & 13 deletions core/src/main/java/org/jruby/util/io/ChannelDescriptor.java
Original file line number Diff line number Diff line change
@@ -36,8 +36,8 @@
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Collections;
import java.util.HashMap;
@@ -164,7 +164,7 @@ private ChannelDescriptor(Channel channel, int fileno, ModeFlags originalModes,

this.readableChannel = channel instanceof ReadableByteChannel;
this.writableChannel = channel instanceof WritableByteChannel;
this.seekableChannel = channel instanceof FileChannel;
this.seekableChannel = channel instanceof SeekableByteChannel;

registerDescriptor(this);
}
@@ -328,7 +328,7 @@ public Channel getChannel() {

/**
* Whether the channel associated with this descriptor is seekable (i.e.
* whether it is instanceof FileChannel).
* whether it is instanceof SeekableByteChannel).
*
* @return true if the associated channel is seekable, false otherwise
*/
@@ -338,7 +338,7 @@ public boolean isSeekable() {

/**
* Set the channel to be explicitly seekable or not, for streams that appear
* to be seekable with the instanceof FileChannel check.
* to be seekable with the instanceof SeekableByteChannel check.
*
* @param canBeSeekable Whether the channel is seekable or not.
*/
@@ -490,7 +490,7 @@ public ChannelDescriptor reopen(RandomAccessFile file, ModeFlags modes) throws I

/**
* Perform a low-level seek operation on the associated channel if it is
* instanceof FileChannel, or raise PipeException if it is not a FileChannel.
* instanceof SeekableByteChannel, or raise PipeException if it is not a SeekableByteChannel.
* Calls checkOpen to confirm the target channel is open. This is equivalent
* to the lseek(2) POSIX function, and like that function it bypasses any
* buffer flushing or invalidation as in ChannelStream.fseek.
@@ -503,27 +503,27 @@ public ChannelDescriptor reopen(RandomAccessFile file, ModeFlags modes) throws I
* @throws org.jruby.util.io.PipeException If the target channel is not seekable
* @throws org.jruby.util.io.BadDescriptorException If the target channel is
* already closed.
* @return the new offset into the FileChannel.
* @return the new offset into the SeekableByteChannel.
*/
public long lseek(long offset, int whence) throws IOException, InvalidValueException, PipeException, BadDescriptorException {
if (seekableChannel) {
checkOpen();

FileChannel fileChannel = (FileChannel)channel;
SeekableByteChannel channel = (SeekableByteChannel) this.channel;
try {
long pos;
switch (whence) {
case PosixShim.SEEK_SET:
pos = offset;
fileChannel.position(pos);
channel.position(pos);
break;
case PosixShim.SEEK_CUR:
pos = fileChannel.position() + offset;
fileChannel.position(pos);
pos = channel.position() + offset;
channel.position(pos);
break;
case PosixShim.SEEK_END:
pos = fileChannel.size() + offset;
fileChannel.position(pos);
pos = channel.size() + offset;
channel.position(pos);
break;
default:
throw new InvalidValueException();
@@ -619,7 +619,7 @@ public int internalWrite(ByteBuffer buffer) throws IOException, BadDescriptorExc
if (isSeekable() && originalModes.isAppendable()) {
// if already in append mode, we don't do our own seeking
if (!isInAppendMode) {
FileChannel fileChannel = (FileChannel)channel;
SeekableByteChannel fileChannel = (SeekableByteChannel) channel;
fileChannel.position(fileChannel.size());
}
}
33 changes: 16 additions & 17 deletions core/src/main/java/org/jruby/util/io/ChannelStream.java
Original file line number Diff line number Diff line change
@@ -42,11 +42,10 @@
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.channels.SelectableChannel;
import java.util.LinkedList;

import org.jruby.Finalizable;
import org.jruby.Ruby;
@@ -407,16 +406,16 @@ private void clearUngotChars() {
*/
@Deprecated
public synchronized ByteList readall() throws IOException, BadDescriptorException {
final long fileSize = descriptor.isSeekable() && descriptor.getChannel() instanceof FileChannel
? ((FileChannel) descriptor.getChannel()).size() : 0;
final long fileSize = descriptor.isSeekable() && descriptor.getChannel() instanceof SeekableByteChannel
? ((SeekableByteChannel) descriptor.getChannel()).size() : 0;
//
// Check file size - special files in /proc have zero size and need to be
// handled by the generic read path.
//
if (fileSize > 0) {
ensureRead();

FileChannel channel = (FileChannel)descriptor.getChannel();
SeekableByteChannel channel = (SeekableByteChannel) descriptor.getChannel();
final long left = fileSize - channel.position() + bufferedInputBytesRemaining();
if (left <= 0) {
eof = true;
@@ -772,7 +771,7 @@ public boolean feof() throws IOException, BadDescriptorException {
public synchronized long fgetpos() throws IOException, PipeException, InvalidValueException, BadDescriptorException {
// Correct position for read / write buffering (we could invalidate, but expensive)
if (descriptor.isSeekable()) {
FileChannel fileChannel = (FileChannel)descriptor.getChannel();
SeekableByteChannel fileChannel = (SeekableByteChannel) descriptor.getChannel();
long pos = fileChannel.position();
// Adjust for buffered data
if (reading) {
@@ -798,7 +797,7 @@ public synchronized long fgetpos() throws IOException, PipeException, InvalidVal
*/
public synchronized void lseek(long offset, int type) throws IOException, InvalidValueException, PipeException, BadDescriptorException {
if (descriptor.isSeekable()) {
FileChannel fileChannel = (FileChannel)descriptor.getChannel();
SeekableByteChannel fileChannel = (SeekableByteChannel) descriptor.getChannel();
clearUngotChars();
int adj = 0;
if (reading) {
@@ -876,7 +875,7 @@ private void ensureReadNonBuffered() throws IOException, BadDescriptorException

private void resetForWrite() throws IOException {
if (descriptor.isSeekable()) {
FileChannel fileChannel = (FileChannel)descriptor.getChannel();
SeekableByteChannel fileChannel = (SeekableByteChannel) descriptor.getChannel();
if (buffer.hasRemaining()) { // we have read ahead, and need to back up
fileChannel.position(fileChannel.position() - buffer.remaining());
}
@@ -919,12 +918,12 @@ private ByteList bufferedRead(int number) throws IOException, BadDescriptorExcep

// 128K seems to be the minimum at which the stat+seek is faster than reallocation
final int BULK_THRESHOLD = 128 * 1024;
if (number >= BULK_THRESHOLD && descriptor.isSeekable() && descriptor.getChannel() instanceof FileChannel) {
if (number >= BULK_THRESHOLD && descriptor.isSeekable() && descriptor.getChannel() instanceof SeekableByteChannel) {
//
// If it is a file channel, then we can pre-allocate the output buffer
// to the total size of buffered + remaining bytes in file
//
FileChannel fileChannel = (FileChannel) descriptor.getChannel();
SeekableByteChannel fileChannel = (SeekableByteChannel) descriptor.getChannel();
resultSize = (int) Math.min(fileChannel.size() - fileChannel.position() + bufferedInputBytesRemaining(), number);
} else {
//
@@ -1166,11 +1165,11 @@ private int bufferedWrite(int c) throws IOException, BadDescriptorException {
public synchronized void ftruncate(long newLength) throws IOException,
BadDescriptorException, InvalidValueException {
Channel ch = descriptor.getChannel();
if (!(ch instanceof FileChannel)) {
if (!(ch instanceof SeekableByteChannel)) {
throw new InvalidValueException();
}
invalidateBuffer();
FileChannel fileChannel = (FileChannel)ch;
SeekableByteChannel fileChannel = (SeekableByteChannel) ch;
long position = fileChannel.position();
if (newLength > fileChannel.size()) {
// truncate can't lengthen files, so we save position, seek/write, and go back
@@ -1197,7 +1196,7 @@ private void invalidateBuffer() throws IOException, BadDescriptorException {
if (reading) {
buffer.flip();
// if the read buffer is ahead, back up
FileChannel fileChannel = (FileChannel)descriptor.getChannel();
SeekableByteChannel fileChannel = (SeekableByteChannel) descriptor.getChannel();
if (posOverrun != 0) fileChannel.position(fileChannel.position() - posOverrun);
}
}
@@ -1359,7 +1358,7 @@ public synchronized ByteList readnonblock(int number) throws IOException, BadDes
selectableChannel.configureBlocking(oldBlocking);
}
}
} else if (descriptor.getChannel() instanceof FileChannel) {
} else if (descriptor.getChannel() instanceof SeekableByteChannel) {
return fread(number);
} else {
return null;
@@ -1372,7 +1371,7 @@ public synchronized ByteList readpartial(int number) throws IOException, BadDesc
if (number == 0) {
return null;
}
if (descriptor.getChannel() instanceof FileChannel) {
if (descriptor.getChannel() instanceof SeekableByteChannel) {
return fread(number);
}

@@ -1386,7 +1385,7 @@ public synchronized ByteList readpartial(int number) throws IOException, BadDesc
}

public synchronized int read(ByteBuffer dst) throws IOException, BadDescriptorException, EOFException {
return read(dst, !(descriptor.getChannel() instanceof FileChannel));
return read(dst, !(descriptor.getChannel() instanceof SeekableByteChannel));
}

public synchronized int read(ByteBuffer dst, boolean partial) throws IOException, BadDescriptorException, EOFException {
@@ -1508,7 +1507,7 @@ public static Stream fdopen(Ruby runtime, ChannelDescriptor descriptor, ModeFlag

private static Stream maybeWrapWithLineEndingWrapper(Stream stream, ModeFlags modes) {
if (modes.isText() || // FIXME: Remove this one textmode is part of transcoding.
(Platform.IS_WINDOWS && stream.getDescriptor().getChannel() instanceof FileChannel && !modes.isBinary())) {
(Platform.IS_WINDOWS && stream.getDescriptor().getChannel() instanceof SeekableByteChannel && !modes.isBinary())) {
return new CRLFStreamWrapper(stream);
}
return stream;

0 comments on commit 125315f

Please sign in to comment.