Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support .NET 8.0 | Add new methods for IZipFile #386

Merged
merged 2 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 70 additions & 11 deletions Source/Testably.Abstractions.Compression/IZipFile.cs
Original file line number Diff line number Diff line change
@@ -1,61 +1,120 @@
using System.IO.Compression;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace Testably.Abstractions;

/// <inheritdoc cref="ZipFile" />
public interface IZipFile : IFileSystemEntity
{
#if FEATURE_COMPRESSION_STREAM
/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, Stream)" />
void CreateFromDirectory(
string sourceDirectoryName,
Stream destination);

/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, Stream, CompressionLevel, bool)" />
void CreateFromDirectory(
string sourceDirectoryName,
Stream destination,
CompressionLevel compressionLevel,
bool includeBaseDirectory);

/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, Stream, CompressionLevel, bool, Encoding)" />
void CreateFromDirectory(
string sourceDirectoryName,
Stream destination,
CompressionLevel compressionLevel,
bool includeBaseDirectory,
Encoding entryNameEncoding);
#endif

/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, string)" />
void CreateFromDirectory(string sourceDirectoryName,
void CreateFromDirectory(
string sourceDirectoryName,
string destinationArchiveFileName);

/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, string, CompressionLevel, bool)" />
void CreateFromDirectory(string sourceDirectoryName,
void CreateFromDirectory(
string sourceDirectoryName,
string destinationArchiveFileName,
CompressionLevel compressionLevel,
bool includeBaseDirectory);

/// <inheritdoc cref="ZipFile.CreateFromDirectory(string, string, CompressionLevel, bool, Encoding)" />
void CreateFromDirectory(string sourceDirectoryName,
void CreateFromDirectory(
string sourceDirectoryName,
string destinationArchiveFileName,
CompressionLevel compressionLevel,
bool includeBaseDirectory,
Encoding entryNameEncoding);

#if FEATURE_COMPRESSION_STREAM
/// <inheritdoc cref="ZipFile.ExtractToDirectory(Stream, string)" />
void ExtractToDirectory(
Stream source,
string destinationDirectoryName);

/// <inheritdoc cref="ZipFile.ExtractToDirectory(Stream, string, bool)" />
void ExtractToDirectory(
Stream source,
string destinationDirectoryName,
bool overwriteFiles);

/// <inheritdoc cref="ZipFile.ExtractToDirectory(Stream, string, Encoding)" />
void ExtractToDirectory(
Stream source,
string destinationDirectoryName,
Encoding entryNameEncoding);

/// <inheritdoc cref="ZipFile.ExtractToDirectory(Stream, string, Encoding, bool)" />
void ExtractToDirectory(
Stream source,
string destinationDirectoryName,
Encoding entryNameEncoding,
bool overwriteFiles);
#endif

/// <inheritdoc cref="ZipFile.ExtractToDirectory(string, string)" />
void ExtractToDirectory(string sourceArchiveFileName,
void ExtractToDirectory(
string sourceArchiveFileName,
string destinationDirectoryName);

#if FEATURE_COMPRESSION_OVERWRITE
/// <inheritdoc cref="ZipFile.ExtractToDirectory(string, string, bool)" />
void ExtractToDirectory(string sourceArchiveFileName,
void ExtractToDirectory(
string sourceArchiveFileName,
string destinationDirectoryName,
bool overwriteFiles);
#endif

/// <inheritdoc cref="ZipFile.ExtractToDirectory(string, string, Encoding?)" />
void ExtractToDirectory(string sourceArchiveFileName,
void ExtractToDirectory(
string sourceArchiveFileName,
string destinationDirectoryName,
Encoding? entryNameEncoding);

#if FEATURE_COMPRESSION_OVERWRITE
/// <inheritdoc cref="ZipFile.ExtractToDirectory(string, string, Encoding?, bool)" />
void ExtractToDirectory(string sourceArchiveFileName,
void ExtractToDirectory(
string sourceArchiveFileName,
string destinationDirectoryName,
Encoding? entryNameEncoding,
bool overwriteFiles);
#endif

/// <inheritdoc cref="ZipFile.Open(string, ZipArchiveMode)" />
IZipArchive Open(string archiveFileName,
IZipArchive Open(
string archiveFileName,
ZipArchiveMode mode);

/// <inheritdoc cref="IZipFile.Open(string, ZipArchiveMode, Encoding?)" />
IZipArchive Open(string archiveFileName,
IZipArchive Open(
string archiveFileName,
ZipArchiveMode mode,
Encoding? entryNameEncoding);

/// <inheritdoc cref="ZipFile.OpenRead(string)" />
IZipArchive OpenRead(string archiveFileName);
IZipArchive OpenRead(
string archiveFileName);
}
113 changes: 112 additions & 1 deletion Source/Testably.Abstractions.Compression/Internal/ZipUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ internal static void CreateFromDirectory(IFileSystem fileSystem,
CompressionLevel? compressionLevel = null,
bool includeBaseDirectory = false,
Encoding? entryNameEncoding = null)

{
sourceDirectoryName = fileSystem.Path.GetFullPath(sourceDirectoryName);
destinationArchiveFileName =
Expand Down Expand Up @@ -114,6 +113,84 @@ internal static void CreateFromDirectory(IFileSystem fileSystem,
}
}

#if FEATURE_COMPRESSION_STREAM
/// <summary>
/// Create a <c>ZipArchive</c> from the files and directories in <paramref name="sourceDirectoryName" />.
/// </summary>
/// <remarks>
/// <see
/// href="https://github.com/dotnet/runtime/blob/v6.0.10/src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFile.Create.cs#L354" />
/// </remarks>
internal static void CreateFromDirectory(
IFileSystem fileSystem,
string sourceDirectoryName,
Stream destination,
CompressionLevel? compressionLevel = null,
bool includeBaseDirectory = false,
Encoding? entryNameEncoding = null)
{
ArgumentNullException.ThrowIfNull(destination);
if (!destination.CanWrite)
{
throw new ArgumentException("The stream is unwritable.", nameof(destination))
{
HResult = -2147024809
};
}

sourceDirectoryName = fileSystem.Path.GetFullPath(sourceDirectoryName);

using (ZipArchive archive = new(destination, ZipArchiveMode.Create,
leaveOpen: true,
entryNameEncoding: entryNameEncoding))
{
bool directoryIsEmpty = true;

IDirectoryInfo di =
fileSystem.DirectoryInfo.New(sourceDirectoryName);

string basePath = di.FullName;

if (includeBaseDirectory && di.Parent != null)
{
basePath = di.Parent.FullName;
}

foreach (IFileSystemInfo file in di
.EnumerateFileSystemInfos(SearchPattern, SearchOption.AllDirectories))
{
directoryIsEmpty = false;

if (file is IFileInfo fileInfo)
{
string entryName = file.FullName
.Substring(basePath.Length + 1)
.Replace("\\", "/");
ZipArchiveEntry entry = compressionLevel.HasValue
? archive.CreateEntry(entryName, compressionLevel.Value)
: archive.CreateEntry(entryName);
using Stream stream = entry.Open();
fileInfo.OpenRead().CopyTo(stream);
}
else if (file is IDirectoryInfo directoryInfo &&
directoryInfo.GetFileSystemInfos().Length == 0)
{
#pragma warning disable CA1845
string entryName = file.FullName.Substring(basePath.Length + 1) + "/";
#pragma warning restore CA1845
archive.CreateEntry(entryName);
}
}

if (includeBaseDirectory && directoryIsEmpty)
{
string entryName = di.Name + "/";
archive.CreateEntry(entryName);
}
}
}
#endif

internal static void ExtractRelativeToDirectory(this IZipArchiveEntry source,
string destinationDirectoryName,
bool overwrite)
Expand Down Expand Up @@ -177,6 +254,40 @@ internal static void ExtractToDirectory(IFileSystem fileSystem,
}
}

#if FEATURE_COMPRESSION_STREAM
/// <summary>
/// Extract the archive at <paramref name="source" /> to the
/// <paramref name="destinationDirectoryName" />.
/// </summary>
internal static void ExtractToDirectory(IFileSystem fileSystem,
Stream source,
string destinationDirectoryName,
Encoding? entryNameEncoding = null,
bool overwriteFiles = false)
{
ArgumentNullException.ThrowIfNull(source);
if (!source.CanRead)
{
throw new ArgumentException("The stream is unreadable.", nameof(source))
{
HResult = -2147024809
};
}

using (ZipArchive archive = new(source, ZipArchiveMode.Read, true, entryNameEncoding))
{
ZipArchiveWrapper wrappedArchive = new(fileSystem, archive);
foreach (ZipArchiveEntry entry in archive.Entries)
{
IZipArchiveEntry wrappedEntry = ZipArchiveEntryWrapper.New(
fileSystem, wrappedArchive, entry);
ExtractRelativeToDirectory(wrappedEntry, destinationDirectoryName,
overwriteFiles);
}
}
}
#endif

internal static void ExtractToFile(IZipArchiveEntry source,
string destinationFileName, bool overwrite)
{
Expand Down
Loading
Loading