ruby-lzma 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/README.markdown +15 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/ext/Alloc.cpp +118 -0
- data/ext/Alloc.h +29 -0
- data/ext/BinTree.h +55 -0
- data/ext/BinTree2.h +12 -0
- data/ext/BinTree3.h +16 -0
- data/ext/BinTree3Z.h +16 -0
- data/ext/BinTree4.h +18 -0
- data/ext/BinTree4b.h +20 -0
- data/ext/BinTreeMain.h +444 -0
- data/ext/BranchX86.c +101 -0
- data/ext/BranchX86.h +19 -0
- data/ext/CRC.cpp +61 -0
- data/ext/CRC.h +36 -0
- data/ext/C_FileIO.h +45 -0
- data/ext/CommandLineParser.h +82 -0
- data/ext/Defs.h +20 -0
- data/ext/FileStreams.h +98 -0
- data/ext/HC.h +55 -0
- data/ext/HC2.h +13 -0
- data/ext/HC3.h +17 -0
- data/ext/HC4.h +19 -0
- data/ext/HC4b.h +21 -0
- data/ext/HCMain.h +350 -0
- data/ext/ICoder.h +156 -0
- data/ext/IMatchFinder.h +63 -0
- data/ext/IStream.h +62 -0
- data/ext/InBuffer.cpp +80 -0
- data/ext/InBuffer.h +76 -0
- data/ext/LZInWindow.cpp +102 -0
- data/ext/LZInWindow.h +84 -0
- data/ext/LZMA.h +82 -0
- data/ext/LZMADecoder.h +248 -0
- data/ext/LZMAEncoder.cpp +1504 -0
- data/ext/LZMAEncoder.h +416 -0
- data/ext/LZOutWindow.cpp +17 -0
- data/ext/LZOutWindow.h +66 -0
- data/ext/LzmaBench.h +11 -0
- data/ext/LzmaDecode.c +588 -0
- data/ext/LzmaDecode.h +131 -0
- data/ext/LzmaRam.cpp +228 -0
- data/ext/LzmaRam.h +46 -0
- data/ext/LzmaRamDecode.c +79 -0
- data/ext/LzmaRamDecode.h +55 -0
- data/ext/MyCom.h +203 -0
- data/ext/MyGuidDef.h +54 -0
- data/ext/MyInitGuid.h +13 -0
- data/ext/MyString.h +631 -0
- data/ext/MyUnknown.h +24 -0
- data/ext/MyWindows.h +183 -0
- data/ext/OutBuffer.cpp +117 -0
- data/ext/OutBuffer.h +64 -0
- data/ext/Pat.h +318 -0
- data/ext/Pat2.h +22 -0
- data/ext/Pat2H.h +24 -0
- data/ext/Pat2R.h +20 -0
- data/ext/Pat3H.h +24 -0
- data/ext/Pat4H.h +24 -0
- data/ext/PatMain.h +989 -0
- data/ext/RangeCoder.h +205 -0
- data/ext/RangeCoderBit.cpp +80 -0
- data/ext/RangeCoderBit.h +120 -0
- data/ext/RangeCoderBitTree.h +161 -0
- data/ext/RangeCoderOpt.h +31 -0
- data/ext/StdAfx.h +8 -0
- data/ext/StreamUtils.cpp +44 -0
- data/ext/StreamUtils.h +11 -0
- data/ext/StringConvert.h +71 -0
- data/ext/StringToInt.h +17 -0
- data/ext/Types.h +19 -0
- data/ext/Vector.h +211 -0
- data/ext/extconf.rb +7 -0
- data/ext/lzma_ruby.cpp +51 -0
- data/ext/lzmalib.h +64 -0
- data/ext/mylib.cpp +81 -0
- data/java/SevenZip/CRC.java +52 -0
- data/java/SevenZip/Compression/LZ/BinTree.java +382 -0
- data/java/SevenZip/Compression/LZ/InWindow.java +131 -0
- data/java/SevenZip/Compression/LZ/OutWindow.java +85 -0
- data/java/SevenZip/Compression/LZMA/Base.java +88 -0
- data/java/SevenZip/Compression/LZMA/Decoder.java +329 -0
- data/java/SevenZip/Compression/LZMA/Encoder.java +1415 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java +55 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java +99 -0
- data/java/SevenZip/Compression/RangeCoder/Decoder.java +88 -0
- data/java/SevenZip/Compression/RangeCoder/Encoder.java +151 -0
- data/java/SevenZip/ICodeProgress.java +6 -0
- data/java/SevenZip/LzmaAlone.java +253 -0
- data/java/SevenZip/LzmaBench.java +391 -0
- data/java/com/ephemeronindustries/lzma/LZMA.java +104 -0
- data/lib/lzma.rb +32 -0
- data/ruby-lzma.gemspec +136 -0
- data/test/test_lzma.rb +42 -0
- metadata +157 -0
data/ext/lzmalib.h
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
/*************************************************************************************************
|
2
|
+
* A thin wrapper library of LZMA
|
3
|
+
*************************************************************************************************/
|
4
|
+
|
5
|
+
|
6
|
+
#ifndef _LZMALIB_H /* duplication check */
|
7
|
+
#define _LZMALIB_H
|
8
|
+
|
9
|
+
#if defined(__cplusplus)
|
10
|
+
#define __LZMALIB_CLINKAGEBEGIN extern "C" {
|
11
|
+
#define __LZMALIB_CLINKAGEEND }
|
12
|
+
#else
|
13
|
+
#define __LZMALIB_CLINKAGEBEGIN
|
14
|
+
#define __LZMALIB_CLINKAGEEND
|
15
|
+
#endif
|
16
|
+
__LZMALIB_CLINKAGEBEGIN
|
17
|
+
|
18
|
+
|
19
|
+
#include <stdlib.h>
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
/*************************************************************************************************
|
24
|
+
* API
|
25
|
+
*************************************************************************************************/
|
26
|
+
|
27
|
+
|
28
|
+
/* Compress a serial object with LZMA encoding.
|
29
|
+
`ptr' specifies the pointer to the region.
|
30
|
+
`size' specifies the size of the region.
|
31
|
+
`sp' specifies the pointer to the variable into which the size of the region of the return
|
32
|
+
value is assigned.
|
33
|
+
If successful, the return value is the pointer to the result object, else, it is `NULL'.
|
34
|
+
Because the region of the return value is allocated with the `malloc' call, it should be
|
35
|
+
released with the `free' call when it is no longer in use. */
|
36
|
+
void *lzma_compress(const void *ptr, int size, int *sp);
|
37
|
+
|
38
|
+
|
39
|
+
/* Decompress a serial object compressed with LZMA encoding.
|
40
|
+
`ptr' specifies the pointer to the region.
|
41
|
+
`size' specifies the size of the region.
|
42
|
+
`sp' specifies the pointer to a variable into which the size of the region of the return
|
43
|
+
value is assigned.
|
44
|
+
If successful, the return value is the pointer to the result object, else, it is `NULL'.
|
45
|
+
Because an additional zero code is appended at the end of the region of the return value,
|
46
|
+
the return value can be treated as a character string. Because the region of the return
|
47
|
+
value is allocated with the `malloc' call, it should be released with the `free' call when it
|
48
|
+
is no longer in use. */
|
49
|
+
void *lzma_decompress(const void *ptr, int size, int *sp);
|
50
|
+
|
51
|
+
|
52
|
+
/* Free a region on memory.
|
53
|
+
`ptr' specifies the pointer to the region. If it is `NULL', this function has no effect.
|
54
|
+
Although this function is just a wrapper of `free' call, this is useful in applications using
|
55
|
+
another package of the `malloc' series. */
|
56
|
+
void lzma_free(void *ptr);
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
__LZMALIB_CLINKAGEEND
|
61
|
+
#endif /* duplication check */
|
62
|
+
|
63
|
+
|
64
|
+
/* END OF FILE */
|
data/ext/mylib.cpp
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#include "lzmalib.h"
|
2
|
+
|
3
|
+
#include "MyWindows.h"
|
4
|
+
#include "MyInitGuid.h"
|
5
|
+
#include "CommandLineParser.h"
|
6
|
+
#include "StringConvert.h"
|
7
|
+
#include "StringToInt.h"
|
8
|
+
#include "FileStreams.h"
|
9
|
+
#include "StreamUtils.h"
|
10
|
+
#include "LZMADecoder.h"
|
11
|
+
#include "LZMAEncoder.h"
|
12
|
+
#include "LzmaBench.h"
|
13
|
+
#include "LzmaRam.h"
|
14
|
+
#include <cstdlib>
|
15
|
+
#include <cstring>
|
16
|
+
|
17
|
+
extern "C" {
|
18
|
+
#include "LzmaRamDecode.h"
|
19
|
+
}
|
20
|
+
|
21
|
+
using namespace std;
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
/*************************************************************************************************
|
27
|
+
* API
|
28
|
+
*************************************************************************************************/
|
29
|
+
|
30
|
+
|
31
|
+
#define __LZMALIB_CLINKAGEBEGIN extern "C" {
|
32
|
+
#define __LZMALIB_CLINKAGEEND }
|
33
|
+
__LZMALIB_CLINKAGEBEGIN
|
34
|
+
|
35
|
+
|
36
|
+
/* Compress a serial object with LZMA encoding. */
|
37
|
+
void *lzma_compress(const void *ptr, int size, int *sp){
|
38
|
+
size_t rsiz = size / 20 * 21 + (1 << 16) + 1;
|
39
|
+
char* rbuf = (char*)malloc(rsiz);
|
40
|
+
if(!rbuf) return NULL;
|
41
|
+
size_t osiz;
|
42
|
+
if(LzmaRamEncode((Byte*)ptr, size, (Byte*)rbuf, rsiz, &osiz,
|
43
|
+
1 << 23, SZ_FILTER_NO) != 0){
|
44
|
+
free(rbuf);
|
45
|
+
return NULL;
|
46
|
+
}
|
47
|
+
rbuf[osiz] = '\0';
|
48
|
+
*sp = osiz;
|
49
|
+
return rbuf;
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
/* Decompress a serial object compressed with LZMA encoding. */
|
54
|
+
void *lzma_decompress(const void *ptr, int size, int *sp){
|
55
|
+
size_t rsiz;
|
56
|
+
if(LzmaRamGetUncompressedSize((const unsigned char*)ptr, size, &rsiz) != 0) return NULL;
|
57
|
+
char* rbuf = (char*)malloc(rsiz + 1);
|
58
|
+
if(!rbuf) return NULL;
|
59
|
+
size_t osiz;
|
60
|
+
if(LzmaRamDecompress((const unsigned char*)ptr, size, (unsigned char*)rbuf, rsiz, &osiz,
|
61
|
+
malloc, free) != 0){
|
62
|
+
free(rbuf);
|
63
|
+
return NULL;
|
64
|
+
}
|
65
|
+
rbuf[osiz] = '\0';
|
66
|
+
if(sp) *sp = osiz;
|
67
|
+
return rbuf;
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
/* Free a region on memory */
|
72
|
+
void lzma_free(void *ptr){
|
73
|
+
free(ptr);
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
__LZMALIB_CLINKAGEEND
|
79
|
+
|
80
|
+
|
81
|
+
/* END OF FILE */
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// SevenZip/CRC.java
|
2
|
+
|
3
|
+
package SevenZip;
|
4
|
+
|
5
|
+
public class CRC
|
6
|
+
{
|
7
|
+
static public int[] Table = new int[256];
|
8
|
+
|
9
|
+
static
|
10
|
+
{
|
11
|
+
for (int i = 0; i < 256; i++)
|
12
|
+
{
|
13
|
+
int r = i;
|
14
|
+
for (int j = 0; j < 8; j++)
|
15
|
+
if ((r & 1) != 0)
|
16
|
+
r = (r >>> 1) ^ 0xEDB88320;
|
17
|
+
else
|
18
|
+
r >>>= 1;
|
19
|
+
Table[i] = r;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
int _value = -1;
|
24
|
+
|
25
|
+
public void Init()
|
26
|
+
{
|
27
|
+
_value = -1;
|
28
|
+
}
|
29
|
+
|
30
|
+
public void Update(byte[] data, int offset, int size)
|
31
|
+
{
|
32
|
+
for (int i = 0; i < size; i++)
|
33
|
+
_value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8);
|
34
|
+
}
|
35
|
+
|
36
|
+
public void Update(byte[] data)
|
37
|
+
{
|
38
|
+
int size = data.length;
|
39
|
+
for (int i = 0; i < size; i++)
|
40
|
+
_value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8);
|
41
|
+
}
|
42
|
+
|
43
|
+
public void UpdateByte(int b)
|
44
|
+
{
|
45
|
+
_value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8);
|
46
|
+
}
|
47
|
+
|
48
|
+
public int GetDigest()
|
49
|
+
{
|
50
|
+
return _value ^ (-1);
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,382 @@
|
|
1
|
+
// LZ.BinTree
|
2
|
+
|
3
|
+
package SevenZip.Compression.LZ;
|
4
|
+
import java.io.IOException;
|
5
|
+
|
6
|
+
|
7
|
+
public class BinTree extends InWindow
|
8
|
+
{
|
9
|
+
int _cyclicBufferPos;
|
10
|
+
int _cyclicBufferSize = 0;
|
11
|
+
int _matchMaxLen;
|
12
|
+
|
13
|
+
int[] _son;
|
14
|
+
int[] _hash;
|
15
|
+
|
16
|
+
int _cutValue = 0xFF;
|
17
|
+
int _hashMask;
|
18
|
+
int _hashSizeSum = 0;
|
19
|
+
|
20
|
+
boolean HASH_ARRAY = true;
|
21
|
+
|
22
|
+
static final int kHash2Size = 1 << 10;
|
23
|
+
static final int kHash3Size = 1 << 16;
|
24
|
+
static final int kBT2HashSize = 1 << 16;
|
25
|
+
static final int kStartMaxLen = 1;
|
26
|
+
static final int kHash3Offset = kHash2Size;
|
27
|
+
static final int kEmptyHashValue = 0;
|
28
|
+
static final int kMaxValForNormalize = (1 << 30) - 1;
|
29
|
+
|
30
|
+
int kNumHashDirectBytes = 0;
|
31
|
+
int kMinMatchCheck = 4;
|
32
|
+
int kFixHashSize = kHash2Size + kHash3Size;
|
33
|
+
|
34
|
+
public void SetType(int numHashBytes)
|
35
|
+
{
|
36
|
+
HASH_ARRAY = (numHashBytes > 2);
|
37
|
+
if (HASH_ARRAY)
|
38
|
+
{
|
39
|
+
kNumHashDirectBytes = 0;
|
40
|
+
kMinMatchCheck = 4;
|
41
|
+
kFixHashSize = kHash2Size + kHash3Size;
|
42
|
+
}
|
43
|
+
else
|
44
|
+
{
|
45
|
+
kNumHashDirectBytes = 2;
|
46
|
+
kMinMatchCheck = 2 + 1;
|
47
|
+
kFixHashSize = 0;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
public void Init() throws IOException
|
55
|
+
{
|
56
|
+
super.Init();
|
57
|
+
for (int i = 0; i < _hashSizeSum; i++)
|
58
|
+
_hash[i] = kEmptyHashValue;
|
59
|
+
_cyclicBufferPos = 0;
|
60
|
+
ReduceOffsets(-1);
|
61
|
+
}
|
62
|
+
|
63
|
+
public void MovePos() throws IOException
|
64
|
+
{
|
65
|
+
if (++_cyclicBufferPos >= _cyclicBufferSize)
|
66
|
+
_cyclicBufferPos = 0;
|
67
|
+
super.MovePos();
|
68
|
+
if (_pos == kMaxValForNormalize)
|
69
|
+
Normalize();
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
public boolean Create(int historySize, int keepAddBufferBefore,
|
80
|
+
int matchMaxLen, int keepAddBufferAfter)
|
81
|
+
{
|
82
|
+
if (historySize > kMaxValForNormalize - 256)
|
83
|
+
return false;
|
84
|
+
_cutValue = 16 + (matchMaxLen >> 1);
|
85
|
+
|
86
|
+
int windowReservSize = (historySize + keepAddBufferBefore +
|
87
|
+
matchMaxLen + keepAddBufferAfter) / 2 + 256;
|
88
|
+
|
89
|
+
super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
|
90
|
+
|
91
|
+
_matchMaxLen = matchMaxLen;
|
92
|
+
|
93
|
+
int cyclicBufferSize = historySize + 1;
|
94
|
+
if (_cyclicBufferSize != cyclicBufferSize)
|
95
|
+
_son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2];
|
96
|
+
|
97
|
+
int hs = kBT2HashSize;
|
98
|
+
|
99
|
+
if (HASH_ARRAY)
|
100
|
+
{
|
101
|
+
hs = historySize - 1;
|
102
|
+
hs |= (hs >> 1);
|
103
|
+
hs |= (hs >> 2);
|
104
|
+
hs |= (hs >> 4);
|
105
|
+
hs |= (hs >> 8);
|
106
|
+
hs >>= 1;
|
107
|
+
hs |= 0xFFFF;
|
108
|
+
if (hs > (1 << 24))
|
109
|
+
hs >>= 1;
|
110
|
+
_hashMask = hs;
|
111
|
+
hs++;
|
112
|
+
hs += kFixHashSize;
|
113
|
+
}
|
114
|
+
if (hs != _hashSizeSum)
|
115
|
+
_hash = new int [_hashSizeSum = hs];
|
116
|
+
return true;
|
117
|
+
}
|
118
|
+
public int GetMatches(int[] distances) throws IOException
|
119
|
+
{
|
120
|
+
int lenLimit;
|
121
|
+
if (_pos + _matchMaxLen <= _streamPos)
|
122
|
+
lenLimit = _matchMaxLen;
|
123
|
+
else
|
124
|
+
{
|
125
|
+
lenLimit = _streamPos - _pos;
|
126
|
+
if (lenLimit < kMinMatchCheck)
|
127
|
+
{
|
128
|
+
MovePos();
|
129
|
+
return 0;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
int offset = 0;
|
134
|
+
int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
135
|
+
int cur = _bufferOffset + _pos;
|
136
|
+
int maxLen = kStartMaxLen; // to avoid items for len < hashSize;
|
137
|
+
int hashValue, hash2Value = 0, hash3Value = 0;
|
138
|
+
|
139
|
+
if (HASH_ARRAY)
|
140
|
+
{
|
141
|
+
int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
|
142
|
+
hash2Value = temp & (kHash2Size - 1);
|
143
|
+
temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
|
144
|
+
hash3Value = temp & (kHash3Size - 1);
|
145
|
+
hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
|
146
|
+
}
|
147
|
+
else
|
148
|
+
hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
|
149
|
+
|
150
|
+
int curMatch = _hash[kFixHashSize + hashValue];
|
151
|
+
if (HASH_ARRAY)
|
152
|
+
{
|
153
|
+
int curMatch2 = _hash[hash2Value];
|
154
|
+
int curMatch3 = _hash[kHash3Offset + hash3Value];
|
155
|
+
_hash[hash2Value] = _pos;
|
156
|
+
_hash[kHash3Offset + hash3Value] = _pos;
|
157
|
+
if (curMatch2 > matchMinPos)
|
158
|
+
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
|
159
|
+
{
|
160
|
+
distances[offset++] = maxLen = 2;
|
161
|
+
distances[offset++] = _pos - curMatch2 - 1;
|
162
|
+
}
|
163
|
+
if (curMatch3 > matchMinPos)
|
164
|
+
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
|
165
|
+
{
|
166
|
+
if (curMatch3 == curMatch2)
|
167
|
+
offset -= 2;
|
168
|
+
distances[offset++] = maxLen = 3;
|
169
|
+
distances[offset++] = _pos - curMatch3 - 1;
|
170
|
+
curMatch2 = curMatch3;
|
171
|
+
}
|
172
|
+
if (offset != 0 && curMatch2 == curMatch)
|
173
|
+
{
|
174
|
+
offset -= 2;
|
175
|
+
maxLen = kStartMaxLen;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
_hash[kFixHashSize + hashValue] = _pos;
|
180
|
+
|
181
|
+
int ptr0 = (_cyclicBufferPos << 1) + 1;
|
182
|
+
int ptr1 = (_cyclicBufferPos << 1);
|
183
|
+
|
184
|
+
int len0, len1;
|
185
|
+
len0 = len1 = kNumHashDirectBytes;
|
186
|
+
|
187
|
+
if (kNumHashDirectBytes != 0)
|
188
|
+
{
|
189
|
+
if (curMatch > matchMinPos)
|
190
|
+
{
|
191
|
+
if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
|
192
|
+
_bufferBase[cur + kNumHashDirectBytes])
|
193
|
+
{
|
194
|
+
distances[offset++] = maxLen = kNumHashDirectBytes;
|
195
|
+
distances[offset++] = _pos - curMatch - 1;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
int count = _cutValue;
|
201
|
+
|
202
|
+
while (true)
|
203
|
+
{
|
204
|
+
if (curMatch <= matchMinPos || count-- == 0)
|
205
|
+
{
|
206
|
+
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
207
|
+
break;
|
208
|
+
}
|
209
|
+
int delta = _pos - curMatch;
|
210
|
+
int cyclicPos = ((delta <= _cyclicBufferPos) ?
|
211
|
+
(_cyclicBufferPos - delta) :
|
212
|
+
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
213
|
+
|
214
|
+
int pby1 = _bufferOffset + curMatch;
|
215
|
+
int len = Math.min(len0, len1);
|
216
|
+
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
217
|
+
{
|
218
|
+
while(++len != lenLimit)
|
219
|
+
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
220
|
+
break;
|
221
|
+
if (maxLen < len)
|
222
|
+
{
|
223
|
+
distances[offset++] = maxLen = len;
|
224
|
+
distances[offset++] = delta - 1;
|
225
|
+
if (len == lenLimit)
|
226
|
+
{
|
227
|
+
_son[ptr1] = _son[cyclicPos];
|
228
|
+
_son[ptr0] = _son[cyclicPos + 1];
|
229
|
+
break;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
|
234
|
+
{
|
235
|
+
_son[ptr1] = curMatch;
|
236
|
+
ptr1 = cyclicPos + 1;
|
237
|
+
curMatch = _son[ptr1];
|
238
|
+
len1 = len;
|
239
|
+
}
|
240
|
+
else
|
241
|
+
{
|
242
|
+
_son[ptr0] = curMatch;
|
243
|
+
ptr0 = cyclicPos;
|
244
|
+
curMatch = _son[ptr0];
|
245
|
+
len0 = len;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
MovePos();
|
249
|
+
return offset;
|
250
|
+
}
|
251
|
+
|
252
|
+
public void Skip(int num) throws IOException
|
253
|
+
{
|
254
|
+
do
|
255
|
+
{
|
256
|
+
int lenLimit;
|
257
|
+
if (_pos + _matchMaxLen <= _streamPos)
|
258
|
+
lenLimit = _matchMaxLen;
|
259
|
+
else
|
260
|
+
{
|
261
|
+
lenLimit = _streamPos - _pos;
|
262
|
+
if (lenLimit < kMinMatchCheck)
|
263
|
+
{
|
264
|
+
MovePos();
|
265
|
+
continue;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
|
270
|
+
int cur = _bufferOffset + _pos;
|
271
|
+
|
272
|
+
int hashValue;
|
273
|
+
|
274
|
+
if (HASH_ARRAY)
|
275
|
+
{
|
276
|
+
int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
|
277
|
+
int hash2Value = temp & (kHash2Size - 1);
|
278
|
+
_hash[hash2Value] = _pos;
|
279
|
+
temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
|
280
|
+
int hash3Value = temp & (kHash3Size - 1);
|
281
|
+
_hash[kHash3Offset + hash3Value] = _pos;
|
282
|
+
hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
|
283
|
+
}
|
284
|
+
else
|
285
|
+
hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
|
286
|
+
|
287
|
+
int curMatch = _hash[kFixHashSize + hashValue];
|
288
|
+
_hash[kFixHashSize + hashValue] = _pos;
|
289
|
+
|
290
|
+
int ptr0 = (_cyclicBufferPos << 1) + 1;
|
291
|
+
int ptr1 = (_cyclicBufferPos << 1);
|
292
|
+
|
293
|
+
int len0, len1;
|
294
|
+
len0 = len1 = kNumHashDirectBytes;
|
295
|
+
|
296
|
+
int count = _cutValue;
|
297
|
+
while (true)
|
298
|
+
{
|
299
|
+
if (curMatch <= matchMinPos || count-- == 0)
|
300
|
+
{
|
301
|
+
_son[ptr0] = _son[ptr1] = kEmptyHashValue;
|
302
|
+
break;
|
303
|
+
}
|
304
|
+
|
305
|
+
int delta = _pos - curMatch;
|
306
|
+
int cyclicPos = ((delta <= _cyclicBufferPos) ?
|
307
|
+
(_cyclicBufferPos - delta) :
|
308
|
+
(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
|
309
|
+
|
310
|
+
int pby1 = _bufferOffset + curMatch;
|
311
|
+
int len = Math.min(len0, len1);
|
312
|
+
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
313
|
+
{
|
314
|
+
while (++len != lenLimit)
|
315
|
+
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
316
|
+
break;
|
317
|
+
if (len == lenLimit)
|
318
|
+
{
|
319
|
+
_son[ptr1] = _son[cyclicPos];
|
320
|
+
_son[ptr0] = _son[cyclicPos + 1];
|
321
|
+
break;
|
322
|
+
}
|
323
|
+
}
|
324
|
+
if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
|
325
|
+
{
|
326
|
+
_son[ptr1] = curMatch;
|
327
|
+
ptr1 = cyclicPos + 1;
|
328
|
+
curMatch = _son[ptr1];
|
329
|
+
len1 = len;
|
330
|
+
}
|
331
|
+
else
|
332
|
+
{
|
333
|
+
_son[ptr0] = curMatch;
|
334
|
+
ptr0 = cyclicPos;
|
335
|
+
curMatch = _son[ptr0];
|
336
|
+
len0 = len;
|
337
|
+
}
|
338
|
+
}
|
339
|
+
MovePos();
|
340
|
+
}
|
341
|
+
while (--num != 0);
|
342
|
+
}
|
343
|
+
|
344
|
+
void NormalizeLinks(int[] items, int numItems, int subValue)
|
345
|
+
{
|
346
|
+
for (int i = 0; i < numItems; i++)
|
347
|
+
{
|
348
|
+
int value = items[i];
|
349
|
+
if (value <= subValue)
|
350
|
+
value = kEmptyHashValue;
|
351
|
+
else
|
352
|
+
value -= subValue;
|
353
|
+
items[i] = value;
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
void Normalize()
|
358
|
+
{
|
359
|
+
int subValue = _pos - _cyclicBufferSize;
|
360
|
+
NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
|
361
|
+
NormalizeLinks(_hash, _hashSizeSum, subValue);
|
362
|
+
ReduceOffsets(subValue);
|
363
|
+
}
|
364
|
+
|
365
|
+
public void SetCutValue(int cutValue) { _cutValue = cutValue; }
|
366
|
+
|
367
|
+
private static final int[] CrcTable = new int[256];
|
368
|
+
|
369
|
+
static
|
370
|
+
{
|
371
|
+
for (int i = 0; i < 256; i++)
|
372
|
+
{
|
373
|
+
int r = i;
|
374
|
+
for (int j = 0; j < 8; j++)
|
375
|
+
if ((r & 1) != 0)
|
376
|
+
r = (r >>> 1) ^ 0xEDB88320;
|
377
|
+
else
|
378
|
+
r >>>= 1;
|
379
|
+
CrcTable[i] = r;
|
380
|
+
}
|
381
|
+
}
|
382
|
+
}
|