/*****************************************************************************/
/* File name: Fhandle.java                                                   */
/* Purpose: to represent file handle - a basic opaque data type in NFS       */
/*          in XDR the opaque datum looks precisely the same as a string     */
/* Last modified: 10.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*                                                                           */
/* This program 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.                                          */
/*                                                                           */
/* This software is distributed 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.                                                        */
/* See file COPYING for your rights (GNU GPL)                                */
/*****************************************************************************/

package mount;

import java.io.*;
import java.lang.reflect.*;
import io.*;


public
class

Fhandle
          implements Serializable
{

  private final static String RCSID =
"$Header: /d/NFS/mount/RCS/Fhandle.java,v 1.16 1999/08/13 20:04:31 vklimov Exp $";

  private byte[] data = null;
  private long fileId = 0;
  private String dirPath = null;
  private String hostName = null;

  private boolean thisIsAMountedFileSystem = false;
  private Fhandle parentDirectoryFhandle = null;
  private FileSystemable fileSystem = null;
  private Filable thisFile = null;
  private InputStream thisFileInputStream = null;
  private Readable thisInputStream = null;
  private String[] directoryEntryNames = null;
  private Fhandle[] directoryEntryFileHandles = null;


  public

  Fhandle()
/*****************************************************************************/
/* Function name: Fhandle                                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: constructor for the Fhandle class                                */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 14.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* Fhandle */
/*---------------------------------------------------------------------------*/

      data = new byte[ Constants.FHSIZE ];
      util.Array.bytefill( data, general.Constants.NULL_BYTE );

    }
/*end of Fhandle*/


  public

  Fhandle( long fileId,
           String hostName,
           String dirPath,
           FileSystemable fileSystem )
/*****************************************************************************/
/* Function name: Fhandle                                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: constructor for the Fhandle class                                */
/* Parameters: fileId                                                        */
/*             hostName                                                      */
/*             dirPath                                                       */
/*             fileSystem                                                    */
/* Returns:                                                                  */
/* Last modified: 20.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      this();

      int i,j,k;
      long intermediateLong;
      long mask;
                                                           /* Fhandle */
/*---------------------------------------------------------------------------*/

      this.fileId = fileId;
      this.hostName = hostName;
      this.dirPath  = dirPath;
      this.fileSystem = fileSystem;

      for (i=0,j=Constants.JAVA_LONG_N_BYTES;
           i<Constants.JAVA_LONG_N_BYTES;
           i++,j--                                  )
        {
          mask = 0xFF;
          for (k=1;k<j;k++)
            mask *= 0x100;
        /*end of for-loop on k*/

          intermediateLong = fileId & mask;
          intermediateLong =
            intermediateLong >>> ((j-1)*010);

          data[i] =
            (byte) intermediateLong;
        }
    /*end of for-loop*/

    }
/*end of Fhandle*/


  protected

  Fhandle( long fileId,
           String hostName,
           String dirPath,
           FileSystemable fileSystem,
           Fhandle parentDirectoryFhandle )
/*****************************************************************************/
/* Function name: Fhandle                                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: constructor for the Fhandle class                                */
/* Parameters: fileId                                                        */
/*             hostName                                                      */
/*             dirPath                                                       */
/*             fileSystem                                                    */
/*             parentDirectoryFhandle                                        */
/* Returns:                                                                  */
/* Last modified: 20.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      this( fileId,    
            hostName,
            dirPath, 
            fileSystem );
                                                           /* Fhandle */
/*---------------------------------------------------------------------------*/

      this.parentDirectoryFhandle = parentDirectoryFhandle;

    }
/*end of Fhandle*/


  public
  void

  putItselfIntoRPCMessage( rpc.Message rpcMessage )
/*****************************************************************************/
/* Function name: putItselfIntoRPCMessage                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: to put this Fhandle object into a RPC message                    */
/* Parameters: rpcMessage                                                    */
/* Returns:                                                                  */
/* Last modified: 16.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                              /* putItselfIntoRPCMessage */
/*---------------------------------------------------------------------------*/

      if (data == null)
        return;                                        /* return ! */
      else
        ;
    /*end of if*/

      rpcMessage.
        putFixedLengthOpaque(
          Constants.FHSIZE,
          data              );

    }
/*end of putItselfIntoRPCMessage*/


  public
  boolean

  getItselfFromRPCMessage( rpc.Message rpcMessage )
/*****************************************************************************/
/* Function name: getItselfFromRPCMessage                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: to get this Fhandle object from a RPC message                    */
/* Parameters: rpcMessage                                                    */
/* Returns: true - if got OK, false - otherwise                              */
/* Last modified: 16.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      long byteToConvert;
                                              /* getItselfFromRPCMessage */
