with Ada.IO_Exceptions;
package body GID.Buffering is
procedure Fill_Buffer(b: in out Input_buffer);
-- ^ Spec here to avoid warning by 'Get_Byte' below (GNAT 2009):
-- warning: call to subprogram with no separate spec prevents inlining
procedure Fill_Buffer(b: in out Input_buffer)
is
--
procedure BlockRead(
buffer : out Byte_Array;
actually_read: out Natural
)
is
use Ada.Streams;
Last_Read: Stream_Element_Offset;
begin
if is_mapping_possible then
declare
SE_Buffer_mapped: Stream_Element_Array (1 .. buffer'Length);
-- direct mapping: buffer = SE_Buffer_mapped
for SE_Buffer_mapped'Address use buffer'Address;
pragma Import (Ada, SE_Buffer_mapped);
begin
Read(b.stream.all, SE_Buffer_mapped, Last_Read);
end;
else
declare
SE_Buffer: Stream_Element_Array (1 .. buffer'Length);
-- need to copy array (slightly slower)
begin
Read(b.stream.all, SE_Buffer, Last_Read);
for i in buffer'Range loop
buffer(i):= U8(SE_Buffer(Stream_Element_Offset(i-buffer'First)+SE_buffer'First));
end loop;
end;
end if;
actually_read:= Natural(Last_Read);
end BlockRead;
--
begin
BlockRead(
buffer => b.data,
actually_read => b.MaxInBufIdx
);
b.InputEoF:= b.MaxInBufIdx = 0;
b.InBufIdx := 1;
end Fill_Buffer;
procedure Attach_Stream(
b : out Input_buffer;
stm : in Stream_Access
)
is
begin
b.stream:= stm;
-- Fill_Buffer(b) will be performed on first call of Get_Byte
end Attach_Stream;
function Is_stream_attached(b: Input_buffer) return Boolean is
begin
return b.stream /= null;
end Is_stream_attached;
procedure Get_Byte(b: in out Input_buffer; byte: out U8) is
begin
if b.InBufIdx > b.MaxInBufIdx then
Fill_Buffer(b);
if b.InputEoF then
raise Ada.IO_Exceptions.End_Error;
end if;
end if;
byte:= b.data(b.InBufIdx);
b.InBufIdx:= b.InBufIdx + 1;
end Get_Byte;
end GID.Buffering;