-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
gid-buffering.adb
79 lines (72 loc) · 2.15 KB
/
gid-buffering.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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;