/*---------------------------------------------------------------------------*/

      data =
        rpcMessage.
          getFixedLengthOpaque(
            Constants.FHSIZE     );

      for (i=0; i<Constants.JAVA_LONG_N_BYTES; i++)
        {
          byteToConvert = (long) data[i];

          if (byteToConvert < 0)
            {
              byteToConvert = byteToConvert + 0x100;
            }
          else
            ;
        /*end of if*/

          fileId = fileId * 0x100;
          fileId = fileId + byteToConvert;

        }
    /*end of for-loop*/

      return true;

    }
/*end of getItselfFromRPCMessage*/


  public
  String

  toString()
/*****************************************************************************/
/* Function name: toString                                                   */
/* File name: Fhandle.java                                                   */
/* Purpose: to represent this Fhandle object as a string                     */
/* Parameters:                                                               */
/* Returns: the string representation of the object                          */
/* Last modified: 19.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      String result;
                                                       /* toString */
/*---------------------------------------------------------------------------*/

      result =
        "fileId=" +
        (new Long( fileId )).toString() +
        "\ndata=" +
        util.Array.
          byteArrayToStringOfHex( data );

      if (hostName == null)
        result = result +
          "\nhostName is null";
      else
        result = result +
          "\nhostName=" + hostName;
    /*end of if*/

      if (dirPath == null)
        result = result +
          "\ndirPath is null";
      else
        result = result +
          "\ndirPath=" + dirPath;
    /*end of if*/

      result += "\n" + "thisIsAMountedFileSystem=" +
                       thisIsAMountedFileSystem;

      result += "\n" + ( (parentDirectoryFhandle == null) ?
                         "parentDirectoryFhandle is null" :
                         "parentDirectoryFhandle is " +
                         parentDirectoryFhandle.getDirPath()
                       );
      result += "\n" + ( (fileSystem == null) ?
                         "fileSystem is null" :
                         "fileSystem is:\n" +
                         fileSystem.toString()
                       );
      result += "\n" + ( (thisFile == null) ?
                         "thisFile is null" :
                         "thisFile is set to something"
                       );
      result += "\n" + ( (directoryEntryNames == null) ?
                         "directoryEntryNames is null" :
                         "directoryEntryNames contains " +
                         directoryEntryNames.length +
                         " names"
                       );
      result += "\n" + ( (directoryEntryFileHandles == null) ?
                         "directoryEntryFileHandles is null" :
                         "directoryEntryFileHandles contains " +
                         directoryEntryFileHandles.length +
                         " file handles"
                       );

      return result;

    }
/*end of toString*/


  public
  int

  hashCode()
/*****************************************************************************/
/* Function name: hashCode                                                   */
/* File name: Fhandle.java                                                   */
/* Purpose: to return hash code (based on protocolNumber)                    */
/*          for this mapping object                                          */
/* Parameters:                                                               */
/* Returns: the hash code                                                    */
/* Last modified: 14.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int result;
      Long l;
                                                       /* hashCode */
/*---------------------------------------------------------------------------*/

      l = new Long( fileId );
      result = l.hashCode();

      return result;

    }
/*end of hashCode*/


  public
  boolean

  equals( Fhandle fhandle )
/*****************************************************************************/
/* Function name: equals                                                     */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object is equal to the argument    */
/* Parameters: fhandle                                                       */
/* Returns: true - if the object are equal, false - otherwise                */
/* Last modified: 20.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
                                                       /* equals */
/*---------------------------------------------------------------------------*/

      i = 0;
      while( i < data.length )
        {
          if (fhandle.data[i] != data[i])
            return false;                              /* return ! */
          else
            i++;
        /*end of if*/
        }
    /*end of while-loop*/

      if (fhandle.fileId != fileId)
        return false;                                     /* return ! */
      else
        ;
    /*end of if */

      if ( ! fhandle.hostName.equals( hostName ) )
        return false;                                     /* return ! */
      else
        ;
    /*end of if */

      if ( ! fhandle.dirPath.equals( dirPath ) )
        return false;
      else
        return true;
    /*end of if */

    }
/*end of equals*/


  public
  long

  getFileId()
/*****************************************************************************/
/* Function name: getFileId                                                  */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the fileId of this Fhandle object                         */
/* Parameters:                                                               */
/* Returns: the fileId                                                       */
/* Last modified: 15.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                         /* getFileId */
/*---------------------------------------------------------------------------*/

      return fileId;

    }
