com.wallstop-studios.unity-helpers 2.0.0-rc79.4 → 2.0.0-rc79.6
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.
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/npm-publish.yml +2 -2
- package/Runtime/Core/Extension/EnumExtensions.cs +1 -1
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs +1 -1
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs.meta +1 -1
- package/Runtime/Core/Extension/StringExtensions.cs +1 -1
- package/Runtime/Core/Helper/ReflectionHelpers.cs +1368 -22
- package/Runtime/Core/Helper/StringInList.cs +3 -21
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +157 -49
- package/Runtime/Utils/Buffers.cs +2 -2
- package/Runtime/Utils/SevenZip/Common/CRC.cs +9 -0
- package/Runtime/Utils/SevenZip/Common/InBuffer.cs +15 -2
- package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +7 -2
- package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +50 -0
- package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +26 -0
- package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +27 -0
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +9 -0
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +80 -17
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +265 -30
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +9 -0
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +13 -1
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +11 -4
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs +54 -0
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs.meta +3 -0
- package/Tests/Runtime/Core/Threading.meta +3 -0
- package/Tests/Runtime/Core.meta +3 -0
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs.meta +1 -1
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
- package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -1
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +961 -0
- package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -2
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
- package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
- package/Tests/Runtime/Utils/BuffersTests.cs +6 -6
- package/Tests/Runtime/Utils/BuffersTests.cs.meta +1 -1
- package/package.json +3 -1
|
@@ -6,21 +6,15 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
|
|
|
6
6
|
|
|
7
7
|
public sealed class StringInList : PropertyAttribute
|
|
8
8
|
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
private bool _shouldRefresh;
|
|
12
|
-
private string[] _list;
|
|
13
|
-
private Func<string[]> _getStringList;
|
|
9
|
+
private readonly Func<string[]> _getStringList;
|
|
14
10
|
|
|
15
11
|
public StringInList(params string[] list)
|
|
16
12
|
{
|
|
17
|
-
|
|
18
|
-
_list = list;
|
|
13
|
+
_getStringList = () => list;
|
|
19
14
|
}
|
|
20
15
|
|
|
21
16
|
public StringInList(Type type, string methodName)
|
|
22
17
|
{
|
|
23
|
-
_shouldRefresh = true;
|
|
24
18
|
MethodInfo method = type.GetMethod(
|
|
25
19
|
methodName,
|
|
26
20
|
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
|
|
@@ -36,18 +30,6 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
|
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
public string[] List
|
|
40
|
-
{
|
|
41
|
-
get
|
|
42
|
-
{
|
|
43
|
-
if (_shouldRefresh)
|
|
44
|
-
{
|
|
45
|
-
return _getStringList();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return _list;
|
|
49
|
-
}
|
|
50
|
-
private set { _list = value; }
|
|
51
|
-
}
|
|
33
|
+
public string[] List => _getStringList();
|
|
52
34
|
}
|
|
53
35
|
}
|
|
@@ -3,116 +3,224 @@ namespace WallstopStudios.UnityHelpers.Core.Threading
|
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Concurrent;
|
|
5
5
|
using System.Threading;
|
|
6
|
+
using System.Threading.Tasks;
|
|
6
7
|
|
|
7
8
|
public sealed class SingleThreadedThreadPool : IDisposable
|
|
8
9
|
{
|
|
9
10
|
public ConcurrentQueue<Exception> Exceptions => _exceptions;
|
|
10
|
-
public int Count => _work.Count +
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
private
|
|
11
|
+
public int Count => _work.Count + (_isWorking ? 1 : 0);
|
|
12
|
+
|
|
13
|
+
private volatile bool _active = true;
|
|
14
|
+
private volatile bool _isWorking;
|
|
15
|
+
private volatile bool _disposed;
|
|
16
|
+
|
|
17
|
+
private readonly Task _workerTask;
|
|
18
|
+
private readonly ConcurrentQueue<WorkItem> _work;
|
|
19
|
+
private readonly SemaphoreSlim _workAvailable;
|
|
18
20
|
private readonly ConcurrentQueue<Exception> _exceptions;
|
|
19
21
|
private readonly TimeSpan _noWorkWaitTime;
|
|
22
|
+
private readonly CancellationTokenSource _cancellationTokenSource;
|
|
20
23
|
|
|
21
24
|
public SingleThreadedThreadPool(
|
|
22
|
-
bool runInBackground =
|
|
25
|
+
bool runInBackground = true,
|
|
23
26
|
TimeSpan? noWorkWaitTime = null
|
|
24
27
|
)
|
|
25
28
|
{
|
|
26
|
-
|
|
27
|
-
_working = 1;
|
|
28
|
-
_work = new ConcurrentQueue<Action>();
|
|
29
|
+
_work = new ConcurrentQueue<WorkItem>();
|
|
29
30
|
_exceptions = new ConcurrentQueue<Exception>();
|
|
30
|
-
|
|
31
|
+
_workAvailable = new SemaphoreSlim(0);
|
|
31
32
|
_noWorkWaitTime = noWorkWaitTime ?? TimeSpan.FromSeconds(1);
|
|
32
|
-
|
|
33
|
-
_worker.Start();
|
|
34
|
-
}
|
|
33
|
+
_cancellationTokenSource = new CancellationTokenSource();
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
_workerTask = runInBackground
|
|
36
|
+
? Task.Run(DoWorkAsync)
|
|
37
|
+
: Task.Factory.StartNew(DoWorkAsync, TaskCreationOptions.LongRunning).Unwrap();
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
public void Enqueue(Action work)
|
|
42
41
|
{
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (_disposed || !_active)
|
|
43
|
+
{
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_work.Enqueue(WorkItem.FromAction(work));
|
|
48
|
+
Signal();
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
public void
|
|
51
|
+
public void Enqueue(Func<Task> work)
|
|
48
52
|
{
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
if (_disposed || !_active)
|
|
54
|
+
{
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
_work.Enqueue(WorkItem.FromTask(work));
|
|
59
|
+
Signal();
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
public void
|
|
62
|
+
public void Enqueue(Func<ValueTask> work)
|
|
54
63
|
{
|
|
55
|
-
if (_disposed)
|
|
64
|
+
if (_disposed || !_active)
|
|
56
65
|
{
|
|
57
66
|
return;
|
|
58
67
|
}
|
|
59
68
|
|
|
60
|
-
|
|
69
|
+
_work.Enqueue(WorkItem.FromValueTask(work));
|
|
70
|
+
Signal();
|
|
71
|
+
}
|
|
61
72
|
|
|
62
|
-
|
|
73
|
+
private void Signal()
|
|
74
|
+
{
|
|
75
|
+
try
|
|
63
76
|
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Swallow
|
|
72
|
-
}
|
|
77
|
+
_workAvailable.Release();
|
|
78
|
+
}
|
|
79
|
+
catch
|
|
80
|
+
{
|
|
81
|
+
// Swallow
|
|
82
|
+
}
|
|
83
|
+
}
|
|
73
84
|
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
public async ValueTask DisposeAsync()
|
|
86
|
+
{
|
|
87
|
+
if (_disposed)
|
|
88
|
+
{
|
|
89
|
+
return;
|
|
76
90
|
}
|
|
77
91
|
|
|
92
|
+
_active = false;
|
|
78
93
|
_disposed = true;
|
|
94
|
+
|
|
95
|
+
_cancellationTokenSource.Cancel();
|
|
96
|
+
Signal();
|
|
97
|
+
try
|
|
98
|
+
{
|
|
99
|
+
await _workerTask.ConfigureAwait(false);
|
|
100
|
+
}
|
|
101
|
+
catch (OperationCanceledException)
|
|
102
|
+
{
|
|
103
|
+
// Expected during shutdown
|
|
104
|
+
}
|
|
105
|
+
catch
|
|
106
|
+
{
|
|
107
|
+
// Swallow other exceptions during disposal
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
_cancellationTokenSource?.Dispose();
|
|
111
|
+
_workAvailable?.Dispose();
|
|
112
|
+
|
|
113
|
+
GC.SuppressFinalize(this);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public void Dispose()
|
|
117
|
+
{
|
|
118
|
+
DisposeAsync().AsTask().GetAwaiter().GetResult();
|
|
79
119
|
}
|
|
80
120
|
|
|
81
|
-
private
|
|
121
|
+
private async Task DoWorkAsync()
|
|
82
122
|
{
|
|
83
|
-
|
|
123
|
+
CancellationToken cancellationToken = _cancellationTokenSource.Token;
|
|
124
|
+
|
|
125
|
+
while (_active && !cancellationToken.IsCancellationRequested)
|
|
84
126
|
{
|
|
85
127
|
try
|
|
86
128
|
{
|
|
87
|
-
if (_work.TryDequeue(out
|
|
129
|
+
if (_work.TryDequeue(out WorkItem workItem))
|
|
88
130
|
{
|
|
89
|
-
|
|
131
|
+
_isWorking = true;
|
|
90
132
|
try
|
|
91
133
|
{
|
|
92
|
-
workItem();
|
|
134
|
+
await workItem.ExecuteAsync().ConfigureAwait(false);
|
|
93
135
|
}
|
|
94
136
|
catch (Exception e)
|
|
95
137
|
{
|
|
96
138
|
_exceptions.Enqueue(e);
|
|
97
139
|
}
|
|
140
|
+
finally
|
|
141
|
+
{
|
|
142
|
+
_isWorking = false;
|
|
143
|
+
}
|
|
98
144
|
}
|
|
99
145
|
else
|
|
100
146
|
{
|
|
101
147
|
try
|
|
102
148
|
{
|
|
103
|
-
|
|
149
|
+
await _workAvailable
|
|
150
|
+
.WaitAsync(_noWorkWaitTime, cancellationToken)
|
|
151
|
+
.ConfigureAwait(false);
|
|
104
152
|
}
|
|
105
|
-
catch (
|
|
153
|
+
catch (OperationCanceledException)
|
|
106
154
|
{
|
|
107
|
-
|
|
155
|
+
break;
|
|
108
156
|
}
|
|
109
157
|
}
|
|
110
158
|
}
|
|
111
|
-
|
|
159
|
+
catch (ObjectDisposedException)
|
|
112
160
|
{
|
|
113
|
-
|
|
161
|
+
break;
|
|
114
162
|
}
|
|
115
163
|
}
|
|
116
164
|
}
|
|
165
|
+
|
|
166
|
+
private enum WorkItemType
|
|
167
|
+
{
|
|
168
|
+
Unknown = 0,
|
|
169
|
+
Action = 1,
|
|
170
|
+
Task = 2,
|
|
171
|
+
ValueTask = 3,
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private readonly struct WorkItem
|
|
175
|
+
{
|
|
176
|
+
private readonly WorkItemType _type;
|
|
177
|
+
private readonly Action _action;
|
|
178
|
+
private readonly Func<Task> _taskFunc;
|
|
179
|
+
private readonly Func<ValueTask> _valueTaskFunc;
|
|
180
|
+
|
|
181
|
+
private WorkItem(
|
|
182
|
+
WorkItemType type,
|
|
183
|
+
Action action = null,
|
|
184
|
+
Func<Task> taskFunc = null,
|
|
185
|
+
Func<ValueTask> valueTaskFunc = null
|
|
186
|
+
)
|
|
187
|
+
{
|
|
188
|
+
_type = type;
|
|
189
|
+
_action = action;
|
|
190
|
+
_taskFunc = taskFunc;
|
|
191
|
+
_valueTaskFunc = valueTaskFunc;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public static WorkItem FromAction(Action action) =>
|
|
195
|
+
new(WorkItemType.Action, action: action);
|
|
196
|
+
|
|
197
|
+
public static WorkItem FromTask(Func<Task> taskFunc) =>
|
|
198
|
+
new(WorkItemType.Task, taskFunc: taskFunc);
|
|
199
|
+
|
|
200
|
+
public static WorkItem FromValueTask(Func<ValueTask> valueTaskFunc) =>
|
|
201
|
+
new(WorkItemType.ValueTask, valueTaskFunc: valueTaskFunc);
|
|
202
|
+
|
|
203
|
+
public ValueTask ExecuteAsync()
|
|
204
|
+
{
|
|
205
|
+
return _type switch
|
|
206
|
+
{
|
|
207
|
+
WorkItemType.Action => ExecuteAction(),
|
|
208
|
+
WorkItemType.Task => ExecuteTask(),
|
|
209
|
+
WorkItemType.ValueTask => _valueTaskFunc(),
|
|
210
|
+
_ => default,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private ValueTask ExecuteAction()
|
|
215
|
+
{
|
|
216
|
+
_action();
|
|
217
|
+
return default;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private async ValueTask ExecuteTask()
|
|
221
|
+
{
|
|
222
|
+
await _taskFunc().ConfigureAwait(false);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
117
225
|
}
|
|
118
226
|
}
|
package/Runtime/Utils/Buffers.cs
CHANGED
|
@@ -35,7 +35,7 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
35
35
|
public static readonly Stack<T> Stack = new();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
public static class
|
|
38
|
+
public static class WallstopGenericPool<T>
|
|
39
39
|
where T : new()
|
|
40
40
|
{
|
|
41
41
|
private static readonly List<T> _pool = new();
|
|
@@ -81,7 +81,7 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
public static class
|
|
84
|
+
public static class WallstopArrayPool<T>
|
|
85
85
|
{
|
|
86
86
|
private static readonly Dictionary<int, List<T[]>> _pool = new();
|
|
87
87
|
private static readonly Action<T[]> _onDispose = Release;
|
|
@@ -14,10 +14,17 @@ namespace SevenZip
|
|
|
14
14
|
{
|
|
15
15
|
uint r = i;
|
|
16
16
|
for (int j = 0; j < 8; j++)
|
|
17
|
+
{
|
|
17
18
|
if ((r & 1) != 0)
|
|
19
|
+
{
|
|
18
20
|
r = (r >> 1) ^ kPoly;
|
|
21
|
+
}
|
|
19
22
|
else
|
|
23
|
+
{
|
|
20
24
|
r >>= 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
21
28
|
Table[i] = r;
|
|
22
29
|
}
|
|
23
30
|
}
|
|
@@ -37,7 +44,9 @@ namespace SevenZip
|
|
|
37
44
|
public void Update(byte[] data, uint offset, uint size)
|
|
38
45
|
{
|
|
39
46
|
for (uint i = 0; i < size; i++)
|
|
47
|
+
{
|
|
40
48
|
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
|
|
49
|
+
}
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
public uint GetDigest()
|
|
@@ -4,10 +4,10 @@ namespace SevenZip.Buffer
|
|
|
4
4
|
{
|
|
5
5
|
public class InBuffer
|
|
6
6
|
{
|
|
7
|
-
byte[] m_Buffer;
|
|
7
|
+
readonly byte[] m_Buffer;
|
|
8
8
|
uint m_Pos;
|
|
9
9
|
uint m_Limit;
|
|
10
|
-
uint m_BufferSize;
|
|
10
|
+
readonly uint m_BufferSize;
|
|
11
11
|
System.IO.Stream m_Stream;
|
|
12
12
|
bool m_StreamWasExhausted;
|
|
13
13
|
ulong m_ProcessedSize;
|
|
@@ -30,7 +30,10 @@ namespace SevenZip.Buffer
|
|
|
30
30
|
public bool ReadBlock()
|
|
31
31
|
{
|
|
32
32
|
if (m_StreamWasExhausted)
|
|
33
|
+
{
|
|
33
34
|
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
34
37
|
m_ProcessedSize += m_Pos;
|
|
35
38
|
int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
|
|
36
39
|
m_Pos = 0;
|
|
@@ -48,8 +51,13 @@ namespace SevenZip.Buffer
|
|
|
48
51
|
public bool ReadByte(byte b) // check it
|
|
49
52
|
{
|
|
50
53
|
if (m_Pos >= m_Limit)
|
|
54
|
+
{
|
|
51
55
|
if (!ReadBlock())
|
|
56
|
+
{
|
|
52
57
|
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
b = m_Buffer[m_Pos++];
|
|
54
62
|
return true;
|
|
55
63
|
}
|
|
@@ -58,8 +66,13 @@ namespace SevenZip.Buffer
|
|
|
58
66
|
{
|
|
59
67
|
// return (byte)m_Stream.ReadByte();
|
|
60
68
|
if (m_Pos >= m_Limit)
|
|
69
|
+
{
|
|
61
70
|
if (!ReadBlock())
|
|
71
|
+
{
|
|
62
72
|
return 0xFF;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
return m_Buffer[m_Pos++];
|
|
64
77
|
}
|
|
65
78
|
|
|
@@ -4,9 +4,9 @@ namespace SevenZip.Buffer
|
|
|
4
4
|
{
|
|
5
5
|
public class OutBuffer
|
|
6
6
|
{
|
|
7
|
-
byte[] m_Buffer;
|
|
7
|
+
readonly byte[] m_Buffer;
|
|
8
8
|
uint m_Pos;
|
|
9
|
-
uint m_BufferSize;
|
|
9
|
+
readonly uint m_BufferSize;
|
|
10
10
|
System.IO.Stream m_Stream;
|
|
11
11
|
ulong m_ProcessedSize;
|
|
12
12
|
|
|
@@ -46,13 +46,18 @@ namespace SevenZip.Buffer
|
|
|
46
46
|
{
|
|
47
47
|
m_Buffer[m_Pos++] = b;
|
|
48
48
|
if (m_Pos >= m_BufferSize)
|
|
49
|
+
{
|
|
49
50
|
FlushData();
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
public void FlushData()
|
|
53
55
|
{
|
|
54
56
|
if (m_Pos == 0)
|
|
57
|
+
{
|
|
55
58
|
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
m_Stream.Write(m_Buffer, 0, (int)m_Pos);
|
|
57
62
|
m_Pos = 0;
|
|
58
63
|
}
|
|
@@ -62,7 +62,10 @@ namespace SevenZip.Compression.LZ
|
|
|
62
62
|
{
|
|
63
63
|
base.Init();
|
|
64
64
|
for (UInt32 i = 0; i < _hashSizeSum; i++)
|
|
65
|
+
{
|
|
65
66
|
_hash[i] = kEmptyHashValue;
|
|
67
|
+
}
|
|
68
|
+
|
|
66
69
|
_cyclicBufferPos = 0;
|
|
67
70
|
ReduceOffsets(-1);
|
|
68
71
|
}
|
|
@@ -70,10 +73,15 @@ namespace SevenZip.Compression.LZ
|
|
|
70
73
|
public new void MovePos()
|
|
71
74
|
{
|
|
72
75
|
if (++_cyclicBufferPos >= _cyclicBufferSize)
|
|
76
|
+
{
|
|
73
77
|
_cyclicBufferPos = 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
74
80
|
base.MovePos();
|
|
75
81
|
if (_pos == kMaxValForNormalize)
|
|
82
|
+
{
|
|
76
83
|
Normalize();
|
|
84
|
+
}
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
public new Byte GetIndexByte(Int32 index)
|
|
@@ -99,7 +107,10 @@ namespace SevenZip.Compression.LZ
|
|
|
99
107
|
)
|
|
100
108
|
{
|
|
101
109
|
if (historySize > kMaxValForNormalize - 256)
|
|
110
|
+
{
|
|
102
111
|
throw new Exception();
|
|
112
|
+
}
|
|
113
|
+
|
|
103
114
|
_cutValue = 16 + (matchMaxLen >> 1);
|
|
104
115
|
|
|
105
116
|
UInt32 windowReservSize =
|
|
@@ -115,7 +126,9 @@ namespace SevenZip.Compression.LZ
|
|
|
115
126
|
|
|
116
127
|
UInt32 cyclicBufferSize = historySize + 1;
|
|
117
128
|
if (_cyclicBufferSize != cyclicBufferSize)
|
|
129
|
+
{
|
|
118
130
|
_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
|
|
131
|
+
}
|
|
119
132
|
|
|
120
133
|
UInt32 hs = kBT2HashSize;
|
|
121
134
|
|
|
@@ -129,20 +142,27 @@ namespace SevenZip.Compression.LZ
|
|
|
129
142
|
hs >>= 1;
|
|
130
143
|
hs |= 0xFFFF;
|
|
131
144
|
if (hs > (1 << 24))
|
|
145
|
+
{
|
|
132
146
|
hs >>= 1;
|
|
147
|
+
}
|
|
148
|
+
|
|
133
149
|
_hashMask = hs;
|
|
134
150
|
hs++;
|
|
135
151
|
hs += kFixHashSize;
|
|
136
152
|
}
|
|
137
153
|
if (hs != _hashSizeSum)
|
|
154
|
+
{
|
|
138
155
|
_hash = new UInt32[_hashSizeSum = hs];
|
|
156
|
+
}
|
|
139
157
|
}
|
|
140
158
|
|
|
141
159
|
public UInt32 GetMatches(UInt32[] distances)
|
|
142
160
|
{
|
|
143
161
|
UInt32 lenLimit;
|
|
144
162
|
if (_pos + _matchMaxLen <= _streamPos)
|
|
163
|
+
{
|
|
145
164
|
lenLimit = _matchMaxLen;
|
|
165
|
+
}
|
|
146
166
|
else
|
|
147
167
|
{
|
|
148
168
|
lenLimit = _streamPos - _pos;
|
|
@@ -170,7 +190,9 @@ namespace SevenZip.Compression.LZ
|
|
|
170
190
|
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
|
171
191
|
}
|
|
172
192
|
else
|
|
193
|
+
{
|
|
173
194
|
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
|
|
195
|
+
}
|
|
174
196
|
|
|
175
197
|
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
|
176
198
|
if (HASH_ARRAY)
|
|
@@ -180,20 +202,29 @@ namespace SevenZip.Compression.LZ
|
|
|
180
202
|
_hash[hash2Value] = _pos;
|
|
181
203
|
_hash[kHash3Offset + hash3Value] = _pos;
|
|
182
204
|
if (curMatch2 > matchMinPos)
|
|
205
|
+
{
|
|
183
206
|
if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
|
|
184
207
|
{
|
|
185
208
|
distances[offset++] = maxLen = 2;
|
|
186
209
|
distances[offset++] = _pos - curMatch2 - 1;
|
|
187
210
|
}
|
|
211
|
+
}
|
|
212
|
+
|
|
188
213
|
if (curMatch3 > matchMinPos)
|
|
214
|
+
{
|
|
189
215
|
if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
|
|
190
216
|
{
|
|
191
217
|
if (curMatch3 == curMatch2)
|
|
218
|
+
{
|
|
192
219
|
offset -= 2;
|
|
220
|
+
}
|
|
221
|
+
|
|
193
222
|
distances[offset++] = maxLen = 3;
|
|
194
223
|
distances[offset++] = _pos - curMatch3 - 1;
|
|
195
224
|
curMatch2 = curMatch3;
|
|
196
225
|
}
|
|
226
|
+
}
|
|
227
|
+
|
|
197
228
|
if (offset != 0 && curMatch2 == curMatch)
|
|
198
229
|
{
|
|
199
230
|
offset -= 2;
|
|
@@ -247,8 +278,13 @@ namespace SevenZip.Compression.LZ
|
|
|
247
278
|
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
|
248
279
|
{
|
|
249
280
|
while (++len != lenLimit)
|
|
281
|
+
{
|
|
250
282
|
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
|
283
|
+
{
|
|
251
284
|
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
252
288
|
if (maxLen < len)
|
|
253
289
|
{
|
|
254
290
|
distances[offset++] = maxLen = len;
|
|
@@ -286,7 +322,9 @@ namespace SevenZip.Compression.LZ
|
|
|
286
322
|
{
|
|
287
323
|
UInt32 lenLimit;
|
|
288
324
|
if (_pos + _matchMaxLen <= _streamPos)
|
|
325
|
+
{
|
|
289
326
|
lenLimit = _matchMaxLen;
|
|
327
|
+
}
|
|
290
328
|
else
|
|
291
329
|
{
|
|
292
330
|
lenLimit = _streamPos - _pos;
|
|
@@ -313,7 +351,9 @@ namespace SevenZip.Compression.LZ
|
|
|
313
351
|
hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
|
|
314
352
|
}
|
|
315
353
|
else
|
|
354
|
+
{
|
|
316
355
|
hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
|
|
356
|
+
}
|
|
317
357
|
|
|
318
358
|
UInt32 curMatch = _hash[kFixHashSize + hashValue];
|
|
319
359
|
_hash[kFixHashSize + hashValue] = _pos;
|
|
@@ -347,8 +387,13 @@ namespace SevenZip.Compression.LZ
|
|
|
347
387
|
if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
|
|
348
388
|
{
|
|
349
389
|
while (++len != lenLimit)
|
|
390
|
+
{
|
|
350
391
|
if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
|
|
392
|
+
{
|
|
351
393
|
break;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
352
397
|
if (len == lenLimit)
|
|
353
398
|
{
|
|
354
399
|
_son[ptr1] = _son[cyclicPos];
|
|
@@ -381,9 +426,14 @@ namespace SevenZip.Compression.LZ
|
|
|
381
426
|
{
|
|
382
427
|
UInt32 value = items[i];
|
|
383
428
|
if (value <= subValue)
|
|
429
|
+
{
|
|
384
430
|
value = kEmptyHashValue;
|
|
431
|
+
}
|
|
385
432
|
else
|
|
433
|
+
{
|
|
386
434
|
value -= subValue;
|
|
435
|
+
}
|
|
436
|
+
|
|
387
437
|
items[i] = value;
|
|
388
438
|
}
|
|
389
439
|
}
|