org.jruby.util.io
Class ChannelDescriptor

java.lang.Object
  extended by org.jruby.util.io.ChannelDescriptor

public class ChannelDescriptor
extends java.lang.Object

ChannelDescriptor provides an abstraction similar to the concept of a "file descriptor" on any POSIX system. In our case, it's a numbered object (fileno) enclosing a Channel (@see java.nio.channels.Channel), FileDescriptor (@see java.io.FileDescriptor), and flags under which the original open occured (@see org.jruby.util.io.ModeFlags). Several operations you would normally expect to use with a POSIX file descriptor are implemented here and used by higher-level classes to implement higher-level IO behavior. Note that the channel specified when constructing a ChannelDescriptor will be reference-counted; that is, until all known references to it through this class have gone away, it will be left open. This is to support operations like "dup" which must produce two independent ChannelDescriptor instances that can be closed separately without affecting the other. At present there's no way to simulate the behavior on some platforms where POSIX dup also allows independent positioning information.


Constructor Summary
ChannelDescriptor(java.nio.channels.Channel channel, int fileno, java.io.FileDescriptor fileDescriptor)
          Construct a new ChannelDescriptor with the given channel, file number, and file descriptor object.
ChannelDescriptor(java.nio.channels.Channel channel, int fileno, ModeFlags originalModes, java.io.FileDescriptor fileDescriptor)
          Construct a new ChannelDescriptor with the given channel, file number, mode flags, and file descriptor object.
ChannelDescriptor(java.io.InputStream baseInputStream, int fileno, ModeFlags originalModes, java.io.FileDescriptor fileDescriptor)
          Special constructor to create the ChannelDescriptor out of the stream, file number, mode flags, and file descriptor object.
 
