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