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