From 486fdf118be9952f56170962c4dbb65e222f4528 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Wed, 7 Jan 2026 10:39:18 +0000 Subject: [PATCH] move to own files and refactor UTF8 usage --- src/SharpCompress/Common/ArchiveEncoding.cs | 52 ------------------- .../Common/ArchiveEncodingExtensions.cs | 28 ++++++++++ src/SharpCompress/Common/IArchiveEncoding.cs | 33 ++++++++++++ .../Zip/Headers/DirectoryEntryHeader.cs | 4 +- .../Common/Zip/Headers/LocalEntryHeader.cs | 2 +- 5 files changed, 64 insertions(+), 55 deletions(-) create mode 100644 src/SharpCompress/Common/ArchiveEncodingExtensions.cs create mode 100644 src/SharpCompress/Common/IArchiveEncoding.cs diff --git a/src/SharpCompress/Common/ArchiveEncoding.cs b/src/SharpCompress/Common/ArchiveEncoding.cs index 3141a4ae..40fe2ea3 100644 --- a/src/SharpCompress/Common/ArchiveEncoding.cs +++ b/src/SharpCompress/Common/ArchiveEncoding.cs @@ -11,55 +11,3 @@ public class ArchiveEncoding : IArchiveEncoding public Encoding? Forced { get; set; } public Func? CustomDecoder { get; set; } } - -public interface IArchiveEncoding -{ - /// - /// Default encoding to use when archive format doesn't specify one. - /// - public Encoding Default { get; set; } - - /// - /// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898. - /// - public Encoding Password { get; set; } - - /// - /// Default encoding to use when archive format specifies UTF-8 encoding. - /// - public Encoding UTF8 { get; set; } - - /// - /// Set this encoding when you want to force it for all encoding operations. - /// - public Encoding? Forced { get; set; } - - /// - /// Set this when you want to use a custom method for all decoding operations. - /// - /// string Func(bytes, index, length) - public Func? CustomDecoder { get; set; } -} - -public static class ArchiveEncodingExtensions -{ - public static Encoding GetEncoding(this IArchiveEncoding encoding) => - encoding.Forced ?? encoding.Default; - - public static Func GetDecoder(this IArchiveEncoding encoding) => - encoding.CustomDecoder - ?? ((bytes, index, count) => encoding.GetEncoding().GetString(bytes, index, count)); - - public static byte[] Encode(this IArchiveEncoding encoding, string str) => - encoding.Default.GetBytes(str); - - public static string Decode(this IArchiveEncoding encoding, byte[] bytes) => - encoding.Decode(bytes, 0, bytes.Length); - - public static string Decode( - this IArchiveEncoding encoding, - byte[] bytes, - int start, - int length - ) => encoding.GetDecoder()(bytes, start, length); -} diff --git a/src/SharpCompress/Common/ArchiveEncodingExtensions.cs b/src/SharpCompress/Common/ArchiveEncodingExtensions.cs new file mode 100644 index 00000000..96e5f19b --- /dev/null +++ b/src/SharpCompress/Common/ArchiveEncodingExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.Text; + +namespace SharpCompress.Common; + +public static class ArchiveEncodingExtensions +{ + extension(IArchiveEncoding encoding) + { + public Encoding GetEncoding(bool useUtf8 = false) => + encoding.Forced ?? (useUtf8 ? encoding.UTF8 : encoding.Default); + + public Func GetDecoder(bool useUtf8) => + encoding.CustomDecoder + ?? ( + (bytes, index, count) => + encoding.GetEncoding(useUtf8).GetString(bytes, index, count) + ); + + public byte[] Encode(string str) => encoding.Default.GetBytes(str); + + public string Decode(byte[] bytes, bool useUtf8 = false) => + encoding.Decode(bytes, 0, bytes.Length, useUtf8); + + public string Decode(byte[] bytes, int start, int length, bool useUtf8 = false) => + encoding.GetDecoder(useUtf8)(bytes, start, length); + } +} diff --git a/src/SharpCompress/Common/IArchiveEncoding.cs b/src/SharpCompress/Common/IArchiveEncoding.cs new file mode 100644 index 00000000..09008181 --- /dev/null +++ b/src/SharpCompress/Common/IArchiveEncoding.cs @@ -0,0 +1,33 @@ +using System; +using System.Text; + +namespace SharpCompress.Common; + +public interface IArchiveEncoding +{ + /// + /// Default encoding to use when archive format doesn't specify one. + /// + public Encoding Default { get; set; } + + /// + /// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898. + /// + public Encoding Password { get; set; } + + /// + /// Default encoding to use when archive format specifies UTF-8 encoding. + /// + public Encoding UTF8 { get; set; } + + /// + /// Set this encoding when you want to force it for all encoding operations. + /// + public Encoding? Forced { get; set; } + + /// + /// Set this when you want to use a custom method for all decoding operations. + /// + /// string Func(bytes, index, length) + public Func? CustomDecoder { get; set; } +} diff --git a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs index cc516e4c..8d5cd2f7 100644 --- a/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/DirectoryEntryHeader.cs @@ -41,8 +41,8 @@ internal class DirectoryEntryHeader : ZipFileEntry if (Flags.HasFlag(HeaderFlags.Efs)) { - Name = ArchiveEncoding.DecodeUTF8(name); - Comment = ArchiveEncoding.DecodeUTF8(comment); + Name = ArchiveEncoding.Decode(name, true); + Comment = ArchiveEncoding.Decode(comment, true); } else { diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs index 7864d8ac..22c36da1 100644 --- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs +++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeader.cs @@ -33,7 +33,7 @@ internal class LocalEntryHeader : ZipFileEntry if (Flags.HasFlag(HeaderFlags.Efs)) { - Name = ArchiveEncoding.DecodeUTF8(name); + Name = ArchiveEncoding.Decode(name, true); } else {