/* FileDescriptor.java -- Opaque file handle class
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
   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.io;

import gnu.java.nio.channels.FileChannelImpl;

import java.nio.channels.ByteChannel;
import java.nio.channels.FileChannel;

/**
 * This class represents an opaque file handle as a Java class.  It should
 * be used only to pass to other methods that expect an object of this
 * type.  No system specific information can be obtained from this object.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 * @date September 24, 1998 
 */
public final class FileDescriptor
{
  /**
   * A <code>FileDescriptor</code> representing the system standard input
   * stream.  This will usually be accessed through the
   * <code>System.in</code>variable.
   */
  public static final FileDescriptor in
  = new FileDescriptor (FileChannelImpl.in);

  /**
   * A <code>FileDescriptor</code> representing the system standard output
   * stream.  This will usually be accessed through the
   * <code>System.out</code>variable.
   */
  public static final FileDescriptor out
  = new FileDescriptor (FileChannelImpl.out);

  /**
   * A <code>FileDescriptor</code> representing the system standard error
   * stream.  This will usually be accessed through the
   * <code>System.err</code>variable.
   */
  public static final FileDescriptor err
  = new FileDescriptor (FileChannelImpl.err);

  final ByteChannel channel;

  /**
   * This method is used to initialize an invalid FileDescriptor object.
   */
  public FileDescriptor()
  {
    channel = null;
  }

  /**
   * This method is used to initialize a FileDescriptor object.
   */
  FileDescriptor(ByteChannel channel)
  {
    this.channel = channel;
  }


  /**
   * This method forces all data that has not yet been physically written to
   * the underlying storage medium associated with this 
   * <code>FileDescriptor</code>
   * to be written out.  This method will not return until all data has
   * been fully written to the underlying device.  If the device does not
   * support this functionality or if an error occurs, then an exception
   * will be thrown.
   */
  public void sync () throws SyncFailedException
  {
    if (channel instanceof FileChannel)
      {
	try
	  {
	    ((FileChannel) channel).force(true); 
	  }
	catch (IOException ex)
	  {
	    if (ex instanceof SyncFailedException)
	      throw (SyncFailedException) ex;
	    else
	      throw new SyncFailedException(ex.toString());
	  }
      }
  }

  /**
   * This methods tests whether or not this object represents a valid open
   * native file handle.
   *
   * @return <code>true</code> if this object represents a valid 
   * native file handle, <code>false</code> otherwise
   */
  public boolean valid ()
  {
    return channel != null && channel.isOpen();
  }
}
