134 lines
4.5 KiB
Diff
134 lines
4.5 KiB
Diff
--- a/zlib-streams.adb
|
|
+++ b/zlib-streams.adb
|
|
@@ -83,6 +83,7 @@ package body ZLib.Streams is
|
|
Stream.Buffer := new Buffer_Subtype;
|
|
Stream.Rest_First := Stream.Buffer'Last + 1;
|
|
Stream.Rest_Last := Stream.Buffer'Last;
|
|
+ Stream.Ahead_Last := Stream.Buffer'First - 1;
|
|
end if;
|
|
end Create;
|
|
|
|
@@ -100,9 +101,9 @@ package body ZLib.Streams is
|
|
loop
|
|
Flush (Stream.Writer, Buffer, Last, Mode);
|
|
|
|
- Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
|
|
+ exit when Last < Buffer'First;
|
|
|
|
- exit when Last < Buffer'Last;
|
|
+ Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
|
|
end loop;
|
|
end Flush;
|
|
|
|
@@ -146,8 +147,71 @@ package body ZLib.Streams is
|
|
Rest_First => Stream.Rest_First,
|
|
Rest_Last => Stream.Rest_Last);
|
|
|
|
+ Ahead_First : Stream_Element_Offset;
|
|
+ Ahead_Last : Stream_Element_Offset;
|
|
+
|
|
begin
|
|
- Read (Stream.Reader, Item, Last);
|
|
+ if Stream.Ahead_Last > Stream.Rest_Last then
|
|
+ Last := Item'First - 1;
|
|
+ Ahead_First := Stream.Rest_Last + 1;
|
|
+
|
|
+ loop
|
|
+ if Last = Item'Last then
|
|
+ Ahead_Last :=
|
|
+ Stream.Rest_Last + Stream.Ahead_Last - Ahead_First + 1;
|
|
+ Stream.Buffer
|
|
+ (Stream.Rest_Last + 1 .. Ahead_Last) :=
|
|
+ Stream.Buffer (Ahead_First .. Stream.Ahead_Last);
|
|
+ Stream.Ahead_Last := Ahead_Last;
|
|
+ return;
|
|
+ end if;
|
|
+
|
|
+ Last := Last + 1;
|
|
+
|
|
+ Item (Last) := Stream.Buffer (Ahead_First);
|
|
+
|
|
+ if Ahead_First = Stream.Ahead_Last then
|
|
+ Stream.Ahead_Last := Stream.Buffer'First - 1;
|
|
+ exit;
|
|
+ end if;
|
|
+
|
|
+ Ahead_First := Ahead_First + 1;
|
|
+ end loop;
|
|
+
|
|
+ if Last < Item'Last then
|
|
+ Read (Stream.Reader, Item (Last + 1 .. Item'Last), Last);
|
|
+ end if;
|
|
+
|
|
+ else
|
|
+ Read (Stream.Reader, Item, Last);
|
|
+ end if;
|
|
+
|
|
+ if not Stream.Reader.Stream_End
|
|
+ and then Stream.Rest_First > Stream.Rest_Last
|
|
+ then
|
|
+ -- Try read ahead to detect end of stream early
|
|
+
|
|
+ Read (Stream.Buffer.all, Stream.Rest_Last);
|
|
+ Stream.Rest_First := Stream.Buffer'First;
|
|
+
|
|
+ if Stream.Rest_Last = Stream.Buffer'Last then
|
|
+ -- No space to read ahead
|
|
+ return;
|
|
+ end if;
|
|
+
|
|
+ Translate
|
|
+ (Stream.Reader,
|
|
+ Stream.Buffer (Stream.Rest_First .. Stream.Rest_Last),
|
|
+ In_Last => Stream.Rest_First,
|
|
+ Out_Data =>
|
|
+ Stream.Buffer (Stream.Rest_Last + 1 .. Stream.Buffer'Last),
|
|
+ Out_Last => Stream.Ahead_Last,
|
|
+ Flush => (if Stream.Rest_First > Stream.Rest_Last
|
|
+ then Finish
|
|
+ else No_Flush));
|
|
+
|
|
+ Stream.Rest_First := Stream.Rest_First + 1;
|
|
+ end if;
|
|
end Read;
|
|
|
|
-------------------
|
|
--- a/zlib-streams.ads
|
|
+++ b/zlib-streams.ads
|
|
@@ -91,6 +91,11 @@ private
|
|
-- We need to have this buffer in the record because not all read data
|
|
-- from back stream could be processed during the read operation.
|
|
|
|
+ Ahead_Last : Stream_Element_Offset;
|
|
+ -- Sometimes the decompressed data is over but the gzip footer still was
|
|
+ -- not read from back stream. We should try to read ahead in case we are
|
|
+ -- suspect this to detect end of stream proper.
|
|
+
|
|
Buffer_Size : Stream_Element_Offset;
|
|
-- Buffer size for write operation.
|
|
-- We do not need to have this buffer in the record because all data
|
|
@@ -102,6 +107,8 @@ private
|
|
end record;
|
|
|
|
function End_Of_Stream (Stream : in Stream_Type) return Boolean is
|
|
- (Stream_End (Stream.Reader));
|
|
+ (Stream_End (Stream.Reader)
|
|
+ and then Stream.Rest_First > Stream.Rest_Last
|
|
+ and then Stream.Rest_Last >= Stream.Ahead_Last);
|
|
|
|
end ZLib.Streams;
|
|
--- a/zlib.ads
|
|
+++ b/zlib.ads
|
|
@@ -263,8 +263,10 @@ package ZLib is
|
|
|
|
Rest_First, Rest_Last : in out Stream_Element_Offset;
|
|
-- Rest_First have to be initialized to Buffer'Last + 1
|
|
- -- Rest_Last have to be initialized to Buffer'Last
|
|
- -- before usage.
|
|
+ -- Rest_Last have to be initialized to Buffer'Last before usage.
|
|
+ -- When no more data provided with first generic parameter procedure
|
|
+ -- Read then the Read_First became Buffer'First and the Read_Last became
|
|
+ -- Buffer'First - 1.
|
|
|
|
Allow_Read_Some : in Boolean := False;
|
|
-- Is it allowed to return Last < Item'Last before end of data
|