Natools

Check-in [c57a785ddb]
Login
Overview
Comment:smaz_4096: new instance of generic Smaz, base-64 and large dictionary
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c57a785ddb61fce5d73e2e813fd88e92c3b12161
User & Date: nat on 2017-01-30 21:33:17
Other Links: manifest | tags
Context
2017-01-31
22:33
tools/smaz: add support for base-4096 variant check-in: e6f252142c user: nat tags: trunk
2017-01-30
21:33
smaz_4096: new instance of generic Smaz, base-64 and large dictionary check-in: c57a785ddb user: nat tags: trunk
2017-01-29
21:32
tools/timekey: add CLI option to configure numer of subsecond digits check-in: b40ac98134 user: nat tags: trunk
Changes

Added src/natools-smaz_4096.ads version [94b20a0ba0].









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
------------------------------------------------------------------------------
-- Copyright (c) 2016-2017, Natacha Porté                                   --
--                                                                          --
-- Permission to use, copy, modify, and distribute this software for any    --
-- purpose with or without fee is hereby granted, provided that the above   --
-- copyright notice and this permission notice appear in all copies.        --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         --
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  --
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   --
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    --
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  --
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           --
------------------------------------------------------------------------------

------------------------------------------------------------------------------
-- Natools.Smaz_4096 provides the subprograms needed to instantiate         --
-- Natools.Smaz_Generic into a variant of the Smaz compression algorithm    --
-- that output directly base-64 printable symbols, but with a dictionary    --
-- indexed by two symbols, allowing a maximum size of 4095 entries.         --
------------------------------------------------------------------------------

with Natools.Smaz_Generic;
with Natools.Smaz_Implementations.Base_4096;

package Natools.Smaz_4096 is new Natools.Smaz_Generic
  (Dictionary_Code => Natools.Smaz_Implementations.Base_4096.Base_4096_Digit,
   Read_Code => Natools.Smaz_Implementations.Base_4096.Read_Code,
   Read_Verbatim => Natools.Smaz_Implementations.Base_4096.Read_Verbatim,
   Skip_Verbatim => Natools.Smaz_Implementations.Base_4096.Skip_Verbatim,
   Verbatim_Size => Natools.Smaz_Implementations.Base_4096.Verbatim_Size,
   Write_Code => Natools.Smaz_Implementations.Base_4096.Write_Code,
   Write_Verbatim => Natools.Smaz_Implementations.Base_4096.Write_Verbatim);

pragma Pure (Natools.Smaz_4096);

Added src/natools-smaz_implementations-base_4096.adb version [e5ed72f68a].













































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
------------------------------------------------------------------------------
-- Copyright (c) 2016-2017, Natacha Porté                                   --
--                                                                          --
-- Permission to use, copy, modify, and distribute this software for any    --
-- purpose with or without fee is hereby granted, provided that the above   --
-- copyright notice and this permission notice appear in all copies.        --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         --
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  --
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   --
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    --
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  --
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           --
------------------------------------------------------------------------------

with Natools.Smaz_Implementations.Base_64_Tools;

