com.wallstop-studios.unity-helpers 2.0.0-rc79.4 → 2.0.0-rc79.5

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.
Files changed (48) hide show
  1. package/.github/dependabot.yml +5 -1
  2. package/.github/workflows/npm-publish.yml +2 -2
  3. package/Runtime/Core/Extension/IReadonlyListExtensions.cs +1 -1
  4. package/Runtime/Core/Extension/IReadonlyListExtensions.cs.meta +1 -1
  5. package/Runtime/Core/Extension/StringExtensions.cs +1 -1
  6. package/Runtime/Core/Helper/StringInList.cs +3 -21
  7. package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +157 -49
  8. package/Runtime/Utils/Buffers.cs +2 -2
  9. package/Runtime/Utils/SevenZip/Common/CRC.cs +9 -0
  10. package/Runtime/Utils/SevenZip/Common/InBuffer.cs +15 -2
  11. package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +7 -2
  12. package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +50 -0
  13. package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +26 -0
  14. package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +27 -0
  15. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +9 -0
  16. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +80 -17
  17. package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +265 -30
  18. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +9 -0
  19. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +13 -1
  20. package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +11 -4
  21. package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs +54 -0
  22. package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs.meta +3 -0
  23. package/Tests/Runtime/Core/Threading.meta +3 -0
  24. package/Tests/Runtime/Core.meta +3 -0
  25. package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
  26. package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
  27. package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
  28. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
  29. package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
  30. package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
  31. package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
  32. package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
  33. package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs +1 -1
  34. package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs.meta +1 -1
  35. package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
  36. package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
  37. package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
  38. package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -1
  39. package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
  40. package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
  41. package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
  42. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -2
  43. package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
  44. package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
  45. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
  46. package/Tests/Runtime/Utils/BuffersTests.cs +6 -6
  47. package/Tests/Runtime/Utils/BuffersTests.cs.meta +1 -1
  48. package/package.json +2 -1
@@ -3,4 +3,8 @@ updates:
3
3
  - package-ecosystem: "github-actions"
4
4
  directory: "/"
5
5
  schedule:
6
- interval: "weekly"
6
+ interval: "weekly"
7
+ assignees:
8
+ - wallstop
9
+ reviewers:
10
+ - wallstop
@@ -14,12 +14,12 @@ jobs:
14
14
 
15
15
  steps:
16
16
  - name: Checkout Repository
17
- uses: actions/checkout@v4
17
+ uses: actions/checkout@v5
18
18
  with:
19
19
  fetch-depth: 0 # Ensure full commit history for version comparison
20
20
 
21
21
  - name: Set up Node.js
22
- uses: actions/setup-node@v4
22
+ uses: actions/setup-node@v5
23
23
  with:
24
24
  node-version: 18
