/* FileChannelImpl.java -- 
   Copyright (C) 2002, 2004, 2005  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 gnu.java.nio.channels;

import gnu.classpath.Configuration;
import gnu.java.nio.FileLockImpl;

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;

  private static native void init();

  static
  {
    if (Configuration.INIT_LOAD_LIBRARY)
      {
        System.loadLibrary("javanio");
      }
    
    init();
  }

  /**
   * This is the actual native file descriptor value
   */
  // System's notion of file descriptor.  It might seem redundant to
  // initialize this given that it is reassigned in the constructors.
  // However, this is necessary because if open() throws an exception
  // we want to make sure this has the value -1.  This is the most
  // efficient way to accomplish that.
  private int fd = -1;

  private long pos;
  private int mode;

  public FileChannelImpl ()
  {
  }

  /* Open a file.  MODE is a combination of the above mode flags. */
  public FileChannelImpl (String path, int mode) throws FileNotFoundException
  {
    fd = open (path, mode);
    this.mode = mode;
  }

  /* Used by init() (native code) */
  FileChannelImpl (int fd, int mode)
  {
    this.fd = fd;
    this.mode = mode;
  }

  public static FileChannelImpl in;
  public static FileChannelImpl out;
  public static FileChannelImpl err;

  private native int open (String path, int mode) throws FileNotFoundException;

  public native int available () throws IOException;
  private native long implPosition () throws IOException;
  private native void seek (long newPosition) throws IOException;
  private native void implTruncate (long size) throws IOException;
  
  public native void unlock (long pos, long len) throws IOException;

  public native long size () throws IOException;
    
  protected native void implCloseChannel() throws IOException;

  /**
   * Makes sure the Channel is properly closed.
   */
  protected void finalize() throws IOException
  {
    this.close();
  }

  public int read (ByteBuffer dst) throws IOException
  {
    int result;
    byte[] buffer = new byte [dst.remaining ()];
    
    result = read (buffer, 0, buffer.length);

    if (result > 0)
      dst.put (buffer, 0, result);

    return result;
  }

  public int read (ByteBuffer dst, long position)
    throws IOException
  {
    if (position < 0)
      throw new IllegalArgumentException ();
    long oldPosition = implPosition ();
    position (position);
    int result = read(dst);
    position (oldPosition);
    
    return result;
  }

  public native int read ()
    throws IOException;

  public native int read (byte[] buffer, int offset, int length)
    throws IOException;

  public long read (ByteBuffer[] dsts, int offset, int length)
    throws IOException
  {
    long result = 0;

    for (int i = offset; i < offset + length; i++)
      {
        result += read (dsts [i]);
      }

    return result;
  }

  public int write (ByteBuffer src) throws IOException
  {
    int len = src.remaining ();
    if (src.hasArray())
      {
	byte[] buffer = src.array();
	write(buffer, src.arrayOffset() + src.position(), len);
	src.position(src.position() + len);
      }
    else
      {
	// Use a more efficient native method! FIXME!
	byte[] buffer = new byte [len];
    	src.get (buffer, 0, len);
	write (buffer, 0, len);
      }
    return len;
  }
    
  public int write (ByteBuffer src, long position)
    throws IOException
  {
    if (position < 0)
      throw new IllegalArgumentException ();

    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 native void write (byte[] buffer, int offset, int length)
    throws IOException;
  
  public native void write (int b) throws IOException;

  public long write(ByteBuffer[] srcs, int offset, int length)
    throws IOException
  {
    long result = 0;

    for (int i = offset;i < offset + length;i++)
      {
        result += write (srcs[i]);
      }
    
    return result;
  }
				   
  public native MappedByteBuffer mapImpl (char mode, long position, int size)
    throws IOException;

  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 & (READ|WRITE)) != (READ|WRITE))
	  throw new NonWritableChannelException();
      }
    else
      throw new IllegalArgumentException ();
    
    if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
      throw new IllegalArgumentException ();
    return mapImpl(nmode, position, (int) size);
  }

  /**
   * msync with the disk
   */
  public void force (boolean metaData) throws IOException
  {
    if (!isOpen ())
      throw new ClosedChannelException ();
  }

  // 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 ();

    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 ();

    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;
  }

  public FileLock tryLock (long position, long size, boolean shared)
    throws IOException
  {
    if (position < 0
        || size < 0)
      throw new IllegalArgumentException ();

    if (!isOpen ())
      throw new ClosedChannelException ();

    if (shared && (mode & READ) == 0)
      throw new NonReadableChannelException ();
	
    if (!shared && (mode & WRITE) == 0)
      throw new NonWritableChannelException ();
	
    boolean completed = false;
    
    try
      {
	begin();
	boolean lockable = lock(position, size, shared, false);
	completed = true;
	return (lockable
		? new FileLockImpl(this, position, size, shared)
		: null);
      }
    finally
      {
	end(completed);
      }
  }

  /** Try to acquire a lock at the given position and size.
   * On success return true.
   * If wait as specified, block until we can get it.
   * Otherwise return false.
   */
  private native boolean lock(long position, long size,
			      boolean shared, boolean wait) throws IOException;
  
  public FileLock lock (long position, long size, boolean shared)
    throws IOException
  {
    if (position < 0
        || size < 0)
      throw new IllegalArgumentException ();

    if (!isOpen ())
      throw new ClosedChannelException ();

    boolean completed = false;

    try
      {
	boolean lockable = 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 ();

    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 ();

    if (!isOpen ())
      throw new ClosedChannelException ();

    if ((mode & WRITE) == 0)
       throw new NonWritableChannelException ();

    if (size < size ())
      implTruncate (size);

    return this;
  }
}
