diff --git a/Directory.Packages.props b/Directory.Packages.props index 439ee797..4f095334 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,18 +1,17 @@ - + - + - - + + - diff --git a/src/SharpCompress/Archives/ArchiveFactory.cs b/src/SharpCompress/Archives/ArchiveFactory.cs index c979b700..870092f1 100644 --- a/src/SharpCompress/Archives/ArchiveFactory.cs +++ b/src/SharpCompress/Archives/ArchiveFactory.cs @@ -45,7 +45,7 @@ public static class ArchiveFactory /// public static IArchive Open(string filePath, ReaderOptions? options = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), options); } @@ -68,7 +68,7 @@ public static class ArchiveFactory /// public static IArchive Open(IEnumerable fileInfos, ReaderOptions? options = null) { - fileInfos.CheckNotNull(nameof(fileInfos)); + fileInfos.NotNull(nameof(fileInfos)); var filesArray = fileInfos.ToArray(); if (filesArray.Length == 0) { @@ -81,7 +81,7 @@ public static class ArchiveFactory return Open(fileInfo, options); } - fileInfo.CheckNotNull(nameof(fileInfo)); + fileInfo.NotNull(nameof(fileInfo)); options ??= new ReaderOptions { LeaveStreamOpen = false }; return FindFactory(fileInfo).Open(filesArray, options); @@ -94,7 +94,7 @@ public static class ArchiveFactory /// public static IArchive Open(IEnumerable streams, ReaderOptions? options = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); var streamsArray = streams.ToArray(); if (streamsArray.Length == 0) { @@ -107,7 +107,7 @@ public static class ArchiveFactory return Open(firstStream, options); } - firstStream.CheckNotNull(nameof(firstStream)); + firstStream.NotNull(nameof(firstStream)); options ??= new ReaderOptions(); return FindFactory(firstStream).Open(streamsArray, options); @@ -129,7 +129,7 @@ public static class ArchiveFactory private static T FindFactory(FileInfo finfo) where T : IFactory { - finfo.CheckNotNull(nameof(finfo)); + finfo.NotNull(nameof(finfo)); using Stream stream = finfo.OpenRead(); return FindFactory(stream); } @@ -137,7 +137,7 @@ public static class ArchiveFactory private static T FindFactory(Stream stream) where T : IFactory { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (!stream.CanRead || !stream.CanSeek) { throw new ArgumentException("Stream should be readable and seekable"); @@ -172,7 +172,7 @@ public static class ArchiveFactory int bufferSize = ReaderOptions.DefaultBufferSize ) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); using Stream s = File.OpenRead(filePath); return IsArchive(s, out type, bufferSize); } @@ -184,7 +184,7 @@ public static class ArchiveFactory ) { type = null; - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (!stream.CanRead || !stream.CanSeek) { @@ -215,7 +215,7 @@ public static class ArchiveFactory /// public static IEnumerable GetFileParts(string part1) { - part1.CheckNotNullOrEmpty(nameof(part1)); + part1.NotNullOrEmpty(nameof(part1)); return GetFileParts(new FileInfo(part1)).Select(a => a.FullName); } @@ -226,7 +226,7 @@ public static class ArchiveFactory /// public static IEnumerable GetFileParts(FileInfo part1) { - part1.CheckNotNull(nameof(part1)); + part1.NotNull(nameof(part1)); yield return part1; foreach (var factory in Factory.Factories.OfType()) diff --git a/src/SharpCompress/Archives/GZip/GZipArchive.cs b/src/SharpCompress/Archives/GZip/GZipArchive.cs index 4437ff57..a0345cdf 100644 --- a/src/SharpCompress/Archives/GZip/GZipArchive.cs +++ b/src/SharpCompress/Archives/GZip/GZipArchive.cs @@ -21,7 +21,7 @@ public class GZipArchive : AbstractWritableArchive /// public static GZipArchive Open(string filePath, ReaderOptions? readerOptions = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); } @@ -32,7 +32,7 @@ public class GZipArchive : AbstractWritableArchive /// public static GZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) { - fileInfo.CheckNotNull(nameof(fileInfo)); + fileInfo.NotNull(nameof(fileInfo)); return new GZipArchive( new SourceStream( fileInfo, @@ -52,7 +52,7 @@ public class GZipArchive : AbstractWritableArchive ReaderOptions? readerOptions = null ) { - fileInfos.CheckNotNull(nameof(fileInfos)); + fileInfos.NotNull(nameof(fileInfos)); var files = fileInfos.ToArray(); return new GZipArchive( new SourceStream( @@ -70,7 +70,7 @@ public class GZipArchive : AbstractWritableArchive /// public static GZipArchive Open(IEnumerable streams, ReaderOptions? readerOptions = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); var strms = streams.ToArray(); return new GZipArchive( new SourceStream( @@ -88,7 +88,7 @@ public class GZipArchive : AbstractWritableArchive /// public static GZipArchive Open(Stream stream, ReaderOptions? readerOptions = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (stream is not { CanSeek: true }) { diff --git a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs index 3d1daa1a..bda1e358 100644 --- a/src/SharpCompress/Archives/IArchiveEntryExtensions.cs +++ b/src/SharpCompress/Archives/IArchiveEntryExtensions.cs @@ -25,7 +25,7 @@ public static class IArchiveEntryExtensions using (entryStream) { using Stream s = new ListeningStream(streamListener, entryStream); - s.TransferTo(streamToWriteTo); + s.CopyTo(streamToWriteTo); } streamListener.FireEntryExtractionEnd(archiveEntry); } diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs index ee4be60e..b3689a9f 100644 --- a/src/SharpCompress/Archives/Rar/RarArchive.cs +++ b/src/SharpCompress/Archives/Rar/RarArchive.cs @@ -95,7 +95,7 @@ public class RarArchive : AbstractArchive /// public static RarArchive Open(string filePath, ReaderOptions? options = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); var fileInfo = new FileInfo(filePath); return new RarArchive( new SourceStream( @@ -113,7 +113,7 @@ public class RarArchive : AbstractArchive /// public static RarArchive Open(FileInfo fileInfo, ReaderOptions? options = null) { - fileInfo.CheckNotNull(nameof(fileInfo)); + fileInfo.NotNull(nameof(fileInfo)); return new RarArchive( new SourceStream( fileInfo, @@ -130,7 +130,7 @@ public class RarArchive : AbstractArchive /// public static RarArchive Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (stream is not { CanSeek: true }) { @@ -150,7 +150,7 @@ public class RarArchive : AbstractArchive ReaderOptions? readerOptions = null ) { - fileInfos.CheckNotNull(nameof(fileInfos)); + fileInfos.NotNull(nameof(fileInfos)); var files = fileInfos.ToArray(); return new RarArchive( new SourceStream( @@ -168,7 +168,7 @@ public class RarArchive : AbstractArchive /// public static RarArchive Open(IEnumerable streams, ReaderOptions? readerOptions = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); var strms = streams.ToArray(); return new RarArchive( new SourceStream( diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs index 323f07ac..ea763409 100644 --- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs +++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs @@ -21,7 +21,7 @@ public class SevenZipArchive : AbstractArchive public static SevenZipArchive Open(string filePath, ReaderOptions? readerOptions = null) { - filePath.CheckNotNullOrEmpty("filePath"); + filePath.NotNullOrEmpty("filePath"); return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); } @@ -32,7 +32,7 @@ public class SevenZipArchive : AbstractArchive public static SevenZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) { - fileInfo.CheckNotNull("fileInfo"); + fileInfo.NotNull("fileInfo"); return new SevenZipArchive( new SourceStream( fileInfo, @@ -52,7 +52,7 @@ public class SevenZipArchive : AbstractArchive public static SevenZipArchive Open(Stream stream, ReaderOptions? readerOptions = null) { - stream.CheckNotNull("stream"); + stream.NotNull("stream"); if (stream is not { CanSeek: true }) { diff --git a/src/SharpCompress/Archives/Tar/TarArchive.cs b/src/SharpCompress/Archives/Tar/TarArchive.cs index 2c9c64c7..39f0fce6 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.cs @@ -22,7 +22,7 @@ public class TarArchive : AbstractWritableArchive /// public static TarArchive Open(string filePath, ReaderOptions? readerOptions = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); } @@ -33,7 +33,7 @@ public class TarArchive : AbstractWritableArchive /// public static TarArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) { - fileInfo.CheckNotNull(nameof(fileInfo)); + fileInfo.NotNull(nameof(fileInfo)); return new TarArchive( new SourceStream( fileInfo, @@ -53,7 +53,7 @@ public class TarArchive : AbstractWritableArchive ReaderOptions? readerOptions = null ) { - fileInfos.CheckNotNull(nameof(fileInfos)); + fileInfos.NotNull(nameof(fileInfos)); var files = fileInfos.ToArray(); return new TarArchive( new SourceStream( @@ -71,7 +71,7 @@ public class TarArchive : AbstractWritableArchive /// public static TarArchive Open(IEnumerable streams, ReaderOptions? readerOptions = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); var strms = streams.ToArray(); return new TarArchive( new SourceStream( @@ -89,7 +89,7 @@ public class TarArchive : AbstractWritableArchive /// public static TarArchive Open(Stream stream, ReaderOptions? readerOptions = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (stream is not { CanSeek: true }) { @@ -178,7 +178,7 @@ public class TarArchive : AbstractWritableArchive using (var entryStream = entry.OpenEntryStream()) { using var memoryStream = new MemoryStream(); - entryStream.TransferTo(memoryStream); + entryStream.CopyTo(memoryStream); memoryStream.Position = 0; var bytes = memoryStream.ToArray(); diff --git a/src/SharpCompress/Archives/Zip/ZipArchive.cs b/src/SharpCompress/Archives/Zip/ZipArchive.cs index a75b4095..35b8e0cb 100644 --- a/src/SharpCompress/Archives/Zip/ZipArchive.cs +++ b/src/SharpCompress/Archives/Zip/ZipArchive.cs @@ -43,7 +43,7 @@ public class ZipArchive : AbstractWritableArchive /// public static ZipArchive Open(string filePath, ReaderOptions? readerOptions = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions()); } @@ -54,7 +54,7 @@ public class ZipArchive : AbstractWritableArchive /// public static ZipArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) { - fileInfo.CheckNotNull(nameof(fileInfo)); + fileInfo.NotNull(nameof(fileInfo)); return new ZipArchive( new SourceStream( fileInfo, @@ -74,7 +74,7 @@ public class ZipArchive : AbstractWritableArchive ReaderOptions? readerOptions = null ) { - fileInfos.CheckNotNull(nameof(fileInfos)); + fileInfos.NotNull(nameof(fileInfos)); var files = fileInfos.ToArray(); return new ZipArchive( new SourceStream( @@ -92,7 +92,7 @@ public class ZipArchive : AbstractWritableArchive /// public static ZipArchive Open(IEnumerable streams, ReaderOptions? readerOptions = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); var strms = streams.ToArray(); return new ZipArchive( new SourceStream( @@ -110,7 +110,7 @@ public class ZipArchive : AbstractWritableArchive /// public static ZipArchive Open(Stream stream, ReaderOptions? readerOptions = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); if (stream is not { CanSeek: true }) { diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack50_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack50_cpp.cs index 2ba0d80c..106caff9 100644 --- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack50_cpp.cs +++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack50_cpp.cs @@ -413,7 +413,7 @@ internal partial class Unpack else //x memcpy(Mem,Window+BlockStart,BlockLength); { - Utility.Copy(Window, BlockStart, Mem, 0, BlockLength); + Buffer.BlockCopy(Window, (int)BlockStart, Mem, 0, (int)BlockLength); } } else @@ -427,9 +427,21 @@ internal partial class Unpack else { //x memcpy(Mem,Window+BlockStart,FirstPartLength); - Utility.Copy(Window, BlockStart, Mem, 0, FirstPartLength); + Buffer.BlockCopy( + Window, + (int)BlockStart, + Mem, + 0, + (int)FirstPartLength + ); //x memcpy(Mem+FirstPartLength,Window,BlockEnd); - Utility.Copy(Window, 0, Mem, FirstPartLength, BlockEnd); + Buffer.BlockCopy( + Window, + 0, + Mem, + (int)FirstPartLength, + (int)BlockEnd + ); } } diff --git a/src/SharpCompress/Factories/Factory.cs b/src/SharpCompress/Factories/Factory.cs index 1b9e23e9..2462f614 100644 --- a/src/SharpCompress/Factories/Factory.cs +++ b/src/SharpCompress/Factories/Factory.cs @@ -34,7 +34,7 @@ public abstract class Factory : IFactory /// must not be null. public static void RegisterFactory(Factory factory) { - factory.CheckNotNull(nameof(factory)); + factory.NotNull(nameof(factory)); _factories.Add(factory); } diff --git a/src/SharpCompress/LazyReadOnlyCollection.cs b/src/SharpCompress/LazyReadOnlyCollection.cs index 9c1b35eb..cc9cb3fd 100644 --- a/src/SharpCompress/LazyReadOnlyCollection.cs +++ b/src/SharpCompress/LazyReadOnlyCollection.cs @@ -4,7 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; -namespace SharpCompress.Helpers; +namespace SharpCompress; internal sealed class LazyReadOnlyCollection : ICollection { diff --git a/src/SharpCompress/NotNullExtensions.cs b/src/SharpCompress/NotNullExtensions.cs index 2245612e..38e6d6d6 100644 --- a/src/SharpCompress/NotNullExtensions.cs +++ b/src/SharpCompress/NotNullExtensions.cs @@ -4,20 +4,19 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; -namespace SharpCompress.Helpers; +namespace SharpCompress; internal static class NotNullExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IEnumerable Empty(this IEnumerable? source) => - source ?? Enumerable.Empty(); + public static IEnumerable Empty(this IEnumerable? source) => source ?? []; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable Empty(this T? source) { if (source is null) { - return Enumerable.Empty(); + return []; } return source.AsEnumerable(); } @@ -68,4 +67,14 @@ internal static class NotNullExtensions return obj.Value; } #endif + + public static string NotNullOrEmpty(this string obj, string name) + { + obj.NotNull(name); + if (obj.Length == 0) + { + throw new ArgumentException("String is empty.", name); + } + return obj; + } } diff --git a/src/SharpCompress/Readers/Arc/ArcReader.cs b/src/SharpCompress/Readers/Arc/ArcReader.cs index 7d58b8d4..b7cf5467 100644 --- a/src/SharpCompress/Readers/Arc/ArcReader.cs +++ b/src/SharpCompress/Readers/Arc/ArcReader.cs @@ -24,7 +24,7 @@ namespace SharpCompress.Readers.Arc /// public static ArcReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); return new ArcReader(stream, options ?? new ReaderOptions()); } diff --git a/src/SharpCompress/Readers/GZip/GZipReader.cs b/src/SharpCompress/Readers/GZip/GZipReader.cs index 73bc4a9d..e10d509a 100644 --- a/src/SharpCompress/Readers/GZip/GZipReader.cs +++ b/src/SharpCompress/Readers/GZip/GZipReader.cs @@ -22,7 +22,7 @@ public class GZipReader : AbstractReader /// public static GZipReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); return new GZipReader(stream, options ?? new ReaderOptions()); } diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs index 2a56ee35..79842e6a 100644 --- a/src/SharpCompress/Readers/Rar/RarReader.cs +++ b/src/SharpCompress/Readers/Rar/RarReader.cs @@ -42,7 +42,7 @@ public abstract class RarReader : AbstractReader public static RarReader Open(string filePath, ReaderOptions? options = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), options); } @@ -71,7 +71,7 @@ public abstract class RarReader : AbstractReader /// public static RarReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); return new SingleVolumeRarReader(stream, options ?? new ReaderOptions()); } @@ -83,7 +83,7 @@ public abstract class RarReader : AbstractReader /// public static RarReader Open(IEnumerable streams, ReaderOptions? options = null) { - streams.CheckNotNull(nameof(streams)); + streams.NotNull(nameof(streams)); return new MultiVolumeRarReader(streams, options ?? new ReaderOptions()); } diff --git a/src/SharpCompress/Readers/ReaderFactory.cs b/src/SharpCompress/Readers/ReaderFactory.cs index 9830c8fb..97846380 100644 --- a/src/SharpCompress/Readers/ReaderFactory.cs +++ b/src/SharpCompress/Readers/ReaderFactory.cs @@ -11,7 +11,7 @@ public static class ReaderFactory { public static IReader Open(string filePath, ReaderOptions? options = null) { - filePath.CheckNotNullOrEmpty(nameof(filePath)); + filePath.NotNullOrEmpty(nameof(filePath)); return Open(new FileInfo(filePath), options); } @@ -29,7 +29,7 @@ public static class ReaderFactory /// public static IReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); options ??= new ReaderOptions() { LeaveStreamOpen = false }; var bStream = new SharpCompressStream(stream, bufferSize: options.BufferSize); diff --git a/src/SharpCompress/Readers/Tar/TarReader.cs b/src/SharpCompress/Readers/Tar/TarReader.cs index aaa0005c..c9218885 100644 --- a/src/SharpCompress/Readers/Tar/TarReader.cs +++ b/src/SharpCompress/Readers/Tar/TarReader.cs @@ -55,7 +55,7 @@ public class TarReader : AbstractReader /// public static TarReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); options = options ?? new ReaderOptions(); var rewindableStream = new SharpCompressStream(stream); diff --git a/src/SharpCompress/Readers/Zip/ZipReader.cs b/src/SharpCompress/Readers/Zip/ZipReader.cs index cda3f3f8..5e82479c 100644 --- a/src/SharpCompress/Readers/Zip/ZipReader.cs +++ b/src/SharpCompress/Readers/Zip/ZipReader.cs @@ -44,7 +44,7 @@ public class ZipReader : AbstractReader /// public static ZipReader Open(Stream stream, ReaderOptions? options = null) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); return new ZipReader(stream, options ?? new ReaderOptions()); } @@ -54,7 +54,7 @@ public class ZipReader : AbstractReader IEnumerable entries ) { - stream.CheckNotNull(nameof(stream)); + stream.NotNull(nameof(stream)); return new ZipReader(stream, options ?? new ReaderOptions(), entries); } diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 6af66164..7c8294c5 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -35,9 +35,14 @@ $(DefineConstants);DEBUG_STREAMS - + + + + + + diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 74974850..19e132d5 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -1,4 +1,3 @@ -global using SharpCompress.Helpers; using System; using System.Buffers; using System.Collections.Generic; @@ -7,10 +6,14 @@ using System.IO; using System.Text; using SharpCompress.Readers; -namespace SharpCompress.Helpers; +namespace SharpCompress; internal static class Utility { + //80kb is a good industry standard temporary buffer size + private const int TEMP_BUFFER_SIZE = 81920; + private static readonly HashSet invalidChars = new(Path.GetInvalidFileNameChars()); + public static ReadOnlyCollection ToReadOnly(this IList items) => new(items); /// @@ -68,60 +71,11 @@ internal static class Utility } } - public static void Copy( - Array sourceArray, - long sourceIndex, - Array destinationArray, - long destinationIndex, - long length - ) - { - if (sourceIndex > int.MaxValue || sourceIndex < int.MinValue) - { - throw new ArgumentOutOfRangeException(nameof(sourceIndex)); - } - - if (destinationIndex > int.MaxValue || destinationIndex < int.MinValue) - { - throw new ArgumentOutOfRangeException(nameof(destinationIndex)); - } - - if (length > int.MaxValue || length < int.MinValue) - { - throw new ArgumentOutOfRangeException(nameof(length)); - } - - Array.Copy( - sourceArray, - (int)sourceIndex, - destinationArray, - (int)destinationIndex, - (int)length - ); - } - public static IEnumerable AsEnumerable(this T item) { yield return item; } - public static void CheckNotNull(this object obj, string name) - { - if (obj is null) - { - throw new ArgumentNullException(name); - } - } - - public static void CheckNotNullOrEmpty(this string obj, string name) - { - obj.CheckNotNull(name); - if (obj.Length == 0) - { - throw new ArgumentException("String is empty.", name); - } - } - public static void Skip(this Stream source, long advanceAmount) { if (source.CanSeek) @@ -130,79 +84,23 @@ internal static class Utility return; } - var buffer = GetTransferByteArray(); - try + using var buffer = MemoryPool.Shared.Rent(TEMP_BUFFER_SIZE); + while (advanceAmount > 0) { - var read = 0; - var readCount = 0; - do + var toRead = (int)Math.Min(buffer.Memory.Length, advanceAmount); + var read = source.Read(buffer.Memory.Slice(0, toRead).Span); + if (read <= 0) { - readCount = buffer.Length; - if (readCount > advanceAmount) - { - readCount = (int)advanceAmount; - } - read = source.Read(buffer, 0, readCount); - if (read <= 0) - { - break; - } - advanceAmount -= read; - if (advanceAmount == 0) - { - break; - } - } while (true); - } - finally - { - ArrayPool.Shared.Return(buffer); + break; + } + advanceAmount -= read; } } public static void Skip(this Stream source) { - var buffer = GetTransferByteArray(); - try - { - do { } while (source.Read(buffer, 0, buffer.Length) == buffer.Length); - } - finally - { - ArrayPool.Shared.Return(buffer); - } - } - - public static bool Find(this Stream source, byte[] array) - { - var buffer = GetTransferByteArray(); - try - { - var count = 0; - var len = source.Read(buffer, 0, buffer.Length); - - do - { - for (var i = 0; i < len; i++) - { - if (array[count] == buffer[i]) - { - count++; - if (count == array.Length) - { - source.Position = source.Position - len + i - array.Length + 1; - return true; - } - } - } - } while ((len = source.Read(buffer, 0, buffer.Length)) > 0); - } - finally - { - ArrayPool.Shared.Return(buffer); - } - - return false; + using var buffer = MemoryPool.Shared.Rent(TEMP_BUFFER_SIZE); + while (source.Read(buffer.Memory.Span) > 0) { } } public static DateTime DosDateToDateTime(ushort iDate, ushort iTime) @@ -271,31 +169,12 @@ internal static class Utility return sTime.AddSeconds(unixtime); } - public static long TransferTo(this Stream source, Stream destination) - { - var array = GetTransferByteArray(); - try - { - long total = 0; - while (ReadTransferBlock(source, array, out var count)) - { - destination.Write(array, 0, count); - total += count; - } - return total; - } - finally - { - ArrayPool.Shared.Return(array); - } - } - public static long TransferTo(this Stream source, Stream destination, long maxLength) { - var array = GetTransferByteArray(); - var maxReadSize = array.Length; + var array = ArrayPool.Shared.Rent(TEMP_BUFFER_SIZE); try { + var maxReadSize = array.Length; long total = 0; var remaining = maxLength; if (remaining < maxReadSize) @@ -331,12 +210,13 @@ internal static class Utility IReaderExtractionListener readerExtractionListener ) { - var array = GetTransferByteArray(); + var array = ArrayPool.Shared.Rent(TEMP_BUFFER_SIZE); try { var iterations = 0; long total = 0; - while (ReadTransferBlock(source, array, out var count)) + int count; + while ((count = source.Read(array, 0, array.Length)) != 0) { total += count; destination.Write(array, 0, count); @@ -351,12 +231,10 @@ internal static class Utility } } - private static bool ReadTransferBlock(Stream source, byte[] array, out int count) => - (count = source.Read(array, 0, array.Length)) != 0; - - private static bool ReadTransferBlock(Stream source, byte[] array, int size, out int count) + private static bool ReadTransferBlock(Stream source, byte[] array, int maxSize, out int count) { - if (size > array.Length) + var size = maxSize; + if (maxSize > array.Length) { size = array.Length; } @@ -364,8 +242,34 @@ internal static class Utility return count != 0; } - private static byte[] GetTransferByteArray() => ArrayPool.Shared.Rent(81920); +#if NET60_OR_GREATER + public static bool ReadFully(this Stream stream, byte[] buffer) + { + try + { + stream.ReadExactly(buffer); + return true; + } + catch (EndOfStreamException) + { + return false; + } + } + + public static bool ReadFully(this Stream stream, Span buffer) + { + try + { + stream.ReadExactly(buffer); + return true; + } + catch (EndOfStreamException) + { + return false; + } + } +#else public static bool ReadFully(this Stream stream, byte[] buffer) { var total = 0; @@ -395,6 +299,7 @@ internal static class Utility } return (total >= buffer.Length); } +#endif public static string TrimNulls(this string source) => source.Replace('\0', ' ').Trim(); @@ -439,7 +344,6 @@ internal static class Utility public static string ReplaceInvalidFileNameChars(string fileName) { - var invalidChars = new HashSet(Path.GetInvalidFileNameChars()); var sb = new StringBuilder(fileName.Length); foreach (var c in fileName) { diff --git a/src/SharpCompress/Writers/GZip/GZipWriter.cs b/src/SharpCompress/Writers/GZip/GZipWriter.cs index 4fbf1bb9..7dd4a7de 100644 --- a/src/SharpCompress/Writers/GZip/GZipWriter.cs +++ b/src/SharpCompress/Writers/GZip/GZipWriter.cs @@ -47,7 +47,7 @@ public sealed class GZipWriter : AbstractWriter var stream = (GZipStream)OutputStream; stream.FileName = filename; stream.LastModified = modificationTime; - source.TransferTo(stream); + source.CopyTo(stream); _wroteToStream = true; } } diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs index 55abe440..f1572823 100644 --- a/src/SharpCompress/Writers/Zip/ZipWriter.cs +++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs @@ -83,7 +83,7 @@ public class ZipWriter : AbstractWriter public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions) { using var output = WriteToStream(entryPath, zipWriterEntryOptions); - source.TransferTo(output); + source.CopyTo(output); } public Stream WriteToStream(string entryPath, ZipWriterEntryOptions options) diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index 8230141d..9ebb1677 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -2,6 +2,15 @@ "version": 2, "dependencies": { ".NETFramework,Version=v4.8": { + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", "requested": "[1.0.3, )", @@ -23,9 +32,30 @@ }, "System.Buffers": { "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" + "requested": "[4.6.1, )", + "resolved": "4.6.1", + "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" + }, + "System.Memory": { + "type": "Direct", + "requested": "[4.6.3, )", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", + "dependencies": { + "System.Buffers": "4.6.1", + "System.Numerics.Vectors": "4.6.1", + "System.Runtime.CompilerServices.Unsafe": "6.1.2" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "ZstdSharp.Port": { "type": "Direct", @@ -55,13 +85,13 @@ }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + "resolved": "4.6.1", + "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + "resolved": "6.1.2", + "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", @@ -70,29 +100,18 @@ "dependencies": { "System.Runtime.CompilerServices.Unsafe": "4.5.3" } - }, + } + }, + ".NETFramework,Version=v4.8.1": { "Microsoft.Bcl.AsyncInterfaces": { - "type": "CentralTransitive", + "type": "Direct", "requested": "[8.0.0, )", - "resolved": "5.0.0", - "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.5.5", - "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", - "dependencies": { - "System.Buffers": "4.5.1", - "System.Numerics.Vectors": "4.5.0", - "System.Runtime.CompilerServices.Unsafe": "4.5.3" - } - } - }, - ".NETFramework,Version=v4.8.1": { "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", "requested": "[1.0.3, )", @@ -114,9 +133,30 @@ }, "System.Buffers": { "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" + "requested": "[4.6.1, )", + "resolved": "4.6.1", + "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" + }, + "System.Memory": { + "type": "Direct", + "requested": "[4.6.3, )", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", + "dependencies": { + "System.Buffers": "4.6.1", + "System.Numerics.Vectors": "4.6.1", + "System.Runtime.CompilerServices.Unsafe": "6.1.2" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } }, "ZstdSharp.Port": { "type": "Direct", @@ -146,13 +186,13 @@ }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + "resolved": "4.6.1", + "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + "resolved": "6.1.2", + "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", @@ -161,26 +201,6 @@ "dependencies": { "System.Runtime.CompilerServices.Unsafe": "4.5.3" } - }, - "Microsoft.Bcl.AsyncInterfaces": { - "type": "CentralTransitive", - "requested": "[8.0.0, )", - "resolved": "5.0.0", - "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==", - "dependencies": { - "System.Threading.Tasks.Extensions": "4.5.4" - } - }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.5.5", - "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", - "dependencies": { - "System.Buffers": "4.5.1", - "System.Numerics.Vectors": "4.5.0", - "System.Runtime.CompilerServices.Unsafe": "4.5.3" - } } }, ".NETStandard,Version=v2.0": { @@ -193,15 +213,6 @@ "System.Threading.Tasks.Extensions": "4.5.4" } }, - "Microsoft.NETFramework.ReferenceAssemblies": { - "type": "Direct", - "requested": "[1.0.3, )", - "resolved": "1.0.3", - "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", - "dependencies": { - "Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3" - } - }, "Microsoft.SourceLink.GitHub": { "type": "Direct", "requested": "[8.0.0, )", @@ -221,21 +232,15 @@ "Microsoft.NETCore.Platforms": "1.1.0" } }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" - }, "System.Memory": { "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==", + "requested": "[4.6.3, )", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", "dependencies": { - "System.Buffers": "4.6.0", - "System.Numerics.Vectors": "4.6.0", - "System.Runtime.CompilerServices.Unsafe": "6.1.0" + "System.Buffers": "4.6.1", + "System.Numerics.Vectors": "4.6.1", + "System.Runtime.CompilerServices.Unsafe": "6.1.2" } }, "System.Text.Encoding.CodePages": { @@ -269,11 +274,6 @@ "resolved": "1.1.0", "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" }, - "Microsoft.NETFramework.ReferenceAssemblies.net461": { - "type": "Transitive", - "resolved": "1.0.3", - "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" - }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "8.0.0", @@ -281,13 +281,13 @@ }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.6.0", - "contentHash": "t+SoieZsRuEyiw/J+qXUbolyO219tKQQI0+2/YI+Qv7YdGValA6WiuokrNKqjrTNsy5ABWU11bdKOzUdheteXg==" + "resolved": "4.6.1", + "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.1.0", - "contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg==" + "resolved": "6.1.2", + "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", @@ -296,18 +296,15 @@ "dependencies": { "System.Runtime.CompilerServices.Unsafe": "4.5.3" } + }, + "System.Buffers": { + "type": "CentralTransitive", + "requested": "[4.6.1, )", + "resolved": "4.6.1", + "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" } }, "net6.0": { - "Microsoft.NETFramework.ReferenceAssemblies": { - "type": "Direct", - "requested": "[1.0.3, )", - "resolved": "1.0.3", - "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", - "dependencies": { - "Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3" - } - }, "Microsoft.SourceLink.GitHub": { "type": "Direct", "requested": "[8.0.0, )", @@ -318,12 +315,6 @@ "Microsoft.SourceLink.Common": "8.0.0" } }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" - }, "ZstdSharp.Port": { "type": "Direct", "requested": "[0.8.6, )", @@ -335,11 +326,6 @@ "resolved": "8.0.0", "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" }, - "Microsoft.NETFramework.ReferenceAssemblies.net461": { - "type": "Transitive", - "resolved": "1.0.3", - "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" - }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "8.0.0", @@ -353,15 +339,6 @@ "resolved": "8.0.17", "contentHash": "x5/y4l8AtshpBOrCZdlE4txw8K3e3s9meBFeZeR3l8hbbku2V7kK6ojhXvrbjg1rk3G+JqL1BI26gtgc1ZrdUw==" }, - "Microsoft.NETFramework.ReferenceAssemblies": { - "type": "Direct", - "requested": "[1.0.3, )", - "resolved": "1.0.3", - "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", - "dependencies": { - "Microsoft.NETFramework.ReferenceAssemblies.net461": "1.0.3" - } - }, "Microsoft.SourceLink.GitHub": { "type": "Direct", "requested": "[8.0.0, )", @@ -372,12 +349,6 @@ "Microsoft.SourceLink.Common": "8.0.0" } }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" - }, "ZstdSharp.Port": { "type": "Direct", "requested": "[0.8.6, )", @@ -389,11 +360,6 @@ "resolved": "8.0.0", "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" }, - "Microsoft.NETFramework.ReferenceAssemblies.net461": { - "type": "Transitive", - "resolved": "1.0.3", - "contentHash": "AmOJZwCqnOCNp6PPcf9joyogScWLtwy0M1WkqfEQ0M9nYwyDD7EX9ZjscKS5iYnyvteX7kzSKFCKt9I9dXA6mA==" - }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "8.0.0", diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs index d7c02d2d..64d69d54 100644 --- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs +++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs @@ -223,7 +223,7 @@ public class RarReaderTests : ReaderTests var destinationFileName = Path.Combine(destdir, file); using var fs = File.OpenWrite(destinationFileName); - entryStream.TransferTo(fs); + entryStream.CopyTo(fs); } } } diff --git a/tests/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj index f5516b91..2afb9938 100644 --- a/tests/SharpCompress.Test/SharpCompress.Test.csproj +++ b/tests/SharpCompress.Test/SharpCompress.Test.csproj @@ -9,6 +9,9 @@ $(DefineConstants);DEBUG_STREAMS + + $(DefineConstants);WINDOWS + @@ -17,7 +20,6 @@ - diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index a676d2da..88c30cfa 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -85,7 +85,7 @@ public class TarReaderTests : ReaderTests var destinationFileName = Path.Combine(destdir, file.NotNull()); using var fs = File.OpenWrite(destinationFileName); - entryStream.TransferTo(fs); + entryStream.CopyTo(fs); } } } diff --git a/tests/SharpCompress.Test/TestBase.cs b/tests/SharpCompress.Test/TestBase.cs index f9cfb8a3..184e6442 100644 --- a/tests/SharpCompress.Test/TestBase.cs +++ b/tests/SharpCompress.Test/TestBase.cs @@ -1,4 +1,3 @@ -global using SharpCompress.Helpers; using System; using System.Collections.Generic; using System.IO; diff --git a/tests/SharpCompress.Test/UtilityTests.cs b/tests/SharpCompress.Test/UtilityTests.cs new file mode 100644 index 00000000..cbd57304 --- /dev/null +++ b/tests/SharpCompress.Test/UtilityTests.cs @@ -0,0 +1,754 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Xunit; + +namespace SharpCompress.Test; + +public class UtilityTests +{ + #region URShift Tests + + [Fact] + public void URShift_Int_PositiveNumber_ShiftsCorrectly() + { + var result = Utility.URShift(16, 2); + Assert.Equal(4, result); + } + + [Fact] + public void URShift_Int_NegativeNumber_PerformsUnsignedShift() + { + // -1 in binary is all 1s (0xFFFFFFFF), shifted right by 1 should be 0x7FFFFFFF + var result = Utility.URShift(-1, 1); + Assert.Equal(int.MaxValue, result); + } + + [Fact] + public void URShift_Int_Zero_ReturnsZero() + { + var result = Utility.URShift(0, 5); + Assert.Equal(0, result); + } + + [Fact] + public void URShift_Long_PositiveNumber_ShiftsCorrectly() + { + var result = Utility.URShift(32L, 3); + Assert.Equal(4L, result); + } + + [Fact] + public void URShift_Long_NegativeNumber_PerformsUnsignedShift() + { + var result = Utility.URShift(-1L, 1); + Assert.Equal(long.MaxValue, result); + } + + [Fact] + public void URShift_Long_Zero_ReturnsZero() + { + var result = Utility.URShift(0L, 10); + Assert.Equal(0L, result); + } + + #endregion + + #region ReadFully Tests + + [Fact] + public void ReadFully_ByteArray_ReadsExactlyRequiredBytes() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + var buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.True(result); + Assert.Equal(data, buffer); + } + + [Fact] + public void ReadFully_ByteArray_ReturnsFalseWhenNotEnoughData() + { + var data = new byte[] { 1, 2, 3 }; + using var stream = new MemoryStream(data); + var buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.False(result); + } + + [Fact] + public void ReadFully_ByteArray_EmptyStream_ReturnsFalse() + { + using var stream = new MemoryStream(); + var buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.False(result); + } + + [Fact] + public void ReadFully_ByteArray_EmptyBuffer_ReturnsTrue() + { + var data = new byte[] { 1, 2, 3 }; + using var stream = new MemoryStream(data); + var buffer = new byte[0]; + + var result = stream.ReadFully(buffer); + + Assert.True(result); + } + + [Fact] + public void ReadFully_Span_ReadsExactlyRequiredBytes() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + Span buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.True(result); + Assert.Equal(data, buffer.ToArray()); + } + + [Fact] + public void ReadFully_Span_ReturnsFalseWhenNotEnoughData() + { + var data = new byte[] { 1, 2, 3 }; + using var stream = new MemoryStream(data); + Span buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.False(result); + } + + [Fact] + public void ReadFully_Span_EmptyStream_ReturnsFalse() + { + using var stream = new MemoryStream(); + Span buffer = new byte[5]; + + var result = stream.ReadFully(buffer); + + Assert.False(result); + } + + [Fact] + public void ReadFully_Span_EmptyBuffer_ReturnsTrue() + { + var data = new byte[] { 1, 2, 3 }; + using var stream = new MemoryStream(data); + Span buffer = new byte[0]; + + var result = stream.ReadFully(buffer); + + Assert.True(result); + } + + #endregion + + #region Skip Tests + + [Fact] + public void Skip_SeekableStream_UsesSeek() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + + stream.Skip(3); + + Assert.Equal(3, stream.Position); + } + + [Fact] + public void Skip_SeekableStream_SkipsCorrectAmount() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + + stream.Skip(2); + var buffer = new byte[2]; + stream.Read(buffer); + + Assert.Equal(new byte[] { 3, 4 }, buffer); + } + + [Fact] + public void Skip_NonSeekableStream_SkipsCorrectAmount() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var seekableStream = new MemoryStream(data); + using var nonSeekableStream = new NonSeekableStream(seekableStream); + + nonSeekableStream.Skip(2); + var buffer = new byte[2]; + nonSeekableStream.Read(buffer); + + Assert.Equal(new byte[] { 3, 4 }, buffer); + } + + [Fact] + public void Skip_NonSeekableStream_SkipsBeyondStreamEnd() + { + var data = new byte[] { 1, 2, 3 }; + using var seekableStream = new MemoryStream(data); + using var nonSeekableStream = new NonSeekableStream(seekableStream); + + // Should not throw, just skip what's available + nonSeekableStream.Skip(10); + + Assert.Equal(-1, nonSeekableStream.ReadByte()); + } + + [Fact] + public void Skip_Parameterless_SkipsEntireStream() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + + stream.Skip(); + + Assert.Equal(-1, stream.ReadByte()); + } + + [Fact] + public void Skip_Zero_DoesNotMove() + { + var data = new byte[] { 1, 2, 3, 4, 5 }; + using var stream = new MemoryStream(data); + stream.Position = 2; + + stream.Skip(0); + + Assert.Equal(2, stream.Position); + } + + #endregion + + #region SetSize Tests + + [Fact] + public void SetSize_GrowsList_AddsZeroBytes() + { + var list = new List { 1, 2, 3 }; + + Utility.SetSize(list, 5); + + Assert.Equal(5, list.Count); + Assert.Equal(new byte[] { 1, 2, 3, 0, 0 }, list); + } + + [Fact] + public void SetSize_ShrinksListByOne() + { + var list = new List { 1, 2, 3, 4, 5 }; + + Utility.SetSize(list, 3); + + Assert.Equal(3, list.Count); + Assert.Equal(new byte[] { 1, 2, 3 }, list); + } + + [Fact] + public void SetSize_ToZero_ClearsAllItems() + { + var list = new List { 1, 2, 3 }; + + Utility.SetSize(list, 0); + + Assert.Empty(list); + } + + [Fact] + public void SetSize_SameSize_NoChange() + { + var list = new List { 1, 2, 3 }; + + Utility.SetSize(list, 3); + + Assert.Equal(3, list.Count); + Assert.Equal(new byte[] { 1, 2, 3 }, list); + } + + #endregion + + #region ForEach Tests + + [Fact] + public void ForEach_ExecutesActionForEachItem() + { + var items = new[] { 1, 2, 3, 4, 5 }; + var results = new List(); + + items.ForEach(x => results.Add(x)); + + Assert.Equal(items, results); + } + + [Fact] + public void ForEach_EmptyCollection_NoExecutions() + { + var items = Array.Empty(); + var count = 0; + + items.ForEach(x => count++); + + Assert.Equal(0, count); + } + + #endregion + + #region AsEnumerable Tests + + [Fact] + public void AsEnumerable_SingleItem_YieldsItem() + { + var item = 42; + + var result = item.AsEnumerable().ToList(); + + Assert.Single(result); + Assert.Equal(42, result[0]); + } + + [Fact] + public void AsEnumerable_String_YieldsString() + { + var item = "test"; + + var result = item.AsEnumerable().ToList(); + + Assert.Single(result); + Assert.Equal("test", result[0]); + } + + #endregion + + #region DosDateToDateTime Tests + + [Fact] + public void DosDateToDateTime_ValidDate_ConvertsCorrectly() + { + // DOS date format: year (7 bits) | month (4 bits) | day (5 bits) + // DOS time format: hour (5 bits) | minute (6 bits) | second (5 bits, in 2-second increments) + // This represents: 2020-01-15 10:30:20 (approximately) + ushort dosDate = (ushort)(((2020 - 1980) << 9) | (1 << 5) | 15); // 2020-01-15 + ushort dosTime = (ushort)((10 << 11) | (30 << 5) | 10); // 10:30:20 + + var result = Utility.DosDateToDateTime(dosDate, dosTime); + + Assert.Equal(2020, result.Year); + Assert.Equal(1, result.Month); + Assert.Equal(15, result.Day); + Assert.Equal(10, result.Hour); + Assert.Equal(30, result.Minute); + Assert.Equal(20, result.Second); + } + + [Fact] + public void DosDateToDateTime_InvalidDate_DefaultsTo1980_01_01() + { + ushort dosDate = ushort.MaxValue; + ushort dosTime = (ushort)((10 << 11) | (30 << 5) | 10); + + var result = Utility.DosDateToDateTime(dosDate, dosTime); + + Assert.Equal(1980, result.Year); + Assert.Equal(1, result.Month); + Assert.Equal(1, result.Day); + } + + [Fact] + public void DosDateToDateTime_InvalidTime_DefaultsToMidnight() + { + ushort dosDate = (ushort)(((2020 - 1980) << 9) | (1 << 5) | 15); + ushort dosTime = ushort.MaxValue; + + var result = Utility.DosDateToDateTime(dosDate, dosTime); + + Assert.Equal(0, result.Hour); + Assert.Equal(0, result.Minute); + Assert.Equal(0, result.Second); + } + + [Fact] + public void DosDateToDateTime_FromUint_ConvertsCorrectly() + { + ushort dosDate = (ushort)(((2020 - 1980) << 9) | (6 << 5) | 20); // 2020-06-20 + ushort dosTime = (ushort)((14 << 11) | (45 << 5) | 15); // 14:45:30 + uint combined = (uint)(dosDate << 16) | dosTime; + + var result = Utility.DosDateToDateTime(combined); + + Assert.Equal(2020, result.Year); + Assert.Equal(6, result.Month); + Assert.Equal(20, result.Day); + Assert.Equal(14, result.Hour); + Assert.Equal(45, result.Minute); + } + + #endregion + + #region DateTimeToDosTime Tests + + [Fact] + public void DateTimeToDosTime_ValidDateTime_ConvertsCorrectly() + { + //always do local time + var dt = new DateTime(2020, 6, 15, 14, 30, 20, DateTimeKind.Local); + + var result = Utility.DateTimeToDosTime(dt); + + // Verify we can convert back + var reversed = Utility.DosDateToDateTime(result); + Assert.Equal(2020, reversed.Year); + Assert.Equal(6, reversed.Month); + Assert.Equal(15, reversed.Day); + Assert.Equal(14, reversed.Hour); + Assert.Equal(30, reversed.Minute); + // Seconds are rounded down to nearest even number in DOS format + Assert.True(reversed.Second == 20 || reversed.Second == 18); + } + + [Fact] + public void DateTimeToDosTime_NullDateTime_ReturnsZero() + { + DateTime? dt = null; + + var result = Utility.DateTimeToDosTime(dt); + + Assert.Equal(0u, result); + } + + #endregion + + #region UnixTimeToDateTime Tests + + [Fact] + public void UnixTimeToDateTime_Zero_Returns1970_01_01() + { + var result = Utility.UnixTimeToDateTime(0); + + Assert.Equal(1970, result.Year); + Assert.Equal(1, result.Month); + Assert.Equal(1, result.Day); + Assert.Equal(0, result.Hour); + Assert.Equal(0, result.Minute); + Assert.Equal(0, result.Second); + } + + [Fact] + public void UnixTimeToDateTime_ValidTimestamp_ConvertsCorrectly() + { + // January 1, 2000 00:00:00 UTC is 946684800 seconds after epoch + var result = Utility.UnixTimeToDateTime(946684800); + + Assert.Equal(2000, result.Year); + Assert.Equal(1, result.Month); + Assert.Equal(1, result.Day); + } + + [Fact] + public void UnixTimeToDateTime_NegativeTimestamp_ReturnsBeforeEpoch() + { + // -86400 is one day before epoch + var result = Utility.UnixTimeToDateTime(-86400); + + Assert.Equal(1969, result.Year); + Assert.Equal(12, result.Month); + Assert.Equal(31, result.Day); + } + + #endregion + + #region TransferTo Tests + + [Fact] + public void TransferTo_WithMaxLength_TransfersCorrectAmount() + { + var sourceData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + using var source = new MemoryStream(sourceData); + using var destination = new MemoryStream(); + + var transferred = source.TransferTo(destination, 5); + + Assert.Equal(5, transferred); + Assert.Equal(new byte[] { 1, 2, 3, 4, 5 }, destination.ToArray()); + } + + [Fact] + public void TransferTo_SourceSmallerThanMax_TransfersAll() + { + var sourceData = new byte[] { 1, 2, 3 }; + using var source = new MemoryStream(sourceData); + using var destination = new MemoryStream(); + + var transferred = source.TransferTo(destination, 100); + + Assert.Equal(3, transferred); + Assert.Equal(sourceData, destination.ToArray()); + } + + [Fact] + public void TransferTo_EmptySource_TransfersNothing() + { + using var source = new MemoryStream(); + using var destination = new MemoryStream(); + + var transferred = source.TransferTo(destination, 100); + + Assert.Equal(0, transferred); + Assert.Empty(destination.ToArray()); + } + + #endregion + + #region SwapUINT32 Tests + + [Fact] + public void SwapUINT32_SimpleValue_SwapsEndianness() + { + uint value = 0x12345678; + + var result = Utility.SwapUINT32(value); + + Assert.Equal(0x78563412u, result); + } + + [Fact] + public void SwapUINT32_Zero_ReturnsZero() + { + var result = Utility.SwapUINT32(0); + + Assert.Equal(0u, result); + } + + [Fact] + public void SwapUINT32_MaxValue_SwapsCorrectly() + { + var result = Utility.SwapUINT32(uint.MaxValue); + + Assert.Equal(uint.MaxValue, result); + } + + [Fact] + public void SwapUINT32_Involution_SwappingTwiceReturnsOriginal() + { + uint value = 0x12345678; + + var result = Utility.SwapUINT32(Utility.SwapUINT32(value)); + + Assert.Equal(value, result); + } + + #endregion + + #region SetLittleUInt32 Tests + + [Fact] + public void SetLittleUInt32_InsertsValueCorrectly() + { + byte[] buffer = new byte[10]; + uint value = 0x12345678; + + Utility.SetLittleUInt32(ref buffer, value, 2); + + Assert.Equal(0x78, buffer[2]); + Assert.Equal(0x56, buffer[3]); + Assert.Equal(0x34, buffer[4]); + Assert.Equal(0x12, buffer[5]); + } + + [Fact] + public void SetLittleUInt32_AtOffset_InsertsBehindOffset() + { + byte[] buffer = new byte[10]; + uint value = 0xDEADBEEF; + + Utility.SetLittleUInt32(ref buffer, value, 5); + + Assert.Equal(0xEF, buffer[5]); + Assert.Equal(0xBE, buffer[6]); + Assert.Equal(0xAD, buffer[7]); + Assert.Equal(0xDE, buffer[8]); + } + + #endregion + + #region SetBigUInt32 Tests + + [Fact] + public void SetBigUInt32_InsertsValueCorrectly() + { + byte[] buffer = new byte[10]; + uint value = 0x12345678; + + Utility.SetBigUInt32(ref buffer, value, 2); + + Assert.Equal(0x12, buffer[2]); + Assert.Equal(0x34, buffer[3]); + Assert.Equal(0x56, buffer[4]); + Assert.Equal(0x78, buffer[5]); + } + + [Fact] + public void SetBigUInt32_AtOffset_InsertsBehindOffset() + { + byte[] buffer = new byte[10]; + uint value = 0xDEADBEEF; + + Utility.SetBigUInt32(ref buffer, value, 5); + + Assert.Equal(0xDE, buffer[5]); + Assert.Equal(0xAD, buffer[6]); + Assert.Equal(0xBE, buffer[7]); + Assert.Equal(0xEF, buffer[8]); + } + + #endregion + + #region ReplaceInvalidFileNameChars Tests + +#if WINDOWS + [Theory] + [InlineData("valid_filename.txt", "valid_filename.txt")] + [InlineData("filetest.txt", "file_name_test.txt")] + [InlineData("<>:\"|?*", "_______")] + public void ReplaceInvalidFileNameChars_Windows(string fileName, string expected) + { + var result = Utility.ReplaceInvalidFileNameChars(fileName); + + Assert.Equal(expected, result); + } + +#else + [Theory] + [InlineData("valid_filename.txt", "valid_filename.txt")] + [InlineData("filetest.txt", "filetest.txt")] + [InlineData("<>:\"|?*", "<>:\"|?*")] + public void ReplaceInvalidFileNameChars_NonWindows(string fileName, string expected) + { + var result = Utility.ReplaceInvalidFileNameChars(fileName); + + Assert.Equal(expected, result); + } +#endif + + #endregion + + #region ToReadOnly Tests + + [Fact] + public void ToReadOnly_IList_ReturnsReadOnlyCollection() + { + var list = new List { 1, 2, 3, 4, 5 }; + + var result = list.ToReadOnly(); + + Assert.Equal(5, result.Count); + Assert.Equal(1, result[0]); + Assert.Equal(5, result[4]); + } + + [Fact] + public void ToReadOnly_EmptyList_ReturnsEmptyReadOnlyCollection() + { + var list = new List(); + + var result = list.ToReadOnly(); + + Assert.Empty(result); + } + + #endregion + + #region TrimNulls Tests + + [Fact] + public void TrimNulls_StringWithNulls_ReplacesAndTrims() + { + var input = " hello\0world\0 "; + + var result = Utility.TrimNulls(input); + + Assert.Equal("hello world", result); + } + + [Fact] + public void TrimNulls_StringWithoutNulls_TrimsWhitespace() + { + var input = " hello world "; + + var result = Utility.TrimNulls(input); + + Assert.Equal("hello world", result); + } + + [Fact] + public void TrimNulls_OnlyNulls_ReturnsEmpty() + { + var input = "\0\0\0"; + + var result = Utility.TrimNulls(input); + + Assert.Empty(result); + } + + #endregion +} + +/// +/// Helper class for testing non-seekable streams +/// +internal class NonSeekableStream : Stream +{ + private readonly Stream _inner; + + public NonSeekableStream(Stream inner) + { + _inner = inner; + } + + public override bool CanRead => _inner.CanRead; + public override bool CanSeek => false; // Force non-seekable + public override bool CanWrite => _inner.CanWrite; + public override long Length => _inner.Length; + public override long Position + { + get => _inner.Position; + set => throw new NotSupportedException("Stream is not seekable"); + } + + public override void Flush() => _inner.Flush(); + + public override int Read(byte[] buffer, int offset, int count) => + _inner.Read(buffer, offset, count); + + public override long Seek(long offset, SeekOrigin origin) => + throw new NotSupportedException("Stream is not seekable"); + + public override void SetLength(long value) => + throw new NotSupportedException("Stream is not seekable"); + + public override void Write(byte[] buffer, int offset, int count) => + _inner.Write(buffer, offset, count); + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _inner.Dispose(); + } + base.Dispose(disposing); + } +} diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 53849e46..a2a1c0cc 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -589,12 +589,10 @@ public class ZipArchiveTests : ArchiveTests } } - [SkippableFact] - public void Zip_Evil_Throws_Exception() +#if WINDOWS + [Fact] + public void Zip_Evil_Throws_Exception_Windows() { - //windows only because of the paths - Skip.IfNot(Environment.OSVersion.Platform == PlatformID.Win32NT); - var zipFile = Path.Combine(TEST_ARCHIVES_PATH, "Zip.Evil.zip"); Assert.ThrowsAny(() => @@ -609,6 +607,7 @@ public class ZipArchiveTests : ArchiveTests } }); } +#endif private class NonSeekableMemoryStream : MemoryStream { diff --git a/tests/SharpCompress.Test/packages.lock.json b/tests/SharpCompress.Test/packages.lock.json index 511e7921..284e7c59 100644 --- a/tests/SharpCompress.Test/packages.lock.json +++ b/tests/SharpCompress.Test/packages.lock.json @@ -4,20 +4,20 @@ ".NETFramework,Version=v4.8": { "AwesomeAssertions": { "type": "Direct", - "requested": "[9.2.0, )", - "resolved": "9.2.0", - "contentHash": "RCkuFyKmesmZR74XLOzYvTpG/IbHfBeFapFTMvFskPzEK4z3YrVmHB2FIFJ0DhwjuIDdPL/hc8zS40IwMAN0BA==", + "requested": "[9.2.1, )", + "resolved": "9.2.1", + "contentHash": "lbwhyQNXxxEGx4oCbFqNfFy2DsywsvNhN6qoOjY4wwhMgI2L9+YrxjyF/M0io99yrvWV1Cjj12LP2QGcC43Uhw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.13.0, )", - "resolved": "17.13.0", - "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", + "requested": "[18.0.0, )", + "resolved": "18.0.0", + "contentHash": "bvxj2Asb7nT+tqOFFerrhQeEjUYLwx0Poi0Rznu63WbqN+A4uDn1t5NWXfAOOQsF6lpmK6N2v+Vvgso7KWZS7g==", "dependencies": { - "Microsoft.CodeCoverage": "17.13.0" + "Microsoft.CodeCoverage": "18.0.0" } }, "Microsoft.NETFramework.ReferenceAssemblies": { @@ -49,20 +49,10 @@ "Microsoft.TestPlatform.ObjectModel": "17.13.0" } }, - "Xunit.SkippableFact": { - "type": "Direct", - "requested": "[1.5.23, )", - "resolved": "1.5.23", - "contentHash": "JlKobLTlsGcuJ8OtoodxL63bUagHSVBnF+oQ2GgnkwNqK+XYjeYyhQasULi5Ebx1MNDGNbOMplQYr89mR+nItQ==", - "dependencies": { - "Validation": "2.5.51", - "xunit.extensibility.execution": "2.4.0" - } - }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.13.0", - "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" + "resolved": "18.0.0", + "contentHash": "DFPhMrsIofgJ1DDU3ModqqRArDm15/bNl4ecmcuBspZkZ4ONYnCC0R8U27WzK7cYv6r8l6Q/fRmvg7cb+I/dJA==" }, "Microsoft.NETFramework.ReferenceAssemblies.net48": { "type": "Transitive", @@ -84,8 +74,8 @@ }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.5.0", - "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + "resolved": "4.6.1", + "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" }, "System.Reflection.Metadata": { "type": "Transitive", @@ -97,8 +87,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + "resolved": "6.1.2", + "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", @@ -108,11 +98,6 @@ "System.Runtime.CompilerServices.Unsafe": "4.5.3" } }, - "Validation": { - "type": "Transitive", - "resolved": "2.5.51", - "contentHash": "g/Aug7PVWaenlJ0QUyt/mEetngkQNsMCuNeRVXbcJED1nZS7JcK+GTU4kz3jcQ7bFuKfi8PF4ExXH7XSFNuSLQ==" - }, "xunit.abstractions": { "type": "Transitive", "resolved": "2.0.3", @@ -156,34 +141,47 @@ "sharpcompress": { "type": "Project", "dependencies": { - "System.Buffers": "[4.6.0, )", + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.Buffers": "[4.6.1, )", + "System.Memory": "[4.6.3, )", + "System.Text.Encoding.CodePages": "[8.0.0, )", "ZstdSharp.Port": "[0.8.6, )" } }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", "requested": "[8.0.0, )", - "resolved": "5.0.0", - "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } }, "System.Buffers": { "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" + "requested": "[4.6.1, )", + "resolved": "4.6.1", + "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" }, "System.Memory": { "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.5.5", - "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "requested": "[4.6.3, )", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", "dependencies": { - "System.Buffers": "4.5.1", - "System.Numerics.Vectors": "4.5.0", - "System.Runtime.CompilerServices.Unsafe": "4.5.3" + "System.Buffers": "4.6.1", + "System.Numerics.Vectors": "4.6.1", + "System.Runtime.CompilerServices.Unsafe": "6.1.2" + } + }, + "System.Text.Encoding.CodePages": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "ZstdSharp.Port": { @@ -201,18 +199,18 @@ "net8.0": { "AwesomeAssertions": { "type": "Direct", - "requested": "[9.2.0, )", - "resolved": "9.2.0", - "contentHash": "RCkuFyKmesmZR74XLOzYvTpG/IbHfBeFapFTMvFskPzEK4z3YrVmHB2FIFJ0DhwjuIDdPL/hc8zS40IwMAN0BA==" + "requested": "[9.2.1, )", + "resolved": "9.2.1", + "contentHash": "lbwhyQNXxxEGx4oCbFqNfFy2DsywsvNhN6qoOjY4wwhMgI2L9+YrxjyF/M0io99yrvWV1Cjj12LP2QGcC43Uhw==" }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.13.0, )", - "resolved": "17.13.0", - "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", + "requested": "[18.0.0, )", + "resolved": "18.0.0", + "contentHash": "bvxj2Asb7nT+tqOFFerrhQeEjUYLwx0Poi0Rznu63WbqN+A4uDn1t5NWXfAOOQsF6lpmK6N2v+Vvgso7KWZS7g==", "dependencies": { - "Microsoft.CodeCoverage": "17.13.0", - "Microsoft.TestPlatform.TestHost": "17.13.0" + "Microsoft.CodeCoverage": "18.0.0", + "Microsoft.TestPlatform.TestHost": "18.0.0" } }, "Microsoft.NETFramework.ReferenceAssemblies": { @@ -247,20 +245,10 @@ "resolved": "3.1.5", "contentHash": "tKi7dSTwP4m5m9eXPM2Ime4Kn7xNf4x4zT9sdLO/G4hZVnQCRiMTWoSZqI/pYTVeI27oPPqHBKYI/DjJ9GsYgA==" }, - "Xunit.SkippableFact": { - "type": "Direct", - "requested": "[1.5.23, )", - "resolved": "1.5.23", - "contentHash": "JlKobLTlsGcuJ8OtoodxL63bUagHSVBnF+oQ2GgnkwNqK+XYjeYyhQasULi5Ebx1MNDGNbOMplQYr89mR+nItQ==", - "dependencies": { - "Validation": "2.5.51", - "xunit.extensibility.execution": "2.4.0" - } - }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.13.0", - "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" + "resolved": "18.0.0", + "contentHash": "DFPhMrsIofgJ1DDU3ModqqRArDm15/bNl4ecmcuBspZkZ4ONYnCC0R8U27WzK7cYv6r8l6Q/fRmvg7cb+I/dJA==" }, "Microsoft.NETFramework.ReferenceAssemblies.net461": { "type": "Transitive", @@ -269,35 +257,38 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.13.0", - "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", + "resolved": "18.0.0", + "contentHash": "Al/a99ymb8UdEEh6DKNiaoFn5i8fvX5PdM9LfU9Z/Q8NJrlyHHzF+LRHLbR+t89gRsJ2fFMpwYxgEn3eH1BQwA==", "dependencies": { - "System.Reflection.Metadata": "1.6.0" + "System.Reflection.Metadata": "8.0.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.13.0", - "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", + "resolved": "18.0.0", + "contentHash": "aAxE8Thr9ZHGrljOYaDeLJqitQi75iE4xeEFn6CEGFirlHSn1KwpKPniuEn6zCLZ90Z3XqNlrC3ZJTuvBov45w==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.13.0", - "Newtonsoft.Json": "13.0.1" + "Microsoft.TestPlatform.ObjectModel": "18.0.0", + "Newtonsoft.Json": "13.0.3" } }, "Newtonsoft.Json": { "type": "Transitive", - "resolved": "13.0.1", - "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" }, "System.Reflection.Metadata": { "type": "Transitive", - "resolved": "1.6.0", - "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" - }, - "Validation": { - "type": "Transitive", - "resolved": "2.5.51", - "contentHash": "g/Aug7PVWaenlJ0QUyt/mEetngkQNsMCuNeRVXbcJED1nZS7JcK+GTU4kz3jcQ7bFuKfi8PF4ExXH7XSFNuSLQ==" + "resolved": "8.0.0", + "contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==", + "dependencies": { + "System.Collections.Immutable": "8.0.0" + } }, "xunit.abstractions": { "type": "Transitive", @@ -342,16 +333,9 @@ "sharpcompress": { "type": "Project", "dependencies": { - "System.Buffers": "[4.6.0, )", "ZstdSharp.Port": "[0.8.6, )" } }, - "System.Buffers": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA==" - }, "ZstdSharp.Port": { "type": "CentralTransitive", "requested": "[0.8.6, )",