/*end of getFileId*/


  public
  Filable

  getFilable()
/*****************************************************************************/
/* Function name: getFilable                                                 */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the thisFile member of this Fhandle object                */
/* Parameters:                                                               */
/* Returns: the thisFile                                                     */
/* Last modified: 09.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                         /* getFilable */
/*---------------------------------------------------------------------------*/

      return thisFile;

    }
/*end of getFilable*/


  public
  FileSystemable

  getFileSystem()
/*****************************************************************************/
/* Function name: getFileSystem                                              */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the fileSystem of this Fhandle object                     */
/* Parameters:                                                               */
/* Returns: the file system                                                  */
/* Last modified: 24.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                         /* getFileSystem */
/*---------------------------------------------------------------------------*/

      return fileSystem;

    }
/*end of getFileSystem*/


  public
  String

  getHostName()
/*****************************************************************************/
/* Function name: getHostName                                                */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the hostName of this Fhandle object                       */
/* Parameters:                                                               */
/* Returns: the hostName                                                     */
/* Last modified: 20.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                         /* getHostName */
/*---------------------------------------------------------------------------*/

      return hostName;

    }
/*end of getHostName*/


  public
  String

  getDirPath()
/*****************************************************************************/
/* Function name: getDirPath                                                 */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the dirPath of this Fhandle object                        */
/* Parameters:                                                               */
/* Returns: the dirPath                                                      */
/* Last modified: 20.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                         /* getDirPath */
/*---------------------------------------------------------------------------*/

      return dirPath;

    }
/*end of getDirPath*/


  public
  String

  getName()
/*****************************************************************************/
/* Function name: getName                                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: to get the name of this Fhandle object                           */
/* Parameters:                                                               */
/* Returns: the name                                                         */
/* Last modified: 22.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int pathSeparatorIndexLast;
      String clearPath;
      String name;
                                                         /* getName */
/*---------------------------------------------------------------------------*/

      clearPath = util.String.
        removeTrailingPathSeparator(
          dirPath                    );

      pathSeparatorIndexLast =
        clearPath.lastIndexOf( File.separator );
      if (pathSeparatorIndexLast >= 0)
        name = clearPath.
                 substring( pathSeparatorIndexLast +
                            File.separator.length() );
      else
        name = clearPath;
    /*end of if*/

      return name;

    }
/*end of getName*/


  public
  boolean

  isDirectory()
/*****************************************************************************/
/* Function name: isDirectory                                                */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object represents a directory      */
/* Parameters:                                                               */
/* Returns: true - if this is a directory, false - otherwise                 */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean isDir;
                                                       /* isDirectory */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return false;                                  /* return ! */
        }
      else
        ;
    /*end of if*/

      isDir = thisFile.isDirectory();

      return isDir;

    }
/*end of isDirectory*/


  public
  Fhandle[]

  list( mount.Registry registry )
/*****************************************************************************/
/* Function name: list                                                       */
/* File name: Fhandle.java                                                   */
/* Purpose: to return an array of Fhandle objects for entries                */
/*          in the directory                                                 */
/*          Saves the updated registry                                       */
/* Parameters: registry                                                      */
/* Returns: the array of file handles or null if there are no entries        */
/* Last modified: 19.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long fileId;
      int i,j,k;
      boolean foundElementName;
      int nFileHandlesToReturn;
      String newEntryName = null;
      String oldEntryName = null;
      String currentDirectoryNameString = null;
      StringBuffer currentDirectoryNameStringBuffer = null;
      Fhandle[] result = null;
                                                              /* list */
