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;