From adca19c30a816c1627a7c436cc8776a918ba5f36 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Sat, 23 Jan 2021 09:14:51 -0500 Subject: [PATCH] Remove icsharp (#2590) Since .NET 4.5, there's been a good framework alternative, and it gets lots of eyes on it. I've heard that it's quite fast in .NET Core too. --- .../BizHawk.Client.Common.csproj | 1 - src/BizHawk.Client.Common/RomLoader.cs | 6 +-- .../movie/import/LsmvImport.cs | 39 ++++++++++--------- .../savestates/ZipStateLoader.cs | 23 ++++++----- src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs | 35 ++++++++++++----- .../BizHawk.Client.EmuHawk.csproj | 1 + src/BizHawk.Client.EmuHawk/packages.config | 1 - .../tools/NES/NESMusicRipper.cs | 38 ++++++------------ .../tools/PCE/PCESoundDebugger.cs | 21 +++------- 9 files changed, 78 insertions(+), 87 deletions(-) diff --git a/src/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/src/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 35f39448b9..827d38e2be 100644 --- a/src/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/src/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -11,7 +11,6 @@ - diff --git a/src/BizHawk.Client.Common/RomLoader.cs b/src/BizHawk.Client.Common/RomLoader.cs index e5fd55ba45..4431157592 100644 --- a/src/BizHawk.Client.Common/RomLoader.cs +++ b/src/BizHawk.Client.Common/RomLoader.cs @@ -13,8 +13,7 @@ using BizHawk.Emulation.Cores.Nintendo.SNES; using BizHawk.Emulation.Cores.Sony.PSX; using BizHawk.Emulation.Cores.Arcades.MAME; using BizHawk.Emulation.DiscSystem; -using ICSharpCode.SharpZipLib.Zip.Compression; -using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using System.IO.Compression; namespace BizHawk.Client.Common { @@ -503,10 +502,11 @@ namespace BizHawk.Client.Common private void LoadPSF(string path, CoreComm nextComm, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game) { + // TODO: Why does the PSF loader need CbDeflater provided? Surely this is a matter internal to it. static byte[] CbDeflater(Stream instream, int size) { var ret = new MemoryStream(); - new InflaterInputStream(instream, new Inflater(false)).CopyTo(ret); + new GZipStream(instream, CompressionMode.Decompress).CopyTo(ret); return ret.ToArray(); } var psf = new PSF(); diff --git a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs index 1ad1e80243..a8dce2510e 100644 --- a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs +++ b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs @@ -1,4 +1,5 @@ using System.IO; +using System.IO.Compression; using System.Linq; using System.Text; using BizHawk.Common; @@ -6,7 +7,6 @@ using BizHawk.Common.IOExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores; using BizHawk.Emulation.Cores.Nintendo.SNES; -using ICSharpCode.SharpZipLib.Zip; namespace BizHawk.Client.Common.movie.import { @@ -22,7 +22,7 @@ namespace BizHawk.Client.Common.movie.import Result.Movie.HeaderEntries[HeaderKeys.Core] = CoreNames.Bsnes; // .LSMV movies are .zip files containing data files. - using (var fs = new FileStream(SourceFile.FullName, FileMode.Open, FileAccess.Read)) + using var fs = new FileStream(SourceFile.FullName, FileMode.Open, FileAccess.Read); { byte[] data = new byte[4]; fs.Read(data, 0, 4); @@ -31,9 +31,10 @@ namespace BizHawk.Client.Common.movie.import Result.Errors.Add("This is not a zip file."); return; } + fs.Position = 0; } - using var zip = new ZipFile(SourceFile.FullName); + using var zip = new ZipArchive(fs, ZipArchiveMode.Read, true); var ss = new LibsnesCore.SnesSyncSettings { @@ -44,11 +45,11 @@ namespace BizHawk.Client.Common.movie.import string platform = "SNES"; - foreach (ZipEntry item in zip) + foreach (var item in zip.Entries) { if (item.Name == "authors") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string authors = Encoding.UTF8.GetString(stream.ReadAllBytes()); string authorList = ""; string authorLast = ""; @@ -86,19 +87,19 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "coreversion") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string coreVersion = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.Comments.Add($"CoreOrigin {coreVersion}"); } else if (item.Name == "gamename") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string gameName = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries[HeaderKeys.GameName] = gameName; } else if (item.Name == "gametype") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string gametype = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); // TODO: Handle the other types. @@ -123,7 +124,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "input") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string input = Encoding.UTF8.GetString(stream.ReadAllBytes()); int lineNum = 0; @@ -157,7 +158,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name.StartsWith("moviesram.")) { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); byte[] movieSram = stream.ReadAllBytes(); if (movieSram.Length != 0) { @@ -168,7 +169,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "port1") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string port1 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries["port1"] = port1; ss.LeftPort = LibsnesControllerDeck.ControllerType.Gamepad; @@ -176,7 +177,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "port2") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string port2 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries["port2"] = port2; ss.RightPort = LibsnesControllerDeck.ControllerType.Gamepad; @@ -184,13 +185,13 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "projectid") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string projectId = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries["ProjectID"] = projectId; } else if (item.Name == "rerecords") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string rerecords = Encoding.UTF8.GetString(stream.ReadAllBytes()); int rerecordCount; @@ -208,7 +209,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name.EndsWith(".sha256")) { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string rom = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); int pos = item.Name.LastIndexOf(".sha256"); string name = item.Name.Substring(0, pos); @@ -221,7 +222,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "subtitles") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string subtitles = Encoding.UTF8.GetString(stream.ReadAllBytes()); using (var reader = new StringReader(subtitles)) { @@ -238,19 +239,19 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "starttime.second") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string startSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries["StartSecond"] = startSecond; } else if (item.Name == "starttime.subsecond") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string startSubSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.HeaderEntries["StartSubSecond"] = startSubSecond; } else if (item.Name == "systemid") { - using var stream = zip.GetInputStream(item); + using var stream = item.Open(); string systemId = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.Comments.Add($"{EmulationOrigin} {systemId}"); } diff --git a/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs b/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs index d2fc44fdaa..6320e47a42 100644 --- a/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs +++ b/src/BizHawk.Client.Common/savestates/ZipStateLoader.cs @@ -1,17 +1,17 @@ using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Linq; -using ICSharpCode.SharpZipLib.Zip; namespace BizHawk.Client.Common { public class ZipStateLoader : IDisposable { - private ZipFile _zip; + private ZipArchive _zip; private Version _ver; private bool _isDisposed; - private Dictionary _entriesByName; + private Dictionary _entriesByName; private ZipStateLoader() { @@ -20,7 +20,6 @@ namespace BizHawk.Client.Common public void Dispose() { Dispose(true); - GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) @@ -30,7 +29,7 @@ namespace BizHawk.Client.Common _isDisposed = true; if (disposing) { - _zip.Close(); + _zip.Dispose(); } } } @@ -53,8 +52,8 @@ namespace BizHawk.Client.Common private void PopulateEntries() { - _entriesByName = new Dictionary(); - foreach (ZipEntry z in _zip) + _entriesByName = new Dictionary(); + foreach (var z in _zip.Entries) { string name = z.Name; int i; @@ -84,17 +83,17 @@ namespace BizHawk.Client.Common try { - ret._zip = new ZipFile(filename); + ret._zip = new ZipArchive(new FileStream(filename, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read); ret.PopulateEntries(); if (!isMovieLoad && !ret.GetLump(BinaryStateLump.Versiontag, false, ret.ReadVersion)) { - ret._zip.Close(); + ret._zip.Dispose(); return null; } return ret; } - catch (ZipException) + catch (IOException) { return null; } @@ -109,8 +108,8 @@ namespace BizHawk.Client.Common { if (_entriesByName.TryGetValue(lump.ReadName, out var e)) { - using var zs = _zip.GetInputStream(e); - callback(zs, e.Size); + using var zs = e.Open(); + callback(zs, e.Length); return true; } diff --git a/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs b/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs index 6f2ae5d10e..0ffd71a75a 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/JMDWriter.cs @@ -6,11 +6,10 @@ using System.Text; using System.Threading; using System.Windows.Forms; using BizHawk.Client.Common; -using ICSharpCode.SharpZipLib.Zip.Compression.Streams; -using ICSharpCode.SharpZipLib.Zip.Compression; using BizHawk.Emulation.Common; using BizHawk.Common; +using System.IO.Compression; namespace BizHawk.Client.EmuHawk { @@ -23,6 +22,25 @@ namespace BizHawk.Client.EmuHawk [VideoWriter("jmd", "JMD writer", "Writes a JPC-rr multidump file (JMD). These can be read and further processed with jpc-streamtools. One JMD file contains all audio (uncompressed) and video (compressed).")] public class JmdWriter : IVideoWriter { + // We formerly used a compressor that supported 0-9 values for compression level + private const int NO_COMPRESSION = 0; + private const int BEST_COMPRESSION = 9; + private const int DEFAULT_COMPRESSION = -1; + private const int BEST_SPEED = 1; + + private static CompressionLevel GetCompressionLevel(int v) + { + switch (v) + { + case NO_COMPRESSION: + return CompressionLevel.NoCompression; + case BEST_COMPRESSION: + return CompressionLevel.Optimal; + default: + return CompressionLevel.Fastest; + } + } + /// /// carries private compression information data /// @@ -47,7 +65,7 @@ namespace BizHawk.Client.EmuHawk /// public CodecToken() { - CompressionLevel = Deflater.DEFAULT_COMPRESSION; + CompressionLevel = DEFAULT_COMPRESSION; NumThreads = 3; } } @@ -531,9 +549,9 @@ namespace BizHawk.Client.EmuHawk // load from config and sanitize int t = Math.Min(Math.Max(config.JmdThreads, 1), 6); - int c = Math.Min(Math.Max(config.JmdCompression, Deflater.NO_COMPRESSION), Deflater.BEST_COMPRESSION); + int c = Math.Min(Math.Max(config.JmdCompression, NO_COMPRESSION), BEST_COMPRESSION); - if (!JmdForm.DoCompressionDlg(ref t, ref c, 1, 6, Deflater.NO_COMPRESSION, Deflater.BEST_COMPRESSION, parent.SelfAsHandle)) + if (!JmdForm.DoCompressionDlg(ref t, ref c, 1, 6, NO_COMPRESSION, BEST_COMPRESSION, parent.SelfAsHandle)) return null; config.JmdThreads = ret.NumThreads = t; @@ -703,11 +721,8 @@ namespace BizHawk.Client.EmuHawk m.WriteByte((byte)(v.BufferWidth & 255)); m.WriteByte((byte)(v.BufferHeight >> 8)); m.WriteByte((byte)(v.BufferHeight & 255)); - var g = new DeflaterOutputStream(m, new Deflater(_token.CompressionLevel)) - { - IsStreamOwner = false // leave memory stream open so we can pick its contents - }; + var g = new GZipStream(m, GetCompressionLevel(_token.CompressionLevel), true); // leave memory stream open so we can pick its contents g.Write(v.VideoBuffer, 0, v.VideoBuffer.Length); g.Flush(); g.Close(); @@ -780,7 +795,7 @@ namespace BizHawk.Client.EmuHawk // load from config and sanitize int t = Math.Min(Math.Max(config.JmdThreads, 1), 6); - int c = Math.Min(Math.Max(config.JmdCompression, Deflater.NO_COMPRESSION), Deflater.BEST_COMPRESSION); + int c = Math.Min(Math.Max(config.JmdCompression, NO_COMPRESSION), BEST_COMPRESSION); ct.CompressionLevel = c; ct.NumThreads = t; diff --git a/src/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/src/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 54cfeb1c12..d820c709ab 100755 --- a/src/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/src/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -14,6 +14,7 @@ + diff --git a/src/BizHawk.Client.EmuHawk/packages.config b/src/BizHawk.Client.EmuHawk/packages.config index 4c21a652e3..1f9ed37b28 100644 --- a/src/BizHawk.Client.EmuHawk/packages.config +++ b/src/BizHawk.Client.EmuHawk/packages.config @@ -3,6 +3,5 @@ - \ No newline at end of file diff --git a/src/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs b/src/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs index 467a07bf11..165c5b0b81 100644 --- a/src/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs +++ b/src/BizHawk.Client.EmuHawk/tools/NES/NESMusicRipper.cs @@ -10,8 +10,8 @@ using BizHawk.Client.Common; using BizHawk.Common; using BizHawk.Emulation.Cores.Nintendo.NES; using BizHawk.Emulation.Common; -using ICSharpCode.SharpZipLib.Core; -using ICSharpCode.SharpZipLib.Zip; +using System.IO.Compression; +using System.Linq; namespace BizHawk.Client.EmuHawk { @@ -95,12 +95,6 @@ namespace BizHawk.Client.EmuHawk public NoiseState Noise; } - private class Stupid : IStaticDataSource - { - public Stream Stream { get; set; } - public Stream GetSource() => Stream; - } - private void Export_Click(object sender, EventArgs e) { //acquire target @@ -120,14 +114,13 @@ namespace BizHawk.Client.EmuHawk // load template - var msSongXml = new MemoryStream(); - var zfTemplate = new ZipFile(templatePath); + XElement templateRoot; + using (var zfTemplate = new ZipArchive(new FileStream(templatePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read)) { - using var zis = zfTemplate.GetInputStream(zfTemplate.GetEntry("Song.xml")); - byte[] buffer = new byte[4096]; // 4K is optimum - StreamUtils.Copy(zis, msSongXml, buffer); + var entry = zfTemplate.Entries.Single(e => e.Name == "Song.xml"); + using var stream = entry.Open(); + templateRoot = XElement.Load(stream); } - var templateRoot = XElement.Parse(Encoding.UTF8.GetString(msSongXml.ToArray())); //get the pattern pool, and whack the child nodes var xPatterns = templateRoot.XPathSelectElement("//Patterns"); @@ -412,18 +405,11 @@ namespace BizHawk.Client.EmuHawk File.Delete(outPath); File.Copy(templatePath, outPath); - var msOutXml = new MemoryStream(); - templateRoot.Save(msOutXml); - msOutXml.Flush(); - msOutXml.Position = 0; - var zfOutput = new ZipFile(outPath); - zfOutput.BeginUpdate(); - zfOutput.Add(new Stupid { Stream = msOutXml }, "Song.xml"); - zfOutput.CommitUpdate(); - zfOutput.Close(); - - // for easier debugging, write patterndata XML - ////DUMP_TO_DISK(msOutXml.ToArray()) + using var zfOutput = new ZipArchive(new FileStream(outPath, FileMode.Create, FileAccess.Write), ZipArchiveMode.Create); + using (var stream = zfOutput.CreateEntry("Song.xml").Open()) + { + templateRoot.Save(stream); + } } private readonly List _log = new List(); diff --git a/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs b/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs index b06cc8c9af..ebe4766a98 100644 --- a/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs @@ -7,8 +7,7 @@ using BizHawk.Client.Common; using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Cores.PCEngine; using BizHawk.Emulation.Common; - -using ICSharpCode.SharpZipLib.Zip; +using System.IO.Compression; namespace BizHawk.Client.EmuHawk { @@ -176,16 +175,10 @@ namespace BizHawk.Client.EmuHawk string tmpFilename = $"{Path.GetTempFileName()}.zip"; using (var stream = new FileStream(tmpFilename, FileMode.Create, FileAccess.Write, FileShare.Read)) { - var zip = new ZipOutputStream(stream) - { - IsStreamOwner = false, - UseZip64 = UseZip64.Off - }; + using var zip = new ZipArchive(stream, ZipArchiveMode.Create); foreach (var entry in _psgEntries) { - var ze = new ZipEntry($"{entry.Name}.wav") { CompressionMethod = CompressionMethod.Deflated }; - zip.PutNextEntry(ze); var ms = new MemoryStream(); var bw = new BinaryWriter(ms); bw.Write(EmptyWav, 0, EmptyWav.Length); @@ -204,13 +197,11 @@ namespace BizHawk.Client.EmuHawk bw.Flush(); var buf = ms.GetBuffer(); - zip.Write(buf, 0, (int)ms.Length); - zip.Flush(); - zip.CloseEntry(); - } - zip.Close(); - stream.Flush(); + var ze = zip.CreateEntry($"{entry.Name}.wav", CompressionLevel.Fastest); + using var zipstream = ze.Open(); + zipstream.Write(buf, 0, (int)ms.Length); + } } System.Diagnostics.Process.Start(tmpFilename); }