From 724f854d9be31e2921a568a2ae39ca2be9a80acc Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Mon, 2 Nov 2020 15:03:15 -0800 Subject: [PATCH 1/8] Use hardware accelerated Adler32 impl --- .../Compressors/Deflate/Adler32.cs | 286 ++++++++++++++++++ .../Compressors/Deflate/DeflateManager.cs | 8 +- .../Compressors/Deflate/Inflate.cs | 9 +- src/SharpCompress/Compressors/Deflate/Zlib.cs | 84 ----- .../Compressors/Deflate/ZlibCodec.cs | 10 +- .../Compressors/Xz/Filters/BlockFilter.cs | 2 +- src/SharpCompress/SharpCompress.csproj | 5 +- 7 files changed, 305 insertions(+), 99 deletions(-) create mode 100644 src/SharpCompress/Compressors/Deflate/Adler32.cs diff --git a/src/SharpCompress/Compressors/Deflate/Adler32.cs b/src/SharpCompress/Compressors/Deflate/Adler32.cs new file mode 100644 index 000000000..95bb76cef --- /dev/null +++ b/src/SharpCompress/Compressors/Deflate/Adler32.cs @@ -0,0 +1,286 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the GNU Affero General Public License, Version 3. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +#if NETCOREAPP3_1 +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif + +namespace SharpCompress.Compressors.Deflate +{ + /// + /// Calculates the 32 bit Adler checksum of a given buffer according to + /// RFC 1950. ZLIB Compressed Data Format Specification version 3.3) + /// + internal static class Adler32 + { + /// + /// The default initial seed value of a Adler32 checksum calculation. + /// + public const uint SeedValue = 1U; + +#if NETCOREAPP3_1 + private const int MinBufferSize = 64; +#endif + + // Largest prime smaller than 65536 + private const uint BASE = 65521; + + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + private const uint NMAX = 5552; + + /// + /// Calculates the Adler32 checksum with the bytes taken from the span. + /// + /// The readonly span of bytes. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Calculate(ReadOnlySpan buffer) + => Calculate(SeedValue, buffer); + + /// + /// Calculates the Adler32 checksum with the bytes taken from the span and seed. + /// + /// The input Adler32 value. + /// The readonly span of bytes. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Calculate(uint adler, ReadOnlySpan buffer) + { + if (buffer.IsEmpty) + { + return SeedValue; + } + +#if NETCOREAPP3_1 + if (Sse3.IsSupported && buffer.Length >= MinBufferSize) + { + return CalculateSse(adler, buffer); + } + + return CalculateScalar(adler, buffer); +#else + return CalculateScalar(adler, buffer); +#endif + } + + // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/adler32_simd.c +#if NETCOREAPP3_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) + { + uint s1 = adler & 0xFFFF; + uint s2 = (adler >> 16) & 0xFFFF; + + // Process the data in blocks. + const int BLOCK_SIZE = 1 << 5; + + uint length = (uint)buffer.Length; + uint blocks = length / BLOCK_SIZE; + length -= blocks * BLOCK_SIZE; + + int index = 0; + fixed (byte* bufferPtr = &buffer[0]) + { + index += (int)blocks * BLOCK_SIZE; + var localBufferPtr = bufferPtr; + + // _mm_setr_epi8 on x86 + var tap1 = Vector128.Create(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + var tap2 = Vector128.Create(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + Vector128 zero = Vector128.Zero; + var ones = Vector128.Create((short)1); + + while (blocks > 0) + { + uint n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */ + if (n > blocks) + { + n = blocks; + } + + blocks -= n; + + // Process n blocks of data. At most NMAX data bytes can be + // processed before s2 must be reduced modulo BASE. + Vector128 v_ps = Vector128.CreateScalar(s1 * n).AsInt32(); + Vector128 v_s2 = Vector128.CreateScalar(s2).AsInt32(); + Vector128 v_s1 = Vector128.Zero; + + do + { + // Load 32 input bytes. + Vector128 bytes1 = Sse3.LoadDquVector128(localBufferPtr); + Vector128 bytes2 = Sse3.LoadDquVector128(localBufferPtr + 16); + + // Add previous block byte sum to v_ps. + v_ps = Sse2.Add(v_ps, v_s1); + + // Horizontally add the bytes for s1, multiply-adds the + // bytes by [ 32, 31, 30, ... ] for s2. + v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes1, zero).AsInt32()); + Vector128 mad1 = Ssse3.MultiplyAddAdjacent(bytes1, tap1); + v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad1, ones)); + + v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes2, zero).AsInt32()); + Vector128 mad2 = Ssse3.MultiplyAddAdjacent(bytes2, tap2); + v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad2, ones)); + + localBufferPtr += BLOCK_SIZE; + } + while (--n > 0); + + v_s2 = Sse2.Add(v_s2, Sse2.ShiftLeftLogical(v_ps, 5)); + + // Sum epi32 ints v_s1(s2) and accumulate in s1(s2). + const byte S2301 = 0b1011_0001; // A B C D -> B A D C + const byte S1032 = 0b0100_1110; // A B C D -> C D A B + + v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S2301)); + v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S1032)); + + s1 += (uint)v_s1.ToScalar(); + + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S2301)); + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S1032)); + + s2 = (uint)v_s2.ToScalar(); + + // Reduce. + s1 %= BASE; + s2 %= BASE; + } + } + + ref byte bufferRef = ref MemoryMarshal.GetReference(buffer); + + if (length > 0) + { + if (length >= 16) + { + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + length -= 16; + } + + while (length-- > 0) + { + s2 += s1 += Unsafe.Add(ref bufferRef, index++); + } + + if (s1 >= BASE) + { + s1 -= BASE; + } + + s2 %= BASE; + } + + return s1 | (s2 << 16); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint CalculateScalar(uint adler, ReadOnlySpan buffer) + { + uint s1 = adler & 0xFFFF; + uint s2 = (adler >> 16) & 0xFFFF; + uint k; + + ref byte bufferRef = ref MemoryMarshal.GetReference(buffer); + uint length = (uint)buffer.Length; + int index = 0; + + while (length > 0) + { + k = length < NMAX ? length : NMAX; + length -= k; + + while (k >= 16) + { + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + k -= 16; + } + + if (k != 0) + { + do + { + s1 += Unsafe.Add(ref bufferRef, index++); + s2 += s1; + } + while (--k != 0); + } + + s1 %= BASE; + s2 %= BASE; + } + + return (s2 << 16) | s1; + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs index c182d5e79..689d78eee 100644 --- a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs +++ b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs @@ -1190,7 +1190,7 @@ private void _fillWindow() // Otherwise, window_size == 2*WSIZE so more >= 2. // If there was sliding, more >= WSIZE. So in all cases, more >= 2. - n = _codec.read_buf(window, strstart + lookahead, more); + n = _codec.ReadBuffer(window, strstart + lookahead, more); lookahead += n; // Initialize the hash value now that we have some input: @@ -1685,7 +1685,7 @@ internal void Reset() Rfc1950BytesEmitted = false; status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE; - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + _codec._Adler32 = Adler32.Calculate(Array.Empty().AsSpan()); last_flush = (int)FlushType.None; @@ -1763,7 +1763,7 @@ internal int SetDictionary(byte[] dictionary) throw new ZlibException("Stream error."); } - _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length); + _codec._Adler32 = Adler32.Calculate(dictionary.AsSpan()); if (length < MIN_MATCH) { @@ -1855,7 +1855,7 @@ internal int Deflate(FlushType flush) pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); } - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + _codec._Adler32 = Adler32.Calculate(Array.Empty().AsSpan()); } // Flush as much pending output as possible diff --git a/src/SharpCompress/Compressors/Deflate/Inflate.cs b/src/SharpCompress/Compressors/Deflate/Inflate.cs index f9b66c0cb..028f4def0 100644 --- a/src/SharpCompress/Compressors/Deflate/Inflate.cs +++ b/src/SharpCompress/Compressors/Deflate/Inflate.cs @@ -118,8 +118,9 @@ internal uint Reset() if (checkfn != null) { - _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0); + _codec._Adler32 = check = Adler32.Calculate(Array.Empty().AsSpan()); } + return oldCheck; } @@ -739,7 +740,7 @@ internal int Flush(int r) // update check information if (checkfn != null) { - _codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes); + _codec._Adler32 = check = Adler32.Calculate(check, window.AsSpan(readAt, nBytes)); } // copy as far as end of window @@ -1879,12 +1880,12 @@ internal int SetDictionary(byte[] dictionary) throw new ZlibException("Stream error."); } - if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32) + if (Adler32.Calculate(1, dictionary.AsSpan()) != _codec._Adler32) { return ZlibConstants.Z_DATA_ERROR; } - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); + _codec._Adler32 = Adler32.Calculate(0, Array.Empty()); if (length >= (1 << wbits)) { diff --git a/src/SharpCompress/Compressors/Deflate/Zlib.cs b/src/SharpCompress/Compressors/Deflate/Zlib.cs index d33cbcc9e..6133feb44 100644 --- a/src/SharpCompress/Compressors/Deflate/Zlib.cs +++ b/src/SharpCompress/Compressors/Deflate/Zlib.cs @@ -405,88 +405,4 @@ static StaticTree() BitLengths = new StaticTree(null, extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS); } } - - /// - /// Computes an Adler-32 checksum. - /// - /// - /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less - /// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum - /// is a required part of the "ZLIB" standard. Applications will almost never need to - /// use this class directly. - /// - internal sealed class Adler - { - // largest prime smaller than 65536 - private static readonly uint BASE = 65521U; - - // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 - private static readonly int NMAX = 5552; - - internal static uint Adler32(uint adler, byte[]? buf, int index, int len) - { - if (buf is null) - { - return 1; - } - - uint s1 = adler & 0xffffU; - uint s2 = (adler >> 16) & 0xffffU; - - while (len > 0) - { - int k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) - { - //s1 += (buf[index++] & 0xff); s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - s1 += buf[index++]; - s2 += s1; - k -= 16; - } - if (k != 0) - { - do - { - s1 += buf[index++]; - s2 += s1; - } - while (--k != 0); - } - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; - } - } } \ No newline at end of file diff --git a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs index e7e2ecb9a..72fd5ade6 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs @@ -173,7 +173,7 @@ internal sealed class ZlibCodec /// /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. /// - public int Adler32 => (int)_Adler32; + public int Adler32Checksum => (int)_Adler32; /// /// Create a ZlibCodec. @@ -720,7 +720,7 @@ OutputBuffer.Length < (NextOut + len)) // this function so some applications may wish to modify it to avoid // allocating a large strm->next_in buffer and copying from it. // (See also flush_pending()). - internal int read_buf(byte[] buf, int start, int size) + internal int ReadBuffer(byte[] buf, int start, int size) { int len = AvailableBytesIn; @@ -728,7 +728,8 @@ internal int read_buf(byte[] buf, int start, int size) { len = size; } - if (len == 0) + + if (len > 0) { return 0; } @@ -737,8 +738,9 @@ internal int read_buf(byte[] buf, int start, int size) if (dstate.WantRfc1950HeaderBytes) { - _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len); + _Adler32 = Adler32.Calculate(_Adler32, InputBuffer.AsSpan(NextIn, len)); } + Array.Copy(InputBuffer, NextIn, buf, start, len); NextIn += len; TotalBytesIn += len; diff --git a/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs index bf6d85e57..875d1b44c 100644 --- a/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs +++ b/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs @@ -39,7 +39,7 @@ public static BlockFilter Read(BinaryReader reader) throw new NotImplementedException($"Filter {filterType} has not yet been implemented"); } - var filter = (BlockFilter)Activator.CreateInstance(FilterMap[filterType]); + var filter = (BlockFilter)Activator.CreateInstance(FilterMap[filterType])!; var sizeOfProperties = reader.ReadXZInteger(); if (sizeOfProperties > int.MaxValue) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 992438a36..cb680b4dd 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -6,8 +6,8 @@ 0.26.0 0.26.0 Adam Hathcock - netstandard2.0;netstandard2.1;net46 - netstandard2.0;netstandard2.1 + netstandard2.0;netstandard2.1;netcoreapp3.1;net46 + netstandard2.0;netcoreapp3.1;netstandard2.1 true false SharpCompress @@ -26,6 +26,7 @@ true true snupkg + true From a07a5115aab25fd1ad06f2bc004f3b0f844c8e05 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Mon, 2 Nov 2020 15:18:14 -0800 Subject: [PATCH 2/8] React to nullable changes --- src/SharpCompress/Common/ExtractionMethods.cs | 6 ++---- src/SharpCompress/Common/Rar/Headers/NewSubHeaderType.cs | 4 +++- src/SharpCompress/Common/SevenZip/CMethodId.cs | 2 +- src/SharpCompress/Compressors/Deflate/GZipStream.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/SharpCompress/Common/ExtractionMethods.cs b/src/SharpCompress/Common/ExtractionMethods.cs index 801661b08..4564df917 100644 --- a/src/SharpCompress/Common/ExtractionMethods.cs +++ b/src/SharpCompress/Common/ExtractionMethods.cs @@ -24,10 +24,8 @@ internal static class ExtractionMethods if (options.ExtractFullPath) { - string folder = Path.GetDirectoryName(entry.Key); - string destdir = Path.GetFullPath( - Path.Combine(fullDestinationDirectoryPath, folder) - ); + string folder = Path.GetDirectoryName(entry.Key)!; + string destdir = Path.GetFullPath(Path.Combine(fullDestinationDirectoryPath, folder!)); if (!Directory.Exists(destdir)) { diff --git a/src/SharpCompress/Common/Rar/Headers/NewSubHeaderType.cs b/src/SharpCompress/Common/Rar/Headers/NewSubHeaderType.cs index 84d50aee2..f3d849553 100644 --- a/src/SharpCompress/Common/Rar/Headers/NewSubHeaderType.cs +++ b/src/SharpCompress/Common/Rar/Headers/NewSubHeaderType.cs @@ -47,8 +47,10 @@ internal bool Equals(byte[] bytes) return true; } - public bool Equals(NewSubHeaderType other) + public bool Equals(NewSubHeaderType? other) { + if (other is null) return false; + return Equals(other._bytes); } } diff --git a/src/SharpCompress/Common/SevenZip/CMethodId.cs b/src/SharpCompress/Common/SevenZip/CMethodId.cs index 03ce8df66..5069b051a 100644 --- a/src/SharpCompress/Common/SevenZip/CMethodId.cs +++ b/src/SharpCompress/Common/SevenZip/CMethodId.cs @@ -24,7 +24,7 @@ public override int GetHashCode() return _id.GetHashCode(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is CMethodId other && Equals(other); } diff --git a/src/SharpCompress/Compressors/Deflate/GZipStream.cs b/src/SharpCompress/Compressors/Deflate/GZipStream.cs index def36904b..9d045d1ff 100644 --- a/src/SharpCompress/Compressors/Deflate/GZipStream.cs +++ b/src/SharpCompress/Compressors/Deflate/GZipStream.cs @@ -447,7 +447,7 @@ private int EmitHeader() // filename if (fnLength != 0) { - Array.Copy(filenameBytes, 0, header, i, fnLength - 1); + Array.Copy(filenameBytes!, 0, header, i, fnLength - 1); i += fnLength - 1; header[i++] = 0; // terminate } @@ -455,7 +455,7 @@ private int EmitHeader() // comment if (cbLength != 0) { - Array.Copy(commentBytes, 0, header, i, cbLength - 1); + Array.Copy(commentBytes!, 0, header, i, cbLength - 1); i += cbLength - 1; header[i++] = 0; // terminate } From 60ab08c28acb0d1080214351a76092f274d1e40e Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Mon, 2 Nov 2020 15:19:08 -0800 Subject: [PATCH 3/8] Register code pages on .NETCOREAPP3.1 --- src/SharpCompress/Common/ArchiveEncoding.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Common/ArchiveEncoding.cs b/src/SharpCompress/Common/ArchiveEncoding.cs index 1f0b6effa..1bb7ac71a 100644 --- a/src/SharpCompress/Common/ArchiveEncoding.cs +++ b/src/SharpCompress/Common/ArchiveEncoding.cs @@ -36,7 +36,7 @@ public ArchiveEncoding(Encoding def, Encoding password) Password = password; } -#if NETSTANDARD1_3 || NETSTANDARD2_0 || NETSTANDARD2_1 +#if !NET46 static ArchiveEncoding() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); From 72121d8982fd2b1799b6817179c1c44c18597898 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Mon, 2 Nov 2020 15:19:31 -0800 Subject: [PATCH 4/8] Remove global config (blocking CI upgrade) --- global.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 global.json diff --git a/global.json b/global.json deleted file mode 100644 index acb1473ab..000000000 --- a/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "3.1.302" - } -} \ No newline at end of file From 6e152cd60930b5bbe0738db3f076672b0ad80710 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 3 Nov 2020 10:07:37 -0800 Subject: [PATCH 5/8] Revert "Remove global config (blocking CI upgrade)" This reverts commit 72121d8982fd2b1799b6817179c1c44c18597898. --- global.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 000000000..acb1473ab --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "3.1.302" + } +} \ No newline at end of file From beec97bb8cb22cfac9996942b3b8cfb779872c93 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 3 Nov 2020 10:22:38 -0800 Subject: [PATCH 6/8] Move Adler32 to Algorithms namespace and fix empty behavior --- .../{Compressors/Deflate => Algorithms}/Adler32.cs | 9 ++++----- src/SharpCompress/Compressors/Deflate/DeflateManager.cs | 6 ++++-- src/SharpCompress/Compressors/Deflate/Inflate.cs | 6 ++++-- src/SharpCompress/Compressors/Deflate/ZlibCodec.cs | 2 ++ 4 files changed, 14 insertions(+), 9 deletions(-) rename src/SharpCompress/{Compressors/Deflate => Algorithms}/Adler32.cs (97%) diff --git a/src/SharpCompress/Compressors/Deflate/Adler32.cs b/src/SharpCompress/Algorithms/Adler32.cs similarity index 97% rename from src/SharpCompress/Compressors/Deflate/Adler32.cs rename to src/SharpCompress/Algorithms/Adler32.cs index 95bb76cef..d0b3279fd 100644 --- a/src/SharpCompress/Compressors/Deflate/Adler32.cs +++ b/src/SharpCompress/Algorithms/Adler32.cs @@ -9,7 +9,7 @@ using System.Runtime.Intrinsics.X86; #endif -namespace SharpCompress.Compressors.Deflate +namespace SharpCompress.Algorithms { /// /// Calculates the 32 bit Adler checksum of a given buffer according to @@ -39,7 +39,9 @@ internal static class Adler32 /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Calculate(ReadOnlySpan buffer) - => Calculate(SeedValue, buffer); + { + return Calculate(SeedValue, buffer); + } /// /// Calculates the Adler32 checksum with the bytes taken from the span and seed. @@ -47,7 +49,6 @@ public static uint Calculate(ReadOnlySpan buffer) /// The input Adler32 value. /// The readonly span of bytes. /// The . - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Calculate(uint adler, ReadOnlySpan buffer) { if (buffer.IsEmpty) @@ -69,7 +70,6 @@ public static uint Calculate(uint adler, ReadOnlySpan buffer) // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/adler32_simd.c #if NETCOREAPP3_1 - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) { uint s1 = adler & 0xFFFF; @@ -213,7 +213,6 @@ private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) } #endif - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint CalculateScalar(uint adler, ReadOnlySpan buffer) { uint s1 = adler & 0xFFFF; diff --git a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs index 689d78eee..99aeccb7c 100644 --- a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs +++ b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs @@ -70,6 +70,8 @@ using System; +using SharpCompress.Algorithms; + namespace SharpCompress.Compressors.Deflate { internal sealed partial class DeflateManager @@ -1685,7 +1687,7 @@ internal void Reset() Rfc1950BytesEmitted = false; status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE; - _codec._Adler32 = Adler32.Calculate(Array.Empty().AsSpan()); + _codec._Adler32 = 1; last_flush = (int)FlushType.None; @@ -1855,7 +1857,7 @@ internal int Deflate(FlushType flush) pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); } - _codec._Adler32 = Adler32.Calculate(Array.Empty().AsSpan()); + _codec._Adler32 = 1; } // Flush as much pending output as possible diff --git a/src/SharpCompress/Compressors/Deflate/Inflate.cs b/src/SharpCompress/Compressors/Deflate/Inflate.cs index 028f4def0..e2e748d53 100644 --- a/src/SharpCompress/Compressors/Deflate/Inflate.cs +++ b/src/SharpCompress/Compressors/Deflate/Inflate.cs @@ -65,6 +65,8 @@ using System; +using SharpCompress.Algorithms; + namespace SharpCompress.Compressors.Deflate { internal sealed class InflateBlocks @@ -118,7 +120,7 @@ internal uint Reset() if (checkfn != null) { - _codec._Adler32 = check = Adler32.Calculate(Array.Empty().AsSpan()); + _codec._Adler32 = check = 1; } return oldCheck; @@ -1885,7 +1887,7 @@ internal int SetDictionary(byte[] dictionary) return ZlibConstants.Z_DATA_ERROR; } - _codec._Adler32 = Adler32.Calculate(0, Array.Empty()); + _codec._Adler32 = 1; if (length >= (1 << wbits)) { diff --git a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs index 72fd5ade6..95f87dff1 100644 --- a/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs +++ b/src/SharpCompress/Compressors/Deflate/ZlibCodec.cs @@ -67,6 +67,8 @@ using System; +using SharpCompress.Algorithms; + namespace SharpCompress.Compressors.Deflate { /// From 994d90b2d21739eaa587e40b2583e437a828fbf7 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 3 Nov 2020 10:23:06 -0800 Subject: [PATCH 7/8] Fix #if to support .NETCOREAPP3.1 --- src/SharpCompress/Polyfills/StreamExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/Polyfills/StreamExtensions.cs b/src/SharpCompress/Polyfills/StreamExtensions.cs index be97c6391..e3285e8ff 100644 --- a/src/SharpCompress/Polyfills/StreamExtensions.cs +++ b/src/SharpCompress/Polyfills/StreamExtensions.cs @@ -1,4 +1,4 @@ -#if !NETSTANDARD2_1 +#if NETSTANDARD2_0 || NET46 using System.Buffers; From 0154680a77ab96f835526d9a6aed0b51713ba385 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 3 Nov 2020 10:23:14 -0800 Subject: [PATCH 8/8] Use C#9 --- src/SharpCompress/SharpCompress.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index cb680b4dd..e1e9b5316 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -21,7 +21,7 @@ false false SharpCompress is a compression library for NET Standard 2.0/2.1//NET 4.6 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented. - 8 + 9 enable true true