1 ----------------------------------------------------------------
   2 --  ZLib for Ada thick binding.                               --
   3 --                                                            --
   4 --  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --
   5 --                                                            --
   6 --  Open source license information is in the zlib.ads file.  --
   7 ----------------------------------------------------------------
   8 --
   9 --  $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
  10 
  11 --  This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
  12 --
  13 --  Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
  14 --  of exactly the correct size is used for decompressed data, and the last
  15 --  few bytes passed in to Zlib are checksum bytes.
  16 
  17 --  This program compresses a string of text, and then decompresses the
  18 --  compressed text into a buffer of the same size as the original text.
  19 
  20 with Ada.Streams; use Ada.Streams;
  21 with Ada.Text_IO;
  22 
  23 with ZLib; use ZLib;
  24 
  25 procedure Buffer_Demo is
  26    EOL  : Character renames ASCII.LF;
  27    Text : constant String
  28      := "Four score and seven years ago our fathers brought forth," & EOL &
  29         "upon this continent, a new nation, conceived in liberty," & EOL &
  30         "and dedicated to the proposition that `all men are created equal'.";
  31 
  32    Source : Stream_Element_Array (1 .. Text'Length);
  33    for Source'Address use Text'Address;
  34 
  35 begin
  36    Ada.Text_IO.Put (Text);
  37    Ada.Text_IO.New_Line;
  38    Ada.Text_IO.Put_Line
  39      ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
  40 
  41    declare
  42       Compressed_Data : Stream_Element_Array (1 .. Text'Length);
  43       L               : Stream_Element_Offset;
  44    begin
  45       Compress : declare
  46          Compressor : Filter_Type;
  47          I : Stream_Element_Offset;
  48       begin
  49          Deflate_Init (Compressor);
  50 
  51          --  Compress the whole of T at once.
  52 
  53          Translate (Compressor, Source, I, Compressed_Data, L, Finish);
  54          pragma Assert (I = Source'Last);
  55 
  56          Close (Compressor);
  57 
  58          Ada.Text_IO.Put_Line
  59            ("Compressed size :   "
  60             & Stream_Element_Offset'Image (L) & " bytes");
  61       end Compress;
  62 
  63       --  Now we decompress the data, passing short blocks of data to Zlib
  64       --  (because this demonstrates the problem - the last block passed will
  65       --  contain checksum information and there will be no output, only a
  66       --  check inside Zlib that the checksum is correct).
  67 
  68       Decompress : declare
  69          Decompressor : Filter_Type;
  70 
  71          Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
  72 
  73          Block_Size : constant := 4;
  74          --  This makes sure that the last block contains
  75          --  only Adler checksum data.
  76 
  77          P : Stream_Element_Offset := Compressed_Data'First - 1;
  78          O : Stream_Element_Offset;
  79       begin
  80          Inflate_Init (Decompressor);
  81 
  82          loop
  83             Translate
  84               (Decompressor,
  85                Compressed_Data
  86                  (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
  87                P,
  88                Uncompressed_Data
  89                  (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
  90                O,
  91                No_Flush);
  92 
  93                Ada.Text_IO.Put_Line
  94                  ("Total in : " & Count'Image (Total_In (Decompressor)) &
  95                   ", out : " & Count'Image (Total_Out (Decompressor)));
  96 
  97                exit when P = L;
  98          end loop;
  99 
 100          Ada.Text_IO.New_Line;
 101          Ada.Text_IO.Put_Line
 102            ("Decompressed text matches original text : "
 103              & Boolean'Image (Uncompressed_Data = Source));
 104       end Decompress;
 105    end;
 106 end Buffer_Demo;