From d9bc125e4a310a02bc7c6be54a234af27b3f9852 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 22 Sep 2016 17:46:21 -0700 Subject: [PATCH] [DatFile] Move DFD features to DatFile; make writing object-based --- RombaSharp/Partials/RombaSharp_Inits.cs | 7 +- SabreTools.Helper/Objects/DATFromDir.cs | 451 -------------- SabreTools.Helper/Objects/Dat/DatFile.cs | 686 ++++++++++++++++----- SabreTools.Helper/Objects/SimpleSort.cs | 10 +- SabreTools.Helper/SabreTools.Helper.csproj | 1 - SabreTools/Partials/SabreTools_Inits.cs | 5 +- 6 files changed, 556 insertions(+), 604 deletions(-) delete mode 100644 SabreTools.Helper/Objects/DATFromDir.cs diff --git a/RombaSharp/Partials/RombaSharp_Inits.cs b/RombaSharp/Partials/RombaSharp_Inits.cs index 8aca316f..6a35ad56 100644 --- a/RombaSharp/Partials/RombaSharp_Inits.cs +++ b/RombaSharp/Partials/RombaSharp_Inits.cs @@ -69,10 +69,9 @@ namespace SabreTools Logger logger = new Logger(false, ""); foreach (string input in inputs) { - DATFromDir dfd = new DATFromDir(input, datdata, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */, - true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, false /* copyFiles */, 4 /* maxDegreeOfParallelism */, _logger); - dfd.Start(); - DatFile.WriteDatfile(dfd.DatData, "", logger); + datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */, + true /* enableGzip */, false /* addBlanks */, false /* addDate */, "__temp__" /* tempDir */, false /* copyFiles */, 4 /* maxDegreeOfParallelism */, _logger); + datdata.WriteToFile("", logger); } logger.Close(); } diff --git a/SabreTools.Helper/Objects/DATFromDir.cs b/SabreTools.Helper/Objects/DATFromDir.cs deleted file mode 100644 index 420699c1..00000000 --- a/SabreTools.Helper/Objects/DATFromDir.cs +++ /dev/null @@ -1,451 +0,0 @@ -using SabreTools.Helper; -using SharpCompress.Common; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace SabreTools -{ - /// - /// Create a DAT file from a specified file, directory, or set thereof - /// - public class DATFromDir - { - // Path-related variables - private string _basePath; - private string _tempDir; - - // User specified inputs - private DatFile _datdata; - private bool _noMD5; - private bool _noSHA1; - private bool _bare; - private bool _archivesAsFiles; - private bool _enableGzip; - private bool _addBlanks; - private bool _addDate; - private bool _copyFiles; - private int _maxDegreeOfParallelism; - - // Other required variables - private Logger _logger; - - // Public variables - public DatFile DatData - { - get { return _datdata; } - } - - /// - /// Create a new DATFromDir object - /// - /// Base folder to be used in creating the DAT - /// DatData object representing the requested output DAT - /// True if MD5 hashes should be skipped over, false otherwise - /// True if SHA-1 hashes should be skipped over, false otherwise - /// True if the date should be omitted from the DAT, false otherwise - /// True if archives should be treated as files, false otherwise - /// True if GZIP archives should be treated as files, false otherwise - /// True if blank items should be created for empty folders, false otherwise - /// True if dates should be archived for all files, false otherwise - /// Name of the directory to create a temp folder in (blank is current directory) - /// True if files should be copied to the temp directory before hashing, false otherwise - /// Integer representing the maximum amount of parallelization to be used - /// Logger object for console and file output - public DATFromDir(string basePath, DatFile datdata, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles, - bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, int maxDegreeOfParallelism, Logger logger) - { - _basePath = Path.GetFullPath(basePath); - _datdata = datdata; - _datdata.Files = new Dictionary>(); - _datdata.Files.Add("null", new List()); - _noMD5 = noMD5; - _noSHA1 = noSHA1; - _bare = bare; - _archivesAsFiles = archivesAsFiles; - _enableGzip = enableGzip; - _addBlanks = addBlanks; - _addDate = addDate; - _tempDir = (String.IsNullOrEmpty(tempDir) ? Path.GetTempPath() : tempDir); - _copyFiles = copyFiles; - _maxDegreeOfParallelism = maxDegreeOfParallelism; - _logger = logger; - } - - /// - /// Process the file, folder, or list of some combination into a DAT file - /// - /// True if the DAT could be created, false otherwise - public bool Start() - { - // If the description is defined but not the name, set the name from the description - if (String.IsNullOrEmpty(_datdata.Name) && !String.IsNullOrEmpty(_datdata.Description)) - { - _datdata.Name = _datdata.Description; - } - - // If the name is defined but not the description, set the description from the name - else if (!String.IsNullOrEmpty(_datdata.Name) && String.IsNullOrEmpty(_datdata.Description)) - { - _datdata.Description = _datdata.Name + (_bare ? "" : " (" + _datdata.Date + ")"); - } - - // If neither the name or description are defined, set them from the automatic values - else if (String.IsNullOrEmpty(_datdata.Name) && String.IsNullOrEmpty(_datdata.Description)) - { - _datdata.Name = _basePath.Split(Path.DirectorySeparatorChar).Last(); - _datdata.Description = _datdata.Name + (_bare ? "" : " (" + _datdata.Date + ")"); - } - - // Process the input folder - _logger.Log("Folder found: " + _basePath); - - // Process the files in all subfolders - List files = Directory.EnumerateFiles(_basePath, "*", SearchOption.AllDirectories).ToList(); - Parallel.ForEach(files, - new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism }, - item => - { - ProcessPossibleArchive(item); - }); - - // Now find all folders that are empty, if we are supposed to - if (!_datdata.Romba && _addBlanks) - { - List empties = Directory.EnumerateDirectories(_basePath, "*", SearchOption.AllDirectories).ToList(); - Parallel.ForEach(empties, - new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism }, - dir => - { - if (Directory.EnumerateFiles(dir, "*", SearchOption.TopDirectoryOnly).Count() == 0) - { - // Get the full path for the directory - string fulldir = Path.GetFullPath(dir); - - // Set the temporary variables - string gamename = ""; - string romname = ""; - - // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom - if (_datdata.Type == "SuperDAT") - { - gamename = fulldir.Remove(0, _basePath.Length + 1); - romname = "-"; - } - - // Otherwise, we want just the top level folder as the game, and the file as everything else - else - { - gamename = fulldir.Remove(0, _basePath.Length + 1).Split(Path.DirectorySeparatorChar)[0]; - romname = Path.Combine(fulldir.Remove(0, _basePath.Length + 1 + gamename.Length), "-"); - } - - // Sanitize the names - if (gamename.StartsWith(Path.DirectorySeparatorChar.ToString())) - { - gamename = gamename.Substring(1); - } - if (gamename.EndsWith(Path.DirectorySeparatorChar.ToString())) - { - gamename = gamename.Substring(0, gamename.Length - 1); - } - if (romname.StartsWith(Path.DirectorySeparatorChar.ToString())) - { - romname = romname.Substring(1); - } - if (romname.EndsWith(Path.DirectorySeparatorChar.ToString())) - { - romname = romname.Substring(0, romname.Length - 1); - } - - _logger.Log("Adding blank empty folder: " + gamename); - _datdata.Files["null"].Add(new Rom(romname, gamename)); - } - }); - } - - // Now that we're done, delete the temp folder (if it's not the default) - _logger.User("Cleaning temp folder"); - try - { - if (_tempDir != Path.GetTempPath()) - { - Directory.Delete(_tempDir, true); - } - } - catch - { - // Just absorb the error for now - } - - return true; - } - - /// - /// Check a given file for hashes, based on current settings - /// - /// Filename of the item to be checked - private void ProcessPossibleArchive(string item) - { - // Define the temporary directory - string tempSubDir = Path.GetFullPath(Path.Combine(_tempDir, Path.GetRandomFileName())) + Path.DirectorySeparatorChar; - - // Special case for if we are in Romba mode (all names are supposed to be SHA-1 hashes) - if (_datdata.Romba) - { - Rom rom = FileTools.GetTorrentGZFileInfo(item, _logger); - - // If the rom is valid, write it out - if (rom.Name != null) - { - // Add the list if it doesn't exist already - string key = rom.Size + "-" + rom.CRC; - - lock (_datdata.Files) - { - if (!_datdata.Files.ContainsKey(key)) - { - _datdata.Files.Add(key, new List()); - } - - _datdata.Files[key].Add(rom); - _logger.User("File added: " + Path.GetFileNameWithoutExtension(item) + Environment.NewLine); - } - - } - else - { - _logger.User("File not added: " + Path.GetFileNameWithoutExtension(item) + Environment.NewLine); - return; - } - - return; - } - - // If we're copying files, copy it first and get the new filename - string newItem = item; - string newBasePath = _basePath; - if (_copyFiles) - { - newBasePath = Path.Combine(_tempDir, Path.GetRandomFileName()); - newItem = Path.GetFullPath(Path.Combine(newBasePath, Path.GetFullPath(item).Remove(0, _basePath.Length + 1))); - Directory.CreateDirectory(Path.GetDirectoryName(newItem)); - File.Copy(item, newItem, true); - } - - // If both deep hash skip flags are set, do a quickscan - if (_noMD5 && _noSHA1) - { - ArchiveType? type = FileTools.GetCurrentArchiveType(newItem, _logger); - - // If we have an archive, scan it - if (type != null && !_archivesAsFiles) - { - List extracted = FileTools.GetArchiveFileInfo(newItem, _logger); - - foreach (Rom rom in extracted) - { - ProcessFileHelper(newItem, - rom, - _basePath, - (Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, _basePath.Length) + Path.GetFileNameWithoutExtension(item)); - } - } - // Otherwise, just get the info on the file itself - else if (File.Exists(newItem)) - { - ProcessFile(newItem, newBasePath, ""); - } - } - // Otherwise, attempt to extract the files to the temporary directory - else - { - bool encounteredErrors = FileTools.ExtractArchive(newItem, - tempSubDir, - (_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), - (!_archivesAsFiles && _enableGzip ? ArchiveScanLevel.Internal : ArchiveScanLevel.External), - (_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), - (_archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), - _logger); - - // If the file was an archive and was extracted successfully, check it - if (!encounteredErrors) - { - _logger.Log(Path.GetFileName(item) + " treated like an archive"); - List extracted = Directory.EnumerateFiles(tempSubDir, "*", SearchOption.AllDirectories).ToList(); - Parallel.ForEach(extracted, - new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism }, - entry => - { - ProcessFile(entry, - tempSubDir, - Path.Combine((_datdata.Type == "SuperDAT" - ? (Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, _basePath.Length) - : ""), - Path.GetFileNameWithoutExtension(item))); - }); - } - // Otherwise, just get the info on the file itself - else if (File.Exists(newItem)) - { - ProcessFile(newItem, newBasePath, ""); - } - } - - // Cue to delete the file if it's a copy - if (_copyFiles && item != newItem) - { - try - { - Directory.Delete(newBasePath, true); - } - catch { } - } - - // Delete the sub temp directory - if (Directory.Exists(tempSubDir)) - { - Directory.Delete(tempSubDir, true); - } - } - - /// - /// Process a single file as a file - /// - /// File to be added - /// Path the represents the parent directory - /// Parent game to be used - private void ProcessFile(string item, string basepath, string parent) - { - _logger.Log(Path.GetFileName(item) + " treated like a file"); - Rom rom = FileTools.GetSingleFileInfo(item, noMD5:_noMD5, noSHA1: _noSHA1, date: _addDate); - - ProcessFileHelper(item, rom, basepath, parent); - } - - /// - /// Process a single file as a file (with found Rom data) - /// - /// File to be added - /// Rom data to be used to write to file - /// Path the represents the parent directory - /// Parent game to be used - private void ProcessFileHelper(string item, DatItem datItem, string basepath, string parent) - { - // If the datItem isn't a Rom or Disk, return - if (datItem.Type != ItemType.Rom && datItem.Type != ItemType.Disk) - { - return; - } - - string key = ""; - if (datItem.Type == ItemType.Rom) - { - key = ((Rom)datItem).Size + "-" + ((Rom)datItem).CRC; - } - else - { - key = ((Disk)datItem).MD5; - } - - // Add the list if it doesn't exist already - lock (_datdata.Files) - { - if (!_datdata.Files.ContainsKey(key)) - { - _datdata.Files.Add(key, new List()); - } - } - - try - { - // If the basepath ends with a directory separator, remove it - if (!basepath.EndsWith(Path.DirectorySeparatorChar.ToString())) - { - basepath += Path.DirectorySeparatorChar.ToString(); - } - - // Make sure we have the full item path - item = Path.GetFullPath(item); - - // Get the data to be added as game and item names - string gamename = ""; - string romname = ""; - - // If the parent is blank, then we have a non-archive file - if (parent == "") - { - // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom - if (_datdata.Type == "SuperDAT") - { - gamename = Path.GetDirectoryName(item.Remove(0, basepath.Length)); - romname = Path.GetFileName(item); - } - - // Otherwise, we want just the top level folder as the game, and the file as everything else - else - { - gamename = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0]; - romname = item.Remove(0, (Path.Combine(basepath, gamename).Length)); - } - } - - // Otherwise, we assume that we have an archive - else - { - // If we have a SuperDAT, we want the archive name as the game, and the file as everything else (?) - if (_datdata.Type == "SuperDAT") - { - gamename = parent; - romname = item.Remove(0, basepath.Length); - } - - // Otherwise, we want the archive name as the game, and the file as everything else - else - { - gamename = parent; - romname = item.Remove(0, basepath.Length); - } - } - - // Sanitize the names - if (gamename.StartsWith(Path.DirectorySeparatorChar.ToString())) - { - gamename = gamename.Substring(1); - } - if (gamename.EndsWith(Path.DirectorySeparatorChar.ToString())) - { - gamename = gamename.Substring(0, gamename.Length - 1); - } - if (romname.StartsWith(Path.DirectorySeparatorChar.ToString())) - { - romname = romname.Substring(1); - } - if (romname.EndsWith(Path.DirectorySeparatorChar.ToString())) - { - romname = romname.Substring(0, romname.Length - 1); - } - - // Update rom information - datItem.Name = romname; - datItem.MachineName = gamename; - datItem.MachineDescription = gamename; - - // Add the file information to the DAT - lock (_datdata.Files) - { - _datdata.Files[key].Add(datItem); - } - - _logger.User("File added: " + romname + Environment.NewLine); - } - catch (IOException ex) - { - _logger.Error(ex.ToString()); - return; - } - } - } -} diff --git a/SabreTools.Helper/Objects/Dat/DatFile.cs b/SabreTools.Helper/Objects/Dat/DatFile.cs index e9d07454..f1a3c445 100644 --- a/SabreTools.Helper/Objects/Dat/DatFile.cs +++ b/SabreTools.Helper/Objects/Dat/DatFile.cs @@ -1,4 +1,5 @@ -using System; +using SharpCompress.Common; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -2337,6 +2338,415 @@ namespace SabreTools.Helper #endregion + #region Populate DAT from Directory + + /// + /// Create a new Dat from a directory + /// + /// Base folder to be used in creating the DAT + /// True if MD5 hashes should be skipped over, false otherwise + /// True if SHA-1 hashes should be skipped over, false otherwise + /// True if the date should be omitted from the DAT, false otherwise + /// True if archives should be treated as files, false otherwise + /// True if GZIP archives should be treated as files, false otherwise + /// True if blank items should be created for empty folders, false otherwise + /// True if dates should be archived for all files, false otherwise + /// Name of the directory to create a temp folder in (blank is current directory) + /// True if files should be copied to the temp directory before hashing, false otherwise + /// Integer representing the maximum amount of parallelization to be used + /// Logger object for console and file output + public bool PopulateDatFromDir(string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles, + bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, int maxDegreeOfParallelism, Logger logger) + { + // If the description is defined but not the name, set the name from the description + if (String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description)) + { + Name = Description; + } + + // If the name is defined but not the description, set the description from the name + else if (!String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) + { + Description = Name + (bare ? "" : " (" + Date + ")"); + } + + // If neither the name or description are defined, set them from the automatic values + else if (String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) + { + Name = basePath.Split(Path.DirectorySeparatorChar).Last(); + Description = Name + (bare ? "" : " (" + Date + ")"); + } + + // Process the input folder + logger.Log("Folder found: " + basePath); + + // Process the files in all subfolders + List files = Directory.EnumerateFiles(basePath, "*", SearchOption.AllDirectories).ToList(); + Parallel.ForEach(files, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }, + item => + { + DFDProcessPossibleArchive(item, basePath, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, + tempDir, copyFiles, maxDegreeOfParallelism, logger); + }); + + // Now find all folders that are empty, if we are supposed to + if (!Romba && addBlanks) + { + List empties = Directory.EnumerateDirectories(basePath, "*", SearchOption.AllDirectories).ToList(); + Parallel.ForEach(empties, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }, + dir => + { + if (Directory.EnumerateFiles(dir, "*", SearchOption.TopDirectoryOnly).Count() == 0) + { + // Get the full path for the directory + string fulldir = Path.GetFullPath(dir); + + // Set the temporary variables + string gamename = ""; + string romname = ""; + + // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom + if (Type == "SuperDAT") + { + gamename = fulldir.Remove(0, basePath.Length + 1); + romname = "-"; + } + + // Otherwise, we want just the top level folder as the game, and the file as everything else + else + { + gamename = fulldir.Remove(0, basePath.Length + 1).Split(Path.DirectorySeparatorChar)[0]; + romname = Path.Combine(fulldir.Remove(0, basePath.Length + 1 + gamename.Length), "-"); + } + + // Sanitize the names + if (gamename.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + gamename = gamename.Substring(1); + } + if (gamename.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + gamename = gamename.Substring(0, gamename.Length - 1); + } + if (romname.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + romname = romname.Substring(1); + } + if (romname.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + romname = romname.Substring(0, romname.Length - 1); + } + + logger.Log("Adding blank empty folder: " + gamename); + Files["null"].Add(new Rom(romname, gamename)); + } + }); + } + + // Now that we're done, delete the temp folder (if it's not the default) + logger.User("Cleaning temp folder"); + try + { + if (tempDir != Path.GetTempPath()) + { + Directory.Delete(tempDir, true); + } + } + catch + { + // Just absorb the error for now + } + + return true; + } + + /// + /// Check a given file for hashes, based on current settings + /// + /// Filename of the item to be checked + /// Base folder to be used in creating the DAT + /// True if MD5 hashes should be skipped over, false otherwise + /// True if SHA-1 hashes should be skipped over, false otherwise + /// True if the date should be omitted from the DAT, false otherwise + /// True if archives should be treated as files, false otherwise + /// True if GZIP archives should be treated as files, false otherwise + /// True if blank items should be created for empty folders, false otherwise + /// True if dates should be archived for all files, false otherwise + /// Name of the directory to create a temp folder in (blank is current directory) + /// True if files should be copied to the temp directory before hashing, false otherwise + /// Integer representing the maximum amount of parallelization to be used + /// Logger object for console and file output + private void DFDProcessPossibleArchive(string item, string basePath, bool noMD5, bool noSHA1, bool bare, bool archivesAsFiles, + bool enableGzip, bool addBlanks, bool addDate, string tempDir, bool copyFiles, int maxDegreeOfParallelism, Logger logger) + { + // Define the temporary directory + string tempSubDir = Path.GetFullPath(Path.Combine(tempDir, Path.GetRandomFileName())) + Path.DirectorySeparatorChar; + + // Special case for if we are in Romba mode (all names are supposed to be SHA-1 hashes) + if (Romba) + { + Rom rom = FileTools.GetTorrentGZFileInfo(item, logger); + + // If the rom is valid, write it out + if (rom.Name != null) + { + // Add the list if it doesn't exist already + string key = rom.Size + "-" + rom.CRC; + + lock (Files) + { + if (!Files.ContainsKey(key)) + { + Files.Add(key, new List()); + } + + Files[key].Add(rom); + logger.User("File added: " + Path.GetFileNameWithoutExtension(item) + Environment.NewLine); + } + + } + else + { + logger.User("File not added: " + Path.GetFileNameWithoutExtension(item) + Environment.NewLine); + return; + } + + return; + } + + // If we're copying files, copy it first and get the new filename + string newItem = item; + string newBasePath = basePath; + if (copyFiles) + { + newBasePath = Path.Combine(tempDir, Path.GetRandomFileName()); + newItem = Path.GetFullPath(Path.Combine(newBasePath, Path.GetFullPath(item).Remove(0, basePath.Length + 1))); + Directory.CreateDirectory(Path.GetDirectoryName(newItem)); + File.Copy(item, newItem, true); + } + + // If both deep hash skip flags are set, do a quickscan + if (noMD5 && noSHA1) + { + ArchiveType? type = FileTools.GetCurrentArchiveType(newItem, logger); + + // If we have an archive, scan it + if (type != null && !archivesAsFiles) + { + List extracted = FileTools.GetArchiveFileInfo(newItem, logger); + + foreach (Rom rom in extracted) + { + DFDProcessFileHelper(newItem, + rom, + basePath, + (Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, basePath.Length) + Path.GetFileNameWithoutExtension(item), + logger); + } + } + // Otherwise, just get the info on the file itself + else if (File.Exists(newItem)) + { + DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, logger); + } + } + // Otherwise, attempt to extract the files to the temporary directory + else + { + bool encounteredErrors = FileTools.ExtractArchive(newItem, + tempSubDir, + (archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), + (!archivesAsFiles && enableGzip ? ArchiveScanLevel.Internal : ArchiveScanLevel.External), + (archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), + (archivesAsFiles ? ArchiveScanLevel.External : ArchiveScanLevel.Internal), + logger); + + // If the file was an archive and was extracted successfully, check it + if (!encounteredErrors) + { + logger.Log(Path.GetFileName(item) + " treated like an archive"); + List extracted = Directory.EnumerateFiles(tempSubDir, "*", SearchOption.AllDirectories).ToList(); + Parallel.ForEach(extracted, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism }, + entry => + { + DFDProcessFile(entry, + Path.Combine((Type == "SuperDAT" + ? (Path.GetDirectoryName(Path.GetFullPath(item)) + Path.DirectorySeparatorChar).Remove(0, basePath.Length) + : ""), + Path.GetFileNameWithoutExtension(item)), + tempSubDir, + noMD5, + noSHA1, + addDate, + logger); + }); + } + // Otherwise, just get the info on the file itself + else if (File.Exists(newItem)) + { + DFDProcessFile(newItem, "", newBasePath, noMD5, noSHA1, addDate, logger); + } + } + + // Cue to delete the file if it's a copy + if (copyFiles && item != newItem) + { + try + { + Directory.Delete(newBasePath, true); + } + catch { } + } + + // Delete the sub temp directory + if (Directory.Exists(tempSubDir)) + { + Directory.Delete(tempSubDir, true); + } + } + + /// + /// Process a single file as a file + /// + /// File to be added + /// Path the represents the parent directory + /// Parent game to be used + private void DFDProcessFile(string item, string parent, string basePath, bool noMD5, bool noSHA1, bool addDate, Logger logger) + { + logger.Log(Path.GetFileName(item) + " treated like a file"); + Rom rom = FileTools.GetSingleFileInfo(item, noMD5: noMD5, noSHA1: noSHA1, date: addDate); + + DFDProcessFileHelper(item, rom, basePath, parent, logger); + } + + /// + /// Process a single file as a file (with found Rom data) + /// + /// File to be added + /// Rom data to be used to write to file + /// Path the represents the parent directory + /// Parent game to be used + private void DFDProcessFileHelper(string item, DatItem datItem, string basepath, string parent, Logger logger) + { + // If the datItem isn't a Rom or Disk, return + if (datItem.Type != ItemType.Rom && datItem.Type != ItemType.Disk) + { + return; + } + + string key = ""; + if (datItem.Type == ItemType.Rom) + { + key = ((Rom)datItem).Size + "-" + ((Rom)datItem).CRC; + } + else + { + key = ((Disk)datItem).MD5; + } + + // Add the list if it doesn't exist already + lock (Files) + { + if (!Files.ContainsKey(key)) + { + Files.Add(key, new List()); + } + } + + try + { + // If the basepath ends with a directory separator, remove it + if (!basepath.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + basepath += Path.DirectorySeparatorChar.ToString(); + } + + // Make sure we have the full item path + item = Path.GetFullPath(item); + + // Get the data to be added as game and item names + string gamename = ""; + string romname = ""; + + // If the parent is blank, then we have a non-archive file + if (parent == "") + { + // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom + if (Type == "SuperDAT") + { + gamename = Path.GetDirectoryName(item.Remove(0, basepath.Length)); + romname = Path.GetFileName(item); + } + + // Otherwise, we want just the top level folder as the game, and the file as everything else + else + { + gamename = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0]; + romname = item.Remove(0, (Path.Combine(basepath, gamename).Length)); + } + } + + // Otherwise, we assume that we have an archive + else + { + // If we have a SuperDAT, we want the archive name as the game, and the file as everything else (?) + if (Type == "SuperDAT") + { + gamename = parent; + romname = item.Remove(0, basepath.Length); + } + + // Otherwise, we want the archive name as the game, and the file as everything else + else + { + gamename = parent; + romname = item.Remove(0, basepath.Length); + } + } + + // Sanitize the names + if (gamename.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + gamename = gamename.Substring(1); + } + if (gamename.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + gamename = gamename.Substring(0, gamename.Length - 1); + } + if (romname.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + romname = romname.Substring(1); + } + if (romname.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + romname = romname.Substring(0, romname.Length - 1); + } + + // Update rom information + datItem.Name = romname; + datItem.MachineName = gamename; + datItem.MachineDescription = gamename; + + // Add the file information to the DAT + lock (Files) + { + Files[key].Add(datItem); + } + + logger.User("File added: " + romname + Environment.NewLine); + } + catch (IOException ex) + { + logger.Error(ex.ToString()); + return; + } + } + + #endregion + #region Statistics /// @@ -2720,7 +3130,7 @@ Please check the log folder if the stats scrolled offscreen"); // If we have roms, output them if (innerDatdata.Files.Count != 0) { - WriteDatfile(innerDatdata, (outDir == "" ? Path.GetDirectoryName(inputFileName) : outDir), logger, overwrite: (outDir != "")); + innerDatdata.WriteToFile((outDir == "" ? Path.GetDirectoryName(inputFileName) : outDir), logger, overwrite: (outDir != "")); } } else if (Directory.Exists(inputFileName)) @@ -2740,7 +3150,7 @@ Please check the log folder if the stats scrolled offscreen"); // If we have roms, output them if (innerDatdata.Files != null && innerDatdata.Files.Count != 0) { - WriteDatfile(innerDatdata, (outDir == "" ? Path.GetDirectoryName(file) : outDir + Path.GetDirectoryName(file).Remove(0, inputFileName.Length - 1)), logger, overwrite: (outDir != "")); + innerDatdata.WriteToFile((outDir == "" ? Path.GetDirectoryName(file) : outDir + Path.GetDirectoryName(file).Remove(0, inputFileName.Length - 1)), logger, overwrite: (outDir != "")); } }); } @@ -2973,13 +3383,13 @@ Please check the log folder if the stats scrolled offscreen"); // Output the difflist (a-b)+(b-a) diff if ((diff & DiffMode.NoDupes) != 0) { - WriteDatfile(outerDiffData, outDir, logger); + outerDiffData.WriteToFile(outDir, logger); } // Output the (ab) diff if ((diff & DiffMode.Dupes) != 0) { - WriteDatfile(dupeData, outDir, logger); + dupeData.WriteToFile(outDir, logger); } // Output the individual (a-b) DATs @@ -2993,7 +3403,7 @@ Please check the log folder if the stats scrolled offscreen"); // If we have more than 0 roms, output if (outDats[j].Files.Count > 0) { - WriteDatfile(outDats[j], path, logger); + outDats[j].WriteToFile(path, logger); } } } @@ -3101,7 +3511,7 @@ Please check the log folder if the stats scrolled offscreen"); // If we have more than 0 roms, output if (outDats[j].Files.Count > 0) { - WriteDatfile(outDats[j], path, logger); + outDats[j].WriteToFile(path, logger); } } logger.User("Outputting complete in " + DateTime.Now.Subtract(start).ToString(@"hh\:mm\:ss\.fffff")); @@ -3143,7 +3553,7 @@ Please check the log folder if the stats scrolled offscreen"); // Output a DAT only if there are roms if (Files.Count != 0) { - WriteDatfile(this, outDir, logger); + WriteToFile(outDir, logger); } } @@ -3166,10 +3576,10 @@ Please check the log folder if the stats scrolled offscreen"); /// The following features have been requested for file output: /// - Have the ability to strip special (non-ASCII) characters from rom information /// - public static bool WriteDatfile(DatFile datdata, string outDir, Logger logger, bool norename = true, bool stats = false, bool ignoreblanks = false, bool overwrite = true) + public bool WriteToFile(string outDir, Logger logger, bool norename = true, bool stats = false, bool ignoreblanks = false, bool overwrite = true) { // If there's nothing there, abort - if (datdata.Files == null || datdata.Files.Count == 0) + if (Files == null || Files.Count == 0) { return false; } @@ -3187,41 +3597,41 @@ Please check the log folder if the stats scrolled offscreen"); } // If the DAT has no output format, default to XML - if (datdata.OutputFormat == 0) + if (OutputFormat == 0) { - datdata.OutputFormat = OutputFormat.Xml; + OutputFormat = OutputFormat.Xml; } // Make sure that the three essential fields are filled in - if (String.IsNullOrEmpty(datdata.FileName) && String.IsNullOrEmpty(datdata.Name) && String.IsNullOrEmpty(datdata.Description)) + if (String.IsNullOrEmpty(FileName) && String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) { - datdata.FileName = datdata.Name = datdata.Description = "Default"; + FileName = Name = Description = "Default"; } - else if (String.IsNullOrEmpty(datdata.FileName) && String.IsNullOrEmpty(datdata.Name) && !String.IsNullOrEmpty(datdata.Description)) + else if (String.IsNullOrEmpty(FileName) && String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description)) { - datdata.FileName = datdata.Name = datdata.Description; + FileName = Name = Description; } - else if (String.IsNullOrEmpty(datdata.FileName) && !String.IsNullOrEmpty(datdata.Name) && String.IsNullOrEmpty(datdata.Description)) + else if (String.IsNullOrEmpty(FileName) && !String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) { - datdata.FileName = datdata.Description = datdata.Name; + FileName = Description = Name; } - else if (String.IsNullOrEmpty(datdata.FileName) && !String.IsNullOrEmpty(datdata.Name) && !String.IsNullOrEmpty(datdata.Description)) + else if (String.IsNullOrEmpty(FileName) && !String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description)) { - datdata.FileName = datdata.Description; + FileName = Description; } - else if (!String.IsNullOrEmpty(datdata.FileName) && String.IsNullOrEmpty(datdata.Name) && String.IsNullOrEmpty(datdata.Description)) + else if (!String.IsNullOrEmpty(FileName) && String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) { - datdata.Name = datdata.Description = datdata.FileName; + Name = Description = FileName; } - else if (!String.IsNullOrEmpty(datdata.FileName) && String.IsNullOrEmpty(datdata.Name) && !String.IsNullOrEmpty(datdata.Description)) + else if (!String.IsNullOrEmpty(FileName) && String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description)) { - datdata.Name = datdata.Description; + Name = Description; } - else if (!String.IsNullOrEmpty(datdata.FileName) && !String.IsNullOrEmpty(datdata.Name) && String.IsNullOrEmpty(datdata.Description)) + else if (!String.IsNullOrEmpty(FileName) && !String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Description)) { - datdata.Description = datdata.Name; + Description = Name; } - else if (!String.IsNullOrEmpty(datdata.FileName) && !String.IsNullOrEmpty(datdata.Name) && !String.IsNullOrEmpty(datdata.Description)) + else if (!String.IsNullOrEmpty(FileName) && !String.IsNullOrEmpty(Name) && !String.IsNullOrEmpty(Description)) { // Nothing is needed } @@ -3229,14 +3639,14 @@ Please check the log folder if the stats scrolled offscreen"); // Output initial statistics, for kicks if (stats) { - datdata.OutputStats(logger, (datdata.RomCount + datdata.DiskCount == 0)); + OutputStats(logger, (RomCount + DiskCount == 0)); } // Bucket roms by game name and optionally dedupe - SortedDictionary> sortable = BucketByGame(datdata.Files, datdata.MergeRoms, norename, logger); + SortedDictionary> sortable = BucketByGame(Files, MergeRoms, norename, logger); // Get the outfile name - Dictionary outfiles = Style.CreateOutfileNames(outDir, datdata, overwrite); + Dictionary outfiles = Style.CreateOutfileNames(outDir, this, overwrite); try { @@ -3249,7 +3659,7 @@ Please check the log folder if the stats scrolled offscreen"); StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(true)); // Write out the header - WriteHeader(sw, outputFormat, datdata, logger); + WriteHeader(sw, outputFormat, logger); // Write out each of the machines and roms int depth = 2, last = -1; @@ -3318,7 +3728,7 @@ Please check the log folder if the stats scrolled offscreen"); } // Now, output the rom data - WriteRomData(sw, outputFormat, rom, lastgame, datdata, depth, logger, ignoreblanks); + WriteRomData(sw, outputFormat, rom, lastgame, depth, logger, ignoreblanks); // Set the new data to compare against splitpath = newsplit; @@ -3327,7 +3737,7 @@ Please check the log folder if the stats scrolled offscreen"); } // Write the file footer out - WriteFooter(sw, outputFormat, datdata, depth, logger); + WriteFooter(sw, outputFormat, depth, logger); logger.Log("File written!" + Environment.NewLine); sw.Dispose(); @@ -3348,10 +3758,9 @@ Please check the log folder if the stats scrolled offscreen"); /// /// StreamWriter to output to /// Output format to write to - /// DatData object representing DAT information /// Logger object for file and console output /// True if the data was written, false on error - public static bool WriteHeader(StreamWriter sw, OutputFormat outputFormat, DatFile datdata, Logger logger) + private bool WriteHeader(StreamWriter sw, OutputFormat outputFormat, Logger logger) { try { @@ -3360,40 +3769,40 @@ Please check the log folder if the stats scrolled offscreen"); { case OutputFormat.ClrMamePro: header = "clrmamepro (\n" + - "\tname \"" + datdata.Name + "\"\n" + - "\tdescription \"" + datdata.Description + "\"\n" + - "\tcategory \"" + datdata.Category + "\"\n" + - "\tversion \"" + datdata.Version + "\"\n" + - "\tdate \"" + datdata.Date + "\"\n" + - "\tauthor \"" + datdata.Author + "\"\n" + - "\temail \"" + datdata.Email + "\"\n" + - "\thomepage \"" + datdata.Homepage + "\"\n" + - "\turl \"" + datdata.Url + "\"\n" + - "\tcomment \"" + datdata.Comment + "\"\n" + - (datdata.ForcePacking == ForcePacking.Unzip ? "\tforcezipping no\n" : "") + - (datdata.ForcePacking == ForcePacking.Zip ? "\tforcezipping yes\n" : "") + - (datdata.ForceMerging == ForceMerging.Full ? "\tforcemerging full\n" : "") + - (datdata.ForceMerging == ForceMerging.Split ? "\tforcemerging split\n" : "") + + "\tname \"" + Name + "\"\n" + + "\tdescription \"" + Description + "\"\n" + + "\tcategory \"" + Category + "\"\n" + + "\tversion \"" + Version + "\"\n" + + "\tdate \"" + Date + "\"\n" + + "\tauthor \"" + Author + "\"\n" + + "\temail \"" + Email + "\"\n" + + "\thomepage \"" + Homepage + "\"\n" + + "\turl \"" + Url + "\"\n" + + "\tcomment \"" + Comment + "\"\n" + + (ForcePacking == ForcePacking.Unzip ? "\tforcezipping no\n" : "") + + (ForcePacking == ForcePacking.Zip ? "\tforcezipping yes\n" : "") + + (ForceMerging == ForceMerging.Full ? "\tforcemerging full\n" : "") + + (ForceMerging == ForceMerging.Split ? "\tforcemerging split\n" : "") + ")\n"; break; case OutputFormat.DOSCenter: header = "DOSCenter (\n" + - "Name: " + datdata.Name + "\"\n" + - "Description: " + datdata.Description + "\"\n" + - "Version: " + datdata.Version + "\"\n" + - "Date: " + datdata.Date + "\"\n" + - "Author: " + datdata.Author + "\"\n" + - "Homepage: " + datdata.Homepage + "\"\n" + - "Comment: " + datdata.Comment + "\"\n" + + "Name: " + Name + "\"\n" + + "Description: " + Description + "\"\n" + + "Version: " + Version + "\"\n" + + "Date: " + Date + "\"\n" + + "Author: " + Author + "\"\n" + + "Homepage: " + Homepage + "\"\n" + + "Comment: " + Comment + "\"\n" + ")\n"; break; case OutputFormat.MissFile: - if (datdata.XSV == true) + if (XSV == true) { header = "\"File Name\"\t\"Internal Name\"\t\"Description\"\t\"Game Name\"\t\"Game Description\"\t\"Type\"\t\"" + "Rom Name\"\t\"Disk Name\"\t\"Size\"\t\"CRC\"\t\"MD5\"\t\"SHA1\"\t\"Nodump\"\n"; } - else if (datdata.XSV == false) + else if (XSV == false) { header = "\"File Name\",\"Internal Name\",\"Description\",\"Game Name\",\"Game Description\",\"Type\",\"" + "Rom Name\",\"Disk Name\",\"Size\",\"CRC\",\"MD5\",\"SHA1\",\"Nodump\"\n"; @@ -3401,16 +3810,16 @@ Please check the log folder if the stats scrolled offscreen"); break; case OutputFormat.RomCenter: header = "[CREDITS]\n" + - "author=" + datdata.Author + "\n" + - "version=" + datdata.Version + "\n" + - "comment=" + datdata.Comment + "\n" + + "author=" + Author + "\n" + + "version=" + Version + "\n" + + "comment=" + Comment + "\n" + "[DAT]\n" + "version=2.50\n" + - "split=" + (datdata.ForceMerging == ForceMerging.Split ? "1" : "0") + "\n" + - "merge=" + (datdata.ForceMerging == ForceMerging.Full ? "1" : "0") + "\n" + + "split=" + (ForceMerging == ForceMerging.Split ? "1" : "0") + "\n" + + "merge=" + (ForceMerging == ForceMerging.Full ? "1" : "0") + "\n" + "[EMULATOR]\n" + - "refname=" + datdata.Name + "\n" + - "version=" + datdata.Description + "\n" + + "refname=" + Name + "\n" + + "version=" + Description + "\n" + "[GAMES]\n"; break; case OutputFormat.SabreDat: @@ -3418,24 +3827,24 @@ Please check the log folder if the stats scrolled offscreen"); "\n\n" + "\n" + "\t
\n" + - "\t\t" + HttpUtility.HtmlEncode(datdata.Name) + "\n" + - "\t\t" + HttpUtility.HtmlEncode(datdata.Description) + "\n" + - (!String.IsNullOrEmpty(datdata.RootDir) ? "\t\t" + HttpUtility.HtmlEncode(datdata.RootDir) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Category) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Category) + "\n" : "") + - "\t\t" + HttpUtility.HtmlEncode(datdata.Version) + "\n" + - (!String.IsNullOrEmpty(datdata.Date) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Date) + "\n" : "") + - "\t\t" + HttpUtility.HtmlEncode(datdata.Author) + "\n" + - (!String.IsNullOrEmpty(datdata.Comment) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Comment) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Type) || datdata.ForcePacking != ForcePacking.None || datdata.ForceMerging != ForceMerging.None || datdata.ForceNodump != ForceNodump.None ? + "\t\t" + HttpUtility.HtmlEncode(Name) + "\n" + + "\t\t" + HttpUtility.HtmlEncode(Description) + "\n" + + (!String.IsNullOrEmpty(RootDir) ? "\t\t" + HttpUtility.HtmlEncode(RootDir) + "\n" : "") + + (!String.IsNullOrEmpty(Category) ? "\t\t" + HttpUtility.HtmlEncode(Category) + "\n" : "") + + "\t\t" + HttpUtility.HtmlEncode(Version) + "\n" + + (!String.IsNullOrEmpty(Date) ? "\t\t" + HttpUtility.HtmlEncode(Date) + "\n" : "") + + "\t\t" + HttpUtility.HtmlEncode(Author) + "\n" + + (!String.IsNullOrEmpty(Comment) ? "\t\t" + HttpUtility.HtmlEncode(Comment) + "\n" : "") + + (!String.IsNullOrEmpty(Type) || ForcePacking != ForcePacking.None || ForceMerging != ForceMerging.None || ForceNodump != ForceNodump.None ? "\t\t\n" + - (!String.IsNullOrEmpty(datdata.Type) ? "\t\t\t\n" : "") + - (datdata.ForcePacking == ForcePacking.Unzip ? "\t\t\t\n" : "") + - (datdata.ForcePacking == ForcePacking.Zip ? "\t\t\t\n" : "") + - (datdata.ForceMerging == ForceMerging.Full ? "\t\t\t\n" : "") + - (datdata.ForceMerging == ForceMerging.Split ? "\t\t\t\n" : "") + - (datdata.ForceNodump == ForceNodump.Ignore ? "\t\t\t\n" : "") + - (datdata.ForceNodump == ForceNodump.Obsolete ? "\t\t\t\n" : "") + - (datdata.ForceNodump == ForceNodump.Required ? "\t\t\t\n" : "") + + (!String.IsNullOrEmpty(Type) ? "\t\t\t\n" : "") + + (ForcePacking == ForcePacking.Unzip ? "\t\t\t\n" : "") + + (ForcePacking == ForcePacking.Zip ? "\t\t\t\n" : "") + + (ForceMerging == ForceMerging.Full ? "\t\t\t\n" : "") + + (ForceMerging == ForceMerging.Split ? "\t\t\t\n" : "") + + (ForceNodump == ForceNodump.Ignore ? "\t\t\t\n" : "") + + (ForceNodump == ForceNodump.Obsolete ? "\t\t\t\n" : "") + + (ForceNodump == ForceNodump.Required ? "\t\t\t\n" : "") + "\t\t\n" : "") + "\t
\n" + @@ -3446,27 +3855,27 @@ Please check the log folder if the stats scrolled offscreen"); "\n\n" + "\n" + "\t
\n" + - "\t\t" + HttpUtility.HtmlEncode(datdata.Name) + "\n" + - "\t\t" + HttpUtility.HtmlEncode(datdata.Description) + "\n" + - (!String.IsNullOrEmpty(datdata.RootDir) ? "\t\t" + HttpUtility.HtmlEncode(datdata.RootDir) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Category) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Category) + "\n" : "") + - "\t\t" + HttpUtility.HtmlEncode(datdata.Version) + "\n" + - (!String.IsNullOrEmpty(datdata.Date) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Date) + "\n" : "") + - "\t\t" + HttpUtility.HtmlEncode(datdata.Author) + "\n" + - (!String.IsNullOrEmpty(datdata.Email) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Email) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Homepage) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Homepage) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Url) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Url) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Comment) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Comment) + "\n" : "") + - (!String.IsNullOrEmpty(datdata.Type) ? "\t\t" + HttpUtility.HtmlEncode(datdata.Type) + "\n" : "") + - (datdata.ForcePacking != ForcePacking.None || datdata.ForceMerging != ForceMerging.None || datdata.ForceNodump != ForceNodump.None ? + "\t\t" + HttpUtility.HtmlEncode(Name) + "\n" + + "\t\t" + HttpUtility.HtmlEncode(Description) + "\n" + + (!String.IsNullOrEmpty(RootDir) ? "\t\t" + HttpUtility.HtmlEncode(RootDir) + "\n" : "") + + (!String.IsNullOrEmpty(Category) ? "\t\t" + HttpUtility.HtmlEncode(Category) + "\n" : "") + + "\t\t" + HttpUtility.HtmlEncode(Version) + "\n" + + (!String.IsNullOrEmpty(Date) ? "\t\t" + HttpUtility.HtmlEncode(Date) + "\n" : "") + + "\t\t" + HttpUtility.HtmlEncode(Author) + "\n" + + (!String.IsNullOrEmpty(Email) ? "\t\t" + HttpUtility.HtmlEncode(Email) + "\n" : "") + + (!String.IsNullOrEmpty(Homepage) ? "\t\t" + HttpUtility.HtmlEncode(Homepage) + "\n" : "") + + (!String.IsNullOrEmpty(Url) ? "\t\t" + HttpUtility.HtmlEncode(Url) + "\n" : "") + + (!String.IsNullOrEmpty(Comment) ? "\t\t" + HttpUtility.HtmlEncode(Comment) + "\n" : "") + + (!String.IsNullOrEmpty(Type) ? "\t\t" + HttpUtility.HtmlEncode(Type) + "\n" : "") + + (ForcePacking != ForcePacking.None || ForceMerging != ForceMerging.None || ForceNodump != ForceNodump.None ? "\t\t\n" : "") + "\t
\n"; @@ -3498,7 +3907,7 @@ Please check the log folder if the stats scrolled offscreen"); /// Last known depth to cycle back from (SabreDAT only) /// Logger object for file and console output /// The new depth of the tag - public static int WriteStartGame(StreamWriter sw, OutputFormat outputFormat, DatItem rom, List newsplit, string lastgame, int depth, int last, Logger logger) + private int WriteStartGame(StreamWriter sw, OutputFormat outputFormat, DatItem rom, List newsplit, string lastgame, int depth, int last, Logger logger) { try { @@ -3573,7 +3982,7 @@ Please check the log folder if the stats scrolled offscreen"); /// Last known depth to cycle back from (SabreDAT only) /// Logger object for file and console output /// The new depth of the tag - public static int WriteEndGame(StreamWriter sw, OutputFormat outputFormat, DatItem rom, List splitpath, List newsplit, string lastgame, int depth, out int last, Logger logger) + private int WriteEndGame(StreamWriter sw, OutputFormat outputFormat, DatItem rom, List splitpath, List newsplit, string lastgame, int depth, out int last, Logger logger) { last = 0; @@ -3641,12 +4050,11 @@ Please check the log folder if the stats scrolled offscreen"); /// Output format to write to /// RomData object to be output /// The name of the last game to be output - /// DatData object representing DAT information /// Current depth to output file at (SabreDAT only) /// Logger object for file and console output /// True if blank roms should be skipped on output, false otherwise (default) /// True if the data was written, false on error - public static bool WriteRomData(StreamWriter sw, OutputFormat outputFormat, DatItem rom, string lastgame, DatFile datdata, int depth, Logger logger, bool ignoreblanks = false) + private bool WriteRomData(StreamWriter sw, OutputFormat outputFormat, DatItem rom, string lastgame, int depth, Logger logger, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks @@ -3736,8 +4144,8 @@ Please check the log folder if the stats scrolled offscreen"); return true; } - string pre = datdata.Prefix + (datdata.Quotes ? "\"" : ""); - string post = (datdata.Quotes ? "\"" : "") + datdata.Postfix; + string pre = Prefix + (Quotes ? "\"" : ""); + string post = (Quotes ? "\"" : "") + Postfix; if (rom.Type == ItemType.Rom) { @@ -3773,7 +4181,7 @@ Please check the log folder if the stats scrolled offscreen"); } // If we're in Romba mode, the state is consistent - if (datdata.Romba) + if (Romba) { if (rom.Type == ItemType.Rom) { @@ -3803,15 +4211,15 @@ Please check the log folder if the stats scrolled offscreen"); } } // If we're in TSV/CSV mode, similarly the state is consistent - else if (datdata.XSV != null) + else if (XSV != null) { - string separator = (datdata.XSV == true ? "\t" : ","); + string separator = (XSV == true ? "\t" : ","); if (rom.Type == ItemType.Rom) { - string inline = "\"" + datdata.FileName + "\"" - + separator + "\"" + datdata.Name + "\"" - + separator + "\"" + datdata.Description + "\"" + string inline = "\"" + FileName + "\"" + + separator + "\"" + Name + "\"" + + separator + "\"" + Description + "\"" + separator + "\"" + rom.MachineName + "\"" + separator + "\"" + rom.MachineDescription + "\"" + separator + "\"rom\"" @@ -3826,9 +4234,9 @@ Please check the log folder if the stats scrolled offscreen"); } else if (rom.Type == ItemType.Disk) { - string inline = "\"" + datdata.FileName + "\"" - + separator + "\"" + datdata.Name + "\"" - + separator + "\"" + datdata.Description + "\"" + string inline = "\"" + FileName + "\"" + + separator + "\"" + Name + "\"" + + separator + "\"" + Description + "\"" + separator + "\"" + rom.MachineName + "\"" + separator + "\"" + rom.MachineDescription + "\"" + separator + "\"disk\"" @@ -3845,33 +4253,33 @@ Please check the log folder if the stats scrolled offscreen"); // Otherwise, use any flags else { - string name = (datdata.UseGame ? rom.MachineName : rom.Name); - if (datdata.RepExt != "" || datdata.RemExt) + string name = (UseGame ? rom.MachineName : rom.Name); + if (RepExt != "" || RemExt) { - if (datdata.RemExt) + if (RemExt) { - datdata.RepExt = ""; + RepExt = ""; } string dir = Path.GetDirectoryName(name); dir = (dir.StartsWith(Path.DirectorySeparatorChar.ToString()) ? dir.Remove(0, 1) : dir); - name = Path.Combine(dir, Path.GetFileNameWithoutExtension(name) + datdata.RepExt); + name = Path.Combine(dir, Path.GetFileNameWithoutExtension(name) + RepExt); } - if (datdata.AddExt != "") + if (AddExt != "") { - name += datdata.AddExt; + name += AddExt; } - if (!datdata.UseGame && datdata.GameName) + if (!UseGame && GameName) { name = Path.Combine(rom.MachineName, name); } - if (datdata.UseGame && rom.MachineName != lastgame) + if (UseGame && rom.MachineName != lastgame) { state += pre + name + post + "\n"; lastgame = rom.MachineName; } - else if (!datdata.UseGame) + else if (!UseGame) { state += pre + name + post + "\n"; } @@ -4050,18 +4458,18 @@ Please check the log folder if the stats scrolled offscreen"); /// Write out DAT footer using the supplied StreamWriter /// /// StreamWriter to output to - /// DatData object representing DAT information + /// Output format to write to /// Current depth to output file at (SabreDAT only) /// Logger object for file and console output /// True if the data was written, false on error - public static bool WriteFooter(StreamWriter sw, OutputFormat outputFormat, DatFile datdata, int depth, Logger logger) + private bool WriteFooter(StreamWriter sw, OutputFormat outputFormat, int depth, Logger logger) { try { string footer = ""; // If we have roms, output the full footer - if (datdata.Files != null && datdata.Files.Count > 0) + if (Files != null && Files.Count > 0) { switch (outputFormat) { @@ -4262,8 +4670,8 @@ Please check the log folder if the stats scrolled offscreen"); } // Then write out both files - bool success = WriteDatfile(datdataA, outDir, logger); - success &= WriteDatfile(datdataB, outDir, logger); + bool success = datdataA.WriteToFile(outDir, logger); + success &= datdataB.WriteToFile(outDir, logger); return success; } @@ -4510,19 +4918,19 @@ Please check the log folder if the stats scrolled offscreen"); bool success = true; if (itemStatus.Files.Count > 0) { - success &= WriteDatfile(itemStatus, outDir, logger); + success &= itemStatus.WriteToFile(outDir, logger); } if (sha1.Files.Count > 0) { - success &= WriteDatfile(sha1, outDir, logger); + success &= sha1.WriteToFile(outDir, logger); } if (md5.Files.Count > 0) { - success &= WriteDatfile(md5, outDir, logger); + success &= md5.WriteToFile(outDir, logger); } if (crc.Files.Count > 0) { - success &= WriteDatfile(crc, outDir, logger); + success &= crc.WriteToFile(outDir, logger); } return success; @@ -4689,15 +5097,15 @@ Please check the log folder if the stats scrolled offscreen"); bool success = true; if (romdat.Files.Count > 0) { - success &= WriteDatfile(romdat, outDir, logger); + success &= romdat.WriteToFile(outDir, logger); } if (diskdat.Files.Count > 0) { - success &= WriteDatfile(diskdat, outDir, logger); + success &= diskdat.WriteToFile(outDir, logger); } if (sampledat.Files.Count > 0) { - success &= WriteDatfile(sampledat, outDir, logger); + success &= sampledat.WriteToFile(outDir, logger); } return success; diff --git a/SabreTools.Helper/Objects/SimpleSort.cs b/SabreTools.Helper/Objects/SimpleSort.cs index 8728176b..af439e9c 100644 --- a/SabreTools.Helper/Objects/SimpleSort.cs +++ b/SabreTools.Helper/Objects/SimpleSort.cs @@ -137,10 +137,8 @@ namespace SabreTools.Helper _logger.User("Processing files:\n"); foreach (string input in _inputs) { - DATFromDir dfd = new DATFromDir(input, _datdata, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */, - true /* enableGzip */, false /* addBlanks */, false /* addDate */, "" /* tempDir */, false /* copyFiles */, 4 /* maxDegreeOfParallelism */, _logger); - dfd.Start(); - _datdata = dfd.DatData; + _datdata.PopulateDatFromDir(input, false /* noMD5 */, false /* noSHA1 */, true /* bare */, false /* archivesAsFiles */, + true /* enableGzip */, false /* addBlanks */, false /* addDate */, "" /* tempDir */, false /* copyFiles */, 4 /* maxDegreeOfParallelism */, _logger); } // Setup the fixdat @@ -179,7 +177,7 @@ namespace SabreTools.Helper // Now output the fixdat to the main folder if (found) { - DatFile.WriteDatfile(_matched, "", _logger, stats: true); + _matched.WriteToFile("", _logger, stats: true); } else { @@ -273,7 +271,7 @@ namespace SabreTools.Helper _datdata.Name = "fixDat_" + _datdata.Name; _datdata.Description = "fixDat_" + _datdata.Description; _datdata.OutputFormat = OutputFormat.Xml; - DatFile.WriteDatfile(_datdata, "", _logger); + _datdata.WriteToFile("", _logger); } return success; diff --git a/SabreTools.Helper/SabreTools.Helper.csproj b/SabreTools.Helper/SabreTools.Helper.csproj index 4236b5f6..6ef2fb38 100644 --- a/SabreTools.Helper/SabreTools.Helper.csproj +++ b/SabreTools.Helper/SabreTools.Helper.csproj @@ -100,7 +100,6 @@ - diff --git a/SabreTools/Partials/SabreTools_Inits.cs b/SabreTools/Partials/SabreTools_Inits.cs index 653b37c7..159617e9 100644 --- a/SabreTools/Partials/SabreTools_Inits.cs +++ b/SabreTools/Partials/SabreTools_Inits.cs @@ -121,13 +121,12 @@ namespace SabreTools datdata.Files = new Dictionary>(); string basePath = Path.GetFullPath(path); - DATFromDir dfd = new DATFromDir(basePath, datdata, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, copyFiles, maxDegreeOfParallelism, _logger); - bool success = dfd.Start(); + bool success = datdata.PopulateDatFromDir(basePath, noMD5, noSHA1, bare, archivesAsFiles, enableGzip, addBlanks, addDate, tempDir, copyFiles, maxDegreeOfParallelism, _logger); // If it was a success, write the DAT out if (success) { - DatFile.WriteDatfile(dfd.DatData, "", _logger); + datdata.WriteToFile("", _logger); } // Otherwise, show the help