From 305a8db75af0eb5e427e6a1e3e998bf9504cbd97 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 25 Oct 2016 21:20:43 -0700 Subject: [PATCH] [ArchiveTools] Add TAR output --- SabreTools.Helper/Data/Build.cs | 2 +- SabreTools.Helper/Dats/DatFile.cs | 1 + SabreTools.Helper/README.1ST | 2 +- SabreTools.Helper/Tools/ArchiveTools.cs | 71 ++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/SabreTools.Helper/Data/Build.cs b/SabreTools.Helper/Data/Build.cs index 50eeacc5..f21e6116 100644 --- a/SabreTools.Helper/Data/Build.cs +++ b/SabreTools.Helper/Data/Build.cs @@ -210,7 +210,7 @@ namespace SabreTools.Helper.Data helptext.Add(" -qs, --quick Enable quick scanning of archives"); helptext.Add(" -ad, --add-date Add original dates from DAT, if possible"); //helptext.Add(" -t7z Enable Torrent7z output"); - //helptext.Add(" -tar Enable TAR output"); + helptext.Add(" -tar Enable TAR output"); helptext.Add(" -tgz Enable TorrentGZ output"); helptext.Add(" -r, --romba Enable Romba depot dir output"); //helptext.Add(" -tlrz Enable TorrentLRZ output"); diff --git a/SabreTools.Helper/Dats/DatFile.cs b/SabreTools.Helper/Dats/DatFile.cs index 15837af3..b235466f 100644 --- a/SabreTools.Helper/Dats/DatFile.cs +++ b/SabreTools.Helper/Dats/DatFile.cs @@ -4752,6 +4752,7 @@ namespace SabreTools.Helper.Dats } break; case OutputFormat.TapeArchive: + ArchiveTools.WriteTAR(pathsToFiles, outDir, romsInGame, logger); break; case OutputFormat.Torrent7Zip: break; diff --git a/SabreTools.Helper/README.1ST b/SabreTools.Helper/README.1ST index 96a93da1..a5e447c1 100644 --- a/SabreTools.Helper/README.1ST +++ b/SabreTools.Helper/README.1ST @@ -384,7 +384,7 @@ Options: files. This format is based on the LZMA container format 7zip, but with custom header information. This is currently unused by any major application. - -tar Enable Tape ARchive output [NOT IMPLEMENTED] + -tar Enable Tape ARchive output Instead of outputting the fiels to folder, files will be rebuilt to Tape ARchive (TAR) files. This format is a standardized storage archive without any compression, usually used with other compression formats around it. It is widely used in backup applications diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs index adddbe04..5a082978 100644 --- a/SabreTools.Helper/Tools/ArchiveTools.cs +++ b/SabreTools.Helper/Tools/ArchiveTools.cs @@ -11,6 +11,7 @@ using Ionic.Zlib; using ROMVault2.SupportedFiles.Zip; using SharpCompress.Archive; using SharpCompress.Archive.SevenZip; +using SharpCompress.Archive.Tar; using SharpCompress.Common; using SharpCompress.Reader; @@ -540,6 +541,7 @@ namespace SabreTools.Helper.Tools /// ArchiveType of inputted file (null on error) public static ArchiveType? GetCurrentArchiveType(string input, Logger logger) { + ArchiveType? outtype = null; // First line of defense is going to be the extension, for better or worse @@ -768,7 +770,74 @@ namespace SabreTools.Helper.Tools /// True if the archive was written properly, false otherwise public static bool WriteTAR(List inputFiles, string outDir, List roms, Logger logger, bool date = false) { - return false; + bool success = false; + + // If the number of inputs is less than the number of available roms, return + if (inputFiles.Count < roms.Count) + { + return success; + } + + // If one of the files doesn't exist, return + foreach (string file in inputFiles) + { + if (!File.Exists(file)) + { + return success; + } + } + + // Get the output archive name from the first rebuild rom + string archiveFileName = Path.Combine(outDir, roms[0].Machine.Name + (roms[0].Machine.Name.EndsWith(".tar") ? "" : ".tar")); + + // Set internal variables + Stream tarstream = new MemoryStream(); + TarArchive tarchive = TarArchive.Create(); + + try + { + // If the full output path doesn't exist, create it + if (!Directory.Exists(Path.GetDirectoryName(archiveFileName))) + { + Directory.CreateDirectory(Path.GetDirectoryName(archiveFileName)); + } + + // We can only overwrite at this point, sorry + tarstream = File.Open(archiveFileName, FileMode.Create, FileAccess.Write); + + // Map all inputs to index + Dictionary inputIndexMap = new Dictionary(); + for (int i = 0; i < inputFiles.Count; i++) + { + inputIndexMap.Add(roms[i].Name.Replace('\\', '/'), i); + } + + // Sort the keys in TZIP order + List keys = inputIndexMap.Keys.ToList(); + keys.Sort(ZipFile.TorrentZipStringCompare); + + // Now add each of the files + foreach (string key in keys) + { + int index = inputIndexMap[key]; + tarchive.AddEntry(key, inputFiles[index]); + } + + tarchive.SaveTo(tarstream, new CompressionInfo { Type = CompressionType.None }); + success = true; + } + catch (Exception ex) + { + success = false; + logger.Error(ex.ToString()); + } + finally + { + tarstream?.Dispose(); + tarchive?.Dispose(); + } + + return success; } ///