/* FileChannel.java --
   Copyright (C) 2002 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 java.nio.channels;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.spi.AbstractInterruptibleChannel;


/**
 * @author Michael Koch
 * @since 1.4
 */
public abstract class FileChannel extends AbstractInterruptibleChannel
  implements ByteChannel, GatheringByteChannel, ScatteringByteChannel
{
  public static class MapMode
  {
    int m;
    public static final MapMode READ_ONLY = new MapMode(0);
    public static final MapMode READ_WRITE = new MapMode(1);
    public static final MapMode PRIVATE = new MapMode(2);

    /**
     * Initializes the MapMode.
     */
    MapMode(int a)
    {
      m = a;
    }

    /**
     * Returns a string representation of the <code>MapMode</code> object.
     */
    public String toString()
    {
      if (this == READ_ONLY)
	return "READ_ONLY";
      else if (this == READ_WRITE)
	return "READ_WRITE";

      return "PRIVATE";
    }
  }

  /**
   * Initializes the channel.
   */
  protected FileChannel()
  {
  }

  /**
   * Maps the file into the memory.
   *
   * @exception IllegalArgumentException If the preconditions on the parameters
   * do not hold.
   * @exception IOException If an I/O error occurs.
   * @exception NonReadableChannelException If mode is READ_ONLY but this channel was
   * not opened for reading.
   * @exception NonWritableChannelException If mode is READ_WRITE or PRIVATE but this
   * channel was not opened for writing.
   */
  public abstract MappedByteBuffer map(MapMode mode, long position, long size)
    throws IOException;

  /**
   * Return the size of the file thus far
   *
   * @exception ClosedChannelException If this channel is closed.
   */
  public abstract long size() throws IOException;

  /**
   * Writes data to the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public final long write(ByteBuffer[] srcs) throws IOException
  {
    long result = 0;

    for (int i = 0; i < srcs.length; i++)
      result += write(srcs[i]);

    return result;
  }

  /**
   * Writes data to the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public abstract int write(ByteBuffer src) throws IOException;

  /**
   * Writes data to the channel.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedByInterruptException If another thread interrupts the
   * current thread while the transfer is in progress, thereby closing both
   * channels and setting the current thread's interrupt status.
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If position is negative.
   * @exception IOException If an I/O error occurs.
   * @exception NonWritableChannelException If this channel was not opened for
   * writing.
   */
  public abstract int write(ByteBuffer srcs, long position)
    throws IOException;

  /**
   * Writes data to the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public abstract long write(ByteBuffer[] srcs, int offset, int length)
    throws IOException;

  /**
   * Reads data from the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public abstract long read(ByteBuffer[] dsts, int offset, int length)
    throws IOException;

  /**
   * Reads data from the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public final long read(ByteBuffer[] dsts) throws IOException
  {
    long result = 0;

    for (int i = 0; i < dsts.length; i++)
      read(dsts[i]);

    return result;
  }

  /**
   * Reads data from the channel.
   *
   * @exception IOException If an I/O error occurs.
   */
  public abstract int read(ByteBuffer dst) throws IOException;

  /**
   * Reads data from the channel.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedByInterruptException If another thread interrupts the
   * current thread while the transfer is in progress, thereby closing both
   * channels and setting the current thread's interrupt status.
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If position is negative.
   * @exception IOException If an I/O error occurs.
   * @exception NonReadableChannelException If this channel was not opened for
   * reading.
   */
  public abstract int read(ByteBuffer dst, long position)
    throws IOException;

  /**
   * Closes the channel.
   *
   * This is called from @see close.
   *
   * @exception IOException If an I/O error occurs.
   */
  protected abstract void implCloseChannel() throws IOException;

  /**
   * msync with the disk
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IOException If an I/O error occurs.
   */
  public abstract void force(boolean metaData) throws IOException;

  /**
   * Creates a file lock for the whole assoziated file.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedChannelException If this channel is closed.
   * @exception FileLockInterruptionException If the invoking thread is
   * interrupted while blocked in this method.
   * @exception IOException If an I/O error occurs.
   * @exception NonReadableChannelException If shared is true and this channel
   * was not opened for reading.
   * @exception NonWritableChannelException If shared is false and this channel
   * was not opened for writing.
   * @exception OverlappingFileLockException If a lock that overlaps the
   * requested region is already held by this Java virtual machine, or if
   * another thread is already blocked in this method and is attempting to lock
   * an overlapping region.
   */
  public final FileLock lock() throws IOException
  {
    return lock(0, Long.MAX_VALUE, false);
  }

  /**
   * Creates a file lock for a region of the assoziated file.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedChannelException If this channel is closed.
   * @exception FileLockInterruptionException If the invoking thread is
   * interrupted while blocked in this method.
   * @exception IllegalArgumentException If the preconditions on the parameters
   * do not hold.
   * @exception IOException If an I/O error occurs.
   * @exception OverlappingFileLockException If a lock that overlaps the
   * requested region is already held by this Java virtual machine, or if
   * another thread is already blocked in this method and is attempting to lock
   * an overlapping region.
   * @exception NonReadableChannelException If shared is true and this channel
   * was not opened for reading.
   * @exception NonWritableChannelException If shared is false and this channel
   * was not opened for writing.
   */
  public abstract FileLock lock(long position, long size, boolean shared)
    throws IOException;

  /**
   * Tries to aqquire alock on the whole assoziated file.
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IOException If an I/O error occurs.
   * @exception OverlappingFileLockException If a lock that overlaps the
   * requested region is already held by this Java virtual machine, or if
   * another thread is already blocked in this method and is attempting to lock
   * an overlapping region.
   */
  public final FileLock tryLock() throws IOException
  {
    return tryLock(0, Long.MAX_VALUE, false);
  }

  /**
   * Tries to aqquire a lock on a region of the assoziated file.
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If the preconditions on the parameters
   * do not hold.
   * @exception IOException If an I/O error occurs.
   * @exception OverlappingFileLockException If a lock that overlaps the
   * requested region is already held by this Java virtual machine, or if
   * another thread is already blocked in this method and is attempting to lock
   * an overlapping region.
   */
  public abstract FileLock tryLock(long position, long size, boolean shared)
    throws IOException;

  /**
   * Returns the current position on the file.
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IOException If an I/O error occurs.
   */
  public abstract long position() throws IOException;

  /**
   * Sets the position of the channel on the assoziated file.
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If newPosition is negative.
   * @exception IOException If an I/O error occurs.
   */
  public abstract FileChannel position(long newPosition)
    throws IOException;

  /**
   * Transfers bytes from this channel's file to the given writable byte
   * channel.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedByInterruptException If another thread interrupts the
   * current thread while the transfer is in progress, thereby closing both
   * channels and setting the current thread's interrupt status.
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If the preconditions on the parameters
   * do not hold.
   * @exception IOException If an I/O error occurs.
   * @exception NonReadableChannelException If this channel was not opened for
   * reading.
   * @exception NonWritableChannelException If the target channel was not
   * opened for writing.
   */
  public abstract long transferTo(long position, long count,
                                  WritableByteChannel target)
    throws IOException;

  /**
   * Transfers bytes from the given readable channel into this channel.
   *
   * @exception AsynchronousCloseException If another thread closes this channel
   * while the transfer is in progress.
   * @exception ClosedByInterruptException If another thread interrupts the
   * current thread while the transfer is in progress, thereby closing both
   * channels and setting the current thread's interrupt status.
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If the preconditions on the parameters
   * do not hold.
   * @exception IOException If an I/O error occurs.
   * @exception NonReadableChannelException If the source channel was not
   * opened for reading.
   * @exception NonWritableChannelException If this channel was not opened for
   * writing.
   */
  public abstract long transferFrom(ReadableByteChannel src, long position,
                                    long count) throws IOException;

  /**
   * Truncates the channel's file at <code>size</code>.
   *
   * @exception ClosedChannelException If this channel is closed.
   * @exception IllegalArgumentException If size is negative.
   * @exception IOException If an I/O error occurs.
   * @exception NonWritableChannelException If this channel was not opened for
   * writing.
   */
  public abstract FileChannel truncate(long size) throws IOException;
}
