File : adagio-decoupled_file_stream.adb
package body Adagio.Decoupled_file_stream is
use type Stream_IO.Count;
-- Overriden primitives:
procedure Read(
Stream : in out Decoupled_file_stream;
Item : out Stream_Element_Array;
Last : out Stream_Element_Offset) is
F: Stream_IO.File_type;
begin
-- Open the associated file:
Stream_IO.Open(F, Stream_IO.In_file, To_string(Stream.File),
"shared=yes");
-- Read requested items from current position:
Stream_IO.Read(F, Item, Last, Stream.Filepos);
-- Close file:
Stream_IO.Close(F);
-- Mark new position:
Set_position
(Stream,
Stream.Filepos + Stream_IO.Positive_count(Last - Item'first + 1));
exception
when others =>
if Stream_IO.Is_open(F) then
Stream_IO.Close(F);
end if;
raise;
end Read;
-- Only reading is implemented.
-- Thus, any call to this raises Unimplemented_error.
procedure Write(
Stream : in out Decoupled_file_stream;
Item : in Stream_Element_Array) is
begin
raise Unimplemented;
end Write;
-- Creation. We need a path to file:
procedure Get_decoupled_file_stream
(Stream: out Decoupled_file_stream;
File: String) is
begin
Stream.File:= To_UString(File);
Stream.Filepos:= Stream_IO.Positive_count'First; -- 1
end Get_decoupled_file_stream;
-- Seek
procedure Set_position
(Stream: in out Decoupled_file_stream;
Pos: Stream_IO.Positive_count) is
begin
Stream.Filepos:= Pos;
end Set_position;
-- Size
function Size(Stream: Decoupled_file_stream) return Stream_IO.Count is
F: Stream_IO.File_type;
size: Stream_IO.Count;
begin
-- Open the associated file:
Stream_IO.Open(F, Stream_IO.In_file, To_string(Stream.File),
"shared=yes");
size:= Stream_IO.Size(F);
Stream_IO.Close(F);
return size;
exception
when others =>
if Stream_IO.Is_open(F) then
Stream_IO.Close(F);
end if;
raise;
end Size;
function End_of_stream(Stream: Decoupled_file_stream)
return boolean is
F: Stream_IO.File_type;
EOF: Boolean;
begin
-- Open the associated file:
Stream_IO.Open(F, Stream_IO.In_file, To_string(Stream.File),
"shared=yes");
EOF:= Stream.Filepos > Stream_IO.Size(F);
-- Close file:
Stream_IO.Close(F);
return EOF;
exception
when others =>
if Stream_IO.Is_open(F) then
Stream_IO.Close(F);
end if;
raise;
end End_of_stream;
end Adagio.Decoupled_file_stream;