zipada_56.0.2_b3043499/extras/lzma_dec.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
--  Standalone, command-line, LZMA Decoder (for .lzma files).

with LZMA.Decoding;

with Ada.Command_Line;                  use Ada.Command_Line;
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO;
with Interfaces;                        use Interfaces;

procedure LZMA_Dec is

  use LZMA;

  f_in, f_out : Ada.Streams.Stream_IO.File_Type;

  --  NB: The Byte I/O below is not buffered, so it is very slow.
  --  You need to implement a circular buffer of type Stream_Element_Array for a fast I/O.
  --  For instance, see the BlockRead in the Zip package for how to do it.

  function Demo_Read_Byte return Byte is
    b : Byte;
  begin
    Byte'Read (Stream (f_in), b);
    return b;
  end Demo_Read_Byte;

  procedure Demo_Write_Byte (b : Byte) is
  begin
    Byte'Write (Stream (f_out), b);
  end Demo_Write_Byte;

  package My_LZMA_Decoding is new LZMA.Decoding (Demo_Read_Byte, Demo_Write_Byte);
  use My_LZMA_Decoding;

  procedure Print_Data_Bytes_Count (title : String; v : Data_Bytes_Count) is
    package CIO is new Integer_IO (Data_Bytes_Count);
  begin
    Put (title);
    Put (" : ");
    CIO.Put (v, 0);
    Put (" bytes");
    New_Line;
  end Print_Data_Bytes_Count;

  lzma_decoder : LZMA_Decoder_Info;
  res : LZMA_Result;

  use type Data_Bytes_Count;

  default_hints : constant LZMA_Hints :=
     (has_size               => True,
      given_size             => dummy_size,
      marker_expected        => False,
      fail_on_bad_range_code => False);

begin
  New_Line;
  Put_Line ("LZMA_Dec, adapted from the LZMA Reference Decoder 9.31 by Igor Pavlov.");
  if Argument_Count = 0 then
    Put_Line ("Use: lzma_dec a.lzma outfile");
    New_Line;
    Put_Line ("NB: The I/O is not buffered => may be slow.");
    Put_Line ("    Consider the UnZipAda tool for a LZMA demo with fast I/O.");
    return;
  elsif Argument_Count /= 2 then
    Put_Line ("You must specify two parameters");
    return;
  end if;
  Open (f_in, In_File, Argument (1));
  Create (f_out, Out_File, Argument (2));

  Decode (lzma_decoder, default_hints, res);

  Put_Line (
    "lc="   & Natural'Image (Literal_context_bits (lzma_decoder)) &
    ", lp=" & Natural'Image (Literal_pos_bits (lzma_decoder)) &
    ", pb=" & Natural'Image (Pos_bits (lzma_decoder))
  );
  Put_Line ("Probability model size =" &
    Unsigned_32'Image (Probability_model_size (lzma_decoder)) & " bytes"
  );
  Put_Line ("Dictionary size in properties =" &
    Unsigned_32'Image (Dictionary_size_in_properties (lzma_decoder)) & " bytes"
  );
  Put_Line ("Dictionary size for decoding  =" &
    Unsigned_32'Image (Dictionary_size (lzma_decoder)) & " bytes"
  );
  New_Line;

  if Unpack_size_defined (lzma_decoder) then
    Print_Data_Bytes_Count ("Uncompressed size as in data header",
      Unpack_size_as_defined (lzma_decoder));
  else
    Put_Line ("Uncompressed size not defined, end marker is expected.");
  end if;
  New_Line;

  Print_Data_Bytes_Count ("Read    ", Data_Bytes_Count (Index (f_in) - 1));
  Print_Data_Bytes_Count ("Written ", Data_Bytes_Count (Index (f_out) - 1));
  case res is
    when LZMA_finished_without_marker =>
       Put_Line ("Finished without end marker");
    when LZMA_finished_with_marker =>
       if Unpack_size_defined (lzma_decoder) then
         if Data_Bytes_Count (Index (f_out) - 1) /= Unpack_size_as_defined (lzma_decoder) then
           Put_Line ("Warning: finished with end marker before the specified size");
         end if;
       end if;
       Put_Line ("Finished with end marker");
  end case;

  if Range_decoder_corrupted (lzma_decoder) then
    Put_Line ("Warning: LZMA stream is corrupted");
  end if;

  Close (f_in);
  Close (f_out);
end LZMA_Dec;