25
25
  registry-url: 'https://registry.npmjs.org/'
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Core.Extension
1
+ namespace WallstopStudios.UnityHelpers.Core.Extension
2
2
  {
3
3
  using System;
4
4
  using System.Collections.Generic;
@@ -1,3 +1,3 @@
1
- fileFormatVersion: 2
1
+ fileFormatVersion: 2
2
2
  guid: 8c6bf3a13af8429cb8e738bd09541780
3
3
  timeCreated: 1757613609
@@ -8,7 +8,7 @@ namespace WallstopStudios.UnityHelpers.Core.Extension
8
8
 
9
9
  public static class StringExtensions
10
10
  {
11
- private static ThreadLocal<StringBuilder> StringBuilderCache = new(() =>
11
+ private static readonly ThreadLocal<StringBuilder> StringBuilderCache = new(() =>
12
12
  new StringBuilder()
13
13
  );
14
14
 
@@ -6,21 +6,15 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
6
6
 
7
7
  public sealed class StringInList : PropertyAttribute
8
8
  {
9
- public delegate string[] GetStringList();
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
- _shouldRefresh = false;
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 + Interlocked.CompareExchange(ref _working, 0, 0);
11
-
12
- private int _active;
13
- private int _working;
14
- private Thread _worker;
15
- private readonly ConcurrentQueue<Action> _work;
16
- private AutoResetEvent _waitHandle;
17
- private bool _disposed;
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 = false,
25
+ bool runInBackground = true,
23
26
  TimeSpan? noWorkWaitTime = null
24
27
  )
25
28
  {
26
- _active = 1;
27
- _working = 1;
28
- _work = new ConcurrentQueue<Action>();
29
+ _work = new ConcurrentQueue<WorkItem>();
29
30
  _exceptions = new ConcurrentQueue<Exception>();
30
- _waitHandle = new AutoResetEvent(false);
31
+ _workAvailable = new SemaphoreSlim(0);
31
32
  _noWorkWaitTime = noWorkWaitTime ?? TimeSpan.FromSeconds(1);
32
- _worker = new Thread(DoWork) { IsBackground = runInBackground };
33
- _worker.Start();
34
- }
33
+ _cancellationTokenSource = new CancellationTokenSource();
35
34
 
36
- ~SingleThreadedThreadPool()
37
- {
38
- Dispose(false);
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
- _work.Enqueue(work);
44
- _ = _waitHandle.Set();
42
+ if (_disposed || !_active)
43
+ {
44
+ return;
45
+ }
46
+
47
+ _work.Enqueue(WorkItem.FromAction(work));
48
+ Signal();
45
49
  }
46
50
 
47
- public void Dispose()
51
+ public void Enqueue(Func<Task> work)
48
52
  {
49
- Dispose(true);
50
- GC.SuppressFinalize(this);
53
+ if (_disposed || !_active)
54
+ {
55
+ return;
56
+ }
57
+
58
+ _work.Enqueue(WorkItem.FromTask(work));
59
+ Signal();
51
60
  }
52
61
 
53
- public void Dispose(bool disposing)
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
- Interlocked.Exchange(ref _active, 0);
69
+ _work.Enqueue(WorkItem.FromValueTask(work));
70
+ Signal();
71
+ }
61
72
 
62
- if (disposing)
73
+ private void Signal()
74
+ {
75
+ try
63
76
  {
64
- try
65
- {
66
- _worker?.Join(TimeSpan.FromSeconds(30));
67
- _waitHandle?.Dispose();
68
- }
69
- catch
70
- {
71
- // Swallow
72
- }
77
+ _workAvailable.Release();
78
+ }
79
+ catch
80
+ {
81
+ // Swallow
82
+ }
83
+ }
73
84
 
74
- _waitHandle = null;
75
- _worker = null;
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 void DoWork()
121
+ private async Task DoWorkAsync()
82
122
  {
83
- while (Interlocked.CompareExchange(ref _active, 0, 0) != 0)
123
+ CancellationToken cancellationToken = _cancellationTokenSource.Token;
124
+
125
+ while (_active && !cancellationToken.IsCancellationRequested)
84
126
  {
85
127
  try
86
128
  {
87
- if (_work.TryDequeue(out Action workItem))
129
+ if (_work.TryDequeue(out WorkItem workItem))
88
130
  {
89
- _ = Interlocked.Exchange(ref _working, 1);
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
- _ = _waitHandle?.WaitOne(_noWorkWaitTime);
149
+ await _workAvailable
150
+ .WaitAsync(_noWorkWaitTime, cancellationToken)
151
+ .ConfigureAwait(false);
104
152
  }
105
- catch (ObjectDisposedException)
153
+ catch (OperationCanceledException)
106
154
  {
107
- return;
155
+ break;
108
156
  }
109
157
  }
110
158
  }
111
- finally
159
+ catch (ObjectDisposedException)
112
160
  {
113
- _ = Interlocked.Exchange(ref _working, 0);
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
  }
@@ -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 GenericPool<T>
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 ArrayPool<T>
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
  }