80 lines
2.2 KiB
Ada
80 lines
2.2 KiB
Ada
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;
|