/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 MapMode READ_ONLY  = new MapMode(0);
    public static MapMode READ_WRITE = new MapMode(1);
    public static 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;
}