Method Summary
 void checkNewModes(ModeFlags newModes)
          Check whether a specified set of mode flags is a superset of this descriptor's original set of mode flags.
 void checkOpen()
          Check whether the isOpen returns true, raising a BadDescriptorException if it returns false.
 void close()
          Close this descriptor.
 ChannelDescriptor dup()
          Mimics the POSIX dup(2) function, returning a new descriptor that references the same open channel.
 ChannelDescriptor dup2(int fileno)
          Mimics the POSIX dup2(2) function, returning a new descriptor that references the same open channel but with a specified fileno.
 void dup2Into(ChannelDescriptor other)
          Mimics the POSIX dup2(2) function, returning a new descriptor that references the same open channel but with a specified fileno.
 java.nio.channels.Channel getChannel()
          The channel associated with this descriptor.
 java.io.FileDescriptor getFileDescriptor()
          Get the FileDescriptor object associated with this descriptor.
 int getFileno()
          Get this descriptor's file number.
 ModeFlags getOriginalModes()
          Get the original mode flags for the descriptor.
 int internalWrite(java.nio.ByteBuffer buffer)
          Write the bytes in the specified byte list to the associated channel.
 boolean isNull()
          Whether the channel associated with this descriptor is a NullChannel, for which many operations are simply noops.
 boolean isOpen()
          Whether the channel associated with this descriptor is open.
 boolean isSeekable()
          Whether the channel associated with this descriptor is seekable (i.e.
 boolean isWritable()
          Whether the channel associated with this descriptor is writable (i.e.
 long lseek(long offset, int whence)
          Perform a low-level seek operation on the associated channel if it is instanceof FileChannel, or raise PipeException if it is not a FileChannel.
static ChannelDescriptor open(java.lang.String cwd, java.lang.String path, ModeFlags flags)
          Open a new descriptor using the given working directory, file path, mode flags, and file permission.
static ChannelDescriptor open(java.lang.String cwd, java.lang.String path, ModeFlags flags, int perm, org.jruby.ext.posix.POSIX posix)
          Open a new descriptor using the given working directory, file path, mode flags, and file permission.
 int read(java.nio.ByteBuffer buffer)
          Perform a low-level read of the remaining number of bytes into the specified byte buffer.
 int read(int number, org.jruby.util.ByteList byteList)
          Perform a low-level read of the specified number of bytes into the specified byte list.
 void setCanBeSeekable(boolean canBeSeekable)
          Set the channel to be explicitly seekable or not, for streams that appear to be seekable with the instanceof FileChannel check.
 int write(java.nio.ByteBuffer buffer)
          Write the bytes in the specified byte list to the associated channel.
 int write(org.jruby.util.ByteList buf)
          Write the bytes in the specified byte list to the associated channel.
 int write(org.jruby.util.ByteList buf, int offset, int len)
          Write the bytes in the specified byte list to the associated channel.
 int write(int c)
          Write the byte represented by the specified int to the associated channel.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ChannelDescriptor

public ChannelDescriptor(java.nio.channels.Channel channel,
                         int fileno,
                         ModeFlags originalModes,
                         java.io.FileDescriptor fileDescriptor)
Construct a new ChannelDescriptor with the given channel, file number, mode flags, and file descriptor object. The channel will be kept open until all ChannelDescriptor references to it have been closed.

Parameters:
channel - The channel for the new descriptor
fileno - The file number for the new descriptor
originalModes - The mode flags for the new descriptor
fileDescriptor - The java.io.FileDescriptor object for the new descriptor

ChannelDescriptor

public ChannelDescriptor(java.io.InputStream baseInputStream,
                         int fileno,
                         ModeFlags originalModes,
                         java.io.FileDescriptor fileDescriptor)
Special constructor to create the ChannelDescriptor out of the stream, file number, mode flags, and file descriptor object. The channel will be created from the provided stream. The channel will be kept open until all ChannelDescriptor references to it have been closed. Note: in most cases, you should not use this constructor, it's reserved mostly for STDIN.

Parameters:
baseInputStream - The stream to create the channel for the new descriptor
fileno - The file number for the new descriptor
originalModes - The mode flags for the new descriptor
fileDescriptor - The java.io.FileDescriptor object for the new descriptor

ChannelDescriptor

public ChannelDescriptor(java.nio.channels.Channel channel,
                         int fileno,
                         java.io.FileDescriptor fileDescriptor)
                  throws InvalidValueException
Construct a new ChannelDescriptor with the given channel, file number, and file descriptor object. The channel will be kept open until all ChannelDescriptor references to it have been closed. The channel's capabilities will be used to determine the "original" set of mode flags.

Parameters:
channel - The channel for the new descriptor
fileno - The file number for the new descriptor
fileDescriptor - The java.io.FileDescriptor object for the new descriptor
Throws:
InvalidValueException
Method Detail

getFileno

public int getFileno()
Get this descriptor's file number.

Returns:
the fileno for this descriptor

getFileDescriptor

public java.io.FileDescriptor getFileDescriptor()
Get the FileDescriptor object associated with this descriptor. This is not guaranteed to be a "valid" descriptor in the terms of the Java implementation, but is provided for completeness and for cases where it is possible to get a valid FileDescriptor for a given channel.

Returns:
the java.io.FileDescriptor object associated with this descriptor

getChannel

public java.nio.channels.Channel getChannel()
The channel associated with this descriptor. The channel will be reference counted through ChannelDescriptor and kept open until all ChannelDescriptor objects have been closed. References that leave ChannelDescriptor through this method will not be counted.

Returns:
the java.nio.channels.Channel associated with this descriptor

isSeekable

public boolean isSeekable()
Whether the channel associated with this descriptor is seekable (i.e. whether it is instanceof FileChannel).

Returns:
true if the associated channel is seekable, false otherwise

setCanBeSeekable

public void setCanBeSeekable(boolean canBeSeekable)
Set the channel to be explicitly seekable or not, for streams that appear to be seekable with the instanceof FileChannel check.

Parameters:
seekable - Whether the channel is seekable or not.

isNull

public boolean isNull()
Whether the channel associated with this descriptor is a NullChannel, for which many operations are simply noops.


isWritable

public boolean isWritable()
Whether the channel associated with this descriptor is writable (i.e. whether it is instanceof WritableByteChannel).

Returns:
true if the associated channel is writable, false otherwise

isOpen

public boolean isOpen()
Whether the channel associated with this descriptor is open.

Returns:
true if the associated channel is open, false otherwise

checkOpen

public void checkOpen()
               throws BadDescriptorException
Check whether the isOpen returns true, raising a BadDescriptorException if it returns false.

Throws:
BadDescriptorException - if isOpen returns false

getOriginalModes

public ModeFlags getOriginalModes()
Get the original mode flags for the descriptor.

Returns:
the original mode flags for the descriptor

checkNewModes

public void checkNewModes(ModeFlags newModes)
                   throws InvalidValueException
Check whether a specified set of mode flags is a superset of this descriptor's original set of mode flags.

Parameters:
newModes - The modes to confirm as superset
Throws:
InvalidValueException - if the modes are not a superset

dup

public ChannelDescriptor dup()
Mimics the POSIX dup(2) function, returning a new descriptor that references the same open channel.

Returns:
A duplicate ChannelDescriptor based on this one

dup2

public ChannelDescriptor dup2(int fileno)
Mimics the POSIX dup2(2) function, returning a new descriptor that references the same open channel but with a specified fileno.

Parameters:
fileno - The fileno to use for the new descriptor
Returns:
A duplicate ChannelDescriptor based on this one

dup2Into

public void dup2Into(ChannelDescriptor other)
              throws BadDescriptorException,
                     java.io.IOException
Mimics the POSIX dup2(2) function, returning a new descriptor that references the same open channel but with a specified fileno. This differs from the fileno version by making the target descriptor into a new reference to the current descriptor's channel, closing it and incrementing reference counts in the process.

Parameters:
fileno - The fileno to use for the new descriptor
Throws:
BadDescriptorException
java.io.IOException

lseek

public long lseek(long offset,
                  int whence)
           throws java.io.IOException,
                  InvalidValueException,
                  PipeException,
                  BadDescriptorException
Perform a low-level seek operation on the associated channel if it is instanceof FileChannel, or raise PipeException if it is not a FileChannel. 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.

Parameters:
offset - the offset value to use
whence - whence to seek
Returns:
the new offset into the FileChannel.
Throws:
java.io.IOException - If there is an exception while seeking
InvalidValueException - If the value specified for offset or whence is invalid
PipeException - If the target channel is not seekable
BadDescriptorException - If the target channel is already closed.

read

public int read(int number,
                org.jruby.util.ByteList byteList)
         throws java.io.IOException,
                BadDescriptorException
Perform a low-level read of the specified number of bytes into the specified byte list. The incoming bytes will be appended to the byte list. This is equivalent to the read(2) POSIX function, and like that function it ignores read and write buffers defined elsewhere.

Parameters:
number - the number of bytes to read
byteList - the byte list on which to append the incoming bytes
Returns:
the number of bytes actually read
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed.
See Also:
java.util.ByteList

read

public int read(java.nio.ByteBuffer buffer)
         throws java.io.IOException,
                BadDescriptorException
Perform a low-level read of the remaining number of bytes into the specified byte buffer. The incoming bytes will be used to fill the remaining space in the target byte buffer. This is equivalent to the read(2) POSIX function, and like that function it ignores read and write buffers defined elsewhere.

Parameters:
buffer - the java.nio.ByteBuffer in which to put the incoming bytes
Returns:
the number of bytes actually read
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed
See Also:
ByteBuffer

internalWrite

public int internalWrite(java.nio.ByteBuffer buffer)
                  throws java.io.IOException,
                         BadDescriptorException
Write the bytes in the specified byte list to the associated channel.

Parameters:
buf - the byte list containing the bytes to be written
Returns:
the number of bytes actually written
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed

write

public int write(java.nio.ByteBuffer buffer)
          throws java.io.IOException,
                 BadDescriptorException
Write the bytes in the specified byte list to the associated channel.

Parameters:
buf - the byte list containing the bytes to be written
Returns:
the number of bytes actually written
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed

write

public int write(org.jruby.util.ByteList buf)
          throws java.io.IOException,
                 BadDescriptorException
Write the bytes in the specified byte list to the associated channel.

Parameters:
buf - the byte list containing the bytes to be written
Returns:
the number of bytes actually written
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed

write

public int write(org.jruby.util.ByteList buf,
                 int offset,
                 int len)
          throws java.io.IOException,
                 BadDescriptorException
Write the bytes in the specified byte list to the associated channel.

Parameters:
buf - the byte list containing the bytes to be written
offset - the offset to start at. this is relative to the begin variable in the but
len - the amount of bytes to write. this should not be longer than the buffer
Returns:
the number of bytes actually written
Throws:
java.io.IOException - if there is an exception during IO
BadDescriptorException - if the associated channel is already closed

write

public int write(int c)
          throws java.io.IOException,
                 BadDescriptorException
Write the byte represented by the specified int to the associated channel.

Parameters:
c - The byte to write
Returns:
1 if the byte was written, 0 if not and -1 if there was an error (@see java.nio.channels.WritableByteChannel.write(java.nio.ByteBuffer))
Throws:
java.io.IOException - If there was an exception during IO
BadDescriptorException - if the associated channel is already closed

open

public static ChannelDescriptor open(java.lang.String cwd,
                                     java.lang.String path,
                                     ModeFlags flags)
                              throws java.io.FileNotFoundException,
                                     DirectoryAsFileException,
                                     FileExistsException,
                                     java.io.IOException
Open a new descriptor using the given working directory, file path, mode flags, and file permission. This is equivalent to the open(2) POSIX function. See org.jruby.util.io.ChannelDescriptor.open(String, String, ModeFlags, int, POSIX) for the version that also sets file permissions.

Parameters:
cwd - the "current working directory" to use when opening the file
path - the file path to open
flags - the mode flags to use for opening the file
Returns:
a new ChannelDescriptor based on the specified parameters
Throws:
java.io.FileNotFoundException - if the target file could not be found and the create flag was not specified
DirectoryAsFileException - if the target file is a directory being opened as a file
FileExistsException - if the target file should be created anew, but already exists
java.io.IOException - if there is an exception during IO

open

public static ChannelDescriptor open(java.lang.String cwd,
                                     java.lang.String path,
                                     ModeFlags flags,
                                     int perm,
                                     org.jruby.ext.posix.POSIX posix)
                              throws java.io.FileNotFoundException,
                                     DirectoryAsFileException,
                                     FileExistsException,
                                     java.io.IOException
Open a new descriptor using the given working directory, file path, mode flags, and file permission. This is equivalent to the open(2) POSIX function.

Parameters:
cwd - the "current working directory" to use when opening the file
path - the file path to open
flags - the mode flags to use for opening the file
perm - the file permissions to use when creating a new file (currently unobserved)
posix - a POSIX api implementation, used for setting permissions; if null, permissions are ignored
Returns:
a new ChannelDescriptor based on the specified parameters
Throws:
java.io.FileNotFoundException - if the target file could not be found and the create flag was not specified
DirectoryAsFileException - if the target file is a directory being opened as a file
FileExistsException - if the target file should be created anew, but already exists
java.io.IOException - if there is an exception during IO

close

public void close()
           throws BadDescriptorException,
                  java.io.IOException
Close this descriptor. If in closing the last ChannelDescriptor reference to the associate channel is closed, the channel itself will be closed.

Throws:
BadDescriptorException - if the associated channel is already closed
java.io.IOException - if there is an exception during IO


Copyright © 2002-2007 JRuby Team. All Rights Reserved.