File : buf_streams.adb


   1 with Ada.Directories;
   2 with Ada.Direct_IO;
   3 with Ada.IO_Exceptions;
   4 
   5 
   6 package body Buf_Streams is
   7    
   8    overriding
   9    procedure Read(Stream : in out Buf_Stream;
  10                   Item   : out Stream_Element_Array;
  11                   Last   : out Stream_Element_Offset) is
  12       NWanted : Stream_Element_Offset := Item'Last - Item'First + 1;
  13       NAvail  : constant Stream_Element_Offset := Stream.Fill_Idx - Stream.Read_Idx;
  14    begin
  15       if NWanted > NAvail then
  16          NWanted := NAvail;
  17          --  raise Ada.IO_Exceptions.End_Error;
  18       end if;
  19       
  20       Item(1 .. NWanted) :=
  21         Stream.Buffer(Stream.Read_Idx .. Stream.Read_Idx + NWanted - 1);
  22       
  23       Stream.Read_Idx := Stream.Read_Idx + NWanted;
  24       Last := Item'First + NWanted - 1;
  25    end Read;
  26    
  27    
  28    overriding
  29    procedure Write(Stream : in out Buf_Stream;
  30                    Item   : in Stream_Element_Array) is
  31       NWanted : constant Stream_Element_Offset := Item'Last - Item'First + 1;
  32       Last    : constant Stream_Element_Offset := Stream.Fill_Idx + NWanted - 1;
  33    begin
  34       if Last > Stream.Buffer'Last then
  35          raise Ada.IO_Exceptions.End_Error; -- no room
  36       end if;
  37       
  38       Stream.Buffer(Stream.Fill_Idx .. Last) := Item;
  39       Stream.Fill_Idx := Stream.Fill_Idx + NWanted;
  40    end Write;
  41    
  42    
  43    procedure Reset(Stream : in out Buf_Stream) is
  44    begin
  45       Stream.Fill_Idx := Stream.Buffer'First;
  46       Stream.Read_Idx := Stream.Buffer'First;
  47    end Reset;
  48    
  49    
  50    function GetFill(Stream : in Buf_Stream) return Natural is
  51    begin
  52       return Natural(Stream.Fill_Idx);
  53    end;
  54    pragma inline(GetFill);
  55    
  56    ---------------------------------------------------------------------------
  57    
  58    procedure Fill_From_File(Stream : in out Buf_Stream;
  59                             Path   : in String) is
  60       
  61       File_Size : constant Stream_Element_Offset :=
  62         Stream_Element_Offset(Ada.Directories.Size(Path));
  63       
  64       Last : constant Stream_Element_Offset := Stream.Fill_Idx + File_Size - 1;
  65       
  66       subtype Buf is Stream_Element_Array(1 .. File_Size);
  67       package Buf_IO is new Ada.Direct_IO(Buf);
  68       
  69       File : Buf_IO.File_Type;
  70    begin
  71       if Last > Stream.Buffer'Last then
  72          raise Ada.IO_Exceptions.End_Error; -- no room
  73       end if;
  74       
  75       Buf_IO.Open(File, Mode => Buf_IO.In_File, Name => Path);
  76       Buf_IO.Read(File, Item => Stream.Buffer(Stream.Fill_Idx .. Last));
  77       Buf_IO.Close(File);
  78       Stream.Fill_Idx := Stream.Fill_Idx + File_Size;
  79    end Fill_From_File;
  80    
  81    
  82    procedure Save_To_File(Stream : in out Buf_Stream;
  83                           Path   : in String) is
  84       subtype Buf is Stream_Element_Array(1 .. Stream.Fill_Idx - 1);
  85       package Buf_IO is new Ada.Direct_IO(Buf);
  86       File : Buf_IO.File_Type;
  87    begin
  88       Buf_IO.Create(File, Mode => Buf_IO.Out_File, Name => Path);
  89       Buf_IO.Write(File, Item => Stream.Buffer(1 .. Stream.Fill_Idx - 1));
  90       Buf_IO.Close(File);
  91    end Save_To_File;
  92    
  93 end Buf_Streams;