/*---------------------------------------------------------------------------*/


      if (fileSystem == null)
        {
          return null;                                       /* return ! */
        }
      else
        ;
    /*end of if*/

      thisFile = fileSystem.
                   getFilableInstance( dirPath );

      if (thisFile == null)
        {
          return null;                                       /* return ! */
        }
      else
        ;
    /*end of if*/

      if (directoryEntryNames == null)
        {
          directoryEntryNames = thisFile.list();
        }
      else
        {
        return directoryEntryFileHandles;              /* return ! */
        }
    /*end of if*/

      currentDirectoryNameStringBuffer = new
        StringBuffer();
      currentDirectoryNameStringBuffer.
        append( (char)
          general.Constants.CURRENT_DIRECTORY_ABBREVIATION );
      currentDirectoryNameString =
        currentDirectoryNameStringBuffer.toString();


      if (parentDirectoryFhandle == null)
        {
          nFileHandlesToReturn =
            directoryEntryNames.length+1;
          result = new Fhandle[ nFileHandlesToReturn ];
          result[0] = new
            Fhandle( this.fileId,
                     null,                              /* do not need host */
                     currentDirectoryNameString,
                     null          );                   /* do not need file */
          j = 1;
        }
      else /* does have a parent directory */
        {
          nFileHandlesToReturn =
            directoryEntryNames.length+2;
          result = new Fhandle[ nFileHandlesToReturn ];
          result[0] = new
            Fhandle( parentDirectoryFhandle.fileId,
                     null,                              /* do not need host */
                     general.Constants.PARENT_DIRECTORY_ABBREVIATION,
                     null          );                   /* do not need file */
          result[1] = new
            Fhandle( this.fileId,
                     null,                              /* do not need host */
                     currentDirectoryNameString,
                     null          );                   /* do not need file */
          j = 2;
        }
    /*end of if*/

      for (i=0; ( (i<directoryEntryNames.length) &&
                  (j<nFileHandlesToReturn)
                );                            i++,j++)
        {
                                                   /* check whether we have */
                                                   /* a handle for this     */
                                                   /* element path already  */
          if (directoryEntryFileHandles != null)
            {
              foundElementName = false;
              k=0;
              while ( (k<directoryEntryFileHandles.length) &&
                      ( ! foundElementName )
                    )
                {
                  newEntryName = directoryEntryNames[i];
                  oldEntryName =
                    directoryEntryFileHandles[k].getName();

                  if (newEntryName.equals( oldEntryName ) )
                    {
                      foundElementName = true;
                    }
                  else
                    k++;
                /*end of if*/
                }
            /*end of while-loop on directoryEntryFileHandles*/

              if (foundElementName)
                {
                  result[j] = directoryEntryFileHandles[k];
                }
              else /* no old file handles */
                {
                  fileId = registry.getUniqueFileId();

                  if (fileId == Constants.FILE_ID_NOT_VALID)
                    {
                      return null;                              /* return ! */
                    }
                  else
                    ;
                /*end of if on fileId*/

                  result[j] = new Fhandle( fileId,
                                           null,  /* do not care about host */
                                           this.dirPath +
                                             File.separator +
                                             directoryEntryNames[i],
                                           this.fileSystem,
                                           this                      );
                  registry.put( result[j] );
                }
            /*end of if on foundElementName*/

            }
          else /* no old file handles */
            {
              fileId = registry.getUniqueFileId();

              if (fileId == Constants.FILE_ID_NOT_VALID)
                {
                  return null;                              /* return ! */
                }
              else
                ;
            /*end of if on fileId*/

              result[j] = new Fhandle( fileId,
                                       null,     /* do not care about host */
                                       this.dirPath +
                                         File.separator +
                                         directoryEntryNames[i],
                                       this.fileSystem,
                                       this                      );
              registry.put( result[j] );
            }
        /*end of if on directoryEntryFileHandles*/
        }
    /*end of for-loop on directoryEntryNames*/

      directoryEntryFileHandles = result;

      registry.save();

      return result;

    }
/*end of list*/


  public
  boolean

  setFilableInstance()
/*****************************************************************************/
/* Function name: setFilableInstance                                         */
/* File name: Fhandle.java                                                   */
/* Purpose: to set thisFile variable to a Filable object                     */
/* Parameters:                                                               */
/* Returns: true if OK, false - otherwise                                    */
/* Last modified: 19.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                  /* setFilableInstance */
/*---------------------------------------------------------------------------*/

      if (fileSystem == null)
        {
          return false;                                       /* return ! */
        }
      else
        ;
    /*end of if*/

      thisFile = fileSystem.
                   getFilableInstance( dirPath );

      if (thisFile == null)
        {
          return false;                                       /* return ! */
        }
      else
        {
          return true;                                        /* return ! */
        }
    /*end of if*/

    }
/*end of setFilableInstance*/


  public
  Readable

  openReadable()
/*****************************************************************************/
/* Function name: openReadable                                               */
/* File name: Fhandle.java                                                   */
/* Purpose: to set thisInputStream variable to an open Readable object       */
/* Parameters:                                                               */
/* Returns: thisInputStream - opened input stream ready to read from or      */
/*          null in case of an error                                         */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                    /* openReadable */
/*---------------------------------------------------------------------------*/

      thisFileInputStream =
        InstanceFileInputStream.open( thisFile );

      if (thisFileInputStream == null)
        {
          return null;                                       /* return ! */
        }
      else /* create a buffered stream */
        ;
    /*end of if*/

      thisInputStream = (Readable) new
        RegularBufferedInputStream(
          thisFileInputStream       );

      if (thisInputStream == null)
        {
          return null;                                       /* return ! */
        }
      else
        {
          return thisInputStream;                            /* return ! */
        }
    /*end of if*/

    }
