diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..c93f299 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,6 @@ + + + true + true + + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..0818efd --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index 39528cf..8fba9ef 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -18,11 +18,11 @@ true - - - - - + + + + + diff --git a/SevenZip/LibraryManager.BinaryResource.cs b/SevenZip/LibraryManager.BinaryResource.cs new file mode 100644 index 0000000..d7a0f65 --- /dev/null +++ b/SevenZip/LibraryManager.BinaryResource.cs @@ -0,0 +1,201 @@ +namespace SevenZip; + +[BinaryResource( +""" +[ +""" + +#if SFX +""" + + { + "Path": "..\\res\\sfx\\7z.sfx", + "Name": "sfx_7z_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zCon.sfx", + "Name": "sfx_7zCon_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zS.sfx", + "Name": "sfx_7zS_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zSD.sfx", + "Name": "sfx_7zSD_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_All.sfx", + "Name": "sfx_7zxSD_All_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_All_x64.sfx", + "Name": "sfx_7zxSD_All_x64_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_Deflate.sfx", + "Name": "sfx_7zxSD_Deflate_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_Deflate_x64.sfx", + "Name": "sfx_7zxSD_Deflate_x64_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_LZMA.sfx", + "Name": "sfx_7zxSD_LZMA_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_LZMA_x64.sfx", + "Name": "sfx_7zxSD_LZMA_x64_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_LZMA2.sfx", + "Name": "sfx_7zxSD_LZMA2_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_LZMA2_x64.sfx", + "Name": "sfx_7zxSD_LZMA2_x64_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_PPMd.sfx", + "Name": "sfx_7zxSD_PPMd_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\7zxSD_PPMd_x64.sfx", + "Name": "sfx_7zxSD_PPMd_x64_sfx", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\Configs.xml", + "Name": "sfx_Configs_xml", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\Configs.xsd", + "Name": "sfx_Configs_xsd", + "Reverse": true + }, + { + "Path": "..\\res\\sfx\\Configs.xslt", + "Name": "sfx_Configs_xslt", + "Reverse": true + }, +""" + +#endif +""" + { + "Path": "..\\res\\arch\\Test.bzip2.7z", + "Name": "arch_Test_bzip2_7z", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.lzma.7z", + "Name": "arch_Test_lzma_7z", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.lzma2.7z", + "Name": "arch_Test_lzma2_7z", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.ppmd.7z", + "Name": "arch_Test_ppmd_7z", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.rar", + "Name": "arch_Test_rar", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.tar", + "Name": "arch_Test_tar", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.txt", + "Name": "arch_Test_txt", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.txt.bz2", + "Name": "arch_Test_txt_bz2", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.txt.gz", + "Name": "arch_Test_txt_gz", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.txt.xz", + "Name": "arch_Test_txt_xz", + "Reverse": true + }, + { + "Path": "..\\res\\arch\\Test.zip", + "Name": "arch_Test_zip", + "Reverse": true + } +] +""", +""" + internal static byte[] GetManifestResource(string fileName, string dirName) => dirName switch + { + "arch" => fileName switch + { + "Test.bzip2.7z" => {arch_Test_bzip2_7z}(), + "Test.lzma.7z" => {arch_Test_lzma_7z}(), + "Test.lzma2.7z" => {arch_Test_lzma2_7z}(), + "Test.ppmd.7z" => {arch_Test_ppmd_7z}(), + "Test.rar" => {arch_Test_rar}(), + "Test.tar" => {arch_Test_tar}(), + "Test.txt" => {arch_Test_txt}(), + "Test.txt.bz2" => {arch_Test_txt_bz2}(), + "Test.txt.gz" => {arch_Test_txt_gz}(), + "Test.txt.xz" => {arch_Test_txt_xz}(), + "Test.zip" => {arch_Test_zip}(), + _ => [], + }, +#if SFX + "sfx" => fileName switch + { + "7z.sfx" => {sfx_7z_sfx}(), + "7zCon.sfx" => {sfx_7zCon_sfx}(), + "7zS.sfx" => {sfx_7zS_sfx}(), + "7zSD.sfx" => {sfx_7zSD_sfx}(), + "7zxSD_All.sfx" => {sfx_7zxSD_All_sfx}(), + "7zxSD_All_x64.sfx" => {sfx_7zxSD_All_x64_sfx}(), + "7zxSD_Deflate.sfx" => {sfx_7zxSD_Deflate_sfx}(), + "7zxSD_Deflate_x64.sfx" => {sfx_7zxSD_Deflate_x64_sfx}(), + "7zxSD_LZMA.sfx" => {sfx_7zxSD_LZMA_sfx}(), + "7zxSD_LZMA_x64.sfx" => {sfx_7zxSD_LZMA_x64_sfx}(), + "7zxSD_LZMA2.sfx" => {sfx_7zxSD_LZMA2_sfx}(), + "7zxSD_LZMA2_x64.sfx" => {sfx_7zxSD_LZMA2_x64_sfx}(), + "7zxSD_PPMd.sfx" => {sfx_7zxSD_PPMd_sfx}(), + "7zxSD_PPMd_x64.sfx" => {sfx_7zxSD_PPMd_x64_sfx}(), + "Configs.xml" => {sfx_Configs_xml}(), + "Configs.xsd" => {sfx_Configs_xsd}(), + "Configs.xslt" => {sfx_Configs_xslt}(), + _ => [], + }, +#endif + _ => [], + }; +""")] +partial class LibraryManager +{ +} \ No newline at end of file diff --git a/SevenZip/LibraryManager.cs b/SevenZip/LibraryManager.cs index c13aacc..317954e 100644 --- a/SevenZip/LibraryManager.cs +++ b/SevenZip/LibraryManager.cs @@ -16,7 +16,7 @@ namespace SevenZip /// /// 7-zip library low-level wrapper. /// - internal static class SevenZipLibraryManager + internal static partial class SevenZipLibraryManager { /// /// Synchronization root for all locking. @@ -287,31 +287,37 @@ public static bool ModifyCapable } } - static readonly string Namespace = Assembly.GetExecutingAssembly().GetManifestResourceNames()[0].Split('.')[0]; - - private static string GetResourceString(string str) + private static unsafe bool ExtractionBenchmark(string archiveFileName, Stream outStream, ref LibraryFeature? features, LibraryFeature testedFeature) { - return Namespace + ".arch." + str; - } + var bytes = LibraryManager.GetManifestResource(archiveFileName, "arch"); + var bytes_span = bytes.AsSpan(); + bytes_span.Reverse(); + fixed (byte* ptr = bytes) + { + try + { + using UnmanagedMemoryStream stream = new(ptr, bytes.Length); - private static bool ExtractionBenchmark(string archiveFileName, Stream outStream, ref LibraryFeature? features, LibraryFeature testedFeature) - { - var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetResourceString(archiveFileName)); + try + { + using (var extractor = new SevenZipExtractor(stream)) + { + extractor.ExtractFile(0, outStream); + } + } + catch (Exception) + { + return false; + } - try - { - using (var extractor = new SevenZipExtractor(stream)) + features |= testedFeature; + return true; + } + finally { - extractor.ExtractFile(0, outStream); + bytes_span.Clear(); } } - catch (Exception) - { - return false; - } - - features |= testedFeature; - return true; } private static bool CompressionBenchmark(Stream inStream, Stream outStream, OutArchiveFormat format, CompressionMethod method, ref LibraryFeature? features, LibraryFeature testedFeature) diff --git a/SevenZip/SevenZip.csproj b/SevenZip/SevenZip.csproj index 2bd979f..d676fa9 100644 --- a/SevenZip/SevenZip.csproj +++ b/SevenZip/SevenZip.csproj @@ -1,7 +1,9 @@ + true SevenZipSharp - netstandard2.0;net472;netcoreapp3.1;net8.0 + + net8.0 true SevenZip.snk SevenZipSharp @@ -33,7 +35,7 @@ - + @@ -74,4 +76,7 @@ C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll --> + + + \ No newline at end of file diff --git a/SevenZip/SevenZipSfx.cs b/SevenZip/SevenZipSfx.cs index aa3571f..d52c223 100644 --- a/SevenZip/SevenZipSfx.cs +++ b/SevenZip/SevenZipSfx.cs @@ -142,7 +142,7 @@ public string ModuleFileName private void CommonInit() { - LoadCommandsFromResource("Configs"); + LoadCommandsFromResource("Configs.xml", "Configs.xsd"); } private static string GetResourceString(string str) @@ -175,79 +175,104 @@ private static SfxModule GetModuleByName(string name) /// /// Loads the commands for each supported sfx module configuration /// - /// The resource name for xml definitions - private void LoadCommandsFromResource(string xmlDefinitions) + /// The resource name for xml definitions + /// The resource name for xsd definitions + private unsafe void LoadCommandsFromResource(string xmlDefinitions_xml, string xmlDefinitions_xsd) { - using (var cfg = Assembly.GetExecutingAssembly().GetManifestResourceStream( - GetResourceString(xmlDefinitions + ".xml"))) + var bytes_cfg = LibraryManager.GetManifestResource(xmlDefinitions_xml, "sfx"); + var bytes_cfg_span = bytes_cfg.AsSpan(); + bytes_cfg_span.Reverse(); + fixed (byte* ptr_cfg = bytes_cfg) { - if (cfg == null) + try { - throw new SevenZipSfxValidationException("The configuration \"" + xmlDefinitions + - "\" does not exist."); - } - using (var schm = Assembly.GetExecutingAssembly().GetManifestResourceStream( - GetResourceString(xmlDefinitions + ".xsd"))) - { - if (schm == null) + if (bytes_cfg.Length == 0) { - throw new SevenZipSfxValidationException("The configuration schema \"" + xmlDefinitions + + throw new SevenZipSfxValidationException("The configuration \"" + xmlDefinitions_xml + "\" does not exist."); } - var sc = new XmlSchemaSet(); - using (var scr = XmlReader.Create(schm)) + + using UnmanagedMemoryStream cfg = new(ptr_cfg, bytes_cfg.Length); + + var bytes_schm = LibraryManager.GetManifestResource(xmlDefinitions_xsd, "sfx"); + var bytes_schm_span = bytes_schm.AsSpan(); + bytes_schm_span.Reverse(); + fixed (byte* ptr_schm = bytes_schm) { - sc.Add(null, scr); - var settings = new XmlReaderSettings {ValidationType = ValidationType.Schema, Schemas = sc}; - var validationErrors = ""; - settings.ValidationEventHandler += - ((s, t) => - { - validationErrors += string.Format(CultureInfo.InvariantCulture, "[{0}]: {1}\n", - t.Severity.ToString(), t.Message); - }); - using (var rdr = XmlReader.Create(cfg, settings)) + try { - _sfxCommands = new Dictionary>(); - rdr.Read(); - rdr.Read(); - rdr.Read(); - rdr.Read(); - rdr.Read(); - rdr.ReadStartElement("sfxConfigs"); - rdr.Read(); - do + if (bytes_schm.Length == 0) + { + throw new SevenZipSfxValidationException("The configuration schema \"" + xmlDefinitions_xsd + + "\" does not exist."); + } + + using UnmanagedMemoryStream schm = new(ptr_schm, bytes_schm.Length); + + var sc = new XmlSchemaSet(); + using (var scr = XmlReader.Create(schm)) { - var mod = GetModuleByName(rdr["modules"]); - rdr.ReadStartElement("config"); - rdr.Read(); - if (rdr.Name == "id") + sc.Add(null, scr); + var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = sc }; + var validationErrors = ""; + settings.ValidationEventHandler += + ((s, t) => + { + validationErrors += string.Format(CultureInfo.InvariantCulture, "[{0}]: {1}\n", + t.Severity.ToString(), t.Message); + }); + using (var rdr = XmlReader.Create(cfg, settings)) { - var cmds = new List(); - _sfxCommands.Add(mod, cmds); + _sfxCommands = new Dictionary>(); + rdr.Read(); + rdr.Read(); + rdr.Read(); + rdr.Read(); + rdr.Read(); + rdr.ReadStartElement("sfxConfigs"); + rdr.Read(); do { - cmds.Add(rdr["command"]); + var mod = GetModuleByName(rdr["modules"]); + rdr.ReadStartElement("config"); rdr.Read(); - rdr.Read(); - } while (rdr.Name == "id"); - rdr.ReadEndElement(); - rdr.Read(); + if (rdr.Name == "id") + { + var cmds = new List(); + _sfxCommands.Add(mod, cmds); + do + { + cmds.Add(rdr["command"]); + rdr.Read(); + rdr.Read(); + } while (rdr.Name == "id"); + rdr.ReadEndElement(); + rdr.Read(); + } + else + { + _sfxCommands.Add(mod, null); + } + } while (rdr.Name == "config"); } - else + if (!string.IsNullOrEmpty(validationErrors)) { - _sfxCommands.Add(mod, null); + throw new SevenZipSfxValidationException( + "\n" + validationErrors.Substring(0, validationErrors.Length - 1)); } - } while (rdr.Name == "config"); + _sfxCommands.Add(SfxModule.Default, _sfxCommands[SfxModule.Extended]); + } } - if (!string.IsNullOrEmpty(validationErrors)) + finally { - throw new SevenZipSfxValidationException( - "\n" + validationErrors.Substring(0, validationErrors.Length - 1)); + bytes_schm_span.Clear(); } - _sfxCommands.Add(SfxModule.Default, _sfxCommands[SfxModule.Extended]); } } + finally + { + bytes_cfg_span.Clear(); + } } } @@ -263,14 +288,14 @@ private void ValidateSettings(SfxSettings settings) } var commands = _sfxCommands[SfxModule]; - + if (commands == null) { return; } - + var invalidCommands = new List(); - + foreach (var command in settings.Keys) { if (!commands.Contains(command)) @@ -278,16 +303,16 @@ private void ValidateSettings(SfxSettings settings) invalidCommands.Add(command); } } - + if (invalidCommands.Count > 0) { var invalidText = new StringBuilder("\nInvalid commands:\n"); - + foreach (var str in invalidCommands) { invalidText.Append(str); } - + throw new SevenZipSfxValidationException(invalidText.ToString()); } } @@ -302,7 +327,7 @@ private static Stream GetSettingsStream(SfxSettings settings) var ms = new MemoryStream(); var buf = Encoding.UTF8.GetBytes(@";!@Install@!UTF-8!" + '\n'); ms.Write(buf, 0, buf.Length); - + foreach (var command in settings.Keys) { buf = @@ -310,10 +335,10 @@ private static Stream GetSettingsStream(SfxSettings settings) settings[command])); ms.Write(buf, 0, buf.Length); } - + buf = Encoding.UTF8.GetBytes(@";!@InstallEnd@!"); ms.Write(buf, 0, buf.Length); - + return ms; } @@ -324,7 +349,7 @@ private SfxSettings GetDefaultSettings() default: return null; case SfxModule.Installer: - var settings = new Dictionary {{"Title", "7-Zip self-extracting archive"}}; + var settings = new Dictionary { { "Title", "7-Zip self-extracting archive" } }; return settings; case SfxModule.Default: case SfxModule.Extended: @@ -360,7 +385,7 @@ private static void WriteStream(Stream src, Stream dest) src.Seek(0, SeekOrigin.Begin); var buf = new byte[32768]; int bytesRead; - + while ((bytesRead = src.Read(buf, 0, buf.Length)) > 0) { dest.Write(buf, 0, bytesRead); diff --git a/SevenZip/arch/Test.bzip2.7z b/res/arch/Test.bzip2.7z similarity index 100% rename from SevenZip/arch/Test.bzip2.7z rename to res/arch/Test.bzip2.7z diff --git a/SevenZip/arch/Test.lzma.7z b/res/arch/Test.lzma.7z similarity index 100% rename from SevenZip/arch/Test.lzma.7z rename to res/arch/Test.lzma.7z diff --git a/SevenZip/arch/Test.lzma2.7z b/res/arch/Test.lzma2.7z similarity index 100% rename from SevenZip/arch/Test.lzma2.7z rename to res/arch/Test.lzma2.7z diff --git a/SevenZip/arch/Test.ppmd.7z b/res/arch/Test.ppmd.7z similarity index 100% rename from SevenZip/arch/Test.ppmd.7z rename to res/arch/Test.ppmd.7z diff --git a/SevenZip/arch/Test.rar b/res/arch/Test.rar similarity index 100% rename from SevenZip/arch/Test.rar rename to res/arch/Test.rar diff --git a/SevenZip/arch/Test.tar b/res/arch/Test.tar similarity index 100% rename from SevenZip/arch/Test.tar rename to res/arch/Test.tar diff --git a/SevenZip/arch/Test.txt b/res/arch/Test.txt similarity index 100% rename from SevenZip/arch/Test.txt rename to res/arch/Test.txt diff --git a/SevenZip/arch/Test.txt.bz2 b/res/arch/Test.txt.bz2 similarity index 100% rename from SevenZip/arch/Test.txt.bz2 rename to res/arch/Test.txt.bz2 diff --git a/SevenZip/arch/Test.txt.gz b/res/arch/Test.txt.gz similarity index 100% rename from SevenZip/arch/Test.txt.gz rename to res/arch/Test.txt.gz diff --git a/SevenZip/arch/Test.txt.xz b/res/arch/Test.txt.xz similarity index 100% rename from SevenZip/arch/Test.txt.xz rename to res/arch/Test.txt.xz diff --git a/SevenZip/arch/Test.zip b/res/arch/Test.zip similarity index 100% rename from SevenZip/arch/Test.zip rename to res/arch/Test.zip diff --git a/SevenZip/sfx/7z.sfx b/res/sfx/7z.sfx similarity index 100% rename from SevenZip/sfx/7z.sfx rename to res/sfx/7z.sfx diff --git a/SevenZip/sfx/7zCon.sfx b/res/sfx/7zCon.sfx similarity index 100% rename from SevenZip/sfx/7zCon.sfx rename to res/sfx/7zCon.sfx diff --git a/SevenZip/sfx/7zS.sfx b/res/sfx/7zS.sfx similarity index 100% rename from SevenZip/sfx/7zS.sfx rename to res/sfx/7zS.sfx diff --git a/SevenZip/sfx/7zSD.sfx b/res/sfx/7zSD.sfx similarity index 100% rename from SevenZip/sfx/7zSD.sfx rename to res/sfx/7zSD.sfx diff --git a/SevenZip/sfx/7zxSD_All.sfx b/res/sfx/7zxSD_All.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_All.sfx rename to res/sfx/7zxSD_All.sfx diff --git a/SevenZip/sfx/7zxSD_All_x64.sfx b/res/sfx/7zxSD_All_x64.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_All_x64.sfx rename to res/sfx/7zxSD_All_x64.sfx diff --git a/SevenZip/sfx/7zxSD_Deflate.sfx b/res/sfx/7zxSD_Deflate.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_Deflate.sfx rename to res/sfx/7zxSD_Deflate.sfx diff --git a/SevenZip/sfx/7zxSD_Deflate_x64.sfx b/res/sfx/7zxSD_Deflate_x64.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_Deflate_x64.sfx rename to res/sfx/7zxSD_Deflate_x64.sfx diff --git a/SevenZip/sfx/7zxSD_LZMA.sfx b/res/sfx/7zxSD_LZMA.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_LZMA.sfx rename to res/sfx/7zxSD_LZMA.sfx diff --git a/SevenZip/sfx/7zxSD_LZMA2.sfx b/res/sfx/7zxSD_LZMA2.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_LZMA2.sfx rename to res/sfx/7zxSD_LZMA2.sfx diff --git a/SevenZip/sfx/7zxSD_LZMA2_x64.sfx b/res/sfx/7zxSD_LZMA2_x64.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_LZMA2_x64.sfx rename to res/sfx/7zxSD_LZMA2_x64.sfx diff --git a/SevenZip/sfx/7zxSD_LZMA_x64.sfx b/res/sfx/7zxSD_LZMA_x64.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_LZMA_x64.sfx rename to res/sfx/7zxSD_LZMA_x64.sfx diff --git a/SevenZip/sfx/7zxSD_PPMd.sfx b/res/sfx/7zxSD_PPMd.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_PPMd.sfx rename to res/sfx/7zxSD_PPMd.sfx diff --git a/SevenZip/sfx/7zxSD_PPMd_x64.sfx b/res/sfx/7zxSD_PPMd_x64.sfx similarity index 100% rename from SevenZip/sfx/7zxSD_PPMd_x64.sfx rename to res/sfx/7zxSD_PPMd_x64.sfx diff --git a/SevenZip/sfx/Configs.xml b/res/sfx/Configs.xml similarity index 100% rename from SevenZip/sfx/Configs.xml rename to res/sfx/Configs.xml diff --git a/SevenZip/sfx/Configs.xsd b/res/sfx/Configs.xsd similarity index 100% rename from SevenZip/sfx/Configs.xsd rename to res/sfx/Configs.xsd diff --git a/SevenZip/sfx/Configs.xslt b/res/sfx/Configs.xslt similarity index 100% rename from SevenZip/sfx/Configs.xslt rename to res/sfx/Configs.xslt diff --git a/SevenZip/sfx/sample.txt b/res/sfx/sample.txt similarity index 100% rename from SevenZip/sfx/sample.txt rename to res/sfx/sample.txt