From d9c42f44a1f67e09d1b2a274786a546e4f5fd4a8 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Sun, 6 Oct 2019 16:51:02 +1000 Subject: [PATCH] Implement IHawkFileArchiveHandler using NuGet package SharpCompress --- .../BizHawk.Client.Common.csproj | 8 ++ .../SharpCompressArchiveHandler.cs | 77 +++++++++++++++++++ BizHawk.Client.Common/packages.config | 4 + BizHawk.Client.EmuHawk/Program.cs | 15 +++- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 BizHawk.Client.Common/SharpCompressArchiveHandler.cs create mode 100644 BizHawk.Client.Common/packages.config diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index c866a9a85c..ea09e5b1f0 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -56,6 +56,10 @@ ..\output\dll\nlua\NLua.dll False + + ..\packages\SharpCompress.0.24.0\lib\net45\SharpCompress.dll + True + @@ -260,6 +264,7 @@ + @@ -321,6 +326,9 @@ BizHawk.Bizware.BizwareGL + + + diff --git a/BizHawk.Client.Common/SharpCompressArchiveHandler.cs b/BizHawk.Client.Common/SharpCompressArchiveHandler.cs new file mode 100644 index 0000000000..e79cbc55e1 --- /dev/null +++ b/BizHawk.Client.Common/SharpCompressArchiveHandler.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using BizHawk.Common; + +using SharpCompress.Archives; +using SharpCompress.Common; + +namespace BizHawk.Client.Common +{ + /// + /// An ArchiveHandler implemented using SharpCompress from NuGet + /// + /// + /// Intended for Unix, which can't use SevenZipSharp, but later we might sacrifice whatever speed advantage that library has for the lower workload of one cross-platform library. + /// + /// + public class SharpCompressArchiveHandler : IHawkFileArchiveHandler + { + private IArchive _archive; + + public void Dispose() + { + _archive?.Dispose(); + _archive = null; + } + + public bool CheckSignature(string fileName, out int offset, out bool isExecutable) + { + offset = 0; + isExecutable = false; + try + { + using (var arcTest = ArchiveFactory.Open(fileName)) + switch (arcTest.Type) + { + case ArchiveType.Zip: + case ArchiveType.SevenZip: + return true; + } + } + catch (Exception _) + { + // ignored + } + return false; + } + + public IHawkFileArchiveHandler Construct(string path) + { + var ret = new SharpCompressArchiveHandler(); + ret.Open(path); + return ret; + } + + private void Open(string path) => _archive = ArchiveFactory.Open(path); + + public List Scan() => + _archive.Entries.Where(e => !e.IsDirectory) + .Select((e, i) => new HawkFileArchiveItem + { + Name = HawkFile.Util_FixArchiveFilename(e.Key), + Size = e.Size, + Index = i, + ArchiveIndex = i + }) + .ToList(); + + public void ExtractFile(int index, Stream stream) + { + using (var entryStream = _archive.Entries.Where(e => !e.IsDirectory).ElementAt(index).OpenEntryStream()) + entryStream.CopyTo(stream); + } + } +} diff --git a/BizHawk.Client.Common/packages.config b/BizHawk.Client.Common/packages.config new file mode 100644 index 0000000000..dcaa847713 --- /dev/null +++ b/BizHawk.Client.Common/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index eff505836a..39a33781a0 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -117,7 +117,20 @@ namespace BizHawk.Client.EmuHawk BizHawk.Common.TempFileManager.Start(); - HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler(); +#if true // switch to if false for system-agnostic glory! + switch (EXE_PROJECT.OSTailoredCode.CurrentOS) + { + case EXE_PROJECT.OSTailoredCode.DistinctOS.Linux: + case EXE_PROJECT.OSTailoredCode.DistinctOS.macOS: + HawkFile.ArchiveHandlerFactory = new SharpCompressArchiveHandler(); + break; + case EXE_PROJECT.OSTailoredCode.DistinctOS.Windows: + HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler(); + break; + } +#else + HawkFile.ArchiveHandlerFactory = new SharpCompressArchiveHandler(); +#endif string cmdConfigFile = ArgParser.GetCmdConfigFile(args); if (cmdConfigFile != null) PathManager.SetDefaultIniPath(cmdConfigFile);