package body Natools.Smaz_Implementations.Base_4096 is

   package Tools renames Natools.Smaz_Implementations.Base_64_Tools;

   use type Ada.Streams.Stream_Element_Offset;

   procedure Read_Code
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : out Base_4096_Digit);
      --  Read two base-64 symbols and assemble them into a base-4096 number


   ------------------------------
   -- Local Helper Subprograms --
   ------------------------------

   procedure Read_Code
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : out Base_4096_Digit)
   is
      Low, High : Tools.Base_64_Digit;
   begin
      Tools.Next_Digit (Input, Offset, Low);
      Tools.Next_Digit (Input, Offset, High);
      Code := Base_4096_Digit (Low) + Base_4096_Digit (High) * 64;
   end Read_Code;



   ----------------------
   -- Public Interface --
   ----------------------

   procedure Read_Code
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : out Base_4096_Digit;
      Verbatim_Length : out Natural;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean) is
   begin
      Read_Code (Input, Offset, Code);

      if Code <= Last_Code then
         Verbatim_Length := 0;
      elsif not Variable_Length_Verbatim then
         Verbatim_Length := Positive (Base_4096_Digit'Last - Code + 1);
         Code := 0;
      elsif Code < Base_4096_Digit'Last then
         Verbatim_Length := Positive (Base_4096_Digit'Last - Code);
         Code := 0;
      else
         Read_Code (Input, Offset, Code);
         Verbatim_Length
           := Natural (Code) + Natural (Base_4096_Digit'Last - Last_Code);
         Code := 0;
      end if;
   end Read_Code;


   procedure Read_Verbatim
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Output : out String) is
   begin
      Tools.Decode (Input, Offset, Output);
   end Read_Verbatim;


   procedure Skip_Verbatim
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Verbatim_Length : in Positive)
   is
      Code : Tools.Base_64_Digit;
   begin
      for I in 1 .. Tools.Image_Length (Verbatim_Length) loop
         Tools.Next_Digit (Input, Offset, Code);
      end loop;
   end Skip_Verbatim;


   function Verbatim_Size
     (Input_Length : in Positive;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean)
     return Ada.Streams.Stream_Element_Count
   is
      Verbatim1_Max_Size : constant Natural
        := Natural (Base_4096_Digit'Last - Last_Code)
         - Boolean'Pos (Variable_Length_Verbatim);
      Verbatim2_Max_Size : constant Natural
        := Natural (Base_4096_Digit'Last) + Verbatim1_Max_Size + 1;

      Input_Index : Natural := 0;
      Remaining_Length, Block_Length : Positive;
      Result : Ada.Streams.Stream_Element_Count := 0;
   begin
      while Input_Index < Input_Length loop
         Remaining_Length := Input_Length - Input_Index;

         if Variable_Length_Verbatim
           and then Remaining_Length > Verbatim1_Max_Size
         then
            Block_Length := Positive'Min
              (Remaining_Length, Verbatim2_Max_Size);
            Result := Result + 4;
         else
            Block_Length := Positive'Min
              (Remaining_Length, Verbatim1_Max_Size);
            Result := Result + 2;
         end if;

         Result := Result + Tools.Image_Length (Block_Length);
         Input_Index := Input_Index + Block_Length;
      end loop;

      return Result;
   end Verbatim_Size;


   procedure Write_Code
     (Output : in out Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : in Base_4096_Digit)
   is
      Low : constant Tools.Base_64_Digit := Tools.Base_64_Digit (Code mod 64);
      High : constant Tools.Base_64_Digit := Tools.Base_64_Digit (Code / 64);
   begin
      Output (Offset + 0) := Tools.Image (Low);
      Output (Offset + 1) := Tools.Image (High);
      Offset := Offset + 2;
   end Write_Code;


   procedure Write_Verbatim
     (Output : in out Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Input : in String;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean)
   is
      Verbatim1_Max_Size : constant Natural
        := Natural (Base_4096_Digit'Last - Last_Code)
         - Boolean'Pos (Variable_Length_Verbatim);
      Verbatim2_Max_Size : constant Natural
        := Natural (Base_4096_Digit'Last) + Verbatim1_Max_Size + 1;

      Input_Index : Positive := Input'First;
      Remaining_Length, Block_Length : Positive;
   begin
      while Input_Index in Input'Range loop
         Remaining_Length := Input'Last - Input_Index + 1;

         if Variable_Length_Verbatim
           and then Remaining_Length > Verbatim1_Max_Size
         then
            Block_Length := Positive'Min
              (Remaining_Length, Verbatim2_Max_Size);
            Write_Code (Output, Offset, Base_4096_Digit'Last);
            Write_Code (Output, Offset, Base_4096_Digit
              (Block_Length - Verbatim1_Max_Size - 1));
         else
            Block_Length := Positive'Min
              (Remaining_Length, Verbatim1_Max_Size);
            Write_Code (Output, Offset, Base_4096_Digit
              (Base_4096_Digit'Last - Base_4096_Digit (Block_Length)
                  + 1 - Boolean'Pos (Variable_Length_Verbatim)));
         end if;

         Tools.Encode
           (Input (Input_Index .. Input_Index + Block_Length - 1),
            Output, Offset);
         Input_Index := Input_Index + Block_Length;
      end loop;
   end Write_Verbatim;

end Natools.Smaz_Implementations.Base_4096;

Added src/natools-smaz_implementations-base_4096.ads version [a3872fabf9].









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
------------------------------------------------------------------------------
-- Copyright (c) 2016-2017, Natacha Porté                                   --
--                                                                          --
-- Permission to use, copy, modify, and distribute this software for any    --
-- purpose with or without fee is hereby granted, provided that the above   --
-- copyright notice and this permission notice appear in all copies.        --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         --
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  --
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   --
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    --
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  --
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           --
------------------------------------------------------------------------------

------------------------------------------------------------------------------
-- Natools.Smaz_Implementations.Base_4096 provides the subprograms needed   --
-- to instantiate Natools.Smaz_Generic into a variant of the Smaz           --
-- compression algorithm that output directly base-64 printable symbols,    --
-- but with a dictionary indexed by two symbols, allowing a maximum size of --
-- 4095 entries.                                                            --
------------------------------------------------------------------------------

with Ada.Streams;

package Natools.Smaz_Implementations.Base_4096 is
   pragma Pure;

   type Base_4096_Digit is range 0 .. 4095;

   procedure Read_Code
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : out Base_4096_Digit;
      Verbatim_Length : out Natural;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean);

   procedure Read_Verbatim
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Output : out String);

   procedure Skip_Verbatim
     (Input : in Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Verbatim_Length : in Positive);

   function Verbatim_Size
     (Input_Length : in Positive;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean)
     return Ada.Streams.Stream_Element_Count;

   procedure Write_Code
     (Output : in out Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Code : in Base_4096_Digit);

   procedure Write_Verbatim
     (Output : in out Ada.Streams.Stream_Element_Array;
      Offset : in out Ada.Streams.Stream_Element_Offset;
      Input : in String;
      Last_Code : in Base_4096_Digit;
      Variable_Length_Verbatim : in Boolean);

end Natools.Smaz_Implementations.Base_4096;