------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUNTIME COMPONENTS                          --
--                                                                          --
--                     S Y S T E M . D I R E C T _ I O                      --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision: 1.17 $
--                                                                          --
--          Copyright (C) 1992-1999 Free Software Foundation, Inc.          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT 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  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
--                                                                          --
------------------------------------------------------------------------------

with Ada.IO_Exceptions;         use Ada.IO_Exceptions;
with Interfaces.C_Streams;      use Interfaces.C_Streams;
with System;                    use System;
with System.File_IO;
with System.Soft_Links;
with Unchecked_Deallocation;

package body System.Direct_IO is

   package FIO renames System.File_IO;
   package SSL renames System.Soft_Links;

   subtype AP is FCB.AFCB_Ptr;
   use type FCB.Shared_Status_Type;

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Set_Position (File : in File_Type);
   --  Sets file position pointer according to value of current index

   -------------------
   -- AFCB_Allocate --
   -------------------

   function AFCB_Allocate (Control_Block : Direct_AFCB) return FCB.AFCB_Ptr is
   begin
      return new Direct_AFCB;
   end AFCB_Allocate;

   ----------------
   -- AFCB_Close --
   ----------------

   --  No special processing required for Direct_IO close

   procedure AFCB_Close (File : access Direct_AFCB) is
   begin
      null;
   end AFCB_Close;

   ---------------
   -- AFCB_Free --
   ---------------

   procedure AFCB_Free (File : access Direct_AFCB) is

      type FCB_Ptr is access all Direct_AFCB;

      FT : FCB_Ptr := FCB_Ptr (File);

      procedure Free is new
        Unchecked_Deallocation (Direct_AFCB, FCB_Ptr);

   begin
      Free (FT);
   end AFCB_Free;

   ------------
   -- Create --
   ------------

   procedure Create
     (File : in out File_Type;
      Mode : in FCB.File_Mode := FCB.Inout_File;
      Name : in String := "";
      Form : in String := "")
   is
      File_Control_Block : Direct_AFCB;

   begin
      FIO.Open (File_Ptr  => AP (File),
                Dummy_FCB => File_Control_Block,
                Mode      => Mode,
                Name      => Name,
                Form      => Form,
                Amethod   => 'D',
                Creat     => True,
                Text      => False);
   end Create;

   -----------------
   -- End_Of_File --
   -----------------

   function End_Of_File (File : in File_Type) return Boolean is
   begin
      FIO.Check_Read_Status (AP (File));
      return Count (File.Index) > Size (File);
   end End_Of_File;

   -----------
   -- Index --
   -----------

   function Index (File : in File_Type) return Positive_Count is
   begin
      FIO.Check_File_Open (AP (File));
      return Count (File.Index);
   end Index;

   ----------
   -- Open --
   ----------

   procedure Open
     (File : in out File_Type;
      Mode : in FCB.File_Mode;
      Name : in String;
      Form : in String := "")
   is
      File_Control_Block : Direct_AFCB;

   begin
      FIO.Open (File_Ptr  => AP (File),
                Dummy_FCB => File_Control_Block,
                Mode      => Mode,
                Name      => Name,
                Form      => Form,
                Amethod   => 'D',
                Creat     => False,
                Text      => False);
   end Open;

   ----------
   -- Read --
   ----------

   procedure Read
     (File : in File_Type;
      Item : Address;
      Size : in Interfaces.C_Streams.size_t;
      From : in Positive_Count)
   is
   begin
      Set_Index (File, From);
      Read (File, Item, Size);
   end Read;

   procedure Read
     (File : in File_Type;
      Item : Address;
      Size : in Interfaces.C_Streams.size_t)
   is
   begin
      FIO.Check_Read_Status (AP (File));

      --  If last operation was not a read, or if in file sharing mode,
      --  then reset the physical pointer of the file to match the index
      --  We lock out task access over the two operations in this case.

      if File.Last_Op /= Op_Read
        or else File.Shared_Status = FCB.Yes
      then
         if End_Of_File (File) then
            raise End_Error;
         end if;

         Locked_Processing : begin
            SSL.Lock_Task.all;
            Set_Position (File);
            FIO.Read_Buf (AP (File), Item, Size);
            SSL.Unlock_Task.all;

         exception
            when others =>
               SSL.Unlock_Task.all;
               raise;
         end Locked_Processing;

      else
         FIO.Read_Buf (AP (File), Item, Size);
      end if;

      File.Index := File.Index + 1;

      --  Set last operation to read, unless we did not read a full record
      --  (happens with the variant record case) in which case we set the
      --  last operation as other, to force the file position to be reset
      --  on the next read.

      if File.Bytes = Size then
         File.Last_Op := Op_Read;
      else
         File.Last_Op := Op_Other;
      end if;
   end Read;

   --  The following is the required overriding for Stream.Read, which is
   --  not used, since we do not do Stream operations on Direct_IO files.

   procedure Read
     (File : in out Direct_AFCB;
      Item : out Ada.Streams.Stream_Element_Array;
      Last : out Ada.Streams.Stream_Element_Offset)
   is
   begin
      raise Program_Error;
   end Read;

   -----------
   -- Reset --
   -----------

   procedure Reset (File : in out File_Type; Mode : in FCB.File_Mode) is
   begin
      FIO.Reset (AP (File), Mode);
      File.Index := 1;
      File.Last_Op := Op_Read;
   end Reset;

   procedure Reset (File : in out File_Type) is
   begin
      FIO.Reset (AP (File));
      File.Index := 1;
      File.Last_Op := Op_Read;
   end Reset;

   ---------------
   -- Set_Index --
   ---------------

   procedure Set_Index (File : in File_Type; To : in Positive_Count) is
   begin
      FIO.Check_File_Open (AP (File));
      File.Index := Count (To);
      File.Last_Op := Op_Other;
   end Set_Index;

   ------------------
   -- Set_Position --
   ------------------

   procedure Set_Position (File : in File_Type) is
   begin
      if fseek
           (File.Stream, long (File.Bytes) *
              long (File.Index - 1), SEEK_SET) /= 0
      then
         raise Use_Error;
      end if;
   end Set_Position;

   ----------
   -- Size --
   ----------

   function Size (File : in File_Type) return Count is
   begin
      FIO.Check_File_Open (AP (File));
      File.Last_Op := Op_Other;

      if fseek (File.Stream, 0, SEEK_END) /= 0 then
         raise Device_Error;
      end if;

      return Count (ftell (File.Stream) / long (File.Bytes));
   end Size;

   -----------
   -- Write --
   -----------

   procedure Write
     (File   : File_Type;
      Item   : Address;
      Size   : in Interfaces.C_Streams.size_t;
      Zeroes : System.Storage_Elements.Storage_Array)

   is
      procedure Do_Write;
      --  Do the actual write

      procedure Do_Write is
      begin
         FIO.Write_Buf (AP (File), Item, Size);

         --  If we did not write the whole record (happens with the variant
         --  record case), then fill out the rest of the record with zeroes.
         --  This is cleaner in any case, and is required for the last
         --  record, since otherwise the length of the file is wrong.

         if File.Bytes > Size then
            FIO.Write_Buf (AP (File), Zeroes'Address, File.Bytes - Size);
         end if;
      end Do_Write;

   --  Start of processing for Write

   begin
      FIO.Check_Write_Status (AP (File));

      --  If last operation was not a write, or if in file sharing mode,
      --  then reset the physical pointer of the file to match the index
      --  We lock out task access over the two operations in this case.

      if File.Last_Op /= Op_Write
        or else File.Shared_Status = FCB.Yes
      then
         Locked_Processing : begin
            SSL.Lock_Task.all;
            Set_Position (File);
            Do_Write;
            SSL.Unlock_Task.all;

         exception
            when others =>
               SSL.Unlock_Task.all;
               raise;
         end Locked_Processing;

      else
         Do_Write;
      end if;

      File.Index := File.Index + 1;

      --  Set last operation to write, unless we did not read a full record
      --  (happens with the variant record case) in which case we set the
      --  last operation as other, to force the file position to be reset
      --  on the next write.

      if File.Bytes = Size then
         File.Last_Op := Op_Write;
      else
         File.Last_Op := Op_Other;
      end if;
   end Write;

   --  The following is the required overriding for Stream.Write, which is
   --  not used, since we do not do Stream operations on Direct_IO files.

   procedure Write
     (File : in out Direct_AFCB;
      Item : in Ada.Streams.Stream_Element_Array)
   is
   begin
      raise Program_Error;
   end Write;

end System.Direct_IO;
