-- Binary files that are opened/created at declaration and closed when finalized
-- See the child package Text for text I/O
-- Copyright (C) by PragmAda Software Engineering
-- Released under the terms of the BSD 3-Clause license; see https://opensource.org/licenses
with Ada.Directories;
with Interfaces;
private with Ada.Finalization;
private with Ada.Direct_IO;
package Controlled_IO is
type File_Handle (<>) is tagged limited private;
-- Opened/created on creation, closed on finalization
-- Can be both read and written
use type Ada.Directories.File_Kind;
function Opened (Name : in String; Form : in String := "") return File_Handle with
Pre => Ada.Directories.Exists (Name) and then Ada.Directories.Kind (Name) = Ada.Directories.Ordinary_File,
Post => Opened'Result.Position = 1;
-- Opens an existing file
function Created (Name : in String; Form : in String := "") return File_Handle with
Post => Created'Result.Position = 1;
-- Creates a new file named Name (deleting any existing file named Name)
function Opened_Or_Created (Name : in String; Form : in String := "") return File_Handle is
(if Ada.Directories.Exists (Name) then Opened (Name, Form) else Created (Name, Form) );
function End_Of_File (File : in File_Handle) return Boolean;
-- Returns File.Position > File.Size
subtype Byte is Interfaces.Unsigned_8;
type Byte_List is array (Positive range <>) of Byte;
type Count_Value is mod 2 ** 64;
subtype Position_Value is Count_Value range 1 .. Count_Value'Last;
function Size (File : in File_Handle) return Count_Value;
-- Returns the current number of bytes in File
procedure Set_Position (File : in out File_Handle; Position : in Position_Value) with
Pre => Position in 1 .. File.Size + 1;
-- Sets the current position of File to Position
function Position (File : in File_Handle) return Position_Value;
-- Returns the current position in File
function Next (File : in out File_Handle) return Byte with
Pre => not File.End_Of_File;
-- Returns the byte in File at the current position and increments the current position
procedure Read (File : in out File_Handle; List : out Byte_List) with
Pre => not File.End_Of_File;
-- Calls File.Next for every Byte in List
-- Raises Ada.IO_Exceptions.End_Error if there are fewer than List'Length bytes left in File
procedure Write (File : in out File_Handle; Value : in Byte);
-- Writes Value to File at the current position and increments the current position
procedure Write (File : in out File_Handle; Value : in Byte_List);
-- Calls File.Write for every Byte in Value
private -- Controlled_IO
package Byte_IO is new Ada.Direct_IO (Element_Type => Byte);
type File_Handle is new Ada.Finalization.Limited_Controlled with record
Handle : Byte_IO.File_Type;
end record;
overriding procedure Finalize (Object : in out File_Handle);
function End_Of_File (File : in File_Handle) return Boolean is
(Byte_IO.End_Of_File (File.Handle) );
function Size (File : in File_Handle) return Count_Value is
(Count_Value (Byte_IO.Size (File.Handle) ) );
function Position (File : in File_Handle) return Position_Value is
(Position_Value (Byte_IO.Index (File.Handle) ) );
end Controlled_IO;