From 9fc299ccb987e4273a69db1cc5e92a3823653326 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 22 Jun 2016 14:17:27 -0700 Subject: [PATCH] [ArchiveTools, SimpleSort] Attempt to play nicely with Mono --- SabreTools.Helper/Tools/ArchiveTools.cs | 141 +++++++++++++++++++++++- SimpleSort/SimpleSort.cs | 28 ++++- 2 files changed, 159 insertions(+), 10 deletions(-) diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs index bab9cd3f..65fef58e 100644 --- a/SabreTools.Helper/Tools/ArchiveTools.cs +++ b/SabreTools.Helper/Tools/ArchiveTools.cs @@ -1,5 +1,10 @@ -using SharpCompress.Common; +using SharpCompress.Archive; +using SharpCompress.Archive.Zip; +using SharpCompress.Common; using SharpCompress.Reader; +using SharpCompress.Reader.Zip; +using SharpCompress.Writer; +using SharpCompress.Writer.Zip; using System; using System.Collections.Generic; using System.IO; @@ -12,7 +17,7 @@ namespace SabreTools.Helper public class ArchiveTools { /// - /// Copy a file either to an output archive or to an output folder + /// Copy a file to an output archive /// /// Input filename to be moved /// Output directory to build to @@ -21,7 +26,7 @@ namespace SabreTools.Helper { string archiveFileName = Path.Combine(output, rom.Game + ".zip"); - ZipArchive outarchive = null; + System.IO.Compression.ZipArchive outarchive = null; try { if (!File.Exists(archiveFileName)) @@ -61,6 +66,55 @@ namespace SabreTools.Helper } } + /// + /// Copy a file to an output archive using SharpCompress + /// + /// Input filename to be moved + /// Output directory to build to + /// RomData representing the new information + public static void WriteToManagedArchive(string input, string output, Rom rom) + { + string archiveFileName = Path.Combine(output, rom.Game + ".zip"); + + // Delete an empty file first + if (File.Exists(archiveFileName) && new FileInfo(archiveFileName).Length == 0) + { + File.Delete(archiveFileName); + } + + // Get if the file should be written out + bool newfile = File.Exists(archiveFileName) && new FileInfo(archiveFileName).Length != 0; + + using (SharpCompress.Archive.Zip.ZipArchive archive = (newfile + ? ArchiveFactory.Open(archiveFileName, Options.LookForHeader) as SharpCompress.Archive.Zip.ZipArchive + : ArchiveFactory.Create(ArchiveType.Zip) as SharpCompress.Archive.Zip.ZipArchive)) + { + try + { + if (File.Exists(input)) + { + archive.AddEntry(rom.Name, input); + } + else if (Directory.Exists(input)) + { + archive.AddAllFromDirectory(input, "*", SearchOption.AllDirectories); + } + + archive.SaveTo(archiveFileName + ".tmp", CompressionType.Deflate); + } + catch (Exception ex) + { + // Don't log archive write errors + } + } + + if (File.Exists(archiveFileName + ".tmp")) + { + File.Delete(archiveFileName); + File.Move(archiveFileName + ".tmp", archiveFileName); + } + } + /// /// Attempt to extract a file as an archive /// @@ -259,7 +313,7 @@ namespace SabreTools.Helper } IReader reader = null; - ZipArchive outarchive = null; + System.IO.Compression.ZipArchive outarchive = null; try { reader = ReaderFactory.Open(File.OpenRead(inputArchive)); @@ -282,7 +336,7 @@ namespace SabreTools.Helper if (outarchive.Mode == ZipArchiveMode.Create || outarchive.GetEntry(destEntryName) == null) { - ZipArchiveEntry iae = outarchive.CreateEntry(destEntryName, CompressionLevel.Optimal) as ZipArchiveEntry; + System.IO.Compression.ZipArchiveEntry iae = outarchive.CreateEntry(destEntryName, CompressionLevel.Optimal) as System.IO.Compression.ZipArchiveEntry; using (Stream iaestream = iae.Open()) { @@ -308,6 +362,83 @@ namespace SabreTools.Helper return success; } + /// + /// Attempt to copy a file between archives using SharpCompress + /// + /// Source archive name + /// Destination archive name + /// Input entry name + /// Output entry name + /// Logger object for file and console output + /// True if the copy was a success, false otherwise + public static bool CopyFileBetweenManagedArchives(string inputArchive, string outputArchive, + string sourceEntryName, string destEntryName, Logger logger) + { + bool success = false; + + // First get the archive types + ArchiveType? iat = GetCurrentArchiveType(inputArchive, logger); + ArchiveType? oat = (File.Exists(outputArchive) ? GetCurrentArchiveType(outputArchive, logger) : ArchiveType.Zip); + + // If we got back null (or the output is not a Zipfile), then it's not an archive, so we we return + if (iat == null || (oat == null || oat != ArchiveType.Zip) || inputArchive == outputArchive) + { + return success; + } + + try + { + using (IReader reader = ReaderFactory.Open(File.OpenRead(inputArchive))) + { + if (iat == ArchiveType.Zip || iat == ArchiveType.SevenZip || iat == ArchiveType.Rar) + { + while (reader.MoveToNextEntry()) + { + logger.Log("Current entry name: '" + reader.Entry.Key + "'"); + if (reader.Entry != null && reader.Entry.Key.Contains(sourceEntryName)) + { + // Get if the file should be written out + bool newfile = File.Exists(outputArchive) && new FileInfo(outputArchive).Length != 0; + + using (SharpCompress.Archive.Zip.ZipArchive archive = (newfile + ? ArchiveFactory.Open(outputArchive, Options.LookForHeader) as SharpCompress.Archive.Zip.ZipArchive + : ArchiveFactory.Create(ArchiveType.Zip) as SharpCompress.Archive.Zip.ZipArchive)) + { + try + { + Stream tempstream = new MemoryStream(); + reader.WriteEntryTo(tempstream); + archive.AddEntry(destEntryName, tempstream); + + archive.SaveTo(outputArchive + ".tmp", CompressionType.Deflate); + } + catch (Exception ex) + { + // Don't log archive write errors + } + } + + if (File.Exists(outputArchive + ".tmp")) + { + File.Delete(outputArchive); + File.Move(outputArchive + ".tmp", outputArchive); + } + + success = true; + } + } + } + } + } + catch (Exception ex) + { + logger.Error(ex.ToString()); + success = false; + } + + return success; + } + /// /// Generate a list of RomData objects from the header values in an archive /// diff --git a/SimpleSort/SimpleSort.cs b/SimpleSort/SimpleSort.cs index 2257b250..272405a3 100644 --- a/SimpleSort/SimpleSort.cs +++ b/SimpleSort/SimpleSort.cs @@ -402,7 +402,7 @@ namespace SabreTools } else { - ArchiveTools.WriteToArchive(input, _outdir, found); + ArchiveTools.WriteToManagedArchive(input, _outdir, found); } } @@ -449,7 +449,7 @@ namespace SabreTools } else { - ArchiveTools.WriteToArchive(newinput, _outdir, found); + ArchiveTools.WriteToManagedArchive(newinput, _outdir, found); } // Then output the headered rom (renamed) @@ -475,7 +475,7 @@ namespace SabreTools else { _logger.Log("Matched name: " + newfound.Name); - ArchiveTools.WriteToArchive(input, _outdir, newfound); + ArchiveTools.WriteToManagedArchive(input, _outdir, newfound); } } @@ -535,8 +535,26 @@ namespace SabreTools { // Copy file between archives _logger.User("Rebuilding file '" + Path.GetFileName(rom.Name) + "' to '" + found.Name + "'"); - string archiveFileName = Path.Combine(_outdir, found.Game + ".zip"); - ArchiveTools.CopyFileBetweenArchives(input, archiveFileName, rom.Name, found.Name, _logger); + + if (Build.MonoEnvironment) + { + string outfile = ArchiveTools.ExtractSingleItemFromArchive(input, rom.Name, _tempdir, _logger); + if (File.Exists(outfile)) + { + ArchiveTools.WriteToManagedArchive(outfile, _outdir, found); + + try + { + File.Delete(outfile); + } + catch { } + } + } + else + { + string archiveFileName = Path.Combine(_outdir, found.Game + ".zip"); + ArchiveTools.CopyFileBetweenManagedArchives(input, archiveFileName, rom.Name, found.Name, _logger); + } } } }