Use explicit enum, add comments

This commit is contained in:
Adam Hathcock
2026-01-07 11:10:15 +00:00
parent 486fdf118b
commit 68451bd75f
5 changed files with 78 additions and 16 deletions

View File

@@ -9,5 +9,5 @@ public class ArchiveEncoding : IArchiveEncoding
public Encoding Password { get; set; } = Encoding.Default;
public Encoding UTF8 { get; set; } = Encoding.UTF8;
public Encoding? Forced { get; set; }
public Func<byte[], int, int, string>? CustomDecoder { get; set; }
public Func<byte[], int, int, EncodingType, string>? CustomDecoder { get; set; }
}

View File

@@ -3,26 +3,85 @@ using System.Text;
namespace SharpCompress.Common;
/// <summary>
/// Specifies the type of encoding to use.
/// </summary>
public enum EncodingType
{
/// <summary>
/// Uses the default encoding.
/// </summary>
Default,
/// <summary>
/// Uses UTF-8 encoding.
/// </summary>
UTF8,
}
/// <summary>
/// Provides extension methods for archive encoding.
/// </summary>
public static class ArchiveEncodingExtensions
{
#if !NETFRAMEWORK
/// <summary>
/// Registers the code pages encoding provider.
/// </summary>
static ArchiveEncodingExtensions() =>
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
#endif
/// <summary>
/// Gets the encoding based on the archive encoding settings.
/// </summary>
/// <param name="useUtf8">Whether to use UTF-8.</param>
/// <returns>The encoding.</returns>
/// <param name="encoding">The archive encoding instance.</param>
extension(IArchiveEncoding encoding)
{
public Encoding GetEncoding(bool useUtf8 = false) =>
encoding.Forced ?? (useUtf8 ? encoding.UTF8 : encoding.Default);
public Func<byte[], int, int, string> GetDecoder(bool useUtf8) =>
/// <summary>
/// Gets the decoder function for the archive encoding.
/// </summary>
/// <returns>The decoder function.</returns>
public Func<byte[], int, int, EncodingType, string> GetDecoder() =>
encoding.CustomDecoder
?? (
(bytes, index, count) =>
encoding.GetEncoding(useUtf8).GetString(bytes, index, count)
(bytes, index, count, type) =>
encoding.GetEncoding(type == EncodingType.UTF8).GetString(bytes, index, count)
);
/// <summary>
/// Encodes a string using the default encoding.
/// </summary>
/// <param name="str">The string to encode.</param>
/// <returns>The encoded bytes.</returns>
public byte[] Encode(string str) => encoding.Default.GetBytes(str);
public string Decode(byte[] bytes, bool useUtf8 = false) =>
encoding.Decode(bytes, 0, bytes.Length, useUtf8);
/// <summary>
/// Decodes bytes using the specified encoding type.
/// </summary>
/// <param name="bytes">The bytes to decode.</param>
/// <param name="type">The encoding type.</param>
/// <returns>The decoded string.</returns>
public string Decode(byte[] bytes, EncodingType type = EncodingType.Default) =>
encoding.Decode(bytes, 0, bytes.Length, type);
public string Decode(byte[] bytes, int start, int length, bool useUtf8 = false) =>
encoding.GetDecoder(useUtf8)(bytes, start, length);
/// <summary>
/// Decodes a portion of bytes using the specified encoding type.
/// </summary>
/// <param name="bytes">The bytes to decode.</param>
/// <param name="start">The start index.</param>
/// <param name="length">The length.</param>
/// <param name="type">The encoding type.</param>
/// <returns>The decoded string.</returns>
public string Decode(
byte[] bytes,
int start,
int length,
EncodingType type = EncodingType.Default
) => encoding.GetDecoder()(bytes, start, length, type);
}
}

View File

@@ -3,20 +3,23 @@ using System.Text;
namespace SharpCompress.Common;
/// <summary>
/// Defines the encoding settings for archives.
/// </summary>
public interface IArchiveEncoding
{
/// <summary>
/// Default encoding to use when archive format doesn't specify one.
/// Default encoding to use when archive format doesn't specify one. Required and defaults to Encoding.Default.
/// </summary>
public Encoding Default { get; set; }
/// <summary>
/// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898.
/// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898. Required and defaults to Encoding.Default.
/// </summary>
public Encoding Password { get; set; }
/// <summary>
/// Default encoding to use when archive format specifies UTF-8 encoding.
/// Default encoding to use when archive format specifies UTF-8 encoding. Required and defaults to Encoding.UTF8.
/// </summary>
public Encoding UTF8 { get; set; }
@@ -28,6 +31,6 @@ public interface IArchiveEncoding
/// <summary>
/// Set this when you want to use a custom method for all decoding operations.
/// </summary>
/// <returns>string Func(bytes, index, length)</returns>
public Func<byte[], int, int, string>? CustomDecoder { get; set; }
/// <returns>string Func(bytes, index, length, EncodingType)</returns>
public Func<byte[], int, int, EncodingType, string>? CustomDecoder { get; set; }
}

View File

@@ -41,8 +41,8 @@ internal class DirectoryEntryHeader : ZipFileEntry
if (Flags.HasFlag(HeaderFlags.Efs))
{
Name = ArchiveEncoding.Decode(name, true);
Comment = ArchiveEncoding.Decode(comment, true);
Name = ArchiveEncoding.Decode(name, EncodingType.UTF8);
Comment = ArchiveEncoding.Decode(comment, EncodingType.UTF8);
}
else
{

View File

@@ -33,7 +33,7 @@ internal class LocalEntryHeader : ZipFileEntry
if (Flags.HasFlag(HeaderFlags.Efs))
{
Name = ArchiveEncoding.Decode(name, true);
Name = ArchiveEncoding.Decode(name, EncodingType.UTF8);
}
else
{