remove extra creates

This commit is contained in:
Adam Hathcock
2026-03-06 11:43:44 +00:00
parent f34ed8bd94
commit 9050a7a64a
6 changed files with 138 additions and 72 deletions

View File

@@ -34,24 +34,6 @@ public static partial class ArchiveFactory
throw new NotSupportedException("Cannot create Archives of type: " + typeof(TOptions));
}
public static ValueTask<IWritableAsyncArchive<TOptions>> CreateAsyncArchive<TOptions>(
CancellationToken cancellationToken = default
)
where TOptions : IWriterOptions
{
cancellationToken.ThrowIfCancellationRequested();
var factory = Factory
.Factories.OfType<IWritableAsyncArchiveFactory<TOptions>>()
.FirstOrDefault();
if (factory is not null)
{
return factory.CreateAsyncArchive(cancellationToken);
}
throw new NotSupportedException("Cannot create Archives of type: " + typeof(TOptions));
}
public static IArchive OpenArchive(string filePath, ReaderOptions? options = null)
{
filePath.NotNullOrEmpty(nameof(filePath));
@@ -202,14 +184,14 @@ public static partial class ArchiveFactory
return false;
}
public static ValueTask<(bool IsArchive, ArchiveType? Type)> IsArchiveAsync(
public static async ValueTask<(bool IsArchive, ArchiveType? Type)> IsArchiveAsync(
string filePath,
CancellationToken cancellationToken = default
)
{
filePath.NotNullOrEmpty(nameof(filePath));
using Stream stream = File.OpenRead(filePath);
return IsArchiveAsync(stream, cancellationToken);
return await IsArchiveAsync(stream, cancellationToken).ConfigureAwait(false);
}
public static async ValueTask<(bool IsArchive, ArchiveType? Type)> IsArchiveAsync(

View File

@@ -1,19 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common.Options;
namespace SharpCompress.Archives;
/// <summary>
/// Decorator for <see cref="Factories.Factory"/> used to declare an archive format as able to create async writable archives.
/// </summary>
public interface IWritableAsyncArchiveFactory<TOptions> : Factories.IFactory
where TOptions : IWriterOptions
{
/// <summary>
/// Creates a new, empty async archive, ready to be written.
/// </summary>
ValueTask<IWritableAsyncArchive<TOptions>> CreateAsyncArchive(
CancellationToken cancellationToken = default
);
}

View File

@@ -27,8 +27,7 @@ public class GZipFactory
IMultiArchiveFactory,
IReaderFactory,
IWriterFactory,
IWritableArchiveFactory<GZipWriterOptions>,
IWritableAsyncArchiveFactory<GZipWriterOptions>
IWritableArchiveFactory<GZipWriterOptions>
{
#region IFactory
@@ -224,14 +223,5 @@ public class GZipFactory
/// <inheritdoc/>
public IWritableArchive<GZipWriterOptions> CreateArchive() => GZipArchive.CreateArchive();
/// <inheritdoc/>
public ValueTask<IWritableAsyncArchive<GZipWriterOptions>> CreateAsyncArchive(
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return GZipArchive.CreateAsyncArchive();
}
#endregion
}

View File

@@ -25,8 +25,7 @@ public class TarFactory
IMultiArchiveFactory,
IReaderFactory,
IWriterFactory,
IWritableArchiveFactory<TarWriterOptions>,
IWritableAsyncArchiveFactory<TarWriterOptions>
IWritableArchiveFactory<TarWriterOptions>
{
#region IFactory
@@ -427,14 +426,5 @@ public class TarFactory
/// <inheritdoc/>
public IWritableArchive<TarWriterOptions> CreateArchive() => TarArchive.CreateArchive();
/// <inheritdoc/>
public ValueTask<IWritableAsyncArchive<TarWriterOptions>> CreateAsyncArchive(
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return TarArchive.CreateAsyncArchive();
}
#endregion
}

View File

@@ -24,8 +24,7 @@ public class ZipFactory
IMultiArchiveFactory,
IReaderFactory,
IWriterFactory,
IWritableArchiveFactory<ZipWriterOptions>,
IWritableAsyncArchiveFactory<ZipWriterOptions>
IWritableArchiveFactory<ZipWriterOptions>
{
#region IFactory
@@ -252,14 +251,5 @@ public class ZipFactory
/// <inheritdoc/>
public IWritableArchive<ZipWriterOptions> CreateArchive() => ZipArchive.CreateArchive();
/// <inheritdoc/>
public ValueTask<IWritableAsyncArchive<ZipWriterOptions>> CreateAsyncArchive(
CancellationToken cancellationToken = default
)
{
cancellationToken.ThrowIfCancellationRequested();
return ZipArchive.CreateAsyncArchive();
}
#endregion
}

View File

@@ -0,0 +1,133 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Factories;
using Xunit;
namespace SharpCompress.Test;
public class ArchiveFactoryTests : TestBase
{
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
[InlineData("Rar.rar", typeof(RarFactory))]
[InlineData("7Zip.nonsolid.7z", typeof(SevenZipFactory))]
public async ValueTask FindFactoryAsync_String_ReturnsExpectedFactory(
string archiveName,
System.Type expectedFactoryType
)
{
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.IsType(expectedFactoryType, factory);
}
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
[InlineData("Rar.rar", typeof(RarFactory))]
[InlineData("7Zip.nonsolid.7z", typeof(SevenZipFactory))]
public async ValueTask FindFactoryAsync_FileInfo_ReturnsExpectedFactory(
string archiveName,
System.Type expectedFactoryType
)
{
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(
new FileInfo(Path.Combine(TEST_ARCHIVES_PATH, archiveName))
);
Assert.IsType(expectedFactoryType, factory);
}
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
public async ValueTask FindFactoryAsync_Stream_PreservesPosition(
string archiveName,
System.Type expectedFactoryType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 7);
var startPosition = stream.Position;
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(stream);
Assert.IsType(expectedFactoryType, factory);
Assert.Equal(startPosition, stream.Position);
}
[Fact]
public async ValueTask FindFactoryAsync_InvalidData_ThrowsArchiveOperationException()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
await Assert.ThrowsAsync<ArchiveOperationException>(async () =>
await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(stream)
);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
[InlineData("Rar.rar", ArchiveType.Rar)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip)]
public async ValueTask IsArchiveAsync_String_ReturnsExpectedType(
string archiveName,
ArchiveType expectedType
)
{
var result = await ArchiveFactory.IsArchiveAsync(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.True(result.IsArchive);
Assert.Equal(expectedType, result.Type);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
public async ValueTask IsArchiveAsync_Stream_PreservesPosition(
string archiveName,
ArchiveType expectedType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 11);
var startPosition = stream.Position;
var result = await ArchiveFactory.IsArchiveAsync(stream);
Assert.True(result.IsArchive);
Assert.Equal(expectedType, result.Type);
Assert.Equal(startPosition, stream.Position);
}
[Fact]
public async ValueTask IsArchiveAsync_InvalidData_ReturnsFalseAndNullType()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
var result = await ArchiveFactory.IsArchiveAsync(stream);
Assert.False(result.IsArchive);
Assert.Null(result.Type);
Assert.Equal(0, stream.Position);
}
private MemoryStream CreatePrefixedArchiveStream(string archiveName, int prefixLength)
{
var archiveBytes = File.ReadAllBytes(Path.Combine(TEST_ARCHIVES_PATH, archiveName));
var buffer = new byte[prefixLength + archiveBytes.Length];
archiveBytes.CopyTo(buffer, prefixLength);
var stream = new MemoryStream(buffer);
stream.Position = prefixLength;
return stream;
}
}