/*end of openReadable*/


  public
  void

  closeReadable()
/*****************************************************************************/
/* Function name: closeReadable                                              */
/* File name: Fhandle.java                                                   */
/* Purpose: to close both the buffered and the underlying file input stream  */
/*          and to set the Input stream variables to null                    */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                    /* closeReadable */
/*---------------------------------------------------------------------------*/

      try
        {
          if (thisInputStream != null)
            {
              thisInputStream.close();
              thisInputStream = null;
            }
          else
            ;
        /*end of if*/
        }
      catch( IOException e )
        {
        }
    /*end of try-catch*/

      try
        {
          if (thisFileInputStream != null)
            {
              thisFileInputStream.close();
              thisFileInputStream = null;
            }
          else
            ;
        /*end of if*/
        }
      catch( IOException e )
        {
        }
    /*end of try-catch*/

    }
/*end of closeReadable*/


  public
  void

  refreshList()
/*****************************************************************************/
/* Function name: refreshList                                                */
/* File name: Fhandle.java                                                   */
/* Purpose: to reread the array of names of entries in the directory         */
/*          into internal cache variable                                     */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 22.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* refreshList */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        return;                                              /* return ! */
      else
        ;
    /*end of if*/

      directoryEntryNames = null;

    }
/*end of refreshList*/


  public
  void

  markAsAMountedFileSystem()
/*****************************************************************************/
/* Function name: markAsAMountedFileSystem                                   */
/* File name: Fhandle.java                                                   */
/* Purpose: to set the flag signifying this is a mounted file system         */
/*          that means e.g. that it does not have a parent directory         */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 22.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* markAsAMountedFileSystem */
/*---------------------------------------------------------------------------*/

      thisIsAMountedFileSystem = true;

    }
/*end of markAsAMountedFileSystem*/


  public
  boolean

  exists()
/*****************************************************************************/
/* Function name: exists                                                     */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object represents an existing file */
/* Parameters:                                                               */
/* Returns: true - if the file does exist, false - otherwise                 */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean result;
                                                       /* exists */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return false;                                  /* return ! */
        }
      else
        ;
    /*end of if*/

      result = thisFile.exists();

      return result;

    }
/*end of exists*/


  public
  boolean

  canRead()
/*****************************************************************************/
/* Function name: canRead                                                    */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object represents a readable file  */
/* Parameters:                                                               */
/* Returns: true - if the file is readable, false - otherwise                */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean result;
                                                       /* canRead */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return false;                                  /* return ! */
        }
      else
        ;
    /*end of if*/

      result = thisFile.canRead();

      return result;

    }
/*end of canRead*/


  public
  boolean

  isFile()
/*****************************************************************************/
/* Function name: isFile                                                     */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object represents a regular file   */
/* Parameters:                                                               */
/* Returns: true - if the file is regular, false - otherwise                 */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean result;
                                                       /* isFile */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return false;                                  /* return ! */
        }
      else
        ;
    /*end of if*/

      result = thisFile.isFile();

      return result;

    }
/*end of isFile*/


  public
  boolean

  canWrite()
/*****************************************************************************/
/* Function name: canWrite                                                   */
/* File name: Fhandle.java                                                   */
/* Purpose: to check whether this Fhandle object represents a writable  file */
/* Parameters:                                                               */
/* Returns: true - if the file is writable, false - otherwise                */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean result;
                                                       /* canWrite */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return false;                                  /* return ! */
        }
      else
        ;
    /*end of if*/

      result = thisFile.canWrite();

      return result;

    }
/*end of canWrite*/


  public
  long

  length()
/*****************************************************************************/
/* Function name: length                                                     */
/* File name: Fhandle.java                                                   */
/* Purpose: to return the length or the file that this Fhandle object        */
/*          represents                                                       */
/* Parameters:                                                               */
/* Returns: the length                                                       */
/* Last modified: 01.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long result;
                                                       /* length */
/*---------------------------------------------------------------------------*/

      if (thisFile == null)
        {
          return 0;                                       /* return ! */
        }
      else
        ;
    /*end of if*/

      result = thisFile.length();

      return result;

    }
/*end of length*/

} /* end of Fhandle class */

/*****************************************************************************/
/* End of file: Fhandle.java                                                 */
/*****************************************************************************/
