ruby-lzma 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +6 -0
  2. data/README.markdown +15 -0
  3. data/Rakefile +53 -0
  4. data/VERSION +1 -0
  5. data/ext/Alloc.cpp +118 -0
  6. data/ext/Alloc.h +29 -0
  7. data/ext/BinTree.h +55 -0
  8. data/ext/BinTree2.h +12 -0
  9. data/ext/BinTree3.h +16 -0
  10. data/ext/BinTree3Z.h +16 -0
  11. data/ext/BinTree4.h +18 -0
  12. data/ext/BinTree4b.h +20 -0
  13. data/ext/BinTreeMain.h +444 -0
  14. data/ext/BranchX86.c +101 -0
  15. data/ext/BranchX86.h +19 -0
  16. data/ext/CRC.cpp +61 -0
  17. data/ext/CRC.h +36 -0
  18. data/ext/C_FileIO.h +45 -0
  19. data/ext/CommandLineParser.h +82 -0
  20. data/ext/Defs.h +20 -0
  21. data/ext/FileStreams.h +98 -0
  22. data/ext/HC.h +55 -0
  23. data/ext/HC2.h +13 -0
  24. data/ext/HC3.h +17 -0
  25. data/ext/HC4.h +19 -0
  26. data/ext/HC4b.h +21 -0
  27. data/ext/HCMain.h +350 -0
  28. data/ext/ICoder.h +156 -0
  29. data/ext/IMatchFinder.h +63 -0
  30. data/ext/IStream.h +62 -0
  31. data/ext/InBuffer.cpp +80 -0
  32. data/ext/InBuffer.h +76 -0
  33. data/ext/LZInWindow.cpp +102 -0
  34. data/ext/LZInWindow.h +84 -0
  35. data/ext/LZMA.h +82 -0
  36. data/ext/LZMADecoder.h +248 -0
  37. data/ext/LZMAEncoder.cpp +1504 -0
  38. data/ext/LZMAEncoder.h +416 -0
  39. data/ext/LZOutWindow.cpp +17 -0
  40. data/ext/LZOutWindow.h +66 -0
  41. data/ext/LzmaBench.h +11 -0
  42. data/ext/LzmaDecode.c +588 -0
  43. data/ext/LzmaDecode.h +131 -0
  44. data/ext/LzmaRam.cpp +228 -0
  45. data/ext/LzmaRam.h +46 -0
  46. data/ext/LzmaRamDecode.c +79 -0
  47. data/ext/LzmaRamDecode.h +55 -0
  48. data/ext/MyCom.h +203 -0
  49. data/ext/MyGuidDef.h +54 -0
  50. data/ext/MyInitGuid.h +13 -0
  51. data/ext/MyString.h +631 -0
  52. data/ext/MyUnknown.h +24 -0
  53. data/ext/MyWindows.h +183 -0
  54. data/ext/OutBuffer.cpp +117 -0
  55. data/ext/OutBuffer.h +64 -0
  56. data/ext/Pat.h +318 -0
  57. data/ext/Pat2.h +22 -0
  58. data/ext/Pat2H.h +24 -0
  59. data/ext/Pat2R.h +20 -0
  60. data/ext/Pat3H.h +24 -0
  61. data/ext/Pat4H.h +24 -0
  62. data/ext/PatMain.h +989 -0
  63. data/ext/RangeCoder.h +205 -0
  64. data/ext/RangeCoderBit.cpp +80 -0
  65. data/ext/RangeCoderBit.h +120 -0
  66. data/ext/RangeCoderBitTree.h +161 -0
  67. data/ext/RangeCoderOpt.h +31 -0
  68. data/ext/StdAfx.h +8 -0
  69. data/ext/StreamUtils.cpp +44 -0
  70. data/ext/StreamUtils.h +11 -0
  71. data/ext/StringConvert.h +71 -0
  72. data/ext/StringToInt.h +17 -0
  73. data/ext/Types.h +19 -0
  74. data/ext/Vector.h +211 -0
  75. data/ext/extconf.rb +7 -0
  76. data/ext/lzma_ruby.cpp +51 -0
  77. data/ext/lzmalib.h +64 -0
  78. data/ext/mylib.cpp +81 -0
  79. data/java/SevenZip/CRC.java +52 -0
  80. data/java/SevenZip/Compression/LZ/BinTree.java +382 -0
  81. data/java/SevenZip/Compression/LZ/InWindow.java +131 -0
  82. data/java/SevenZip/Compression/LZ/OutWindow.java +85 -0
  83. data/java/SevenZip/Compression/LZMA/Base.java +88 -0
  84. data/java/SevenZip/Compression/LZMA/Decoder.java +329 -0
  85. data/java/SevenZip/Compression/LZMA/Encoder.java +1415 -0
  86. data/java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java +55 -0
  87. data/java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java +99 -0
  88. data/java/SevenZip/Compression/RangeCoder/Decoder.java +88 -0
  89. data/java/SevenZip/Compression/RangeCoder/Encoder.java +151 -0
  90. data/java/SevenZip/ICodeProgress.java +6 -0
  91. data/java/SevenZip/LzmaAlone.java +253 -0
  92. data/java/SevenZip/LzmaBench.java +391 -0
  93. data/java/com/ephemeronindustries/lzma/LZMA.java +104 -0
  94. data/lib/lzma.rb +32 -0
  95. data/ruby-lzma.gemspec +136 -0
  96. data/test/test_lzma.rb +42 -0
  97. metadata +157 -0
