-------------------------------------------------------------------------------
--
--  <STRONG>Copyright &copy; 2001, 2002 by Thomas Wolf.</STRONG>
--  <BLOCKQUOTE>
--    This piece of software 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. This software is distributed in the hope that it will
--    be useful, but <EM>without any warranty</EM>; without even the implied
--    warranty of <EM>merchantability or fitness for a particular purpose.</EM>
--    See the GNU General Public License for  more details. You should have
--    received a copy of the GNU General Public License with this distribution,
--    see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
--    Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
--    USA.
--  </BLOCKQUOTE>
--  <BLOCKQUOTE>
--    As a special exception from the GPL, 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 GPL. This exception does not however invalidate any
--    other reasons why the executable file might be covered by the GPL.
--  </BLOCKQUOTE>
--
--  <AUTHOR>
--    Thomas Wolf  (TW) <E_MAIL>
--  </AUTHOR>
--
--  <PURPOSE>
--    Provides a generic function to unconditionally open (or create) a file.
--  </PURPOSE>
--
--  <NOT_TASK_SAFE>
--
--  <STORAGE>
--     @Copy_File@ dynamically allocates and deallocates a buffer.
--  </STORAGE>
--
--  <HISTORY>
--    02-MAR-2002   TW  Initial version.
--    09-JUN-2003   TW  Added 'Copy_File'.
--  </HISTORY>
-------------------------------------------------------------------------------

pragma License (Modified_GPL);

package Util.Files is

   pragma Elaborate_Body;

   generic
      type File_Type is limited private;
      type File_Mode is (<>);
      with procedure Open
             (File : in out File_Type;
              Mode : in     File_Mode;
              Name : in     String;
              Form : in     String);
      with procedure Create
             (File : in out File_Type;
              Mode : in     File_Mode;
              Name : in     String;
              Form : in     String);
   procedure Open_G
     (File : in out File_Type;
      Mode : in     File_Mode;
      Name : in     String;
      Form : in     String := "");
   --  First tries to open the file; if that fails, tries to create the file.

   type Buffer_Size is new Natural range 2 ** 10 .. 2 ** 20;
   --  Buffer size in bytes. Range is from 8k to 1M.


   Default_Buffer_Size : constant Buffer_Size := 2 ** 16;
   --  64kB.

   File_Exists : exception;

   procedure Copy_File
     (From      : in String;
      To        : in String      := "";
      Overwrite : in Boolean     := False;
      Buffer    : in Buffer_Size := Default_Buffer_Size);
   --  Safe file copy operation, it is abort deferred, but not task-safe.
   --
   --  Both @From@ and @To@ may contain pathes; if @From@ specifies a
   --  non-existing file, or @To@ contains the specification of a non-existing
   --  directory, the exception @Ada:IO_Exceptions.Name_Error@ will be raised.
   --  If @From@ specifies a directory, an unspecified exception may be raised,
   --  typically, this will be @Ada.IO_Exceptions.Use_Error@.
   --
   --  If both @To@ and @From@ specify the same file, an unspecified exception
   --  may be raised, typically, this will be @Ada.IO_Exceptions.Status_Error@.
   --
   --  If @To@ specifies an existing file and @Overwrite@ is @False@, the
   --  exception @File_Exists@ is raised.
   --
   --  If @To@ is the empty string, the file specified by @From@ is copied
   --  into the current directory.
   --
   --  The operation will copy the file in chunks of at most @Buffer@ bytes.
   --  The buffer for these chunks is allocated and deallocated dynamically.
   --
   --  If @To@ specifies only a directory, the file name is taken from @From@.
   --  If the operation fails halfway through, @To@ will be removed if it had
   --  been opened and the exception reporting the failure is propagated.

private

   procedure Copy
     (From      : in String;
      To        : in String;
      Overwrite : in Boolean;
      Buffer    : in Buffer_Size);
   --  Same as the above @Copy_File@, but just <EM>assumes</EM> that both
   --  @From@ and @To@ are full file specifications.
   --
   --  @Copy_File@ above calls this to actually copy the file.

end Util.Files;
