annotate src/zlib-1.2.8/contrib/ada/zlib.adb @ 84:08ae793730bd

Add null config files
author Chris Cannam
date Mon, 02 Mar 2020 14:03:47 +0000
parents 5ea0608b923f
children
rev   line source
Chris@43 1 ----------------------------------------------------------------
Chris@43 2 -- ZLib for Ada thick binding. --
Chris@43 3 -- --
Chris@43 4 -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
Chris@43 5 -- --
Chris@43 6 -- Open source license information is in the zlib.ads file. --
Chris@43 7 ----------------------------------------------------------------
Chris@43 8
Chris@43 9 -- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
Chris@43 10
Chris@43 11 with Ada.Exceptions;
Chris@43 12 with Ada.Unchecked_Conversion;
Chris@43 13 with Ada.Unchecked_Deallocation;
Chris@43 14
Chris@43 15 with Interfaces.C.Strings;
Chris@43 16
Chris@43 17 with ZLib.Thin;
Chris@43 18
Chris@43 19 package body ZLib is
Chris@43 20
Chris@43 21 use type Thin.Int;
Chris@43 22
Chris@43 23 type Z_Stream is new Thin.Z_Stream;
Chris@43 24
Chris@43 25 type Return_Code_Enum is
Chris@43 26 (OK,
Chris@43 27 STREAM_END,
Chris@43 28 NEED_DICT,
Chris@43 29 ERRNO,
Chris@43 30 STREAM_ERROR,
Chris@43 31 DATA_ERROR,
Chris@43 32 MEM_ERROR,
Chris@43 33 BUF_ERROR,
Chris@43 34 VERSION_ERROR);
Chris@43 35
Chris@43 36 type Flate_Step_Function is access
Chris@43 37 function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
Chris@43 38 pragma Convention (C, Flate_Step_Function);
Chris@43 39
Chris@43 40 type Flate_End_Function is access
Chris@43 41 function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
Chris@43 42 pragma Convention (C, Flate_End_Function);
Chris@43 43
Chris@43 44 type Flate_Type is record
Chris@43 45 Step : Flate_Step_Function;
Chris@43 46 Done : Flate_End_Function;
Chris@43 47 end record;
Chris@43 48
Chris@43 49 subtype Footer_Array is Stream_Element_Array (1 .. 8);
Chris@43 50
Chris@43 51 Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
Chris@43 52 := (16#1f#, 16#8b#, -- Magic header
Chris@43 53 16#08#, -- Z_DEFLATED
Chris@43 54 16#00#, -- Flags
Chris@43 55 16#00#, 16#00#, 16#00#, 16#00#, -- Time
Chris@43 56 16#00#, -- XFlags
Chris@43 57 16#03# -- OS code
Chris@43 58 );
Chris@43 59 -- The simplest gzip header is not for informational, but just for
Chris@43 60 -- gzip format compatibility.
Chris@43 61 -- Note that some code below is using assumption
Chris@43 62 -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make
Chris@43 63 -- Simple_GZip_Header'Last <= Footer_Array'Last.
Chris@43 64
Chris@43 65 Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
Chris@43 66 := (0 => OK,
Chris@43 67 1 => STREAM_END,
Chris@43 68 2 => NEED_DICT,
Chris@43 69 -1 => ERRNO,
Chris@43 70 -2 => STREAM_ERROR,
Chris@43 71 -3 => DATA_ERROR,
Chris@43 72 -4 => MEM_ERROR,
Chris@43 73 -5 => BUF_ERROR,
Chris@43 74 -6 => VERSION_ERROR);
Chris@43 75
Chris@43 76 Flate : constant array (Boolean) of Flate_Type
Chris@43 77 := (True => (Step => Thin.Deflate'Access,
Chris@43 78 Done => Thin.DeflateEnd'Access),
Chris@43 79 False => (Step => Thin.Inflate'Access,
Chris@43 80 Done => Thin.InflateEnd'Access));
Chris@43 81
Chris@43 82 Flush_Finish : constant array (Boolean) of Flush_Mode
Chris@43 83 := (True => Finish, False => No_Flush);
Chris@43 84
Chris@43 85 procedure Raise_Error (Stream : in Z_Stream);
Chris@43 86 pragma Inline (Raise_Error);
Chris@43 87
Chris@43 88 procedure Raise_Error (Message : in String);
Chris@43 89 pragma Inline (Raise_Error);
Chris@43 90
Chris@43 91 procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
Chris@43 92
Chris@43 93 procedure Free is new Ada.Unchecked_Deallocation
Chris@43 94 (Z_Stream, Z_Stream_Access);
Chris@43 95
Chris@43 96 function To_Thin_Access is new Ada.Unchecked_Conversion
Chris@43 97 (Z_Stream_Access, Thin.Z_Streamp);
Chris@43 98
Chris@43 99 procedure Translate_GZip
Chris@43 100 (Filter : in out Filter_Type;
Chris@43 101 In_Data : in Ada.Streams.Stream_Element_Array;
Chris@43 102 In_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 103 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 104 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 105 Flush : in Flush_Mode);
Chris@43 106 -- Separate translate routine for make gzip header.
Chris@43 107
Chris@43 108 procedure Translate_Auto
Chris@43 109 (Filter : in out Filter_Type;
Chris@43 110 In_Data : in Ada.Streams.Stream_Element_Array;
Chris@43 111 In_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 112 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 113 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 114 Flush : in Flush_Mode);
Chris@43 115 -- translate routine without additional headers.
Chris@43 116
Chris@43 117 -----------------
Chris@43 118 -- Check_Error --
Chris@43 119 -----------------
Chris@43 120
Chris@43 121 procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
Chris@43 122 use type Thin.Int;
Chris@43 123 begin
Chris@43 124 if Code /= Thin.Z_OK then
Chris@43 125 Raise_Error
Chris@43 126 (Return_Code_Enum'Image (Return_Code (Code))
Chris@43 127 & ": " & Last_Error_Message (Stream));
Chris@43 128 end if;
Chris@43 129 end Check_Error;
Chris@43 130
Chris@43 131 -----------
Chris@43 132 -- Close --
Chris@43 133 -----------
Chris@43 134
Chris@43 135 procedure Close
Chris@43 136 (Filter : in out Filter_Type;
Chris@43 137 Ignore_Error : in Boolean := False)
Chris@43 138 is
Chris@43 139 Code : Thin.Int;
Chris@43 140 begin
Chris@43 141 if not Ignore_Error and then not Is_Open (Filter) then
Chris@43 142 raise Status_Error;
Chris@43 143 end if;
Chris@43 144
Chris@43 145 Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
Chris@43 146
Chris@43 147 if Ignore_Error or else Code = Thin.Z_OK then
Chris@43 148 Free (Filter.Strm);
Chris@43 149 else
Chris@43 150 declare
Chris@43 151 Error_Message : constant String
Chris@43 152 := Last_Error_Message (Filter.Strm.all);
Chris@43 153 begin
Chris@43 154 Free (Filter.Strm);
Chris@43 155 Ada.Exceptions.Raise_Exception
Chris@43 156 (ZLib_Error'Identity,
Chris@43 157 Return_Code_Enum'Image (Return_Code (Code))
Chris@43 158 & ": " & Error_Message);
Chris@43 159 end;
Chris@43 160 end if;
Chris@43 161 end Close;
Chris@43 162
Chris@43 163 -----------
Chris@43 164 -- CRC32 --
Chris@43 165 -----------
Chris@43 166
Chris@43 167 function CRC32
Chris@43 168 (CRC : in Unsigned_32;
Chris@43 169 Data : in Ada.Streams.Stream_Element_Array)
Chris@43 170 return Unsigned_32
Chris@43 171 is
Chris@43 172 use Thin;
Chris@43 173 begin
Chris@43 174 return Unsigned_32 (crc32 (ULong (CRC),
Chris@43 175 Data'Address,
Chris@43 176 Data'Length));
Chris@43 177 end CRC32;
Chris@43 178
Chris@43 179 procedure CRC32
Chris@43 180 (CRC : in out Unsigned_32;
Chris@43 181 Data : in Ada.Streams.Stream_Element_Array) is
Chris@43 182 begin
Chris@43 183 CRC := CRC32 (CRC, Data);
Chris@43 184 end CRC32;
Chris@43 185
Chris@43 186 ------------------
Chris@43 187 -- Deflate_Init --
Chris@43 188 ------------------
Chris@43 189
Chris@43 190 procedure Deflate_Init
Chris@43 191 (Filter : in out Filter_Type;
Chris@43 192 Level : in Compression_Level := Default_Compression;
Chris@43 193 Strategy : in Strategy_Type := Default_Strategy;
Chris@43 194 Method : in Compression_Method := Deflated;
Chris@43 195 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Chris@43 196 Memory_Level : in Memory_Level_Type := Default_Memory_Level;
Chris@43 197 Header : in Header_Type := Default)
Chris@43 198 is
Chris@43 199 use type Thin.Int;
Chris@43 200 Win_Bits : Thin.Int := Thin.Int (Window_Bits);
Chris@43 201 begin
Chris@43 202 if Is_Open (Filter) then
Chris@43 203 raise Status_Error;
Chris@43 204 end if;
Chris@43 205
Chris@43 206 -- We allow ZLib to make header only in case of default header type.
Chris@43 207 -- Otherwise we would either do header by ourselfs, or do not do
Chris@43 208 -- header at all.
Chris@43 209
Chris@43 210 if Header = None or else Header = GZip then
Chris@43 211 Win_Bits := -Win_Bits;
Chris@43 212 end if;
Chris@43 213
Chris@43 214 -- For the GZip CRC calculation and make headers.
Chris@43 215
Chris@43 216 if Header = GZip then
Chris@43 217 Filter.CRC := 0;
Chris@43 218 Filter.Offset := Simple_GZip_Header'First;
Chris@43 219 else
Chris@43 220 Filter.Offset := Simple_GZip_Header'Last + 1;
Chris@43 221 end if;
Chris@43 222
Chris@43 223 Filter.Strm := new Z_Stream;
Chris@43 224 Filter.Compression := True;
Chris@43 225 Filter.Stream_End := False;
Chris@43 226 Filter.Header := Header;
Chris@43 227
Chris@43 228 if Thin.Deflate_Init
Chris@43 229 (To_Thin_Access (Filter.Strm),
Chris@43 230 Level => Thin.Int (Level),
Chris@43 231 method => Thin.Int (Method),
Chris@43 232 windowBits => Win_Bits,
Chris@43 233 memLevel => Thin.Int (Memory_Level),
Chris@43 234 strategy => Thin.Int (Strategy)) /= Thin.Z_OK
Chris@43 235 then
Chris@43 236 Raise_Error (Filter.Strm.all);
Chris@43 237 end if;
Chris@43 238 end Deflate_Init;
Chris@43 239
Chris@43 240 -----------
Chris@43 241 -- Flush --
Chris@43 242 -----------
Chris@43 243
Chris@43 244 procedure Flush
Chris@43 245 (Filter : in out Filter_Type;
Chris@43 246 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 247 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 248 Flush : in Flush_Mode)
Chris@43 249 is
Chris@43 250 No_Data : Stream_Element_Array := (1 .. 0 => 0);
Chris@43 251 Last : Stream_Element_Offset;
Chris@43 252 begin
Chris@43 253 Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
Chris@43 254 end Flush;
Chris@43 255
Chris@43 256 -----------------------
Chris@43 257 -- Generic_Translate --
Chris@43 258 -----------------------
Chris@43 259
Chris@43 260 procedure Generic_Translate
Chris@43 261 (Filter : in out ZLib.Filter_Type;
Chris@43 262 In_Buffer_Size : in Integer := Default_Buffer_Size;
Chris@43 263 Out_Buffer_Size : in Integer := Default_Buffer_Size)
Chris@43 264 is
Chris@43 265 In_Buffer : Stream_Element_Array
Chris@43 266 (1 .. Stream_Element_Offset (In_Buffer_Size));
Chris@43 267 Out_Buffer : Stream_Element_Array
Chris@43 268 (1 .. Stream_Element_Offset (Out_Buffer_Size));
Chris@43 269 Last : Stream_Element_Offset;
Chris@43 270 In_Last : Stream_Element_Offset;
Chris@43 271 In_First : Stream_Element_Offset;
Chris@43 272 Out_Last : Stream_Element_Offset;
Chris@43 273 begin
Chris@43 274 Main : loop
Chris@43 275 Data_In (In_Buffer, Last);
Chris@43 276
Chris@43 277 In_First := In_Buffer'First;
Chris@43 278
Chris@43 279 loop
Chris@43 280 Translate
Chris@43 281 (Filter => Filter,
Chris@43 282 In_Data => In_Buffer (In_First .. Last),
Chris@43 283 In_Last => In_Last,
Chris@43 284 Out_Data => Out_Buffer,
Chris@43 285 Out_Last => Out_Last,
Chris@43 286 Flush => Flush_Finish (Last < In_Buffer'First));
Chris@43 287
Chris@43 288 if Out_Buffer'First <= Out_Last then
Chris@43 289 Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
Chris@43 290 end if;
Chris@43 291
Chris@43 292 exit Main when Stream_End (Filter);
Chris@43 293
Chris@43 294 -- The end of in buffer.
Chris@43 295
Chris@43 296 exit when In_Last = Last;
Chris@43 297
Chris@43 298 In_First := In_Last + 1;
Chris@43 299 end loop;
Chris@43 300 end loop Main;
Chris@43 301
Chris@43 302 end Generic_Translate;
Chris@43 303
Chris@43 304 ------------------
Chris@43 305 -- Inflate_Init --
Chris@43 306 ------------------
Chris@43 307
Chris@43 308 procedure Inflate_Init
Chris@43 309 (Filter : in out Filter_Type;
Chris@43 310 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Chris@43 311 Header : in Header_Type := Default)
Chris@43 312 is
Chris@43 313 use type Thin.Int;
Chris@43 314 Win_Bits : Thin.Int := Thin.Int (Window_Bits);
Chris@43 315
Chris@43 316 procedure Check_Version;
Chris@43 317 -- Check the latest header types compatibility.
Chris@43 318
Chris@43 319 procedure Check_Version is
Chris@43 320 begin
Chris@43 321 if Version <= "1.1.4" then
Chris@43 322 Raise_Error
Chris@43 323 ("Inflate header type " & Header_Type'Image (Header)
Chris@43 324 & " incompatible with ZLib version " & Version);
Chris@43 325 end if;
Chris@43 326 end Check_Version;
Chris@43 327
Chris@43 328 begin
Chris@43 329 if Is_Open (Filter) then
Chris@43 330 raise Status_Error;
Chris@43 331 end if;
Chris@43 332
Chris@43 333 case Header is
Chris@43 334 when None =>
Chris@43 335 Check_Version;
Chris@43 336
Chris@43 337 -- Inflate data without headers determined
Chris@43 338 -- by negative Win_Bits.
Chris@43 339
Chris@43 340 Win_Bits := -Win_Bits;
Chris@43 341 when GZip =>
Chris@43 342 Check_Version;
Chris@43 343
Chris@43 344 -- Inflate gzip data defined by flag 16.
Chris@43 345
Chris@43 346 Win_Bits := Win_Bits + 16;
Chris@43 347 when Auto =>
Chris@43 348 Check_Version;
Chris@43 349
Chris@43 350 -- Inflate with automatic detection
Chris@43 351 -- of gzip or native header defined by flag 32.
Chris@43 352
Chris@43 353 Win_Bits := Win_Bits + 32;
Chris@43 354 when Default => null;
Chris@43 355 end case;
Chris@43 356
Chris@43 357 Filter.Strm := new Z_Stream;
Chris@43 358 Filter.Compression := False;
Chris@43 359 Filter.Stream_End := False;
Chris@43 360 Filter.Header := Header;
Chris@43 361
Chris@43 362 if Thin.Inflate_Init
Chris@43 363 (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
Chris@43 364 then
Chris@43 365 Raise_Error (Filter.Strm.all);
Chris@43 366 end if;
Chris@43 367 end Inflate_Init;
Chris@43 368
Chris@43 369 -------------
Chris@43 370 -- Is_Open --
Chris@43 371 -------------
Chris@43 372
Chris@43 373 function Is_Open (Filter : in Filter_Type) return Boolean is
Chris@43 374 begin
Chris@43 375 return Filter.Strm /= null;
Chris@43 376 end Is_Open;
Chris@43 377
Chris@43 378 -----------------
Chris@43 379 -- Raise_Error --
Chris@43 380 -----------------
Chris@43 381
Chris@43 382 procedure Raise_Error (Message : in String) is
Chris@43 383 begin
Chris@43 384 Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
Chris@43 385 end Raise_Error;
Chris@43 386
Chris@43 387 procedure Raise_Error (Stream : in Z_Stream) is
Chris@43 388 begin
Chris@43 389 Raise_Error (Last_Error_Message (Stream));
Chris@43 390 end Raise_Error;
Chris@43 391
Chris@43 392 ----------
Chris@43 393 -- Read --
Chris@43 394 ----------
Chris@43 395
Chris@43 396 procedure Read
Chris@43 397 (Filter : in out Filter_Type;
Chris@43 398 Item : out Ada.Streams.Stream_Element_Array;
Chris@43 399 Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 400 Flush : in Flush_Mode := No_Flush)
Chris@43 401 is
Chris@43 402 In_Last : Stream_Element_Offset;
Chris@43 403 Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
Chris@43 404 V_Flush : Flush_Mode := Flush;
Chris@43 405
Chris@43 406 begin
Chris@43 407 pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
Chris@43 408 pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
Chris@43 409
Chris@43 410 loop
Chris@43 411 if Rest_Last = Buffer'First - 1 then
Chris@43 412 V_Flush := Finish;
Chris@43 413
Chris@43 414 elsif Rest_First > Rest_Last then
Chris@43 415 Read (Buffer, Rest_Last);
Chris@43 416 Rest_First := Buffer'First;
Chris@43 417
Chris@43 418 if Rest_Last < Buffer'First then
Chris@43 419 V_Flush := Finish;
Chris@43 420 end if;
Chris@43 421 end if;
Chris@43 422
Chris@43 423 Translate
Chris@43 424 (Filter => Filter,
Chris@43 425 In_Data => Buffer (Rest_First .. Rest_Last),
Chris@43 426 In_Last => In_Last,
Chris@43 427 Out_Data => Item (Item_First .. Item'Last),
Chris@43 428 Out_Last => Last,
Chris@43 429 Flush => V_Flush);
Chris@43 430
Chris@43 431 Rest_First := In_Last + 1;
Chris@43 432
Chris@43 433 exit when Stream_End (Filter)
Chris@43 434 or else Last = Item'Last
Chris@43 435 or else (Last >= Item'First and then Allow_Read_Some);
Chris@43 436
Chris@43 437 Item_First := Last + 1;
Chris@43 438 end loop;
Chris@43 439 end Read;
Chris@43 440
Chris@43 441 ----------------
Chris@43 442 -- Stream_End --
Chris@43 443 ----------------
Chris@43 444
Chris@43 445 function Stream_End (Filter : in Filter_Type) return Boolean is
Chris@43 446 begin
Chris@43 447 if Filter.Header = GZip and Filter.Compression then
Chris@43 448 return Filter.Stream_End
Chris@43 449 and then Filter.Offset = Footer_Array'Last + 1;
Chris@43 450 else
Chris@43 451 return Filter.Stream_End;
Chris@43 452 end if;
Chris@43 453 end Stream_End;
Chris@43 454
Chris@43 455 --------------
Chris@43 456 -- Total_In --
Chris@43 457 --------------
Chris@43 458
Chris@43 459 function Total_In (Filter : in Filter_Type) return Count is
Chris@43 460 begin
Chris@43 461 return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
Chris@43 462 end Total_In;
Chris@43 463
Chris@43 464 ---------------
Chris@43 465 -- Total_Out --
Chris@43 466 ---------------
Chris@43 467
Chris@43 468 function Total_Out (Filter : in Filter_Type) return Count is
Chris@43 469 begin
Chris@43 470 return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
Chris@43 471 end Total_Out;
Chris@43 472
Chris@43 473 ---------------
Chris@43 474 -- Translate --
Chris@43 475 ---------------
Chris@43 476
Chris@43 477 procedure Translate
Chris@43 478 (Filter : in out Filter_Type;
Chris@43 479 In_Data : in Ada.Streams.Stream_Element_Array;
Chris@43 480 In_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 481 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 482 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 483 Flush : in Flush_Mode) is
Chris@43 484 begin
Chris@43 485 if Filter.Header = GZip and then Filter.Compression then
Chris@43 486 Translate_GZip
Chris@43 487 (Filter => Filter,
Chris@43 488 In_Data => In_Data,
Chris@43 489 In_Last => In_Last,
Chris@43 490 Out_Data => Out_Data,
Chris@43 491 Out_Last => Out_Last,
Chris@43 492 Flush => Flush);
Chris@43 493 else
Chris@43 494 Translate_Auto
Chris@43 495 (Filter => Filter,
Chris@43 496 In_Data => In_Data,
Chris@43 497 In_Last => In_Last,
Chris@43 498 Out_Data => Out_Data,
Chris@43 499 Out_Last => Out_Last,
Chris@43 500 Flush => Flush);
Chris@43 501 end if;
Chris@43 502 end Translate;
Chris@43 503
Chris@43 504 --------------------
Chris@43 505 -- Translate_Auto --
Chris@43 506 --------------------
Chris@43 507
Chris@43 508 procedure Translate_Auto
Chris@43 509 (Filter : in out Filter_Type;
Chris@43 510 In_Data : in Ada.Streams.Stream_Element_Array;
Chris@43 511 In_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 512 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 513 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 514 Flush : in Flush_Mode)
Chris@43 515 is
Chris@43 516 use type Thin.Int;
Chris@43 517 Code : Thin.Int;
Chris@43 518
Chris@43 519 begin
Chris@43 520 if not Is_Open (Filter) then
Chris@43 521 raise Status_Error;
Chris@43 522 end if;
Chris@43 523
Chris@43 524 if Out_Data'Length = 0 and then In_Data'Length = 0 then
Chris@43 525 raise Constraint_Error;
Chris@43 526 end if;
Chris@43 527
Chris@43 528 Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
Chris@43 529 Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length);
Chris@43 530
Chris@43 531 Code := Flate (Filter.Compression).Step
Chris@43 532 (To_Thin_Access (Filter.Strm),
Chris@43 533 Thin.Int (Flush));
Chris@43 534
Chris@43 535 if Code = Thin.Z_STREAM_END then
Chris@43 536 Filter.Stream_End := True;
Chris@43 537 else
Chris@43 538 Check_Error (Filter.Strm.all, Code);
Chris@43 539 end if;
Chris@43 540
Chris@43 541 In_Last := In_Data'Last
Chris@43 542 - Stream_Element_Offset (Avail_In (Filter.Strm.all));
Chris@43 543 Out_Last := Out_Data'Last
Chris@43 544 - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
Chris@43 545 end Translate_Auto;
Chris@43 546
Chris@43 547 --------------------
Chris@43 548 -- Translate_GZip --
Chris@43 549 --------------------
Chris@43 550
Chris@43 551 procedure Translate_GZip
Chris@43 552 (Filter : in out Filter_Type;
Chris@43 553 In_Data : in Ada.Streams.Stream_Element_Array;
Chris@43 554 In_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 555 Out_Data : out Ada.Streams.Stream_Element_Array;
Chris@43 556 Out_Last : out Ada.Streams.Stream_Element_Offset;
Chris@43 557 Flush : in Flush_Mode)
Chris@43 558 is
Chris@43 559 Out_First : Stream_Element_Offset;
Chris@43 560
Chris@43 561 procedure Add_Data (Data : in Stream_Element_Array);
Chris@43 562 -- Add data to stream from the Filter.Offset till necessary,
Chris@43 563 -- used for add gzip headr/footer.
Chris@43 564
Chris@43 565 procedure Put_32
Chris@43 566 (Item : in out Stream_Element_Array;
Chris@43 567 Data : in Unsigned_32);
Chris@43 568 pragma Inline (Put_32);
Chris@43 569
Chris@43 570 --------------
Chris@43 571 -- Add_Data --
Chris@43 572 --------------
Chris@43 573
Chris@43 574 procedure Add_Data (Data : in Stream_Element_Array) is
Chris@43 575 Data_First : Stream_Element_Offset renames Filter.Offset;
Chris@43 576 Data_Last : Stream_Element_Offset;
Chris@43 577 Data_Len : Stream_Element_Offset; -- -1
Chris@43 578 Out_Len : Stream_Element_Offset; -- -1
Chris@43 579 begin
Chris@43 580 Out_First := Out_Last + 1;
Chris@43 581
Chris@43 582 if Data_First > Data'Last then
Chris@43 583 return;
Chris@43 584 end if;
Chris@43 585
Chris@43 586 Data_Len := Data'Last - Data_First;
Chris@43 587 Out_Len := Out_Data'Last - Out_First;
Chris@43 588
Chris@43 589 if Data_Len <= Out_Len then
Chris@43 590 Out_Last := Out_First + Data_Len;
Chris@43 591 Data_Last := Data'Last;
Chris@43 592 else
Chris@43 593 Out_Last := Out_Data'Last;
Chris@43 594 Data_Last := Data_First + Out_Len;
Chris@43 595 end if;
Chris@43 596
Chris@43 597 Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
Chris@43 598
Chris@43 599 Data_First := Data_Last + 1;
Chris@43 600 Out_First := Out_Last + 1;
Chris@43 601 end Add_Data;
Chris@43 602
Chris@43 603 ------------
Chris@43 604 -- Put_32 --
Chris@43 605 ------------
Chris@43 606
Chris@43 607 procedure Put_32
Chris@43 608 (Item : in out Stream_Element_Array;
Chris@43 609 Data : in Unsigned_32)
Chris@43 610 is
Chris@43 611 D : Unsigned_32 := Data;
Chris@43 612 begin
Chris@43 613 for J in Item'First .. Item'First + 3 loop
Chris@43 614 Item (J) := Stream_Element (D and 16#FF#);
Chris@43 615 D := Shift_Right (D, 8);
Chris@43 616 end loop;
Chris@43 617 end Put_32;
Chris@43 618
Chris@43 619 begin
Chris@43 620 Out_Last := Out_Data'First - 1;
Chris@43 621
Chris@43 622 if not Filter.Stream_End then
Chris@43 623 Add_Data (Simple_GZip_Header);
Chris@43 624
Chris@43 625 Translate_Auto
Chris@43 626 (Filter => Filter,
Chris@43 627 In_Data => In_Data,
Chris@43 628 In_Last => In_Last,
Chris@43 629 Out_Data => Out_Data (Out_First .. Out_Data'Last),
Chris@43 630 Out_Last => Out_Last,
Chris@43 631 Flush => Flush);
Chris@43 632
Chris@43 633 CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
Chris@43 634 end if;
Chris@43 635
Chris@43 636 if Filter.Stream_End and then Out_Last <= Out_Data'Last then
Chris@43 637 -- This detection method would work only when
Chris@43 638 -- Simple_GZip_Header'Last > Footer_Array'Last
Chris@43 639
Chris@43 640 if Filter.Offset = Simple_GZip_Header'Last + 1 then
Chris@43 641 Filter.Offset := Footer_Array'First;
Chris@43 642 end if;
Chris@43 643
Chris@43 644 declare
Chris@43 645 Footer : Footer_Array;
Chris@43 646 begin
Chris@43 647 Put_32 (Footer, Filter.CRC);
Chris@43 648 Put_32 (Footer (Footer'First + 4 .. Footer'Last),
Chris@43 649 Unsigned_32 (Total_In (Filter)));
Chris@43 650 Add_Data (Footer);
Chris@43 651 end;
Chris@43 652 end if;
Chris@43 653 end Translate_GZip;
Chris@43 654
Chris@43 655 -------------
Chris@43 656 -- Version --
Chris@43 657 -------------
Chris@43 658
Chris@43 659 function Version return String is
Chris@43 660 begin
Chris@43 661 return Interfaces.C.Strings.Value (Thin.zlibVersion);
Chris@43 662 end Version;
Chris@43 663
Chris@43 664 -----------
Chris@43 665 -- Write --
Chris@43 666 -----------
Chris@43 667
Chris@43 668 procedure Write
Chris@43 669 (Filter : in out Filter_Type;
Chris@43 670 Item : in Ada.Streams.Stream_Element_Array;
Chris@43 671 Flush : in Flush_Mode := No_Flush)
Chris@43 672 is
Chris@43 673 Buffer : Stream_Element_Array (1 .. Buffer_Size);
Chris@43 674 In_Last : Stream_Element_Offset;
Chris@43 675 Out_Last : Stream_Element_Offset;
Chris@43 676 In_First : Stream_Element_Offset := Item'First;
Chris@43 677 begin
Chris@43 678 if Item'Length = 0 and Flush = No_Flush then
Chris@43 679 return;
Chris@43 680 end if;
Chris@43 681
Chris@43 682 loop
Chris@43 683 Translate
Chris@43 684 (Filter => Filter,
Chris@43 685 In_Data => Item (In_First .. Item'Last),
Chris@43 686 In_Last => In_Last,
Chris@43 687 Out_Data => Buffer,
Chris@43 688 Out_Last => Out_Last,
Chris@43 689 Flush => Flush);
Chris@43 690
Chris@43 691 if Out_Last >= Buffer'First then
Chris@43 692 Write (Buffer (1 .. Out_Last));
Chris@43 693 end if;
Chris@43 694
Chris@43 695 exit when In_Last = Item'Last or Stream_End (Filter);
Chris@43 696
Chris@43 697 In_First := In_Last + 1;
Chris@43 698 end loop;
Chris@43 699 end Write;
Chris@43 700
Chris@43 701 end ZLib;