| ---------------------------------------------------------------- | |
| -- 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; |