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
119
120
121
122
123
124
125 | with Ada.Command_Line; use Ada.Command_Line;
with Ada.Calendar; use Ada.Calendar;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Direct_IO;
with Interfaces; use Interfaces;
with LZH;
procedure LZHuf is
package Byte_IO is new Ada.Direct_IO (Unsigned_8);
use Byte_IO;
package CIO is new Integer_IO (Byte_IO.Count);
package FIO is new Float_IO (Float);
Infile : Byte_IO.File_Type;
Outfile : Byte_IO.File_Type;
Isize, Osize : Byte_IO.Count;
Dots : constant := 16;
Done_Dots : Natural := 0;
Idot : Byte_IO.Count;
procedure Display_Progress (Done : Float) is
New_Done_Dots : constant Natural :=
Natural (Float (Dots) * Done);
begin
for I in Done_Dots + 1 .. New_Done_Dots loop
Put ('.');
end loop;
Done_Dots := New_Done_Dots;
end Display_Progress;
function Read_IO_Byte return Unsigned_8 is
pragma Inline (Read_IO_Byte);
B : Unsigned_8;
I : constant Byte_IO.Count := Index (Infile);
begin
Read (Infile, B);
if I = 1 then
Display_Progress (0.0);
elsif I = Isize then
Display_Progress (1.0);
elsif Idot = 0 or else I mod Idot = 0 then
Display_Progress (Float (I) / Float (Isize));
end if;
return B;
end Read_IO_Byte;
function File_More_bytes return Boolean is
begin
return not End_Of_File (Infile);
end File_More_bytes;
procedure Write_IO_Byte (B : Unsigned_8) is
pragma Inline (Write_IO_Byte);
begin
Write (Outfile, B);
end Write_IO_Byte;
package File_LZH is
new LZH (
Read_byte => Read_IO_Byte,
More_bytes => File_More_bytes,
Write_byte => Write_IO_Byte
);
use File_LZH;
type T_Action is (Do_Encode, Do_Decode);
Action : T_Action;
T0, T1 : Time;
seconds_elapsed : Duration;
begin
if Argument_Count /= 3 then
Put_Line (
"Usage: lzhuf e(ncode-compress)|d(ecode-decompress) infile outfile");
return;
end if;
declare
S : constant String := Argument (1);
begin
case S (1) is
when 'e' | 'E' => Action := Do_Encode;
when 'd' | 'D' => Action := Do_Decode;
when others =>
Put_Line (
"! Use [d] for decoding-decompression or" &
" [e] for encoding-compression"
);
return;
end case;
end;
Byte_IO.Open (Infile, Byte_IO.In_File, Argument (2));
Isize := Byte_IO.Size (Infile);
Idot := Isize / Dots;
Byte_IO.Create (Outfile, Name => Argument (3));
Put (" In:"); CIO.Put (Isize); Put (" [");
T0 := Clock;
--
case Action is
when Do_Encode => Encode;
when Do_Decode => Decode;
end case;
--
T1 := Clock;
Byte_IO.Close (Infile);
Osize := Byte_IO.Size (Outfile);
Byte_IO.Close (Outfile);
Put ("] Out:"); CIO.Put (Osize);
if Isize /= 0 and Osize /= 0 then
Put (" ");
case Action is
when Do_Encode => CIO.Put ((100 * Osize) / Isize, 0);
when Do_Decode => CIO.Put ((100 * Isize) / Osize, 0);
end case;
Put ("%,");
end if;
seconds_elapsed := T1 - T0;
FIO.Put (Float (seconds_elapsed), 4, 2, 0);
Put_Line (" seconds.");
end LZHuf;
|