chd 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +30 -0
- data/chd.gemspec +29 -0
- data/ext/chd.c +1008 -0
- data/ext/extconf.rb +60 -0
- data/lib/chd/cd.rb +272 -0
- data/lib/chd/metadata.rb +196 -0
- data/lib/chd/version.rb +4 -0
- data/lib/chd.rb +21 -0
- data/libchdr/CMakeLists.txt +104 -0
- data/libchdr/LICENSE.txt +24 -0
- data/libchdr/README.md +7 -0
- data/libchdr/deps/lzma-19.00/CMakeLists.txt +33 -0
- data/libchdr/deps/lzma-19.00/LICENSE +3 -0
- data/libchdr/deps/lzma-19.00/include/7zTypes.h +375 -0
- data/libchdr/deps/lzma-19.00/include/Alloc.h +51 -0
- data/libchdr/deps/lzma-19.00/include/Bra.h +64 -0
- data/libchdr/deps/lzma-19.00/include/Compiler.h +33 -0
- data/libchdr/deps/lzma-19.00/include/CpuArch.h +336 -0
- data/libchdr/deps/lzma-19.00/include/Delta.h +19 -0
- data/libchdr/deps/lzma-19.00/include/LzFind.h +121 -0
- data/libchdr/deps/lzma-19.00/include/LzHash.h +57 -0
- data/libchdr/deps/lzma-19.00/include/Lzma86.h +111 -0
- data/libchdr/deps/lzma-19.00/include/LzmaDec.h +234 -0
- data/libchdr/deps/lzma-19.00/include/LzmaEnc.h +76 -0
- data/libchdr/deps/lzma-19.00/include/LzmaLib.h +131 -0
- data/libchdr/deps/lzma-19.00/include/Precomp.h +10 -0
- data/libchdr/deps/lzma-19.00/include/Sort.h +18 -0
- data/libchdr/deps/lzma-19.00/lzma-history.txt +446 -0
- data/libchdr/deps/lzma-19.00/lzma.txt +328 -0
- data/libchdr/deps/lzma-19.00/lzma.vcxproj +543 -0
- data/libchdr/deps/lzma-19.00/lzma.vcxproj.filters +17 -0
- data/libchdr/deps/lzma-19.00/src/Alloc.c +455 -0
- data/libchdr/deps/lzma-19.00/src/Bra86.c +82 -0
- data/libchdr/deps/lzma-19.00/src/BraIA64.c +53 -0
- data/libchdr/deps/lzma-19.00/src/CpuArch.c +218 -0
- data/libchdr/deps/lzma-19.00/src/Delta.c +64 -0
- data/libchdr/deps/lzma-19.00/src/LzFind.c +1127 -0
- data/libchdr/deps/lzma-19.00/src/Lzma86Dec.c +54 -0
- data/libchdr/deps/lzma-19.00/src/LzmaDec.c +1185 -0
- data/libchdr/deps/lzma-19.00/src/LzmaEnc.c +1330 -0
- data/libchdr/deps/lzma-19.00/src/Sort.c +141 -0
- data/libchdr/deps/zlib-1.2.11/CMakeLists.txt +29 -0
- data/libchdr/deps/zlib-1.2.11/ChangeLog +1515 -0
- data/libchdr/deps/zlib-1.2.11/FAQ +368 -0
- data/libchdr/deps/zlib-1.2.11/INDEX +68 -0
- data/libchdr/deps/zlib-1.2.11/Makefile +5 -0
- data/libchdr/deps/zlib-1.2.11/Makefile.in +410 -0
- data/libchdr/deps/zlib-1.2.11/README +115 -0
- data/libchdr/deps/zlib-1.2.11/adler32.c +186 -0
- data/libchdr/deps/zlib-1.2.11/compress.c +86 -0
- data/libchdr/deps/zlib-1.2.11/configure +921 -0
- data/libchdr/deps/zlib-1.2.11/crc32.c +442 -0
- data/libchdr/deps/zlib-1.2.11/crc32.h +441 -0
- data/libchdr/deps/zlib-1.2.11/deflate.c +2163 -0
- data/libchdr/deps/zlib-1.2.11/deflate.h +349 -0
- data/libchdr/deps/zlib-1.2.11/doc/algorithm.txt +209 -0
- data/libchdr/deps/zlib-1.2.11/doc/rfc1950.txt +619 -0
- data/libchdr/deps/zlib-1.2.11/doc/rfc1951.txt +955 -0
- data/libchdr/deps/zlib-1.2.11/doc/rfc1952.txt +675 -0
- data/libchdr/deps/zlib-1.2.11/doc/txtvsbin.txt +107 -0
- data/libchdr/deps/zlib-1.2.11/gzclose.c +25 -0
- data/libchdr/deps/zlib-1.2.11/gzguts.h +218 -0
- data/libchdr/deps/zlib-1.2.11/gzlib.c +637 -0
- data/libchdr/deps/zlib-1.2.11/gzread.c +654 -0
- data/libchdr/deps/zlib-1.2.11/gzwrite.c +665 -0
- data/libchdr/deps/zlib-1.2.11/infback.c +640 -0
- data/libchdr/deps/zlib-1.2.11/inffast.c +323 -0
- data/libchdr/deps/zlib-1.2.11/inffast.h +11 -0
- data/libchdr/deps/zlib-1.2.11/inffixed.h +94 -0
- data/libchdr/deps/zlib-1.2.11/inflate.c +1561 -0
- data/libchdr/deps/zlib-1.2.11/inflate.h +125 -0
- data/libchdr/deps/zlib-1.2.11/inftrees.c +304 -0
- data/libchdr/deps/zlib-1.2.11/inftrees.h +62 -0
- data/libchdr/deps/zlib-1.2.11/make_vms.com +867 -0
- data/libchdr/deps/zlib-1.2.11/treebuild.xml +116 -0
- data/libchdr/deps/zlib-1.2.11/trees.c +1203 -0
- data/libchdr/deps/zlib-1.2.11/trees.h +128 -0
- data/libchdr/deps/zlib-1.2.11/uncompr.c +93 -0
- data/libchdr/deps/zlib-1.2.11/zconf.h +534 -0
- data/libchdr/deps/zlib-1.2.11/zconf.h.cmakein +536 -0
- data/libchdr/deps/zlib-1.2.11/zconf.h.in +534 -0
- data/libchdr/deps/zlib-1.2.11/zlib.3 +149 -0
- data/libchdr/deps/zlib-1.2.11/zlib.3.pdf +0 -0
- data/libchdr/deps/zlib-1.2.11/zlib.h +1912 -0
- data/libchdr/deps/zlib-1.2.11/zlib.map +94 -0
- data/libchdr/deps/zlib-1.2.11/zlib.pc.cmakein +13 -0
- data/libchdr/deps/zlib-1.2.11/zlib.pc.in +13 -0
- data/libchdr/deps/zlib-1.2.11/zlib2ansi +152 -0
- data/libchdr/deps/zlib-1.2.11/zutil.c +325 -0
- data/libchdr/deps/zlib-1.2.11/zutil.h +271 -0
- data/libchdr/include/dr_libs/dr_flac.h +12280 -0
- data/libchdr/include/libchdr/bitstream.h +43 -0
- data/libchdr/include/libchdr/cdrom.h +110 -0
- data/libchdr/include/libchdr/chd.h +427 -0
- data/libchdr/include/libchdr/chdconfig.h +10 -0
- data/libchdr/include/libchdr/coretypes.h +60 -0
- data/libchdr/include/libchdr/flac.h +50 -0
- data/libchdr/include/libchdr/huffman.h +90 -0
- data/libchdr/pkg-config.pc.in +10 -0
- data/libchdr/src/libchdr_bitstream.c +125 -0
- data/libchdr/src/libchdr_cdrom.c +415 -0
- data/libchdr/src/libchdr_chd.c +2744 -0
- data/libchdr/src/libchdr_flac.c +302 -0
- data/libchdr/src/libchdr_huffman.c +545 -0
- data/libchdr/src/link.T +5 -0
- data/libchdr/tests/CMakeLists.txt +2 -0
- data/libchdr/tests/benchmark.c +52 -0
- metadata +183 -0
@@ -0,0 +1,1127 @@
|
|
1
|
+
/* LzFind.c -- Match finder for LZ algorithms
|
2
|
+
2018-07-08 : Igor Pavlov : Public domain */
|
3
|
+
|
4
|
+
#include "Precomp.h"
|
5
|
+
|
6
|
+
#include <string.h>
|
7
|
+
|
8
|
+
#include "LzFind.h"
|
9
|
+
#include "LzHash.h"
|
10
|
+
|
11
|
+
#define kEmptyHashValue 0
|
12
|
+
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
13
|
+
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
14
|
+
#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
|
15
|
+
#define kMaxHistorySize ((UInt32)7 << 29)
|
16
|
+
|
17
|
+
#define kStartMaxLen 3
|
18
|
+
|
19
|
+
static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
20
|
+
{
|
21
|
+
if (!p->directInput)
|
22
|
+
{
|
23
|
+
ISzAlloc_Free(alloc, p->bufferBase);
|
24
|
+
p->bufferBase = NULL;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
29
|
+
|
30
|
+
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
|
31
|
+
{
|
32
|
+
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
33
|
+
if (p->directInput)
|
34
|
+
{
|
35
|
+
p->blockSize = blockSize;
|
36
|
+
return 1;
|
37
|
+
}
|
38
|
+
if (!p->bufferBase || p->blockSize != blockSize)
|
39
|
+
{
|
40
|
+
LzInWindow_Free(p, alloc);
|
41
|
+
p->blockSize = blockSize;
|
42
|
+
p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
|
43
|
+
}
|
44
|
+
return (p->bufferBase != NULL);
|
45
|
+
}
|
46
|
+
|
47
|
+
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
48
|
+
|
49
|
+
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
50
|
+
|
51
|
+
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
52
|
+
{
|
53
|
+
p->posLimit -= subValue;
|
54
|
+
p->pos -= subValue;
|
55
|
+
p->streamPos -= subValue;
|
56
|
+
}
|
57
|
+
|
58
|
+
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
59
|
+
{
|
60
|
+
if (p->streamEndWasReached || p->result != SZ_OK)
|
61
|
+
return;
|
62
|
+
|
63
|
+
/* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
|
64
|
+
|
65
|
+
if (p->directInput)
|
66
|
+
{
|
67
|
+
UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
|
68
|
+
if (curSize > p->directInputRem)
|
69
|
+
curSize = (UInt32)p->directInputRem;
|
70
|
+
p->directInputRem -= curSize;
|
71
|
+
p->streamPos += curSize;
|
72
|
+
if (p->directInputRem == 0)
|
73
|
+
p->streamEndWasReached = 1;
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
for (;;)
|
78
|
+
{
|
79
|
+
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
80
|
+
size_t size = (p->bufferBase + p->blockSize - dest);
|
81
|
+
if (size == 0)
|
82
|
+
return;
|
83
|
+
|
84
|
+
p->result = ISeqInStream_Read(p->stream, dest, &size);
|
85
|
+
if (p->result != SZ_OK)
|
86
|
+
return;
|
87
|
+
if (size == 0)
|
88
|
+
{
|
89
|
+
p->streamEndWasReached = 1;
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
p->streamPos += (UInt32)size;
|
93
|
+
if (p->streamPos - p->pos > p->keepSizeAfter)
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
void MatchFinder_MoveBlock(CMatchFinder *p)
|
99
|
+
{
|
100
|
+
memmove(p->bufferBase,
|
101
|
+
p->buffer - p->keepSizeBefore,
|
102
|
+
(size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
|
103
|
+
p->buffer = p->bufferBase + p->keepSizeBefore;
|
104
|
+
}
|
105
|
+
|
106
|
+
int MatchFinder_NeedMove(CMatchFinder *p)
|
107
|
+
{
|
108
|
+
if (p->directInput)
|
109
|
+
return 0;
|
110
|
+
/* if (p->streamEndWasReached) return 0; */
|
111
|
+
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
112
|
+
}
|
113
|
+
|
114
|
+
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
115
|
+
{
|
116
|
+
if (p->streamEndWasReached)
|
117
|
+
return;
|
118
|
+
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
119
|
+
MatchFinder_ReadBlock(p);
|
120
|
+
}
|
121
|
+
|
122
|
+
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
123
|
+
{
|
124
|
+
if (MatchFinder_NeedMove(p))
|
125
|
+
MatchFinder_MoveBlock(p);
|
126
|
+
MatchFinder_ReadBlock(p);
|
127
|
+
}
|
128
|
+
|
129
|
+
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
130
|
+
{
|
131
|
+
p->cutValue = 32;
|
132
|
+
p->btMode = 1;
|
133
|
+
p->numHashBytes = 4;
|
134
|
+
p->bigHash = 0;
|
135
|
+
}
|
136
|
+
|
137
|
+
#define kCrcPoly 0xEDB88320
|
138
|
+
|
139
|
+
void MatchFinder_Construct(CMatchFinder *p)
|
140
|
+
{
|
141
|
+
unsigned i;
|
142
|
+
p->bufferBase = NULL;
|
143
|
+
p->directInput = 0;
|
144
|
+
p->hash = NULL;
|
145
|
+
p->expectedDataSize = (UInt64)(Int64)-1;
|
146
|
+
MatchFinder_SetDefaultSettings(p);
|
147
|
+
|
148
|
+
for (i = 0; i < 256; i++)
|
149
|
+
{
|
150
|
+
UInt32 r = (UInt32)i;
|
151
|
+
unsigned j;
|
152
|
+
for (j = 0; j < 8; j++)
|
153
|
+
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
154
|
+
p->crc[i] = r;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
|
159
|
+
{
|
160
|
+
ISzAlloc_Free(alloc, p->hash);
|
161
|
+
p->hash = NULL;
|
162
|
+
}
|
163
|
+
|
164
|
+
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
165
|
+
{
|
166
|
+
MatchFinder_FreeThisClassMemory(p, alloc);
|
167
|
+
LzInWindow_Free(p, alloc);
|
168
|
+
}
|
169
|
+
|
170
|
+
static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
|
171
|
+
{
|
172
|
+
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
173
|
+
if (sizeInBytes / sizeof(CLzRef) != num)
|
174
|
+
return NULL;
|
175
|
+
return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
|
176
|
+
}
|
177
|
+
|
178
|
+
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
179
|
+
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
180
|
+
ISzAllocPtr alloc)
|
181
|
+
{
|
182
|
+
UInt32 sizeReserv;
|
183
|
+
|
184
|
+
if (historySize > kMaxHistorySize)
|
185
|
+
{
|
186
|
+
MatchFinder_Free(p, alloc);
|
187
|
+
return 0;
|
188
|
+
}
|
189
|
+
|
190
|
+
sizeReserv = historySize >> 1;
|
191
|
+
if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
|
192
|
+
else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
|
193
|
+
|
194
|
+
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
195
|
+
|
196
|
+
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
197
|
+
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
198
|
+
|
199
|
+
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
200
|
+
|
201
|
+
if (LzInWindow_Create(p, sizeReserv, alloc))
|
202
|
+
{
|
203
|
+
UInt32 newCyclicBufferSize = historySize + 1;
|
204
|
+
UInt32 hs;
|
205
|
+
p->matchMaxLen = matchMaxLen;
|
206
|
+
{
|
207
|
+
p->fixedHashSize = 0;
|
208
|
+
if (p->numHashBytes == 2)
|
209
|
+
hs = (1 << 16) - 1;
|
210
|
+
else
|
211
|
+
{
|
212
|
+
hs = historySize;
|
213
|
+
if (hs > p->expectedDataSize)
|
214
|
+
hs = (UInt32)p->expectedDataSize;
|
215
|
+
if (hs != 0)
|
216
|
+
hs--;
|
217
|
+
hs |= (hs >> 1);
|
218
|
+
hs |= (hs >> 2);
|
219
|
+
hs |= (hs >> 4);
|
220
|
+
hs |= (hs >> 8);
|
221
|
+
hs >>= 1;
|
222
|
+
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
223
|
+
if (hs > (1 << 24))
|
224
|
+
{
|
225
|
+
if (p->numHashBytes == 3)
|
226
|
+
hs = (1 << 24) - 1;
|
227
|
+
else
|
228
|
+
hs >>= 1;
|
229
|
+
/* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
|
230
|
+
}
|
231
|
+
}
|
232
|
+
p->hashMask = hs;
|
233
|
+
hs++;
|
234
|
+
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
235
|
+
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
236
|
+
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
237
|
+
hs += p->fixedHashSize;
|
238
|
+
}
|
239
|
+
|
240
|
+
{
|
241
|
+
size_t newSize;
|
242
|
+
size_t numSons;
|
243
|
+
p->historySize = historySize;
|
244
|
+
p->hashSizeSum = hs;
|
245
|
+
p->cyclicBufferSize = newCyclicBufferSize;
|
246
|
+
|
247
|
+
numSons = newCyclicBufferSize;
|
248
|
+
if (p->btMode)
|
249
|
+
numSons <<= 1;
|
250
|
+
newSize = hs + numSons;
|
251
|
+
|
252
|
+
if (p->hash && p->numRefs == newSize)
|
253
|
+
return 1;
|
254
|
+
|
255
|
+
MatchFinder_FreeThisClassMemory(p, alloc);
|
256
|
+
p->numRefs = newSize;
|
257
|
+
p->hash = AllocRefs(newSize, alloc);
|
258
|
+
|
259
|
+
if (p->hash)
|
260
|
+
{
|
261
|
+
p->son = p->hash + p->hashSizeSum;
|
262
|
+
return 1;
|
263
|
+
}
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
MatchFinder_Free(p, alloc);
|
268
|
+
return 0;
|
269
|
+
}
|
270
|
+
|
271
|
+
static void MatchFinder_SetLimits(CMatchFinder *p)
|
272
|
+
{
|
273
|
+
UInt32 limit = kMaxValForNormalize - p->pos;
|
274
|
+
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
275
|
+
|
276
|
+
if (limit2 < limit)
|
277
|
+
limit = limit2;
|
278
|
+
limit2 = p->streamPos - p->pos;
|
279
|
+
|
280
|
+
if (limit2 <= p->keepSizeAfter)
|
281
|
+
{
|
282
|
+
if (limit2 > 0)
|
283
|
+
limit2 = 1;
|
284
|
+
}
|
285
|
+
else
|
286
|
+
limit2 -= p->keepSizeAfter;
|
287
|
+
|
288
|
+
if (limit2 < limit)
|
289
|
+
limit = limit2;
|
290
|
+
|
291
|
+
{
|
292
|
+
UInt32 lenLimit = p->streamPos - p->pos;
|
293
|
+
if (lenLimit > p->matchMaxLen)
|
294
|
+
lenLimit = p->matchMaxLen;
|
295
|
+
p->lenLimit = lenLimit;
|
296
|
+
}
|
297
|
+
p->posLimit = p->pos + limit;
|
298
|
+
}
|
299
|
+
|
300
|
+
|
301
|
+
void MatchFinder_Init_LowHash(CMatchFinder *p)
|
302
|
+
{
|
303
|
+
size_t i;
|
304
|
+
CLzRef *items = p->hash;
|
305
|
+
size_t numItems = p->fixedHashSize;
|
306
|
+
for (i = 0; i < numItems; i++)
|
307
|
+
items[i] = kEmptyHashValue;
|
308
|
+
}
|
309
|
+
|
310
|
+
|
311
|
+
void MatchFinder_Init_HighHash(CMatchFinder *p)
|
312
|
+
{
|
313
|
+
size_t i;
|
314
|
+
CLzRef *items = p->hash + p->fixedHashSize;
|
315
|
+
size_t numItems = (size_t)p->hashMask + 1;
|
316
|
+
for (i = 0; i < numItems; i++)
|
317
|
+
items[i] = kEmptyHashValue;
|
318
|
+
}
|
319
|
+
|
320
|
+
|
321
|
+
void MatchFinder_Init_3(CMatchFinder *p, int readData)
|
322
|
+
{
|
323
|
+
p->cyclicBufferPos = 0;
|
324
|
+
p->buffer = p->bufferBase;
|
325
|
+
p->pos =
|
326
|
+
p->streamPos = p->cyclicBufferSize;
|
327
|
+
p->result = SZ_OK;
|
328
|
+
p->streamEndWasReached = 0;
|
329
|
+
|
330
|
+
if (readData)
|
331
|
+
MatchFinder_ReadBlock(p);
|
332
|
+
|
333
|
+
MatchFinder_SetLimits(p);
|
334
|
+
}
|
335
|
+
|
336
|
+
|
337
|
+
void MatchFinder_Init(CMatchFinder *p)
|
338
|
+
{
|
339
|
+
MatchFinder_Init_HighHash(p);
|
340
|
+
MatchFinder_Init_LowHash(p);
|
341
|
+
MatchFinder_Init_3(p, True);
|
342
|
+
}
|
343
|
+
|
344
|
+
|
345
|
+
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
346
|
+
{
|
347
|
+
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
348
|
+
}
|
349
|
+
|
350
|
+
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
|
351
|
+
{
|
352
|
+
size_t i;
|
353
|
+
for (i = 0; i < numItems; i++)
|
354
|
+
{
|
355
|
+
UInt32 value = items[i];
|
356
|
+
if (value <= subValue)
|
357
|
+
value = kEmptyHashValue;
|
358
|
+
else
|
359
|
+
value -= subValue;
|
360
|
+
items[i] = value;
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
static void MatchFinder_Normalize(CMatchFinder *p)
|
365
|
+
{
|
366
|
+
UInt32 subValue = MatchFinder_GetSubValue(p);
|
367
|
+
MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
|
368
|
+
MatchFinder_ReduceOffsets(p, subValue);
|
369
|
+
}
|
370
|
+
|
371
|
+
|
372
|
+
MY_NO_INLINE
|
373
|
+
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
374
|
+
{
|
375
|
+
if (p->pos == kMaxValForNormalize)
|
376
|
+
MatchFinder_Normalize(p);
|
377
|
+
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
378
|
+
MatchFinder_CheckAndMoveAndRead(p);
|
379
|
+
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
380
|
+
p->cyclicBufferPos = 0;
|
381
|
+
MatchFinder_SetLimits(p);
|
382
|
+
}
|
383
|
+
|
384
|
+
|
385
|
+
/*
|
386
|
+
(lenLimit > maxLen)
|
387
|
+
*/
|
388
|
+
MY_FORCE_INLINE
|
389
|
+
static UInt32 * Hc_GetMatchesSpec(unsigned lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
390
|
+
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
391
|
+
UInt32 *distances, unsigned maxLen)
|
392
|
+
{
|
393
|
+
/*
|
394
|
+
son[_cyclicBufferPos] = curMatch;
|
395
|
+
for (;;)
|
396
|
+
{
|
397
|
+
UInt32 delta = pos - curMatch;
|
398
|
+
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
399
|
+
return distances;
|
400
|
+
{
|
401
|
+
const Byte *pb = cur - delta;
|
402
|
+
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
403
|
+
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
404
|
+
{
|
405
|
+
UInt32 len = 0;
|
406
|
+
while (++len != lenLimit)
|
407
|
+
if (pb[len] != cur[len])
|
408
|
+
break;
|
409
|
+
if (maxLen < len)
|
410
|
+
{
|
411
|
+
maxLen = len;
|
412
|
+
*distances++ = len;
|
413
|
+
*distances++ = delta - 1;
|
414
|
+
if (len == lenLimit)
|
415
|
+
return distances;
|
416
|
+
}
|
417
|
+
}
|
418
|
+
}
|
419
|
+
}
|
420
|
+
*/
|
421
|
+
|
422
|
+
const Byte *lim = cur + lenLimit;
|
423
|
+
son[_cyclicBufferPos] = curMatch;
|
424
|
+
do
|
425
|
+
{
|
426
|
+
UInt32 delta = pos - curMatch;
|
427
|
+
if (delta >= _cyclicBufferSize)
|
428
|
+
break;
|
429
|
+
{
|
430
|
+
ptrdiff_t diff;
|
431
|
+
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
432
|
+
diff = (ptrdiff_t)0 - delta;
|
433
|
+
if (cur[maxLen] == cur[maxLen + diff])
|
434
|
+
{
|
435
|
+
const Byte *c = cur;
|
436
|
+
while (*c == c[diff])
|
437
|
+
{
|
438
|
+
if (++c == lim)
|
439
|
+
{
|
440
|
+
distances[0] = (UInt32)(lim - cur);
|
441
|
+
distances[1] = delta - 1;
|
442
|
+
return distances + 2;
|
443
|
+
}
|
444
|
+
}
|
445
|
+
{
|
446
|
+
unsigned len = (unsigned)(c - cur);
|
447
|
+
if (maxLen < len)
|
448
|
+
{
|
449
|
+
maxLen = len;
|
450
|
+
distances[0] = (UInt32)len;
|
451
|
+
distances[1] = delta - 1;
|
452
|
+
distances += 2;
|
453
|
+
}
|
454
|
+
}
|
455
|
+
}
|
456
|
+
}
|
457
|
+
}
|
458
|
+
while (--cutValue);
|
459
|
+
|
460
|
+
return distances;
|
461
|
+
}
|
462
|
+
|
463
|
+
|
464
|
+
MY_FORCE_INLINE
|
465
|
+
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
466
|
+
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
467
|
+
UInt32 *distances, UInt32 maxLen)
|
468
|
+
{
|
469
|
+
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
|
470
|
+
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
|
471
|
+
unsigned len0 = 0, len1 = 0;
|
472
|
+
for (;;)
|
473
|
+
{
|
474
|
+
UInt32 delta = pos - curMatch;
|
475
|
+
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
476
|
+
{
|
477
|
+
*ptr0 = *ptr1 = kEmptyHashValue;
|
478
|
+
return distances;
|
479
|
+
}
|
480
|
+
{
|
481
|
+
CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
482
|
+
const Byte *pb = cur - delta;
|
483
|
+
unsigned len = (len0 < len1 ? len0 : len1);
|
484
|
+
UInt32 pair0 = pair[0];
|
485
|
+
if (pb[len] == cur[len])
|
486
|
+
{
|
487
|
+
if (++len != lenLimit && pb[len] == cur[len])
|
488
|
+
while (++len != lenLimit)
|
489
|
+
if (pb[len] != cur[len])
|
490
|
+
break;
|
491
|
+
if (maxLen < len)
|
492
|
+
{
|
493
|
+
maxLen = (UInt32)len;
|
494
|
+
*distances++ = (UInt32)len;
|
495
|
+
*distances++ = delta - 1;
|
496
|
+
if (len == lenLimit)
|
497
|
+
{
|
498
|
+
*ptr1 = pair0;
|
499
|
+
*ptr0 = pair[1];
|
500
|
+
return distances;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
}
|
504
|
+
if (pb[len] < cur[len])
|
505
|
+
{
|
506
|
+
*ptr1 = curMatch;
|
507
|
+
ptr1 = pair + 1;
|
508
|
+
curMatch = *ptr1;
|
509
|
+
len1 = len;
|
510
|
+
}
|
511
|
+
else
|
512
|
+
{
|
513
|
+
*ptr0 = curMatch;
|
514
|
+
ptr0 = pair;
|
515
|
+
curMatch = *ptr0;
|
516
|
+
len0 = len;
|
517
|
+
}
|
518
|
+
}
|
519
|
+
}
|
520
|
+
}
|
521
|
+
|
522
|
+
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
523
|
+
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
524
|
+
{
|
525
|
+
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
|
526
|
+
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
|
527
|
+
unsigned len0 = 0, len1 = 0;
|
528
|
+
for (;;)
|
529
|
+
{
|
530
|
+
UInt32 delta = pos - curMatch;
|
531
|
+
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
532
|
+
{
|
533
|
+
*ptr0 = *ptr1 = kEmptyHashValue;
|
534
|
+
return;
|
535
|
+
}
|
536
|
+
{
|
537
|
+
CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
538
|
+
const Byte *pb = cur - delta;
|
539
|
+
unsigned len = (len0 < len1 ? len0 : len1);
|
540
|
+
if (pb[len] == cur[len])
|
541
|
+
{
|
542
|
+
while (++len != lenLimit)
|
543
|
+
if (pb[len] != cur[len])
|
544
|
+
break;
|
545
|
+
{
|
546
|
+
if (len == lenLimit)
|
547
|
+
{
|
548
|
+
*ptr1 = pair[0];
|
549
|
+
*ptr0 = pair[1];
|
550
|
+
return;
|
551
|
+
}
|
552
|
+
}
|
553
|
+
}
|
554
|
+
if (pb[len] < cur[len])
|
555
|
+
{
|
556
|
+
*ptr1 = curMatch;
|
557
|
+
ptr1 = pair + 1;
|
558
|
+
curMatch = *ptr1;
|
559
|
+
len1 = len;
|
560
|
+
}
|
561
|
+
else
|
562
|
+
{
|
563
|
+
*ptr0 = curMatch;
|
564
|
+
ptr0 = pair;
|
565
|
+
curMatch = *ptr0;
|
566
|
+
len0 = len;
|
567
|
+
}
|
568
|
+
}
|
569
|
+
}
|
570
|
+
}
|
571
|
+
|
572
|
+
#define MOVE_POS \
|
573
|
+
++p->cyclicBufferPos; \
|
574
|
+
p->buffer++; \
|
575
|
+
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
576
|
+
|
577
|
+
#define MOVE_POS_RET MOVE_POS return (UInt32)offset;
|
578
|
+
|
579
|
+
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
580
|
+
|
581
|
+
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
582
|
+
unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
|
583
|
+
lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
584
|
+
cur = p->buffer;
|
585
|
+
|
586
|
+
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
587
|
+
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
588
|
+
|
589
|
+
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
590
|
+
|
591
|
+
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
592
|
+
offset = (unsigned)(GetMatchesSpec1((UInt32)lenLimit, curMatch, MF_PARAMS(p), \
|
593
|
+
distances + offset, (UInt32)maxLen) - distances); MOVE_POS_RET;
|
594
|
+
|
595
|
+
#define SKIP_FOOTER \
|
596
|
+
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
597
|
+
|
598
|
+
#define UPDATE_maxLen { \
|
599
|
+
ptrdiff_t diff = (ptrdiff_t)0 - d2; \
|
600
|
+
const Byte *c = cur + maxLen; \
|
601
|
+
const Byte *lim = cur + lenLimit; \
|
602
|
+
for (; c != lim; c++) if (*(c + diff) != *c) break; \
|
603
|
+
maxLen = (unsigned)(c - cur); }
|
604
|
+
|
605
|
+
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
606
|
+
{
|
607
|
+
unsigned offset;
|
608
|
+
GET_MATCHES_HEADER(2)
|
609
|
+
HASH2_CALC;
|
610
|
+
curMatch = p->hash[hv];
|
611
|
+
p->hash[hv] = p->pos;
|
612
|
+
offset = 0;
|
613
|
+
GET_MATCHES_FOOTER(offset, 1)
|
614
|
+
}
|
615
|
+
|
616
|
+
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
617
|
+
{
|
618
|
+
unsigned offset;
|
619
|
+
GET_MATCHES_HEADER(3)
|
620
|
+
HASH_ZIP_CALC;
|
621
|
+
curMatch = p->hash[hv];
|
622
|
+
p->hash[hv] = p->pos;
|
623
|
+
offset = 0;
|
624
|
+
GET_MATCHES_FOOTER(offset, 2)
|
625
|
+
}
|
626
|
+
|
627
|
+
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
628
|
+
{
|
629
|
+
UInt32 h2, d2, pos;
|
630
|
+
unsigned maxLen, offset;
|
631
|
+
UInt32 *hash;
|
632
|
+
GET_MATCHES_HEADER(3)
|
633
|
+
|
634
|
+
HASH3_CALC;
|
635
|
+
|
636
|
+
hash = p->hash;
|
637
|
+
pos = p->pos;
|
638
|
+
|
639
|
+
d2 = pos - hash[h2];
|
640
|
+
|
641
|
+
curMatch = (hash + kFix3HashSize)[hv];
|
642
|
+
|
643
|
+
hash[h2] = pos;
|
644
|
+
(hash + kFix3HashSize)[hv] = pos;
|
645
|
+
|
646
|
+
maxLen = 2;
|
647
|
+
offset = 0;
|
648
|
+
|
649
|
+
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
650
|
+
{
|
651
|
+
UPDATE_maxLen
|
652
|
+
distances[0] = (UInt32)maxLen;
|
653
|
+
distances[1] = d2 - 1;
|
654
|
+
offset = 2;
|
655
|
+
if (maxLen == lenLimit)
|
656
|
+
{
|
657
|
+
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
|
658
|
+
MOVE_POS_RET;
|
659
|
+
}
|
660
|
+
}
|
661
|
+
|
662
|
+
GET_MATCHES_FOOTER(offset, maxLen)
|
663
|
+
}
|
664
|
+
|
665
|
+
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
666
|
+
{
|
667
|
+
UInt32 h2, h3, d2, d3, pos;
|
668
|
+
unsigned maxLen, offset;
|
669
|
+
UInt32 *hash;
|
670
|
+
GET_MATCHES_HEADER(4)
|
671
|
+
|
672
|
+
HASH4_CALC;
|
673
|
+
|
674
|
+
hash = p->hash;
|
675
|
+
pos = p->pos;
|
676
|
+
|
677
|
+
d2 = pos - hash [h2];
|
678
|
+
d3 = pos - (hash + kFix3HashSize)[h3];
|
679
|
+
|
680
|
+
curMatch = (hash + kFix4HashSize)[hv];
|
681
|
+
|
682
|
+
hash [h2] = pos;
|
683
|
+
(hash + kFix3HashSize)[h3] = pos;
|
684
|
+
(hash + kFix4HashSize)[hv] = pos;
|
685
|
+
|
686
|
+
maxLen = 0;
|
687
|
+
offset = 0;
|
688
|
+
|
689
|
+
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
690
|
+
{
|
691
|
+
maxLen = 2;
|
692
|
+
distances[0] = 2;
|
693
|
+
distances[1] = d2 - 1;
|
694
|
+
offset = 2;
|
695
|
+
}
|
696
|
+
|
697
|
+
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
698
|
+
{
|
699
|
+
maxLen = 3;
|
700
|
+
distances[(size_t)offset + 1] = d3 - 1;
|
701
|
+
offset += 2;
|
702
|
+
d2 = d3;
|
703
|
+
}
|
704
|
+
|
705
|
+
if (offset != 0)
|
706
|
+
{
|
707
|
+
UPDATE_maxLen
|
708
|
+
distances[(size_t)offset - 2] = (UInt32)maxLen;
|
709
|
+
if (maxLen == lenLimit)
|
710
|
+
{
|
711
|
+
SkipMatchesSpec((UInt32)lenLimit, curMatch, MF_PARAMS(p));
|
712
|
+
MOVE_POS_RET;
|
713
|
+
}
|
714
|
+
}
|
715
|
+
|
716
|
+
if (maxLen < 3)
|
717
|
+
maxLen = 3;
|
718
|
+
|
719
|
+
GET_MATCHES_FOOTER(offset, maxLen)
|
720
|
+
}
|
721
|
+
|
722
|
+
/*
|
723
|
+
static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
724
|
+
{
|
725
|
+
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
|
726
|
+
UInt32 *hash;
|
727
|
+
GET_MATCHES_HEADER(5)
|
728
|
+
|
729
|
+
HASH5_CALC;
|
730
|
+
|
731
|
+
hash = p->hash;
|
732
|
+
pos = p->pos;
|
733
|
+
|
734
|
+
d2 = pos - hash [h2];
|
735
|
+
d3 = pos - (hash + kFix3HashSize)[h3];
|
736
|
+
d4 = pos - (hash + kFix4HashSize)[h4];
|
737
|
+
|
738
|
+
curMatch = (hash + kFix5HashSize)[hv];
|
739
|
+
|
740
|
+
hash [h2] = pos;
|
741
|
+
(hash + kFix3HashSize)[h3] = pos;
|
742
|
+
(hash + kFix4HashSize)[h4] = pos;
|
743
|
+
(hash + kFix5HashSize)[hv] = pos;
|
744
|
+
|
745
|
+
maxLen = 0;
|
746
|
+
offset = 0;
|
747
|
+
|
748
|
+
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
749
|
+
{
|
750
|
+
distances[0] = maxLen = 2;
|
751
|
+
distances[1] = d2 - 1;
|
752
|
+
offset = 2;
|
753
|
+
if (*(cur - d2 + 2) == cur[2])
|
754
|
+
distances[0] = maxLen = 3;
|
755
|
+
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
756
|
+
{
|
757
|
+
distances[2] = maxLen = 3;
|
758
|
+
distances[3] = d3 - 1;
|
759
|
+
offset = 4;
|
760
|
+
d2 = d3;
|
761
|
+
}
|
762
|
+
}
|
763
|
+
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
764
|
+
{
|
765
|
+
distances[0] = maxLen = 3;
|
766
|
+
distances[1] = d3 - 1;
|
767
|
+
offset = 2;
|
768
|
+
d2 = d3;
|
769
|
+
}
|
770
|
+
|
771
|
+
if (d2 != d4 && d4 < p->cyclicBufferSize
|
772
|
+
&& *(cur - d4) == *cur
|
773
|
+
&& *(cur - d4 + 3) == *(cur + 3))
|
774
|
+
{
|
775
|
+
maxLen = 4;
|
776
|
+
distances[(size_t)offset + 1] = d4 - 1;
|
777
|
+
offset += 2;
|
778
|
+
d2 = d4;
|
779
|
+
}
|
780
|
+
|
781
|
+
if (offset != 0)
|
782
|
+
{
|
783
|
+
UPDATE_maxLen
|
784
|
+
distances[(size_t)offset - 2] = maxLen;
|
785
|
+
if (maxLen == lenLimit)
|
786
|
+
{
|
787
|
+
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
788
|
+
MOVE_POS_RET;
|
789
|
+
}
|
790
|
+
}
|
791
|
+
|
792
|
+
if (maxLen < 4)
|
793
|
+
maxLen = 4;
|
794
|
+
|
795
|
+
GET_MATCHES_FOOTER(offset, maxLen)
|
796
|
+
}
|
797
|
+
*/
|
798
|
+
|
799
|
+
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
800
|
+
{
|
801
|
+
UInt32 h2, h3, d2, d3, pos;
|
802
|
+
unsigned maxLen, offset;
|
803
|
+
UInt32 *hash;
|
804
|
+
GET_MATCHES_HEADER(4)
|
805
|
+
|
806
|
+
HASH4_CALC;
|
807
|
+
|
808
|
+
hash = p->hash;
|
809
|
+
pos = p->pos;
|
810
|
+
|
811
|
+
d2 = pos - hash [h2];
|
812
|
+
d3 = pos - (hash + kFix3HashSize)[h3];
|
813
|
+
curMatch = (hash + kFix4HashSize)[hv];
|
814
|
+
|
815
|
+
hash [h2] = pos;
|
816
|
+
(hash + kFix3HashSize)[h3] = pos;
|
817
|
+
(hash + kFix4HashSize)[hv] = pos;
|
818
|
+
|
819
|
+
maxLen = 0;
|
820
|
+
offset = 0;
|
821
|
+
|
822
|
+
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
823
|
+
{
|
824
|
+
maxLen = 2;
|
825
|
+
distances[0] = 2;
|
826
|
+
distances[1] = d2 - 1;
|
827
|
+
offset = 2;
|
828
|
+
}
|
829
|
+
|
830
|
+
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
831
|
+
{
|
832
|
+
maxLen = 3;
|
833
|
+
distances[(size_t)offset + 1] = d3 - 1;
|
834
|
+
offset += 2;
|
835
|
+
d2 = d3;
|
836
|
+
}
|
837
|
+
|
838
|
+
if (offset != 0)
|
839
|
+
{
|
840
|
+
UPDATE_maxLen
|
841
|
+
distances[(size_t)offset - 2] = (UInt32)maxLen;
|
842
|
+
if (maxLen == lenLimit)
|
843
|
+
{
|
844
|
+
p->son[p->cyclicBufferPos] = curMatch;
|
845
|
+
MOVE_POS_RET;
|
846
|
+
}
|
847
|
+
}
|
848
|
+
|
849
|
+
if (maxLen < 3)
|
850
|
+
maxLen = 3;
|
851
|
+
|
852
|
+
offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
853
|
+
distances + offset, maxLen) - (distances));
|
854
|
+
MOVE_POS_RET
|
855
|
+
}
|
856
|
+
|
857
|
+
/*
|
858
|
+
static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
859
|
+
{
|
860
|
+
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
|
861
|
+
UInt32 *hash;
|
862
|
+
GET_MATCHES_HEADER(5)
|
863
|
+
|
864
|
+
HASH5_CALC;
|
865
|
+
|
866
|
+
hash = p->hash;
|
867
|
+
pos = p->pos;
|
868
|
+
|
869
|
+
d2 = pos - hash [h2];
|
870
|
+
d3 = pos - (hash + kFix3HashSize)[h3];
|
871
|
+
d4 = pos - (hash + kFix4HashSize)[h4];
|
872
|
+
|
873
|
+
curMatch = (hash + kFix5HashSize)[hv];
|
874
|
+
|
875
|
+
hash [h2] = pos;
|
876
|
+
(hash + kFix3HashSize)[h3] = pos;
|
877
|
+
(hash + kFix4HashSize)[h4] = pos;
|
878
|
+
(hash + kFix5HashSize)[hv] = pos;
|
879
|
+
|
880
|
+
maxLen = 0;
|
881
|
+
offset = 0;
|
882
|
+
|
883
|
+
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
884
|
+
{
|
885
|
+
distances[0] = maxLen = 2;
|
886
|
+
distances[1] = d2 - 1;
|
887
|
+
offset = 2;
|
888
|
+
if (*(cur - d2 + 2) == cur[2])
|
889
|
+
distances[0] = maxLen = 3;
|
890
|
+
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
891
|
+
{
|
892
|
+
distances[2] = maxLen = 3;
|
893
|
+
distances[3] = d3 - 1;
|
894
|
+
offset = 4;
|
895
|
+
d2 = d3;
|
896
|
+
}
|
897
|
+
}
|
898
|
+
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
899
|
+
{
|
900
|
+
distances[0] = maxLen = 3;
|
901
|
+
distances[1] = d3 - 1;
|
902
|
+
offset = 2;
|
903
|
+
d2 = d3;
|
904
|
+
}
|
905
|
+
|
906
|
+
if (d2 != d4 && d4 < p->cyclicBufferSize
|
907
|
+
&& *(cur - d4) == *cur
|
908
|
+
&& *(cur - d4 + 3) == *(cur + 3))
|
909
|
+
{
|
910
|
+
maxLen = 4;
|
911
|
+
distances[(size_t)offset + 1] = d4 - 1;
|
912
|
+
offset += 2;
|
913
|
+
d2 = d4;
|
914
|
+
}
|
915
|
+
|
916
|
+
if (offset != 0)
|
917
|
+
{
|
918
|
+
UPDATE_maxLen
|
919
|
+
distances[(size_t)offset - 2] = maxLen;
|
920
|
+
if (maxLen == lenLimit)
|
921
|
+
{
|
922
|
+
p->son[p->cyclicBufferPos] = curMatch;
|
923
|
+
MOVE_POS_RET;
|
924
|
+
}
|
925
|
+
}
|
926
|
+
|
927
|
+
if (maxLen < 4)
|
928
|
+
maxLen = 4;
|
929
|
+
|
930
|
+
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
931
|
+
distances + offset, maxLen) - (distances));
|
932
|
+
MOVE_POS_RET
|
933
|
+
}
|
934
|
+
*/
|
935
|
+
|
936
|
+
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
937
|
+
{
|
938
|
+
unsigned offset;
|
939
|
+
GET_MATCHES_HEADER(3)
|
940
|
+
HASH_ZIP_CALC;
|
941
|
+
curMatch = p->hash[hv];
|
942
|
+
p->hash[hv] = p->pos;
|
943
|
+
offset = (unsigned)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
944
|
+
distances, 2) - (distances));
|
945
|
+
MOVE_POS_RET
|
946
|
+
}
|
947
|
+
|
948
|
+
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
949
|
+
{
|
950
|
+
do
|
951
|
+
{
|
952
|
+
SKIP_HEADER(2)
|
953
|
+
HASH2_CALC;
|
954
|
+
curMatch = p->hash[hv];
|
955
|
+
p->hash[hv] = p->pos;
|
956
|
+
SKIP_FOOTER
|
957
|
+
}
|
958
|
+
while (--num != 0);
|
959
|
+
}
|
960
|
+
|
961
|
+
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
962
|
+
{
|
963
|
+
do
|
964
|
+
{
|
965
|
+
SKIP_HEADER(3)
|
966
|
+
HASH_ZIP_CALC;
|
967
|
+
curMatch = p->hash[hv];
|
968
|
+
p->hash[hv] = p->pos;
|
969
|
+
SKIP_FOOTER
|
970
|
+
}
|
971
|
+
while (--num != 0);
|
972
|
+
}
|
973
|
+
|
974
|
+
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
975
|
+
{
|
976
|
+
do
|
977
|
+
{
|
978
|
+
UInt32 h2;
|
979
|
+
UInt32 *hash;
|
980
|
+
SKIP_HEADER(3)
|
981
|
+
HASH3_CALC;
|
982
|
+
hash = p->hash;
|
983
|
+
curMatch = (hash + kFix3HashSize)[hv];
|
984
|
+
hash[h2] =
|
985
|
+
(hash + kFix3HashSize)[hv] = p->pos;
|
986
|
+
SKIP_FOOTER
|
987
|
+
}
|
988
|
+
while (--num != 0);
|
989
|
+
}
|
990
|
+
|
991
|
+
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
992
|
+
{
|
993
|
+
do
|
994
|
+
{
|
995
|
+
UInt32 h2, h3;
|
996
|
+
UInt32 *hash;
|
997
|
+
SKIP_HEADER(4)
|
998
|
+
HASH4_CALC;
|
999
|
+
hash = p->hash;
|
1000
|
+
curMatch = (hash + kFix4HashSize)[hv];
|
1001
|
+
hash [h2] =
|
1002
|
+
(hash + kFix3HashSize)[h3] =
|
1003
|
+
(hash + kFix4HashSize)[hv] = p->pos;
|
1004
|
+
SKIP_FOOTER
|
1005
|
+
}
|
1006
|
+
while (--num != 0);
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
/*
|
1010
|
+
static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
1011
|
+
{
|
1012
|
+
do
|
1013
|
+
{
|
1014
|
+
UInt32 h2, h3, h4;
|
1015
|
+
UInt32 *hash;
|
1016
|
+
SKIP_HEADER(5)
|
1017
|
+
HASH5_CALC;
|
1018
|
+
hash = p->hash;
|
1019
|
+
curMatch = (hash + kFix5HashSize)[hv];
|
1020
|
+
hash [h2] =
|
1021
|
+
(hash + kFix3HashSize)[h3] =
|
1022
|
+
(hash + kFix4HashSize)[h4] =
|
1023
|
+
(hash + kFix5HashSize)[hv] = p->pos;
|
1024
|
+
SKIP_FOOTER
|
1025
|
+
}
|
1026
|
+
while (--num != 0);
|
1027
|
+
}
|
1028
|
+
*/
|
1029
|
+
|
1030
|
+
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
1031
|
+
{
|
1032
|
+
do
|
1033
|
+
{
|
1034
|
+
UInt32 h2, h3;
|
1035
|
+
UInt32 *hash;
|
1036
|
+
SKIP_HEADER(4)
|
1037
|
+
HASH4_CALC;
|
1038
|
+
hash = p->hash;
|
1039
|
+
curMatch = (hash + kFix4HashSize)[hv];
|
1040
|
+
hash [h2] =
|
1041
|
+
(hash + kFix3HashSize)[h3] =
|
1042
|
+
(hash + kFix4HashSize)[hv] = p->pos;
|
1043
|
+
p->son[p->cyclicBufferPos] = curMatch;
|
1044
|
+
MOVE_POS
|
1045
|
+
}
|
1046
|
+
while (--num != 0);
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
/*
|
1050
|
+
static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
1051
|
+
{
|
1052
|
+
do
|
1053
|
+
{
|
1054
|
+
UInt32 h2, h3, h4;
|
1055
|
+
UInt32 *hash;
|
1056
|
+
SKIP_HEADER(5)
|
1057
|
+
HASH5_CALC;
|
1058
|
+
hash = p->hash;
|
1059
|
+
curMatch = hash + kFix5HashSize)[hv];
|
1060
|
+
hash [h2] =
|
1061
|
+
(hash + kFix3HashSize)[h3] =
|
1062
|
+
(hash + kFix4HashSize)[h4] =
|
1063
|
+
(hash + kFix5HashSize)[hv] = p->pos;
|
1064
|
+
p->son[p->cyclicBufferPos] = curMatch;
|
1065
|
+
MOVE_POS
|
1066
|
+
}
|
1067
|
+
while (--num != 0);
|
1068
|
+
}
|
1069
|
+
*/
|
1070
|
+
|
1071
|
+
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
1072
|
+
{
|
1073
|
+
do
|
1074
|
+
{
|
1075
|
+
SKIP_HEADER(3)
|
1076
|
+
HASH_ZIP_CALC;
|
1077
|
+
curMatch = p->hash[hv];
|
1078
|
+
p->hash[hv] = p->pos;
|
1079
|
+
p->son[p->cyclicBufferPos] = curMatch;
|
1080
|
+
MOVE_POS
|
1081
|
+
}
|
1082
|
+
while (--num != 0);
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
1086
|
+
{
|
1087
|
+
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
1088
|
+
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
1089
|
+
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
1090
|
+
if (!p->btMode)
|
1091
|
+
{
|
1092
|
+
/* if (p->numHashBytes <= 4) */
|
1093
|
+
{
|
1094
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
1095
|
+
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
1096
|
+
}
|
1097
|
+
/*
|
1098
|
+
else
|
1099
|
+
{
|
1100
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
|
1101
|
+
vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
|
1102
|
+
}
|
1103
|
+
*/
|
1104
|
+
}
|
1105
|
+
else if (p->numHashBytes == 2)
|
1106
|
+
{
|
1107
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
1108
|
+
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
1109
|
+
}
|
1110
|
+
else if (p->numHashBytes == 3)
|
1111
|
+
{
|
1112
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
1113
|
+
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
1114
|
+
}
|
1115
|
+
else /* if (p->numHashBytes == 4) */
|
1116
|
+
{
|
1117
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
1118
|
+
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
1119
|
+
}
|
1120
|
+
/*
|
1121
|
+
else
|
1122
|
+
{
|
1123
|
+
vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
|
1124
|
+
vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
|
1125
|
+
}
|
1126
|
+
*/
|
1127
|
+
}
|