data/ext/Pat2.h ADDED
@@ -0,0 +1,22 @@
1
+ // Pat2.h
2
+
3
+ #ifndef __PAT2__H
4
+ #define __PAT2__H
5
+
6
+ #undef PAT_CLSID
7
+ #define PAT_CLSID CLSID_CMatchFinderPat2
8
+
9
+ #undef PAT_NAMESPACE
10
+ #define PAT_NAMESPACE NPat2
11
+
12
+ #define __AUTO_REMOVE
13
+ #define __NODE_2_BITS
14
+
15
+ #include "Pat.h"
16
+ #include "PatMain.h"
17
+
18
+ #undef __AUTO_REMOVE
19
+ #undef __NODE_2_BITS
20
+
21
+ #endif
22
+
data/ext/Pat2H.h ADDED
@@ -0,0 +1,24 @@
1
+ // Pat2H.h
2
+
3
+ #ifndef __PAT2H__H
4
+ #define __PAT2H__H
5
+
6
+ #undef PAT_CLSID
7
+ #define PAT_CLSID CLSID_CMatchFinderPat2H
8
+
9
+ #undef PAT_NAMESPACE
10
+ #define PAT_NAMESPACE NPat2H
11
+
12
+ #define __AUTO_REMOVE
13
+ #define __NODE_2_BITS
14
+ #define __HASH_3
15
+
16
+ #include "Pat.h"
17
+ #include "PatMain.h"
18
+
19
+ #undef __AUTO_REMOVE
20
+ #undef __NODE_2_BITS
21
+ #undef __HASH_3
22
+
23
+ #endif
24
+
data/ext/Pat2R.h ADDED
@@ -0,0 +1,20 @@
1
+ // Pat2R.h
2
+
3
+ #ifndef __PAT2R__H
4
+ #define __PAT2R__H
5
+
6
+ #undef PAT_CLSID
7
+ #define PAT_CLSID CLSID_CMatchFinderPat2R
8
+
9
+ #undef PAT_NAMESPACE
10
+ #define PAT_NAMESPACE NPat2R
11
+
12
+ #define __NODE_2_BITS
13
+
14
+ #include "Pat.h"
15
+ #include "PatMain.h"
16
+
17
+ #undef __NODE_2_BITS
18
+
19
+ #endif
20
+
data/ext/Pat3H.h ADDED
@@ -0,0 +1,24 @@
1
+ // Pat3H.h
2
+
3
+ #ifndef __PAT3H__H
4
+ #define __PAT3H__H
5
+
6
+ #undef PAT_CLSID
7
+ #define PAT_CLSID CLSID_CMatchFinderPat3H
8
+
9
+ #undef PAT_NAMESPACE
10
+ #define PAT_NAMESPACE NPat3H
11
+
12
+ #define __AUTO_REMOVE
13
+ #define __NODE_3_BITS
14
+ #define __HASH_3
15
+
16
+ #include "Pat.h"
17
+ #include "PatMain.h"
18
+
19
+ #undef __AUTO_REMOVE
20
+ #undef __NODE_3_BITS
21
+ #undef __HASH_3
22
+
23
+ #endif
24
+
data/ext/Pat4H.h ADDED
@@ -0,0 +1,24 @@
1
+ // Pat4H.h
2
+
3
+ #ifndef __PAT4H__H
4
+ #define __PAT4H__H
5
+
6
+ #undef PAT_CLSID
7
+ #define PAT_CLSID CLSID_CMatchFinderPat4H
8
+
9
+ #undef PAT_NAMESPACE
10
+ #define PAT_NAMESPACE NPat4H
11
+
12
+ #define __AUTO_REMOVE
13
+ #define __NODE_4_BITS
14
+ #define __HASH_3
15
+
16
+ #include "Pat.h"
17
+ #include "PatMain.h"
18
+
19
+ #undef __AUTO_REMOVE
20
+ #undef __NODE_4_BITS
21
+ #undef __HASH_3
22
+
23
+ #endif
24
+
data/ext/PatMain.h ADDED
@@ -0,0 +1,989 @@
1
+ // PatMain.h
2
+
3
+ #include "Defs.h"
4
+ #include "Alloc.h"
5
+
6
+ namespace PAT_NAMESPACE {
7
+
8
+ STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *callback)
9
+ {
10
+ m_Callback = callback;
11
+ return S_OK;
12
+ }
13
+
14
+ void CPatricia::BeforeMoveBlock()
15
+ {
16
+ if (m_Callback)
17
+ m_Callback->BeforeChangingBufferPos();
18
+ CLZInWindow::BeforeMoveBlock();
19
+ }
20
+
21
+ void CPatricia::AfterMoveBlock()
22
+ {
23
+ if (m_Callback)
24
+ m_Callback->AfterChangingBufferPos();
25
+ CLZInWindow::AfterMoveBlock();
26
+ }
27
+
28
+ const UInt32 kMatchStartValue2 = 2;
29
+ const UInt32 kDescendantEmptyValue2 = kMatchStartValue2 - 1;
30
+ const UInt32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1;
31
+
32
+ #ifdef __HASH_3
33
+
34
+ static const UInt32 kNumHashBytes = 3;
35
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
36
+
37
+ static const UInt32 kNumHash2Bytes = 2;
38
+ static const UInt32 kHash2Size = 1 << (8 * kNumHash2Bytes);
39
+ static const UInt32 kPrevHashSize = kNumHash2Bytes;
40
+
41
+ #else
42
+
43
+ static const UInt32 kNumHashBytes = 2;
44
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
45
+ static const UInt32 kPrevHashSize = 0;
46
+
47
+ #endif
48
+
49
+
50
+ CPatricia::CPatricia():
51
+ m_HashDescendants(0),
52
+ #ifdef __HASH_3
53
+ m_Hash2Descendants(0),
54
+ #endif
55
+ m_Nodes(0),
56
+ m_TmpBacks(0)
57
+ {
58
+ }
59
+
60
+ CPatricia::~CPatricia()
61
+ {
62
+ FreeMemory();
63
+ }
64
+
65
+ void CPatricia::FreeMemory()
66
+ {
67
+ MyFree(m_TmpBacks);
68
+ m_TmpBacks = 0;
69
+
70
+ ::BigFree(m_Nodes);
71
+ m_Nodes = 0;
72
+
73
+ ::BigFree(m_HashDescendants);
74
+ m_HashDescendants = 0;
75
+
76
+ #ifdef __HASH_3
77
+
78
+ ::BigFree(m_Hash2Descendants);
79
+ m_Hash2Descendants = 0;
80
+
81
+ CLZInWindow::Free();
82
+
83
+ #endif
84
+ }
85
+
86
+ STDMETHODIMP CPatricia::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
87
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
88
+ {
89
+ FreeMemory();
90
+ int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8;
91
+ if (kNumBitsInNumSameBits < 32 && ((matchMaxLen * MY_BYTE_SIZE) > ((UInt32)1 << kNumBitsInNumSameBits)))
92
+ return E_INVALIDARG;
93
+
94
+ const UInt32 kAlignMask = (1 << 16) - 1;
95
+ UInt32 windowReservSize = historySize;
96
+ windowReservSize += kAlignMask;
97
+ windowReservSize &= ~(kAlignMask);
98
+
99
+ const UInt32 kMinReservSize = (1 << 19);
100
+ if (windowReservSize < kMinReservSize)
101
+ windowReservSize = kMinReservSize;
102
+ windowReservSize += 256;
103
+
104
+ if (!CLZInWindow::Create(historySize + keepAddBufferBefore,
105
+ matchMaxLen + keepAddBufferAfter, windowReservSize))
106
+ return E_OUTOFMEMORY;
107
+
108
+ _sizeHistory = historySize;
109
+ _matchMaxLen = matchMaxLen;
110
+ m_HashDescendants = (CDescendant *)BigAlloc(kHashSize * sizeof(CDescendant));
111
+ if (m_HashDescendants == 0)
112
+ {
113
+ FreeMemory();
114
+ return E_OUTOFMEMORY;
115
+ }
116
+
117
+ #ifdef __HASH_3
118
+ m_Hash2Descendants = (CDescendant *)BigAlloc(kHash2Size * sizeof(CDescendant));
119
+ if (m_Hash2Descendants == 0)
120
+ {
121
+ FreeMemory();
122
+ return E_OUTOFMEMORY;
123
+ }
124
+ #endif
125
+
126
+ #ifdef __AUTO_REMOVE
127
+
128
+ #ifdef __HASH_3
129
+ m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 19);
130
+ #else
131
+ m_NumNodes = historySize + _sizeHistory * 4 / 8 + (1 << 10);
132
+ #endif
133
+
134
+ #else
135
+
136
+ UInt32 m_NumNodes = historySize;
137
+
138
+ #endif
139
+
140
+ const UInt32 kMaxNumNodes = UInt32(1) << (sizeof(CIndex) * 8 - 1);
141
+ if (m_NumNodes + 32 > kMaxNumNodes)
142
+ return E_INVALIDARG;
143
+
144
+ // m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 2) * sizeof(CNode));
145
+ m_Nodes = (CNode *)::BigAlloc((m_NumNodes + 12) * sizeof(CNode));
146
+ if (m_Nodes == 0)
147
+ {
148
+ FreeMemory();
149
+ return E_OUTOFMEMORY;
150
+ }
151
+
152
+ m_TmpBacks = (UInt32 *)MyAlloc((_matchMaxLen + 1) * sizeof(UInt32));
153
+ if (m_TmpBacks == 0)
154
+ {
155
+ FreeMemory();
156
+ return E_OUTOFMEMORY;
157
+ }
158
+ return S_OK;
159
+ }
160
+
161
+ STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream)
162
+ {
163
+ RINOK(CLZInWindow::Init(aStream));
164
+
165
+ // memset(m_HashDescendants, 0xFF, kHashSize * sizeof(m_HashDescendants[0]));
166
+
167
+ #ifdef __HASH_3
168
+ for (UInt32 i = 0; i < kHash2Size; i++)
169
+ m_Hash2Descendants[i].MatchPointer = kDescendantsNotInitilized2;
170
+ #else
171
+ for (UInt32 i = 0; i < kHashSize; i++)
172
+ m_HashDescendants[i].MakeEmpty();
173
+ #endif
174
+
175
+ m_Nodes[0].NextFreeNode = 1;
176
+ m_FreeNode = 0;
177
+ m_FreeNodeMax = 0;
178
+ #ifdef __AUTO_REMOVE
179
+ m_NumUsedNodes = 0;
180
+ #else
181
+ m_SpecialRemoveMode = false;
182
+ #endif
183
+ m_SpecialMode = false;
184
+ return S_OK;
185
+ }
186
+
187
+ STDMETHODIMP_(void) CPatricia::ReleaseStream()
188
+ {
189
+ // CLZInWindow::ReleaseStream();
190
+ }
191
+
192
+ // pos = _pos + kNumHashBytes
193
+ // fullCurrentLimit = currentLimit + kNumHashBytes
194
+ // fullMatchLen = matchLen + kNumHashBytes
195
+
196
+ void CPatricia::ChangeLastMatch(UInt32 hashValue)
197
+ {
198
+ UInt32 pos = _pos + kNumHashBytes - 1;
199
+ UInt32 descendantIndex;
200
+ const Byte *currentBytePointer = _buffer + pos;
201
+ UInt32 numLoadedBits = 0;
202
+ Byte curByte = 0; // = 0 to disable warning of GCC
203
+ CNodePointer node = &m_Nodes[m_HashDescendants[hashValue].NodePointer];
204
+
205
+ while(true)
206
+ {
207
+ UInt32 numSameBits = node->NumSameBits;
208
+ if(numSameBits > 0)
209
+ {
210
+ if (numLoadedBits < numSameBits)
211
+ {
212
+ numSameBits -= numLoadedBits;
213
+ currentBytePointer += (numSameBits / MY_BYTE_SIZE);
214
+ numSameBits %= MY_BYTE_SIZE;
215
+ curByte = *currentBytePointer++;
216
+ numLoadedBits = MY_BYTE_SIZE;
217
+ }
218
+ curByte >>= numSameBits;
219
+ numLoadedBits -= numSameBits;
220
+ }
221
+ if(numLoadedBits == 0)
222
+ {
223
+ curByte = *currentBytePointer++;
224
+ numLoadedBits = MY_BYTE_SIZE;
225
+ }
226
+ descendantIndex = (curByte & kSubNodesMask);
227
+ node->LastMatch = pos;
228
+ numLoadedBits -= kNumSubBits;
229
+ curByte >>= kNumSubBits;
230
+ if(node->Descendants[descendantIndex].IsNode())
231
+ node = &m_Nodes[node->Descendants[descendantIndex].NodePointer];
232
+ else
233
+ break;
234
+ }
235
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
236
+ }
237
+
238
+ UInt32 CPatricia::GetLongestMatch(UInt32 *distances)
239
+ {
240
+ UInt32 fullCurrentLimit;
241
+ if (_pos + _matchMaxLen <= _streamPos)
242
+ fullCurrentLimit = _matchMaxLen;
243
+ else
244
+ {
245
+ fullCurrentLimit = _streamPos - _pos;
246
+ if(fullCurrentLimit < kNumHashBytes)
247
+ return 0;
248
+ }
249
+ UInt32 pos = _pos + kNumHashBytes;
250
+
251
+ #ifdef __HASH_3
252
+ UInt32 hash2Value = ((UInt32(_buffer[_pos])) << 8) | _buffer[_pos + 1];
253
+ UInt32 hashValue = (hash2Value << 8) | _buffer[_pos + 2];
254
+ CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value];
255
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
256
+ if(hash2Descendant.MatchPointer <= kDescendantEmptyValue2)
257
+ {
258
+ if(hash2Descendant.MatchPointer == kDescendantsNotInitilized2)
259
+ {
260
+ UInt32 base = hashValue & 0xFFFF00;
261
+ for (UInt32 i = 0; i < 0x100; i++)
262
+ m_HashDescendants[base + i].MakeEmpty();
263
+ }
264
+ hash2Descendant.MatchPointer = pos + kMatchStartValue2;
265
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
266
+ return 0;
267
+ }
268
+
269
+ distances[kNumHash2Bytes] = pos - (hash2Descendant.MatchPointer - kMatchStartValue2) - 1;
270
+ hash2Descendant.MatchPointer = pos + kMatchStartValue2;
271
+ #ifdef __AUTO_REMOVE
272
+ if (distances[kNumHash2Bytes] >= _sizeHistory)
273
+ {
274
+ if (hashDescendant.IsNode())
275
+ RemoveNode(hashDescendant.NodePointer);
276
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
277
+ return 0;
278
+ }
279
+ #endif
280
+ if (fullCurrentLimit == kNumHash2Bytes)
281
+ return kNumHash2Bytes;
282
+
283
+ #else
284
+ UInt32 hashValue = UInt32(GetIndexByte(1)) | (UInt32(GetIndexByte(0)) << 8);
285
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
286
+ #endif
287
+
288
+
289
+ if(m_SpecialMode)
290
+ {
291
+ if(hashDescendant.IsMatch())
292
+ m_NumNotChangedCycles = 0;
293
+ if(m_NumNotChangedCycles >= _sizeHistory - 1)
294
+ {
295
+ ChangeLastMatch(hashValue);
296
+ m_NumNotChangedCycles = 0;
297
+ }
298
+ if(GetIndexByte(fullCurrentLimit - 1) == GetIndexByte(fullCurrentLimit - 2))
299
+ {
300
+ if(hashDescendant.IsMatch())
301
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
302
+ else
303
+ m_NumNotChangedCycles++;
304
+ for(UInt32 i = kNumHashBytes; i <= fullCurrentLimit; i++)
305
+ distances[i] = 0;
306
+ return fullCurrentLimit;
307
+ }
308
+ else if(m_NumNotChangedCycles > 0)
309
+ ChangeLastMatch(hashValue);
310
+ m_SpecialMode = false;
311
+ }
312
+
313
+ if(hashDescendant.IsEmpty())
314
+ {
315
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
316
+ return kPrevHashSize;
317
+ }
318
+
319
+ UInt32 currentLimit = fullCurrentLimit - kNumHashBytes;
320
+
321
+ if(hashDescendant.IsMatch())
322
+ {
323
+ CMatchPointer matchPointer = hashDescendant.MatchPointer;
324
+ UInt32 backReal = pos - (matchPointer - kMatchStartValue);
325
+ UInt32 back = backReal - 1;
326
+ #ifdef __AUTO_REMOVE
327
+ if (back >= _sizeHistory)
328
+ {
329
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
330
+ return kPrevHashSize;
331
+ }
332
+ #endif
333
+
334
+ UInt32 matchLen;
335
+ distances += kNumHashBytes;
336
+ Byte *buffer = _buffer + pos;
337
+ for(matchLen = 0; true; matchLen++)
338
+ {
339
+ *distances++ = back;
340
+ if (matchLen == currentLimit)
341
+ {
342
+ hashDescendant.MatchPointer = pos + kMatchStartValue;
343
+ return kNumHashBytes + matchLen;
344
+ }
345
+ if (buffer[matchLen] != buffer[(size_t)matchLen - backReal])
346
+ break;
347
+ }
348
+
349
+ // UInt32 matchLen = GetMatchLen(kNumHashBytes, back, currentLimit);
350
+
351
+ UInt32 fullMatchLen = matchLen + kNumHashBytes;
352
+ hashDescendant.NodePointer = m_FreeNode;
353
+ CNodePointer node = &m_Nodes[m_FreeNode];
354
+ m_FreeNode = node->NextFreeNode;
355
+ #ifdef __AUTO_REMOVE
356
+ m_NumUsedNodes++;
357
+ #endif
358
+ if (m_FreeNode > m_FreeNodeMax)
359
+ {
360
+ m_FreeNodeMax = m_FreeNode;
361
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
362
+ }
363
+
364
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
365
+ node->Descendants[i].NodePointer = kDescendantEmptyValue;
366
+ node->LastMatch = pos;
367
+
368
+ Byte byteNew = GetIndexByte(fullMatchLen);
369
+ Byte byteOld = GetIndexByte(fullMatchLen - backReal);
370
+ Byte bitsNew, bitsOld;
371
+ UInt32 numSameBits = matchLen * MY_BYTE_SIZE;
372
+ while (true)
373
+ {
374
+ bitsNew = (byteNew & kSubNodesMask);
375
+ bitsOld = (byteOld & kSubNodesMask);
376
+ if(bitsNew != bitsOld)
377
+ break;
378
+ byteNew >>= kNumSubBits;
379
+ byteOld >>= kNumSubBits;
380
+ numSameBits += kNumSubBits;
381
+ }
382
+ node->NumSameBits = CSameBitsType(numSameBits);
383
+ node->Descendants[bitsNew].MatchPointer = pos + kMatchStartValue;
384
+ node->Descendants[bitsOld].MatchPointer = matchPointer;
385
+ return fullMatchLen;
386
+ }
387
+ const Byte *baseCurrentBytePointer = _buffer + pos;
388
+ const Byte *currentBytePointer = baseCurrentBytePointer;
389
+ UInt32 numLoadedBits = 0;
390
+ Byte curByte = 0;
391
+ CIndex *nodePointerPointer = &hashDescendant.NodePointer;
392
+ CNodePointer node = &m_Nodes[*nodePointerPointer];
393
+ distances += kNumHashBytes;
394
+ const Byte *bytePointerLimit = baseCurrentBytePointer + currentLimit;
395
+ const Byte *currentAddingOffset = _buffer;
396
+
397
+ #ifdef __AUTO_REMOVE
398
+ UInt32 lowPos;
399
+ if (pos > _sizeHistory)
400
+ lowPos = pos - _sizeHistory;
401
+ else
402
+ lowPos = 0;
403
+ #endif
404
+
405
+ while(true)
406
+ {
407
+ #ifdef __AUTO_REMOVE
408
+ if (node->LastMatch < lowPos)
409
+ {
410
+ RemoveNode(*nodePointerPointer);
411
+ *nodePointerPointer = pos + kMatchStartValue;
412
+ if (currentBytePointer == baseCurrentBytePointer)
413
+ return kPrevHashSize;
414
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
415
+ }
416
+ #endif
417
+ if(numLoadedBits == 0)
418
+ {
419
+ *distances++ = pos - node->LastMatch - 1;
420
+ if(currentBytePointer >= bytePointerLimit)
421
+ {
422
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
423
+ node->Descendants[i].MatchPointer = pos + kMatchStartValue;
424
+ node->LastMatch = pos;
425
+ node->NumSameBits = 0;
426
+ return fullCurrentLimit;
427
+ }
428
+ curByte = (*currentBytePointer++);
429
+ currentAddingOffset++;
430
+ numLoadedBits = MY_BYTE_SIZE;
431
+ }
432
+ UInt32 numSameBits = node->NumSameBits;
433
+ if(numSameBits > 0)
434
+ {
435
+ Byte byteXOR = ((*(currentAddingOffset + node->LastMatch -1)) >>
436
+ (MY_BYTE_SIZE - numLoadedBits)) ^ curByte;
437
+ while(numLoadedBits <= numSameBits)
438
+ {
439
+ if(byteXOR != 0)
440
+ {
441
+ AddInternalNode(node, nodePointerPointer, curByte, byteXOR,
442
+ numSameBits, pos);
443
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
444
+ }
445
+ *distances++ = pos - node->LastMatch - 1;
446
+ numSameBits -= numLoadedBits;
447
+ if(currentBytePointer >= bytePointerLimit)
448
+ {
449
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
450
+ node->Descendants[i].MatchPointer = pos + kMatchStartValue;
451
+ node->LastMatch = pos;
452
+ node->NumSameBits = CSameBitsType(node->NumSameBits - numSameBits);
453
+ return fullCurrentLimit;
454
+ }
455
+ numLoadedBits = MY_BYTE_SIZE;
456
+ curByte = (*currentBytePointer++);
457
+ byteXOR = curByte ^ (*(currentAddingOffset + node->LastMatch));
458
+ currentAddingOffset++;
459
+ }
460
+ if((byteXOR & ((1 << numSameBits) - 1)) != 0)
461
+ {
462
+ AddInternalNode(node, nodePointerPointer, curByte, byteXOR,
463
+ numSameBits, pos);
464
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
465
+ }
466
+ curByte >>= numSameBits;
467
+ numLoadedBits -= numSameBits;
468
+ }
469
+ UInt32 descendantIndex = (curByte & kSubNodesMask);
470
+ numLoadedBits -= kNumSubBits;
471
+ nodePointerPointer = &node->Descendants[descendantIndex].NodePointer;
472
+ UInt32 nextNodeIndex = *nodePointerPointer;
473
+ node->LastMatch = pos;
474
+ if (nextNodeIndex < kDescendantEmptyValue)
475
+ {
476
+ curByte >>= kNumSubBits;
477
+ node = &m_Nodes[nextNodeIndex];
478
+ }
479
+ else if (nextNodeIndex == kDescendantEmptyValue)
480
+ {
481
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
482
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
483
+ }
484
+ else
485
+ break;
486
+ }
487
+
488
+ UInt32 descendantIndex = (curByte & kSubNodesMask);
489
+ curByte >>= kNumSubBits;
490
+ CMatchPointer matchPointer = node->Descendants[descendantIndex].MatchPointer;
491
+ CMatchPointer realMatchPointer;
492
+ realMatchPointer = matchPointer - kMatchStartValue;
493
+
494
+ #ifdef __AUTO_REMOVE
495
+ if (realMatchPointer < lowPos)
496
+ {
497
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
498
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
499
+ }
500
+ #endif
501
+
502
+ Byte byteXOR;
503
+ UInt32 numSameBits = 0;
504
+ if(numLoadedBits != 0)
505
+ {
506
+ Byte matchByte = *(currentAddingOffset + realMatchPointer -1);
507
+ matchByte >>= (MY_BYTE_SIZE - numLoadedBits);
508
+ byteXOR = matchByte ^ curByte;
509
+ if(byteXOR != 0)
510
+ {
511
+ AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex);
512
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
513
+ }
514
+ numSameBits += numLoadedBits;
515
+ }
516
+
517
+ const Byte *matchBytePointer = _buffer + realMatchPointer +
518
+ (currentBytePointer - baseCurrentBytePointer);
519
+ for(; currentBytePointer < bytePointerLimit; numSameBits += MY_BYTE_SIZE)
520
+ {
521
+ curByte = (*currentBytePointer++);
522
+ *distances++ = pos - realMatchPointer - 1;
523
+ byteXOR = curByte ^ (*matchBytePointer++);
524
+ if(byteXOR != 0)
525
+ {
526
+ AddLeafNode(node, curByte, byteXOR, numSameBits, pos, descendantIndex);
527
+ return kNumHashBytes + (UInt32)(currentBytePointer - baseCurrentBytePointer - 1);
528
+ }
529
+ }
530
+ *distances = pos - realMatchPointer - 1;
531
+ node->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
532
+
533
+ if(*distances == 0)
534
+ {
535
+ m_SpecialMode = true;
536
+ m_NumNotChangedCycles = 0;
537
+ }
538
+ return fullCurrentLimit;
539
+ }
540
+
541
+ STDMETHODIMP_(void) CPatricia::DummyLongestMatch()
542
+ {
543
+ GetLongestMatch(m_TmpBacks);
544
+ }
545
+
546
+
547
+ // ------------------------------------
548
+ // Remove Match
549
+
550
+ typedef Byte CRemoveDataWord;
551
+
552
+ static const int kSizeRemoveDataWordInBits = MY_BYTE_SIZE * sizeof(CRemoveDataWord);
553
+
554
+ #ifndef __AUTO_REMOVE
555
+
556
+ void CPatricia::RemoveMatch()
557
+ {
558
+ if(m_SpecialRemoveMode)
559
+ {
560
+ if(GetIndexByte(_matchMaxLen - 1 - _sizeHistory) ==
561
+ GetIndexByte(_matchMaxLen - _sizeHistory))
562
+ return;
563
+ m_SpecialRemoveMode = false;
564
+ }
565
+ UInt32 pos = _pos + kNumHashBytes - _sizeHistory;
566
+
567
+ #ifdef __HASH_3
568
+ const Byte *pp = _buffer + _pos - _sizeHistory;
569
+ UInt32 hash2Value = ((UInt32(pp[0])) << 8) | pp[1];
570
+ UInt32 hashValue = (hash2Value << 8) | pp[2];
571
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
572
+ CDescendant &hash2Descendant = m_Hash2Descendants[hash2Value];
573
+ if (hash2Descendant >= kMatchStartValue2)
574
+ if(hash2Descendant.MatchPointer == pos + kMatchStartValue2)
575
+ hash2Descendant.MatchPointer = kDescendantEmptyValue2;
576
+ #else
577
+ UInt32 hashValue = UInt32(GetIndexByte(1 - _sizeHistory)) |
578
+ (UInt32(GetIndexByte(0 - _sizeHistory)) << 8);
579
+ CDescendant &hashDescendant = m_HashDescendants[hashValue];
580
+ #endif
581
+
582
+ if(hashDescendant.IsEmpty())
583
+ return;
584
+ if(hashDescendant.IsMatch())
585
+ {
586
+ if(hashDescendant.MatchPointer == pos + kMatchStartValue)
587
+ hashDescendant.MakeEmpty();
588
+ return;
589
+ }
590
+
591
+ UInt32 descendantIndex;
592
+ const CRemoveDataWord *currentPointer = (const CRemoveDataWord *)(_buffer + pos);
593
+ UInt32 numLoadedBits = 0;
594
+ CRemoveDataWord curWord = 0; // = 0 to disable GCC warning
595
+
596
+ CIndex *nodePointerPointer = &hashDescendant.NodePointer;
597
+
598
+ CNodePointer node = &m_Nodes[hashDescendant.NodePointer];
599
+
600
+ while(true)
601
+ {
602
+ if(numLoadedBits == 0)
603
+ {
604
+ curWord = *currentPointer++;
605
+ numLoadedBits = kSizeRemoveDataWordInBits;
606
+ }
607
+ UInt32 numSameBits = node->NumSameBits;
608
+ if(numSameBits > 0)
609
+ {
610
+ if (numLoadedBits <= numSameBits)
611
+ {
612
+ numSameBits -= numLoadedBits;
613
+ currentPointer += (numSameBits / kSizeRemoveDataWordInBits);
614
+ numSameBits %= kSizeRemoveDataWordInBits;
615
+ curWord = *currentPointer++;
616
+ numLoadedBits = kSizeRemoveDataWordInBits;
617
+ }
618
+ curWord >>= numSameBits;
619
+ numLoadedBits -= numSameBits;
620
+ }
621
+ descendantIndex = (curWord & kSubNodesMask);
622
+ numLoadedBits -= kNumSubBits;
623
+ curWord >>= kNumSubBits;
624
+ UInt32 nextNodeIndex = node->Descendants[descendantIndex].NodePointer;
625
+ if (nextNodeIndex < kDescendantEmptyValue)
626
+ {
627
+ nodePointerPointer = &node->Descendants[descendantIndex].NodePointer;
628
+ node = &m_Nodes[nextNodeIndex];
629
+ }
630
+ else
631
+ break;
632
+ }
633
+ if (node->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue)
634
+ {
635
+ const Byte *currentBytePointer = _buffer + _pos - _sizeHistory;
636
+ const Byte *currentBytePointerLimit = currentBytePointer + _matchMaxLen;
637
+ for(;currentBytePointer < currentBytePointerLimit; currentBytePointer++)
638
+ if(*currentBytePointer != *(currentBytePointer+1))
639
+ return;
640
+ m_SpecialRemoveMode = true;
641
+ return;
642
+ }
643
+
644
+ UInt32 numNodes = 0, numMatches = 0;
645
+
646
+ UInt32 i;
647
+ for (i = 0; i < kNumSubNodes; i++)
648
+ {
649
+ UInt32 nodeIndex = node->Descendants[i].NodePointer;
650
+ if (nodeIndex < kDescendantEmptyValue)
651
+ numNodes++;
652
+ else if (nodeIndex > kDescendantEmptyValue)
653
+ numMatches++;
654
+ }
655
+ numMatches -= 1;
656
+ if (numNodes + numMatches > 1)
657
+ {
658
+ node->Descendants[descendantIndex].MakeEmpty();
659
+ return;
660
+ }
661
+ if(numNodes == 1)
662
+ {
663
+ UInt32 i;
664
+ for (i = 0; i < kNumSubNodes; i++)
665
+ if (node->Descendants[i].IsNode())
666
+ break;
667
+ UInt32 nextNodeIndex = node->Descendants[i].NodePointer;
668
+ CNodePointer nextNode = &m_Nodes[nextNodeIndex];
669
+ nextNode->NumSameBits += node->NumSameBits + kNumSubBits;
670
+ *node = *nextNode;
671
+
672
+ nextNode->NextFreeNode = m_FreeNode;
673
+ m_FreeNode = nextNodeIndex;
674
+ return;
675
+ }
676
+ UInt32 matchPointer = 0; // = 0 to disable GCC warning
677
+ for (i = 0; i < kNumSubNodes; i++)
678
+ if (node->Descendants[i].IsMatch() && i != descendantIndex)
679
+ {
680
+ matchPointer = node->Descendants[i].MatchPointer;
681
+ break;
682
+ }
683
+ node->NextFreeNode = m_FreeNode;
684
+ m_FreeNode = *nodePointerPointer;
685
+ *nodePointerPointer = matchPointer;
686
+ }
687
+ #endif
688
+
689
+
690
+ // Commented code is more correct, but it gives warning
691
+ // on GCC: (1 << 32)
692
+ // So we use kMatchStartValue twice:
693
+ // kMatchStartValue = UInt32(1) << (kNumBitsInIndex - 1);
694
+ // must be defined in Pat.h
695
+ /*
696
+ const UInt32 kNormalizeStartPos = (UInt32(1) << (kNumBitsInIndex)) -
697
+ kMatchStartValue - kNumHashBytes - 1;
698
+ */
699
+ const UInt32 kNormalizeStartPos = kMatchStartValue - kNumHashBytes - 1;
700
+
701
+ STDMETHODIMP CPatricia::MovePos()
702
+ {
703
+ #ifndef __AUTO_REMOVE
704
+ if(_pos >= _sizeHistory)
705
+ RemoveMatch();
706
+ #endif
707
+ RINOK(CLZInWindow::MovePos());
708
+ #ifdef __AUTO_REMOVE
709
+ if (m_NumUsedNodes >= m_NumNodes)
710
+ TestRemoveNodes();
711
+ #endif
712
+ if (_pos >= kNormalizeStartPos)
713
+ {
714
+ #ifdef __AUTO_REMOVE
715
+ TestRemoveNodesAndNormalize();
716
+ #else
717
+ Normalize();
718
+ #endif
719
+ }
720
+ return S_OK;
721
+ }
722
+
723
+ #ifndef __AUTO_REMOVE
724
+
725
+ void CPatricia::NormalizeDescendant(CDescendant &descendant, UInt32 subValue)
726
+ {
727
+ if (descendant.IsEmpty())
728
+ return;
729
+ if (descendant.IsMatch())
730
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
731
+ else
732
+ {
733
+ CNode &node = m_Nodes[descendant.NodePointer];
734
+ node.LastMatch = node.LastMatch - subValue;
735
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
736
+ NormalizeDescendant(node.Descendants[i], subValue);
737
+ }
738
+ }
739
+
740
+ void CPatricia::Normalize()
741
+ {
742
+ UInt32 subValue = _pos - _sizeHistory;
743
+ CLZInWindow::ReduceOffsets(subValue);
744
+
745
+ #ifdef __HASH_3
746
+
747
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
748
+ {
749
+ CDescendant &descendant = m_Hash2Descendants[hash];
750
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
751
+ {
752
+ UInt32 base = hash << 8;
753
+ for (UInt32 i = 0; i < 0x100; i++)
754
+ NormalizeDescendant(m_HashDescendants[base + i], subValue);
755
+ }
756
+ if (descendant.MatchPointer < kMatchStartValue2)
757
+ continue;
758
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
759
+ }
760
+
761
+ #else
762
+
763
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
764
+ NormalizeDescendant(m_HashDescendants[hash], subValue);
765
+
766
+ #endif
767
+
768
+ }
769
+
770
+ #else
771
+
772
+ void CPatricia::TestRemoveDescendant(CDescendant &descendant, UInt32 limitPos)
773
+ {
774
+ CNode &node = m_Nodes[descendant.NodePointer];
775
+ UInt32 numChilds = 0;
776
+ UInt32 childIndex = 0; // = 0 to disable GCC warning
777
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
778
+ {
779
+ CDescendant &descendant2 = node.Descendants[i];
780
+ if (descendant2.IsEmpty())
781
+ continue;
782
+ if (descendant2.IsMatch())
783
+ {
784
+ if (descendant2.MatchPointer < limitPos)
785
+ descendant2.MakeEmpty();
786
+ else
787
+ {
788
+ numChilds++;
789
+ childIndex = i;
790
+ }
791
+ }
792
+ else
793
+ {
794
+ TestRemoveDescendant(descendant2, limitPos);
795
+ if (!descendant2.IsEmpty())
796
+ {
797
+ numChilds++;
798
+ childIndex = i;
799
+ }
800
+ }
801
+ }
802
+ if (numChilds > 1)
803
+ return;
804
+
805
+ CIndex nodePointerTemp = descendant.NodePointer;
806
+ if (numChilds == 1)
807
+ {
808
+ const CDescendant &descendant2 = node.Descendants[childIndex];
809
+ if (descendant2.IsNode())
810
+ m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits;
811
+ descendant = descendant2;
812
+ }
813
+ else
814
+ descendant.MakeEmpty();
815
+ node.NextFreeNode = m_FreeNode;
816
+ m_FreeNode = nodePointerTemp;
817
+ m_NumUsedNodes--;
818
+ }
819
+
820
+ void CPatricia::RemoveNode(UInt32 index)
821
+ {
822
+ CNode &node = m_Nodes[index];
823
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
824
+ {
825
+ CDescendant &descendant2 = node.Descendants[i];
826
+ if (descendant2.IsNode())
827
+ RemoveNode(descendant2.NodePointer);
828
+ }
829
+ node.NextFreeNode = m_FreeNode;
830
+ m_FreeNode = index;
831
+ m_NumUsedNodes--;
832
+ }
833
+
834
+ void CPatricia::TestRemoveNodes()
835
+ {
836
+ UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
837
+
838
+ #ifdef __HASH_3
839
+
840
+ UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
841
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
842
+ {
843
+ CDescendant &descendant = m_Hash2Descendants[hash];
844
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
845
+ {
846
+ UInt32 base = hash << 8;
847
+ for (UInt32 i = 0; i < 0x100; i++)
848
+ {
849
+ CDescendant &descendant = m_HashDescendants[base + i];
850
+ if (descendant.IsEmpty())
851
+ continue;
852
+ if (descendant.IsMatch())
853
+ {
854
+ if (descendant.MatchPointer < limitPos)
855
+ descendant.MakeEmpty();
856
+ }
857
+ else
858
+ TestRemoveDescendant(descendant, limitPos);
859
+ }
860
+ }
861
+ if (descendant.MatchPointer < kMatchStartValue2)
862
+ continue;
863
+ if (descendant.MatchPointer < limitPos2)
864
+ descendant.MatchPointer = kDescendantEmptyValue2;
865
+ }
866
+
867
+ #else
868
+
869
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
870
+ {
871
+ CDescendant &descendant = m_HashDescendants[hash];
872
+ if (descendant.IsEmpty())
873
+ continue;
874
+ if (descendant.IsMatch())
875
+ {
876
+ if (descendant.MatchPointer < limitPos)
877
+ descendant.MakeEmpty();
878
+ }
879
+ else
880
+ TestRemoveDescendant(descendant, limitPos);
881
+ }
882
+
883
+ #endif
884
+ }
885
+
886
+ void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &descendant,
887
+ UInt32 limitPos, UInt32 subValue)
888
+ {
889
+ if (descendant.IsEmpty())
890
+ return;
891
+ if (descendant.IsMatch())
892
+ {
893
+ if (descendant.MatchPointer < limitPos)
894
+ descendant.MakeEmpty();
895
+ else
896
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
897
+ return;
898
+ }
899
+ CNode &node = m_Nodes[descendant.NodePointer];
900
+ UInt32 numChilds = 0;
901
+ UInt32 childIndex = 0; // = 0 to disable GCC warning
902
+ for (UInt32 i = 0; i < kNumSubNodes; i++)
903
+ {
904
+ CDescendant &descendant2 = node.Descendants[i];
905
+ TestRemoveAndNormalizeDescendant(descendant2, limitPos, subValue);
906
+ if (!descendant2.IsEmpty())
907
+ {
908
+ numChilds++;
909
+ childIndex = i;
910
+ }
911
+ }
912
+ if (numChilds > 1)
913
+ {
914
+ node.LastMatch = node.LastMatch - subValue;
915
+ return;
916
+ }
917
+
918
+ CIndex nodePointerTemp = descendant.NodePointer;
919
+ if (numChilds == 1)
920
+ {
921
+ const CDescendant &descendant2 = node.Descendants[childIndex];
922
+ if (descendant2.IsNode())
923
+ m_Nodes[descendant2.NodePointer].NumSameBits += node.NumSameBits + kNumSubBits;
924
+ descendant = descendant2;
925
+ }
926
+ else
927
+ descendant.MakeEmpty();
928
+ node.NextFreeNode = m_FreeNode;
929
+ m_FreeNode = nodePointerTemp;
930
+ m_NumUsedNodes--;
931
+ }
932
+
933
+ void CPatricia::TestRemoveNodesAndNormalize()
934
+ {
935
+ UInt32 subValue = _pos - _sizeHistory;
936
+ UInt32 limitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
937
+ CLZInWindow::ReduceOffsets(subValue);
938
+
939
+ #ifdef __HASH_3
940
+
941
+ UInt32 limitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
942
+ for(UInt32 hash = 0; hash < kHash2Size; hash++)
943
+ {
944
+ CDescendant &descendant = m_Hash2Descendants[hash];
945
+ if (descendant.MatchPointer != kDescendantsNotInitilized2)
946
+ {
947
+ UInt32 base = hash << 8;
948
+ for (UInt32 i = 0; i < 0x100; i++)
949
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[base + i], limitPos, subValue);
950
+ }
951
+ if (descendant.MatchPointer < kMatchStartValue2)
952
+ continue;
953
+ if (descendant.MatchPointer < limitPos2)
954
+ descendant.MatchPointer = kDescendantEmptyValue2;
955
+ else
956
+ descendant.MatchPointer = descendant.MatchPointer - subValue;
957
+ }
958
+
959
+ #else
960
+
961
+ for(UInt32 hash = 0; hash < kHashSize; hash++)
962
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[hash], limitPos, subValue);
963
+
964
+ #endif
965
+ }
966
+
967
+ #endif
968
+
969
+ STDMETHODIMP_(Byte) CPatricia::GetIndexByte(Int32 index)
970
+ {
971
+ return CLZInWindow::GetIndexByte(index);
972
+ }
973
+
974
+ STDMETHODIMP_(UInt32) CPatricia::GetMatchLen(Int32 index, UInt32 back, UInt32 limit)
975
+ {
976
+ return CLZInWindow::GetMatchLen(index, back, limit);
977
+ }
978
+
979
+ STDMETHODIMP_(UInt32) CPatricia::GetNumAvailableBytes()
980
+ {
981
+ return CLZInWindow::GetNumAvailableBytes();
982
+ }
983
+
984
+ STDMETHODIMP_(const Byte *) CPatricia::GetPointerToCurrentPos()
985
+ {
986
+ return CLZInWindow::GetPointerToCurrentPos();
987
+ }
988
+
989
+ }