Home | History | Annotate | Download | only in ada
      1 ----------------------------------------------------------------
      2 --  ZLib for Ada thick binding.                               --
      3 --                                                            --
      4 --  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
      5 --                                                            --
      6 --  Open source license information is in the zlib.ads file.  --
      7 ----------------------------------------------------------------
      8 
      9 --  $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
     10 
     11 --  The program has a few aims.
     12 --  1. Test ZLib.Ada95 thick binding functionality.
     13 --  2. Show the example of use main functionality of the ZLib.Ada95 binding.
     14 --  3. Build this program automatically compile all ZLib.Ada95 packages under
     15 --     GNAT Ada95 compiler.
     16 
     17 with ZLib.Streams;
     18 with Ada.Streams.Stream_IO;
     19 with Ada.Numerics.Discrete_Random;
     20 
     21 with Ada.Text_IO;
     22 
     23 with Ada.Calendar;
     24 
     25 procedure Test is
     26 
     27    use Ada.Streams;
     28    use Stream_IO;
     29 
     30    ------------------------------------
     31    --  Test configuration parameters --
     32    ------------------------------------
     33 
     34    File_Size   : Count   := 100_000;
     35    Continuous  : constant Boolean := False;
     36 
     37    Header      : constant ZLib.Header_Type := ZLib.Default;
     38                                               --  ZLib.None;
     39                                               --  ZLib.Auto;
     40                                               --  ZLib.GZip;
     41    --  Do not use Header other then Default in ZLib versions 1.1.4
     42    --  and older.
     43 
     44    Strategy    : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
     45    Init_Random : constant := 10;
     46 
     47    -- End --
     48 
     49    In_File_Name  : constant String := "testzlib.in";
     50    --  Name of the input file
     51 
     52    Z_File_Name   : constant String := "testzlib.zlb";
     53    --  Name of the compressed file.
     54 
     55    Out_File_Name : constant String := "testzlib.out";
     56    --  Name of the decompressed file.
     57 
     58    File_In   : File_Type;
     59    File_Out  : File_Type;
     60    File_Back : File_Type;
     61    File_Z    : ZLib.Streams.Stream_Type;
     62 
     63    Filter : ZLib.Filter_Type;
     64 
     65    Time_Stamp : Ada.Calendar.Time;
     66 
     67    procedure Generate_File;
     68    --  Generate file of spetsified size with some random data.
     69    --  The random data is repeatable, for the good compression.
     70 
     71    procedure Compare_Streams
     72      (Left, Right : in out Root_Stream_Type'Class);
     73    --  The procedure compearing data in 2 streams.
     74    --  It is for compare data before and after compression/decompression.
     75 
     76    procedure Compare_Files (Left, Right : String);
     77    --  Compare files. Based on the Compare_Streams.
     78 
     79    procedure Copy_Streams
     80      (Source, Target : in out Root_Stream_Type'Class;
     81       Buffer_Size    : in     Stream_Element_Offset := 1024);
     82    --  Copying data from one stream to another. It is for test stream
     83    --  interface of the library.
     84 
     85    procedure Data_In
     86      (Item : out Stream_Element_Array;
     87       Last : out Stream_Element_Offset);
     88    --  this procedure is for generic instantiation of
     89    --  ZLib.Generic_Translate.
     90    --  reading data from the File_In.
     91 
     92    procedure Data_Out (Item : in Stream_Element_Array);
     93    --  this procedure is for generic instantiation of
     94    --  ZLib.Generic_Translate.
     95    --  writing data to the File_Out.
     96 
     97    procedure Stamp;
     98    --  Store the timestamp to the local variable.
     99 
    100    procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
    101    --  Print the time statistic with the message.
    102 
    103    procedure Translate is new ZLib.Generic_Translate
    104                                 (Data_In  => Data_In,
    105                                  Data_Out => Data_Out);
    106    --  This procedure is moving data from File_In to File_Out
    107    --  with compression or decompression, depend on initialization of
    108    --  Filter parameter.
    109 
    110    -------------------
    111    -- Compare_Files --
    112    -------------------
    113 
    114    procedure Compare_Files (Left, Right : String) is
    115       Left_File, Right_File : File_Type;
    116    begin
    117       Open (Left_File, In_File, Left);
    118       Open (Right_File, In_File, Right);
    119       Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
    120       Close (Left_File);
    121       Close (Right_File);
    122    end Compare_Files;
    123 
    124    ---------------------
    125    -- Compare_Streams --
    126    ---------------------
    127 
    128    procedure Compare_Streams
    129      (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
    130    is
    131       Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
    132       Left_Last, Right_Last : Stream_Element_Offset;
    133    begin
    134       loop
    135          Read (Left, Left_Buffer, Left_Last);
    136          Read (Right, Right_Buffer, Right_Last);
    137 
    138          if Left_Last /= Right_Last then
    139             Ada.Text_IO.Put_Line ("Compare error :"
    140               & Stream_Element_Offset'Image (Left_Last)
    141               & " /= "
    142               & Stream_Element_Offset'Image (Right_Last));
    143 
    144             raise Constraint_Error;
    145 
    146          elsif Left_Buffer (0 .. Left_Last)
    147                /= Right_Buffer (0 .. Right_Last)
    148          then
    149             Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
    150             raise Constraint_Error;
    151 
    152          end if;
    153 
    154          exit when Left_Last < Left_Buffer'Last;
    155       end loop;
    156    end Compare_Streams;
    157 
    158    ------------------
    159    -- Copy_Streams --
    160    ------------------
    161 
    162    procedure Copy_Streams
    163      (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
    164       Buffer_Size    : in     Stream_Element_Offset := 1024)
    165    is
    166       Buffer : Stream_Element_Array (1 .. Buffer_Size);
    167       Last   : Stream_Element_Offset;
    168    begin
    169       loop
    170          Read  (Source, Buffer, Last);
    171          Write (Target, Buffer (1 .. Last));
    172 
    173          exit when Last < Buffer'Last;
    174       end loop;
    175    end Copy_Streams;
    176 
    177    -------------
    178    -- Data_In --
    179    -------------
    180 
    181    procedure Data_In
    182      (Item : out Stream_Element_Array;
    183       Last : out Stream_Element_Offset) is
    184    begin
    185       Read (File_In, Item, Last);
    186    end Data_In;
    187 
    188    --------------
    189    -- Data_Out --
    190    --------------
    191 
    192    procedure Data_Out (Item : in Stream_Element_Array) is
    193    begin
    194       Write (File_Out, Item);
    195    end Data_Out;
    196 
    197    -------------------
    198    -- Generate_File --
    199    -------------------
    200 
    201    procedure Generate_File is
    202       subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
    203 
    204       package Random_Elements is
    205          new Ada.Numerics.Discrete_Random (Visible_Symbols);
    206 
    207       Gen    : Random_Elements.Generator;
    208       Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
    209 
    210       Buffer_Count : constant Count := File_Size / Buffer'Length;
    211       --  Number of same buffers in the packet.
    212 
    213       Density : constant Count := 30; --  from 0 to Buffer'Length - 2;
    214 
    215       procedure Fill_Buffer (J, D : in Count);
    216       --  Change the part of the buffer.
    217 
    218       -----------------
    219       -- Fill_Buffer --
    220       -----------------
    221 
    222       procedure Fill_Buffer (J, D : in Count) is
    223       begin
    224          for K in 0 .. D loop
    225             Buffer
    226               (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
    227              := Random_Elements.Random (Gen);
    228 
    229          end loop;
    230       end Fill_Buffer;
    231 
    232    begin
    233       Random_Elements.Reset (Gen, Init_Random);
    234 
    235       Create (File_In, Out_File, In_File_Name);
    236 
    237       Fill_Buffer (1, Buffer'Length - 2);
    238 
    239       for J in 1 .. Buffer_Count loop
    240          Write (File_In, Buffer);
    241 
    242          Fill_Buffer (J, Density);
    243       end loop;
    244 
    245       --  fill remain size.
    246 
    247       Write
    248         (File_In,
    249          Buffer
    250            (1 .. Stream_Element_Offset
    251                    (File_Size - Buffer'Length * Buffer_Count)));
    252 
    253       Flush (File_In);
    254       Close (File_In);
    255    end Generate_File;
    256 
    257    ---------------------
    258    -- Print_Statistic --
    259    ---------------------
    260 
    261    procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
    262       use Ada.Calendar;
    263       use Ada.Text_IO;
    264 
    265       package Count_IO is new Integer_IO (ZLib.Count);
    266 
    267       Curr_Dur : Duration := Clock - Time_Stamp;
    268    begin
    269       Put (Msg);
    270 
    271       Set_Col (20);
    272       Ada.Text_IO.Put ("size =");
    273 
    274       Count_IO.Put
    275         (Data_Size,
    276          Width => Stream_IO.Count'Image (File_Size)'Length);
    277 
    278       Put_Line (" duration =" & Duration'Image (Curr_Dur));
    279    end Print_Statistic;
    280 
    281    -----------
    282    -- Stamp --
    283    -----------
    284 
    285    procedure Stamp is
    286    begin
    287       Time_Stamp := Ada.Calendar.Clock;
    288    end Stamp;
    289 
    290 begin
    291    Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
    292 
    293    loop
    294       Generate_File;
    295 
    296       for Level in ZLib.Compression_Level'Range loop
    297 
    298          Ada.Text_IO.Put_Line ("Level ="
    299             & ZLib.Compression_Level'Image (Level));
    300 
    301          --  Test generic interface.
    302          Open   (File_In, In_File, In_File_Name);
    303          Create (File_Out, Out_File, Z_File_Name);
    304 
    305          Stamp;
    306 
    307          --  Deflate using generic instantiation.
    308 
    309          ZLib.Deflate_Init
    310                (Filter   => Filter,
    311                 Level    => Level,
    312                 Strategy => Strategy,
    313                 Header   => Header);
    314 
    315          Translate (Filter);
    316          Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
    317          ZLib.Close (Filter);
    318 
    319          Close (File_In);
    320          Close (File_Out);
    321 
    322          Open   (File_In, In_File, Z_File_Name);
    323          Create (File_Out, Out_File, Out_File_Name);
    324 
    325          Stamp;
    326 
    327          --  Inflate using generic instantiation.
    328 
    329          ZLib.Inflate_Init (Filter, Header => Header);
    330 
    331          Translate (Filter);
    332          Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
    333 
    334          ZLib.Close (Filter);
    335 
    336          Close (File_In);
    337          Close (File_Out);
    338 
    339          Compare_Files (In_File_Name, Out_File_Name);
    340 
    341          --  Test stream interface.
    342 
    343          --  Compress to the back stream.
    344 
    345          Open   (File_In, In_File, In_File_Name);
    346          Create (File_Back, Out_File, Z_File_Name);
    347 
    348          Stamp;
    349 
    350          ZLib.Streams.Create
    351            (Stream          => File_Z,
    352             Mode            => ZLib.Streams.Out_Stream,
    353             Back            => ZLib.Streams.Stream_Access
    354                                  (Stream (File_Back)),
    355             Back_Compressed => True,
    356             Level           => Level,
    357             Strategy        => Strategy,
    358             Header          => Header);
    359 
    360          Copy_Streams
    361            (Source => Stream (File_In).all,
    362             Target => File_Z);
    363 
    364          --  Flushing internal buffers to the back stream.
    365 
    366          ZLib.Streams.Flush (File_Z, ZLib.Finish);
    367 
    368          Print_Statistic ("Write compress",
    369                           ZLib.Streams.Write_Total_Out (File_Z));
    370 
    371          ZLib.Streams.Close (File_Z);
    372 
    373          Close (File_In);
    374          Close (File_Back);
    375 
    376          --  Compare reading from original file and from
    377          --  decompression stream.
    378 
    379          Open (File_In,   In_File, In_File_Name);
    380          Open (File_Back, In_File, Z_File_Name);
    381 
    382          ZLib.Streams.Create
    383            (Stream          => File_Z,
    384             Mode            => ZLib.Streams.In_Stream,
    385             Back            => ZLib.Streams.Stream_Access
    386                                  (Stream (File_Back)),
    387             Back_Compressed => True,
    388             Header          => Header);
    389 
    390          Stamp;
    391          Compare_Streams (Stream (File_In).all, File_Z);
    392 
    393          Print_Statistic ("Read decompress",
    394                           ZLib.Streams.Read_Total_Out (File_Z));
    395 
    396          ZLib.Streams.Close (File_Z);
    397          Close (File_In);
    398          Close (File_Back);
    399 
    400          --  Compress by reading from compression stream.
    401 
    402          Open (File_Back, In_File, In_File_Name);
    403          Create (File_Out, Out_File, Z_File_Name);
    404 
    405          ZLib.Streams.Create
    406            (Stream          => File_Z,
    407             Mode            => ZLib.Streams.In_Stream,
    408             Back            => ZLib.Streams.Stream_Access
    409                                  (Stream (File_Back)),
    410             Back_Compressed => False,
    411             Level           => Level,
    412             Strategy        => Strategy,
    413             Header          => Header);
    414 
    415          Stamp;
    416          Copy_Streams
    417            (Source => File_Z,
    418             Target => Stream (File_Out).all);
    419 
    420          Print_Statistic ("Read compress",
    421                           ZLib.Streams.Read_Total_Out (File_Z));
    422 
    423          ZLib.Streams.Close (File_Z);
    424 
    425          Close (File_Out);
    426          Close (File_Back);
    427 
    428          --  Decompress to decompression stream.
    429 
    430          Open   (File_In,   In_File, Z_File_Name);
    431          Create (File_Back, Out_File, Out_File_Name);
    432 
    433          ZLib.Streams.Create
    434            (Stream          => File_Z,
    435             Mode            => ZLib.Streams.Out_Stream,
    436             Back            => ZLib.Streams.Stream_Access
    437                                  (Stream (File_Back)),
    438             Back_Compressed => False,
    439             Header          => Header);
    440 
    441          Stamp;
    442 
    443          Copy_Streams
    444            (Source => Stream (File_In).all,
    445             Target => File_Z);
    446 
    447          Print_Statistic ("Write decompress",
    448                           ZLib.Streams.Write_Total_Out (File_Z));
    449 
    450          ZLib.Streams.Close (File_Z);
    451          Close (File_In);
    452          Close (File_Back);
    453 
    454          Compare_Files (In_File_Name, Out_File_Name);
    455       end loop;
    456 
    457       Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
    458 
    459       exit when not Continuous;
    460 
    461       File_Size := File_Size + 1;
    462    end loop;
    463 end Test;
    464