|
|
----------------------------------------------------------------
-- ZLib for Ada thick binding. --
-- --
-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
-- --
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
-- The program has a few aims.
-- 1. Test ZLib.Ada95 thick binding functionality.
-- 2. Show the example of use main functionality of the ZLib.Ada95 binding.
-- 3. Build this program automatically compile all ZLib.Ada95 packages under
-- GNAT Ada95 compiler.
with ZLib.Streams; with Ada.Streams.Stream_IO; with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
with Ada.Calendar;
procedure Test is
use Ada.Streams; use Stream_IO;
------------------------------------
-- Test configuration parameters --
------------------------------------
File_Size : Count := 100_000; Continuous : constant Boolean := False;
Header : constant ZLib.Header_Type := ZLib.Default; -- ZLib.None;
-- ZLib.Auto;
-- ZLib.GZip;
-- Do not use Header other then Default in ZLib versions 1.1.4
-- and older.
Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy; Init_Random : constant := 10;
-- End --
In_File_Name : constant String := "testzlib.in"; -- Name of the input file
Z_File_Name : constant String := "testzlib.zlb"; -- Name of the compressed file.
Out_File_Name : constant String := "testzlib.out"; -- Name of the decompressed file.
File_In : File_Type; File_Out : File_Type; File_Back : File_Type; File_Z : ZLib.Streams.Stream_Type;
Filter : ZLib.Filter_Type;
Time_Stamp : Ada.Calendar.Time;
procedure Generate_File; -- Generate file of spetsified size with some random data.
-- The random data is repeatable, for the good compression.
procedure Compare_Streams (Left, Right : in out Root_Stream_Type'Class); -- The procedure compearing data in 2 streams.
-- It is for compare data before and after compression/decompression.
procedure Compare_Files (Left, Right : String); -- Compare files. Based on the Compare_Streams.
procedure Copy_Streams (Source, Target : in out Root_Stream_Type'Class; Buffer_Size : in Stream_Element_Offset := 1024); -- Copying data from one stream to another. It is for test stream
-- interface of the library.
procedure Data_In (Item : out Stream_Element_Array; Last : out Stream_Element_Offset); -- this procedure is for generic instantiation of
-- ZLib.Generic_Translate.
-- reading data from the File_In.
procedure Data_Out (Item : in Stream_Element_Array); -- this procedure is for generic instantiation of
-- ZLib.Generic_Translate.
-- writing data to the File_Out.
procedure Stamp; -- Store the timestamp to the local variable.
procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count); -- Print the time statistic with the message.
procedure Translate is new ZLib.Generic_Translate (Data_In => Data_In, Data_Out => Data_Out); -- This procedure is moving data from File_In to File_Out
-- with compression or decompression, depend on initialization of
-- Filter parameter.
-------------------
-- Compare_Files --
-------------------
procedure Compare_Files (Left, Right : String) is Left_File, Right_File : File_Type; begin Open (Left_File, In_File, Left); Open (Right_File, In_File, Right); Compare_Streams (Stream (Left_File).all, Stream (Right_File).all); Close (Left_File); Close (Right_File); end Compare_Files;
---------------------
-- Compare_Streams --
---------------------
procedure Compare_Streams (Left, Right : in out Ada.Streams.Root_Stream_Type'Class) is Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#); Left_Last, Right_Last : Stream_Element_Offset; begin loop Read (Left, Left_Buffer, Left_Last); Read (Right, Right_Buffer, Right_Last);
if Left_Last /= Right_Last then Ada.Text_IO.Put_Line ("Compare error :" & Stream_Element_Offset'Image (Left_Last) & " /= " & Stream_Element_Offset'Image (Right_Last));
raise Constraint_Error;
elsif Left_Buffer (0 .. Left_Last) /= Right_Buffer (0 .. Right_Last) then Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal."); raise Constraint_Error;
end if;
exit when Left_Last < Left_Buffer'Last; end loop; end Compare_Streams;
------------------
-- Copy_Streams --
------------------
procedure Copy_Streams (Source, Target : in out Ada.Streams.Root_Stream_Type'Class; Buffer_Size : in Stream_Element_Offset := 1024) is Buffer : Stream_Element_Array (1 .. Buffer_Size); Last : Stream_Element_Offset; begin loop Read (Source, Buffer, Last); Write (Target, Buffer (1 .. Last));
exit when Last < Buffer'Last; end loop; end Copy_Streams;
-------------
-- Data_In --
-------------
procedure Data_In (Item : out Stream_Element_Array; Last : out Stream_Element_Offset) is begin Read (File_In, Item, Last); end Data_In;
--------------
-- Data_Out --
--------------
procedure Data_Out (Item : in Stream_Element_Array) is begin Write (File_Out, Item); end Data_Out;
-------------------
-- Generate_File --
-------------------
procedure Generate_File is subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
package Random_Elements is new Ada.Numerics.Discrete_Random (Visible_Symbols);
Gen : Random_Elements.Generator; Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
Buffer_Count : constant Count := File_Size / Buffer'Length; -- Number of same buffers in the packet.
Density : constant Count := 30; -- from 0 to Buffer'Length - 2;
procedure Fill_Buffer (J, D : in Count); -- Change the part of the buffer.
-----------------
-- Fill_Buffer --
-----------------
procedure Fill_Buffer (J, D : in Count) is begin for K in 0 .. D loop Buffer (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1)) := Random_Elements.Random (Gen);
end loop; end Fill_Buffer;
begin Random_Elements.Reset (Gen, Init_Random);
Create (File_In, Out_File, In_File_Name);
Fill_Buffer (1, Buffer'Length - 2);
for J in 1 .. Buffer_Count loop Write (File_In, Buffer);
Fill_Buffer (J, Density); end loop;
-- fill remain size.
Write (File_In, Buffer (1 .. Stream_Element_Offset (File_Size - Buffer'Length * Buffer_Count)));
Flush (File_In); Close (File_In); end Generate_File;
---------------------
-- Print_Statistic --
---------------------
procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is use Ada.Calendar; use Ada.Text_IO;
package Count_IO is new Integer_IO (ZLib.Count);
Curr_Dur : Duration := Clock - Time_Stamp; begin Put (Msg);
Set_Col (20); Ada.Text_IO.Put ("size =");
Count_IO.Put (Data_Size, Width => Stream_IO.Count'Image (File_Size)'Length);
Put_Line (" duration =" & Duration'Image (Curr_Dur)); end Print_Statistic;
-----------
-- Stamp --
-----------
procedure Stamp is begin Time_Stamp := Ada.Calendar.Clock; end Stamp;
begin Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
loop Generate_File;
for Level in ZLib.Compression_Level'Range loop
Ada.Text_IO.Put_Line ("Level =" & ZLib.Compression_Level'Image (Level));
-- Test generic interface.
Open (File_In, In_File, In_File_Name); Create (File_Out, Out_File, Z_File_Name);
Stamp;
-- Deflate using generic instantiation.
ZLib.Deflate_Init (Filter => Filter, Level => Level, Strategy => Strategy, Header => Header);
Translate (Filter); Print_Statistic ("Generic compress", ZLib.Total_Out (Filter)); ZLib.Close (Filter);
Close (File_In); Close (File_Out);
Open (File_In, In_File, Z_File_Name); Create (File_Out, Out_File, Out_File_Name);
Stamp;
-- Inflate using generic instantiation.
ZLib.Inflate_Init (Filter, Header => Header);
Translate (Filter); Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
ZLib.Close (Filter);
Close (File_In); Close (File_Out);
Compare_Files (In_File_Name, Out_File_Name);
-- Test stream interface.
-- Compress to the back stream.
Open (File_In, In_File, In_File_Name); Create (File_Back, Out_File, Z_File_Name);
Stamp;
ZLib.Streams.Create (Stream => File_Z, Mode => ZLib.Streams.Out_Stream, Back => ZLib.Streams.Stream_Access (Stream (File_Back)), Back_Compressed => True, Level => Level, Strategy => Strategy, Header => Header);
Copy_Streams (Source => Stream (File_In).all, Target => File_Z);
-- Flushing internal buffers to the back stream.
ZLib.Streams.Flush (File_Z, ZLib.Finish);
Print_Statistic ("Write compress", ZLib.Streams.Write_Total_Out (File_Z));
ZLib.Streams.Close (File_Z);
Close (File_In); Close (File_Back);
-- Compare reading from original file and from
-- decompression stream.
Open (File_In, In_File, In_File_Name); Open (File_Back, In_File, Z_File_Name);
ZLib.Streams.Create (Stream => File_Z, Mode => ZLib.Streams.In_Stream, Back => ZLib.Streams.Stream_Access (Stream (File_Back)), Back_Compressed => True, Header => Header);
Stamp; Compare_Streams (Stream (File_In).all, File_Z);
Print_Statistic ("Read decompress", ZLib.Streams.Read_Total_Out (File_Z));
ZLib.Streams.Close (File_Z); Close (File_In); Close (File_Back);
-- Compress by reading from compression stream.
Open (File_Back, In_File, In_File_Name); Create (File_Out, Out_File, Z_File_Name);
ZLib.Streams.Create (Stream => File_Z, Mode => ZLib.Streams.In_Stream, Back => ZLib.Streams.Stream_Access (Stream (File_Back)), Back_Compressed => False, Level => Level, Strategy => Strategy, Header => Header);
Stamp; Copy_Streams (Source => File_Z, Target => Stream (File_Out).all);
Print_Statistic ("Read compress", ZLib.Streams.Read_Total_Out (File_Z));
ZLib.Streams.Close (File_Z);
Close (File_Out); Close (File_Back);
-- Decompress to decompression stream.
Open (File_In, In_File, Z_File_Name); Create (File_Back, Out_File, Out_File_Name);
ZLib.Streams.Create (Stream => File_Z, Mode => ZLib.Streams.Out_Stream, Back => ZLib.Streams.Stream_Access (Stream (File_Back)), Back_Compressed => False, Header => Header);
Stamp;
Copy_Streams (Source => Stream (File_In).all, Target => File_Z);
Print_Statistic ("Write decompress", ZLib.Streams.Write_Total_Out (File_Z));
ZLib.Streams.Close (File_Z); Close (File_In); Close (File_Back);
Compare_Files (In_File_Name, Out_File_Name); end loop;
Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
exit when not Continuous;
File_Size := File_Size + 1; end loop; end Test;
|