summaryrefslogtreecommitdiff
path: root/gnu/java/nio/FileChannelImpl.java
diff options
context:
space:
mode:
authorCasey Marshall <csm@gnu.org>2006-09-17 07:31:39 +0000
committerCasey Marshall <csm@gnu.org>2006-09-17 07:31:39 +0000
commit133e014be0604b45f8ccede687acf1ea979d4955 (patch)
tree03bfec201e509081586497b0e4db7944e633cab7 /gnu/java/nio/FileChannelImpl.java
parenta344c95abdd44f1c697d0520bf97ac3c8403a3b6 (diff)
downloadclasspath-133e014be0604b45f8ccede687acf1ea979d4955.tar.gz
2006-09-16 Casey Marshall <csm@gnu.org>
* NEWS: updated. * configure.ac (AC_CHECK_HEADERS): check for `sys/event.h'. (AC_CHECK_FUNCS): add checks for readv, writev, getifaddrs, kqueue, and kevent. (HAVE_INET6): define if IPv6 is supported. * gnu/java/net/PlainDatagramSocketImpl.java (channel): new field. (native_fd): removed. (impl): new field. (<init>): throw IOException; initialize fields. (finalize): removed. (getNativeFD): removed. (bind): use `PlainSocketImpl.bind.' (create): use `PlainSocketImpl.initSocket.' (disconnect): use `PlainSocketImpl.disconnect.' (getLocalPort): new method. (send): use `VMChannel.send.' (receive): use `VMChannel.receive.' (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (close): use `VMChannel.State.close.' (join): use `PlainSocketImpl.join.' (leave): use `PlainSocketImpl.leave.' (joinGroup, leaveGroup): implemented. * gnu/java/net/PlainSocketImpl.java: make non-final. (native_fd): removed. (impl): new field. (channel): new field. (<init>): initialize `impl.' (finalize, getNativeFD): removed. (setOption): use `PlainSocketImpl.setOption.' (getOption): use `PlainSocketImpl.getOption.' (shutdownInput): use `PlainSocketImpl.shutdownInput.' (shutdownOutput): use `PlainSocketImpl.shutdownOutput.' (create): create `channel,' initialize `impl's native state. (connect): use `connect(SocketAddress, int).' (connect): use `SocketChannelImpl.connect;' initialize `address' and `port.' (bind): use `VMPlainSocketImpl.bind.' (listen): use `VMPlainSocketImpl.listen.' (accept): use `SocketChannelImpl.accept.' (available): use `VMChannel.available.' (close): use `PlainSocketImpl.close.' (sendUrgentData): use `PlainSocketImpl.sendUrgentData.' (getVMChannel, getInetAddress, getLocalPort, getLocalAddress, getPort): new methods. (SocketInputStream.read): use `VMChannel.read.' (SocketInputStream.read): use `SocketChannel.read.' (SocketOutputStream.write): use `VMChannel.write.' (SocketOutputStream.write): use `SocketChannel.write.' * gnu/java/nio/DatagramChannelImpl.java: implement VMChannel. (channel): new field. (<init>): initialize `channel.' (implCloseSelectableChannel): use `VMChannel.close.' (implConfigureBlocking): use `VMChannel.setBlocking.' (connect): use `VMChannel.connect.' (disconnect): use `VMChannel.disconnect.' (isConnected): use `VMChannel.getPeerAddress.' (write): use `VMChannel.write.' (write): use `VMChannel.writeGathering.' (read): use `VMChannel.read.' (read): use `VMChannel.readScattering.' (receive): use `VMChannel.receive.' (send): use `VMChannel.send.' (getVMChannel): new method. * gnu/java/nio/DatagramChannelSelectionKey.java (getNativeFD): access native FD through VMChannel.State. * gnu/java/nio/FileChannelImpl.java: moved from gnu/java/nio/channels/FileChannelImpl.java. * gnu/java/nio/FileLockImpl.java: fix imports. * gnu/java/nio/KqueueSelectionKeyImpl.java: new file. * gnu/java/nio/KqueueSelectorImpl.java: new file. * gnu/java/nio/NIOSocket.java (impl): removed. (channel): new field. (<init>): init superclass with a `NIOSocketImpl;' init `channel.' (getPlainSocketImpl, setChannel): removed. (isConnected): new method. * gnu/java/nio/NIOSocketImpl.java: new file. * gnu/java/nio/PipeImpl.java (SourceChannelImpl): implement `VMChannelOwner.' (SourceChannelImpl.native_fd): removed. (SourceChannelImpl.<init>): init with a `VMChannel.' (SourceChannelImpl.getNativeFD): removed. (SourceChannelImpl.getVMChannel): new method. (SourceChannelImpl.implCloseSelectableChannel): implement. (SinkChannelImpl): implement `VMChannelOwner.' (SinkChannelImpl.native_fd): removed. (SinkChannelImpl.<init>): init with a `VMChannel.' (SinkChannelImpl.implCloseSelectableChannel): implement. (SinkChannelImpl.getNativeFD): removed. (SinkChannelImpl.getVMChannel): new method. * gnu/java/nio/SelectionKeyImpl.java (getNativeFD): mark deprecated. * gnu/java/nio/SelectorProviderImpl.java (SELECTOR_IMPL_KQUEUE, SELECTOR_IMPL_EPOLL, SELECTOR_IMPL): new constants. (openSelector): return kqueue selector if available. * gnu/java/nio/ServerSocketChannelImpl.java: implement `VMChannelOwner.' (channel): new field. (<init>): init `channel.' (finalizer): check if the `VMChannel.State' is valid. (implCloseSelectableChannel): use `VMChannel.close.' (implConfigureBlocking): use `VMChannel.setBlocking.' (accept): use `VMChannel.accept.' (getVMChannel): new method. * gnu/java/nio/ServerSocketChannelSelectionKey.java (getNativeFD): access native FD through `VMChannel.State.' * gnu/java/nio/SocketChannelImpl.java: implement `VMChannelOwner.' (impl): removed. (channel, connected, connectAddress): new field. (<init>): new constructors. (getPlainSocketImpl): removed. (implCloseSelectableChannel): use `VMChannel.close.' (implConfigureBlocking): use `VMChannel.setBlocking.' (connect): use `connect(SocketAddress,int).' (connect): use `VMChannel.connect.' (finishConnect): don't use a selector. (isConnected): use `VMChannel.getPeerAddress.' (read): use `VMChannel.read.' (read): use `VMChannel.readScattering.' (write): use `VMChannel.write.' (write): use `VMChannel.writeGathering.' (getVMChannel): new method. * gnu/java/nio/SocketChannelSelectionKey.java (getNativeFD): get native FD from `VMChannel.State.' * gnu/java/nio/SocketChannelSelectionKeyImpl.java (getNativeFD): get native FD from `VMChannel.State.' * gnu/java/nio/VMChannelOwner.java: new file. * gnu/java/nio/channels/FileChannelImpl.java: removed. * include/Makefile.am: generate `gnu_java_nio_FileChannelImpl.h' and `gnu_java_nio_KqueueSelectorImpl.h;' don't generate `gnu_java_nio_channels_FileChannelImpl.h.' * include/gnu_java_net_VMPlainSocketImpl.h: regenerated. * include/gnu_java_nio_FileChannelImpl.h: new file. * include/gnu_java_nio_KqueueSelectorImpl.h: new file. * include/gnu_java_nio_VMChannel.h: regenerated. * include/gnu_java_nio_VMPipe.h: regenerated. * include/java_net_VMNetworkInterface.h: regenerated. * java/io/FileDescriptor.java: fix imports. * java/io/FileInputStream.java (<init>): handle exceptions. (read): wrap the destination arary. * java/io/FileOutputStream.java (<init>): handle exceptions. (write): wrap the source array. * java/io/RandomAccessFile.java (<init>): handle exceptions. * java/net/DatagramSocket.java (<init>): handle exceptions. (receive): handle length/port setting. (connect): bind to any address/port if the argument is null. * java/net/NetworkInterface.java (name, inetAddress): removed. (netif): new field. (<init>): make private. (getName): return `netif.name.' (getInetAddresses): access `netif.addresses.' (getDisplayName): return `netif.name.' (getByName, getByAddress): handle changes to `VMNetworkInterface.' (condense): removed. (getNetworkInterfaces): handle changes to `VMNetworkInterface.' (equals): compare `netif' fields. (hashCode): get hash codes from `netif.' (toString): use a StringBuffer. * java/net/ServerSocket.java (close): don't set `impl' to null. (isClosed): use `VMChannel.State.isClosed.' * java/net/Socket.java (getLocalAddress): don't use `getOption' if the `SocketImpl' is a `PlainSocketImpl.' (close): just close the `impl.' (toString): use `super.toString' in the value we return. (isConnected): just access `impl,' not `getImpl.' (isBound): use `PlainSocketImpl' methods if we can. (isClosed): look at `VMChannel.State.' * native/jni/classpath/jcl.c (JNI_OnLoad): new function. (JCL_NewRawDataObject): don't initialize cached fields here; throw an exception if they were not. (JCL_GetRawData): throw an exception if cached fields weren't created. * native/jni/java-lang/java_lang_VMProcess.c: handle FileChannelImpl move. * native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c (IO_EXCEPTION, SOCKET_EXCEPTION, BIND_EXCEPTION, THROW_NO_NETWORK): new macros. (Java_gnu_java_net_VMPlainSocketImpl_bind): reipmlemented. (Java_gnu_java_net_VMPlainSocketImpl_bind6): new function. (Java_gnu_java_net_VMPlainSocketImpl_listen): reimplemented. (java_sockopt): new enum. (Java_gnu_java_net_VMPlainSocketImpl_setOption): reimplemented. (Java_gnu_java_net_VMPlainSocketImpl_getOption): reimplemented. (Java_gnu_java_net_VMPlainSocketImpl_shutdownInput): reimplemented. (Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput): reimplemented. (Java_gnu_java_net_VMPlainSocketImpl_sendUrgentData): new function. (Java_gnu_java_net_VMPlainSocketImpl_join): new function. (Java_gnu_java_net_VMPlainSocketImpl_join6): new function. (Java_gnu_java_net_VMPlainSocketImpl_read): removed. (Java_gnu_java_net_VMPlainSocketImpl_leave): new function. (Java_gnu_java_net_VMPlainSocketImpl_leave6): new function. (Java_gnu_java_net_VMPlainSocketImpl_joinGroup): new function. (Java_gnu_java_net_VMPlainSocketImpl_write): removed. (Java_gnu_java_net_VMPlainSocketImpl_joinGroup6): new function. (Java_gnu_java_net_VMPlainSocketImpl_leaveGroup): new function. (Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6): new function. (getif_address): new function. (getif_index): new function. * native/jni/java-net/java_net_VMNetworkInterface.c (java_net_VMNetworkInterface_init, java_net_VMNetworkInterface_addAddress): new file-scope globals. (Java_java_net_VMNetworkInterface_initIds): new function. (struct netif_entry): new struct. (free_netif_list): new function. (Java_java_net_VMNetworkInterface_getInterfaces): removed. (Java_java_net_VMNetworkInterface_getVMInterfaces): new function. * native/jni/java-nio/Makefile.am (libjavanio_la_SOURCES): remove gnu_java_nio_channels_FileChannelImpl.c, add gnu_java_nio_KqueueSelectorImpl.c. * native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c: new file. * native/jni/java-nio/gnu_java_nio_VMChannel.c (INTERRUPTED_IO_EXCEPTION, SOCKET_TIMEOUT_EXCEPTION, ALIGN_UP, ALIGN_DOWN): new macros. (JCL_init_buffer): get the address through GetDirectBufferAddress if possible. (Java_gnu_java_nio_VMChannel_stdin_1fd, Java_gnu_java_nio_VMChannel_stdout_1fd, Java_gnu_java_nio_VMChannel_stderr_1fd): new functions. (Java_gnu_java_nio_VMChannel_setBlocking): fix setting blocking value. (Java_gnu_java_nio_VMChannel_read): renamed... (Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2): to this; handle interrupted IO; add HAVE_READ check. (Java_gnu_java_nio_VMChannel_write): renamed... (Java_gnu_java_nio_VMChannel_write__ILjava_nio_ByteBuffer_2): to this; handle zero-length write; add HAVE_WRITE check. (Java_gnu_java_nio_VMChannel_receive): new function. (Java_gnu_java_nio_VMChannel_send): new function. (Java_gnu_java_nio_VMChannel_send6): new function. (Java_gnu_java_nio_VMChannel_read__I): new function. (Java_gnu_java_nio_VMChannel_write__II): new function. (Java_gnu_java_nio_VMChannel_socket): new function. (Java_gnu_java_nio_VMChannel_connect): new function. (Java_gnu_java_nio_VMChannel_connect6): new function. (Java_gnu_java_nio_VMChannel_getsockname): new function. (Java_gnu_java_nio_VMChannel_getpeername): new function. (Java_gnu_java_nio_VMChannel_accept): new function. (Java_gnu_java_nio_VMChannel_disconnect): new function. (Java_gnu_java_nio_VMChannel_close): new function. (Java_gnu_java_nio_VMChannel_available): new function. (FileChannel_mode): new enum. (Java_gnu_java_nio_VMChannel_open): new function. (Java_gnu_java_nio_VMChannel_position): new function. (Java_gnu_java_nio_VMChannel_seek): new function. (Java_gnu_java_nio_VMChannel_truncate): new funciton. (Java_gnu_java_nio_VMChannel_lock): new function. (Java_gnu_java_nio_VMChannel_unlock): new function. (Java_gnu_java_nio_VMChannel_size): new function. (Java_gnu_java_nio_VMChannel_map): new function. (Java_gnu_java_nio_VMChannel_flush): new function. * native/jni/java-nio/gnu_java_nio_VMPipe.c (Java_gnu_java_nio_VMPipe_init): removed. (Java_gnu_java_nio_VMPipe_pipe0): new function. * native/jni/java-nio/javanio.c: new file. * native/jni/java-nio/javanio.h: new file. * native/jni/native-lib/cpnet.c (cpnet_getHostByName): fix for systems without `gethostbyname_r.' * vm/reference/gnu/java/net/VMPlainSocketImpl.java (nfd): new field. (<init>, <init>): new constructors. (setOption, getOption): make instance methods; defer to native implementation. (connect): removed. (bind): make an instance method; defer to native methods. (accept): removed. (available): removed. (listen): make an instance method; defer to native method. (read): removed. (join, leave): new methods. (write): removed. (joinGroup, leaveGroup): new methods. (shutdownInput, shutdownOutput): make instance methods. (sendUrgentData): removed. (State): new class. * vm/reference/gnu/java/nio/VMChannel.java: make final. (fd): removed. (nfd): new field. (<init>): new, public constructors. (getVMChannel): methods removed. (getState, getStdin, getStdout, getStderr, stdin_fd, stdout_fd, stderr_fd): new methods. (setBlocking): make an instance method. (available): new method. (read): get native fd from `nfd.' (read): new single-byte read method. (readScattering): get native fd from `nfd.' (receive): new method. (write, writeGathering): get native fd from `nfd.' (send): new method. (write): new single-byte write method. (initSocket): new method. (connect): new method. (disconnect): new method. (getLocalAddress): new method. (getPeerAddress): new method. (accept): new method. (openFile): new method. (position): new method. (seek): new method. (truncate): new method. (lock): new method. (unlock): new method. (size): new method. (map): new method. (flush): new method. (close): new method. (State): new class. (Kind): new class. * vm/reference/gnu/java/nio/VMPipe.java (init): removed. (pipe, pipe0): new method. * vm/reference/java/net/VMNetworkInterface.java (name, addresses): new fields. (<clinit>): call `initIds.' (initIds): new method. (getInterfaces): removed. (getVMInterfaces): new method. (addAddress): new method. * vm/reference/java/nio/channels/VMChannels.java: fix imports.
Diffstat (limited to 'gnu/java/nio/FileChannelImpl.java')
-rw-r--r--gnu/java/nio/FileChannelImpl.java572
1 files changed, 572 insertions, 0 deletions
diff --git a/gnu/java/nio/FileChannelImpl.java b/gnu/java/nio/FileChannelImpl.java
new file mode 100644
index 000000000..419124050
--- /dev/null
+++ b/gnu/java/nio/FileChannelImpl.java
@@ -0,0 +1,572 @@
+/* FileChannelImpl.java --
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.nio;
+
+import gnu.classpath.Configuration;
+import gnu.java.nio.FileLockImpl;
+import gnu.java.nio.VMChannel;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.NonWritableChannelException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+
+/**
+ * This file is not user visible !
+ * But alas, Java does not have a concept of friendly packages
+ * so this class is public.
+ * Instances of this class are created by invoking getChannel
+ * Upon a Input/Output/RandomAccessFile object.
+ */
+public final class FileChannelImpl extends FileChannel
+{
+ // These are mode values for open().
+ public static final int READ = 1;
+ public static final int WRITE = 2;
+ public static final int APPEND = 4;
+
+ // EXCL is used only when making a temp file.
+ public static final int EXCL = 8;
+ public static final int SYNC = 16;
+ public static final int DSYNC = 32;
+
+ public static final FileChannelImpl in;
+ public static final FileChannelImpl out;
+ public static final FileChannelImpl err;
+
+ //private static native void init();
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanio");
+ }
+
+ //init();
+
+ FileChannelImpl ch = null;
+ try
+ {
+ ch = new FileChannelImpl(VMChannel.getStdin(), READ);
+ }
+ catch (IOException ioe)
+ {
+ throw new Error(ioe);
+ }
+ in = ch;
+
+ ch = null;
+ try
+ {
+ ch = new FileChannelImpl(VMChannel.getStdout(), WRITE);
+ }
+ catch (IOException ioe)
+ {
+ throw new Error(ioe);
+ }
+ out = ch;
+
+ ch = null;
+ try
+ {
+ ch = new FileChannelImpl(VMChannel.getStderr(), WRITE);
+ }
+ catch (IOException ioe)
+ {
+ throw new Error(ioe);
+ }
+ err = ch;
+ }
+
+ /**
+ * This is the actual native file descriptor value
+ */
+ private VMChannel ch;
+
+ private int mode;
+
+ final String description;
+
+ /* Open a file. MODE is a combination of the above mode flags. */
+ /* This is a static factory method, so that VM implementors can decide
+ * substitute subclasses of FileChannelImpl. */
+ public static FileChannelImpl create(File file, int mode)
+ throws IOException
+ {
+ return new FileChannelImpl(file, mode);
+ }
+
+ private FileChannelImpl(File file, int mode)
+ throws IOException
+ {
+ String path = file.getPath();
+ description = path;
+ this.mode = mode;
+ this.ch = new VMChannel();
+ ch.openFile(path, mode);
+
+ // First open the file and then check if it is a a directory
+ // to avoid race condition.
+ if (file.isDirectory())
+ {
+ try
+ {
+ close();
+ }
+ catch (IOException e)
+ {
+ /* ignore it */
+ }
+
+ throw new FileNotFoundException(description + " is a directory");
+ }
+ }
+
+ /**
+ * Constructor for default channels in, out and err.
+ *
+ * Used by init() (native code).
+ *
+ * @param fd the file descriptor (0, 1, 2 for stdin, stdout, stderr).
+ *
+ * @param mode READ or WRITE
+ */
+ FileChannelImpl (VMChannel ch, int mode)
+ {
+ this.mode = mode;
+ this.description = "descriptor(" + ch.getState() + ")";
+ this.ch = ch;
+ }
+
+ public int available() throws IOException
+ {
+ return ch.available();
+ }
+
+ private long implPosition() throws IOException
+ {
+ return ch.position();
+ }
+
+ private void seek(long newPosition) throws IOException
+ {
+ ch.seek(newPosition);
+ }
+
+ private void implTruncate(long size) throws IOException
+ {
+ ch.truncate(size);
+ }
+
+ public void unlock(long pos, long len) throws IOException
+ {
+ ch.unlock(pos, len);
+ }
+
+ public long size () throws IOException
+ {
+ return ch.size();
+ }
+
+ protected void implCloseChannel() throws IOException
+ {
+ ch.close();
+ }
+
+ /**
+ * Makes sure the Channel is properly closed.
+ */
+ protected void finalize() throws IOException
+ {
+ if (ch.getState().isValid())
+ close();
+ }
+
+ public int read (ByteBuffer dst) throws IOException
+ {
+ return ch.read(dst);
+ }
+
+ public int read (ByteBuffer dst, long position)
+ throws IOException
+ {
+ if (position < 0)
+ throw new IllegalArgumentException ("position: " + position);
+ long oldPosition = implPosition ();
+ position (position);
+ int result = read(dst);
+ position (oldPosition);
+
+ return result;
+ }
+
+ public int read() throws IOException
+ {
+ return ch.read();
+ }
+
+ public long read (ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ return ch.readScattering(dsts, offset, length);
+ }
+
+ public int write (ByteBuffer src) throws IOException
+ {
+ return ch.write(src);
+ }
+
+ public int write (ByteBuffer src, long position)
+ throws IOException
+ {
+ if (position < 0)
+ throw new IllegalArgumentException ("position: " + position);
+
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ if ((mode & WRITE) == 0)
+ throw new NonWritableChannelException ();
+
+ int result;
+ long oldPosition;
+
+ oldPosition = implPosition ();
+ seek (position);
+ result = write(src);
+ seek (oldPosition);
+
+ return result;
+ }
+
+ public void write (int b) throws IOException
+ {
+ ch.write(b);
+ }
+
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ return ch.writeGathering(srcs, offset, length);
+ }
+
+ public MappedByteBuffer map (FileChannel.MapMode mode,
+ long position, long size)
+ throws IOException
+ {
+ char nmode = 0;
+ if (mode == MapMode.READ_ONLY)
+ {
+ nmode = 'r';
+ if ((this.mode & READ) == 0)
+ throw new NonReadableChannelException();
+ }
+ else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
+ {
+ nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
+ if ((this.mode & WRITE) != WRITE)
+ throw new NonWritableChannelException();
+ if ((this.mode & READ) != READ)
+ throw new NonReadableChannelException();
+ }
+ else
+ throw new IllegalArgumentException ("mode: " + mode);
+
+ if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
+ throw new IllegalArgumentException ("position: " + position
+ + ", size: " + size);
+ return ch.map(nmode, position, (int) size);
+ }
+
+ /**
+ * msync with the disk
+ */
+ public void force (boolean metaData) throws IOException
+ {
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ ch.flush(metaData);
+ }
+
+ // like transferTo, but with a count of less than 2Gbytes
+ private int smallTransferTo (long position, int count,
+ WritableByteChannel target)
+ throws IOException
+ {
+ ByteBuffer buffer;
+ try
+ {
+ // Try to use a mapped buffer if we can. If this fails for
+ // any reason we'll fall back to using a ByteBuffer.
+ buffer = map (MapMode.READ_ONLY, position, count);
+ }
+ catch (IOException e)
+ {
+ buffer = ByteBuffer.allocate (count);
+ read (buffer, position);
+ buffer.flip();
+ }
+
+ return target.write (buffer);
+ }
+
+ public long transferTo (long position, long count,
+ WritableByteChannel target)
+ throws IOException
+ {
+ if (position < 0
+ || count < 0)
+ throw new IllegalArgumentException ("position: " + position
+ + ", count: " + count);
+
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ if ((mode & READ) == 0)
+ throw new NonReadableChannelException ();
+
+ final int pageSize = 65536;
+ long total = 0;
+
+ while (count > 0)
+ {
+ int transferred
+ = smallTransferTo (position, (int)Math.min (count, pageSize),
+ target);
+ if (transferred < 0)
+ break;
+ total += transferred;
+ position += transferred;
+ count -= transferred;
+ }
+
+ return total;
+ }
+
+ // like transferFrom, but with a count of less than 2Gbytes
+ private int smallTransferFrom (ReadableByteChannel src, long position,
+ int count)
+ throws IOException
+ {
+ ByteBuffer buffer = null;
+
+ if (src instanceof FileChannel)
+ {
+ try
+ {
+ // Try to use a mapped buffer if we can. If this fails
+ // for any reason we'll fall back to using a ByteBuffer.
+ buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
+ count);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ if (buffer == null)
+ {
+ buffer = ByteBuffer.allocate ((int) count);
+ src.read (buffer);
+ buffer.flip();
+ }
+
+ return write (buffer, position);
+ }
+
+ public long transferFrom (ReadableByteChannel src, long position,
+ long count)
+ throws IOException
+ {
+ if (position < 0
+ || count < 0)
+ throw new IllegalArgumentException ("position: " + position
+ + ", count: " + count);
+
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ if ((mode & WRITE) == 0)
+ throw new NonWritableChannelException ();
+
+ final int pageSize = 65536;
+ long total = 0;
+
+ while (count > 0)
+ {
+ int transferred = smallTransferFrom (src, position,
+ (int)Math.min (count, pageSize));
+ if (transferred < 0)
+ break;
+ total += transferred;
+ position += transferred;
+ count -= transferred;
+ }
+
+ return total;
+ }
+
+ // Shared sanity checks between lock and tryLock methods.
+ private void lockCheck(long position, long size, boolean shared)
+ throws IOException
+ {
+ if (position < 0
+ || size < 0)
+ throw new IllegalArgumentException ("position: " + position
+ + ", size: " + size);
+
+ if (!isOpen ())
+ throw new ClosedChannelException();
+
+ if (shared && ((mode & READ) == 0))
+ throw new NonReadableChannelException();
+
+ if (!shared && ((mode & WRITE) == 0))
+ throw new NonWritableChannelException();
+ }
+
+ public FileLock tryLock (long position, long size, boolean shared)
+ throws IOException
+ {
+ lockCheck(position, size, shared);
+
+ boolean completed = false;
+ try
+ {
+ begin();
+ boolean lockable = ch.lock(position, size, shared, false);
+ completed = true;
+ return (lockable
+ ? new FileLockImpl(this, position, size, shared)
+ : null);
+ }
+ finally
+ {
+ end(completed);
+ }
+ }
+
+ public FileLock lock (long position, long size, boolean shared)
+ throws IOException
+ {
+ lockCheck(position, size, shared);
+
+ boolean completed = false;
+ try
+ {
+ boolean lockable = ch.lock(position, size, shared, true);
+ completed = true;
+ return (lockable
+ ? new FileLockImpl(this, position, size, shared)
+ : null);
+ }
+ finally
+ {
+ end(completed);
+ }
+ }
+
+ public long position ()
+ throws IOException
+ {
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ return implPosition ();
+ }
+
+ public FileChannel position (long newPosition)
+ throws IOException
+ {
+ if (newPosition < 0)
+ throw new IllegalArgumentException ("newPosition: " + newPosition);
+
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ // FIXME note semantics if seeking beyond eof.
+ // We should seek lazily - only on a write.
+ seek (newPosition);
+ return this;
+ }
+
+ public FileChannel truncate (long size)
+ throws IOException
+ {
+ if (size < 0)
+ throw new IllegalArgumentException ("size: " + size);
+
+ if (!isOpen ())
+ throw new ClosedChannelException ();
+
+ if ((mode & WRITE) == 0)
+ throw new NonWritableChannelException ();
+
+ if (size < size ())
+ implTruncate (size);
+
+ return this;
+ }
+
+ public String toString()
+ {
+ return (super.toString()
+ + "[ fd: " + ch.getState()
+ + "; mode: " + Integer.toOctalString(mode)
+ + "; " + description + " ]");
+ }
+
+ /**
+ * @return The native file descriptor.
+ * /
+ public int getNativeFD()
+ {
+ return fd;
+ }*/
+}