diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index 8f23c01d..181637c3 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -1572,11 +1572,8 @@ namespace SabreTools.Library.DatFiles /// True to allow SL DATs to have game names used instead of descriptions, false otherwise (default) /// Filter object to be passed to the DatItem level /// Type of the split that should be performed (split, merged, fully merged) - /// True if we are supposed to trim names to NTFS length, false otherwise - /// True if all games should be replaced by '!', false otherwise - /// String representing root directory to compare against for length calculation public void DetermineUpdateType(List inputPaths, List basePaths, string outDir, UpdateMode updateMode, bool inplace, bool skip, - bool bare, bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType, bool trim, bool single, string root) + bool bare, bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType) { // Ensure we only have files in the inputs List inputFileNames = Utilities.GetOnlyFilesFromInputs(inputPaths, appendparent: true); @@ -1585,7 +1582,7 @@ namespace SabreTools.Library.DatFiles // If we're in standard update mode, run through all of the inputs if (updateMode == UpdateMode.None) { - Update(inputFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, trim, single, root); + Update(inputFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType); return; } @@ -1601,7 +1598,7 @@ namespace SabreTools.Library.DatFiles // Populate the combined data and get the headers List datHeaders = PopulateUserData(inputFileNames, inplace, clean, - remUnicode, descAsName, outDir, filter, splitType, trim, single, root); + remUnicode, descAsName, outDir, filter, splitType); // If we're in merging mode if ((updateMode & UpdateMode.Merge) != 0) @@ -1624,13 +1621,13 @@ namespace SabreTools.Library.DatFiles // If we have diff against mode else if ((updateMode & UpdateMode.DiffAgainst) != 0) { - DiffAgainst(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, trim, single, root); + DiffAgainst(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType); } // If we have one of the base replacement modes else if ((updateMode & UpdateMode.BaseReplace) != 0 || (updateMode & UpdateMode.ReverseBaseReplace) != 0) { - BaseReplace(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, trim, single, root); + BaseReplace(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType); } return; @@ -1648,12 +1645,9 @@ namespace SabreTools.Library.DatFiles /// Optional param for output directory /// Filter object to be passed to the DatItem level /// Type of the split that should be performed (split, merged, fully merged) - /// True if we are supposed to trim names to NTFS length, false otherwise - /// True if all games should be replaced by '!', false otherwise - /// String representing root directory to compare against for length calculation /// List of DatData objects representing headers private List PopulateUserData(List inputs, bool inplace, bool clean, bool remUnicode, bool descAsName, - string outDir, Filter filter, SplitType splitType, bool trim, bool single, string root) + string outDir, Filter filter, SplitType splitType) { DatFile[] datHeaders = new DatFile[inputs.Count]; InternalStopwatch watch = new InternalStopwatch("Processing individual DATs"); @@ -1693,7 +1687,7 @@ namespace SabreTools.Library.DatFiles }); // Now that we have a merged DAT, filter it - Filter(filter, single, trim, root); + filter.FilterDatFile(this); watch.Stop(); @@ -1716,7 +1710,7 @@ namespace SabreTools.Library.DatFiles /// True if all games should be replaced by '!', false otherwise /// String representing root directory to compare against for length calculation public void BaseReplace(List inputFileNames, List baseFileNames, string outDir, bool inplace, bool clean, bool remUnicode, - bool descAsName, Filter filter, SplitType splitType, bool trim, bool single, string root) + bool descAsName, Filter filter, SplitType splitType) { // First we want to parse all of the base DATs into the input InternalStopwatch watch = new InternalStopwatch("Populating base DAT for replacement..."); @@ -1803,7 +1797,7 @@ namespace SabreTools.Library.DatFiles /// True if all games should be replaced by '!', false otherwise /// String representing root directory to compare against for length calculation public void DiffAgainst(List inputFileNames, List baseFileNames, string outDir, bool inplace, bool clean, bool remUnicode, - bool descAsName, Filter filter, SplitType splitType, bool trim, bool single, string root) + bool descAsName, Filter filter, SplitType splitType) { // First we want to parse all of the base DATs into the input InternalStopwatch watch = new InternalStopwatch("Populating base DAT for comparison..."); @@ -2167,7 +2161,7 @@ namespace SabreTools.Library.DatFiles /// True if all games should be replaced by '!', false otherwise /// String representing root directory to compare against for length calculation public void Update(List inputFileNames, string outDir, bool inplace, bool clean, bool remUnicode, bool descAsName, - Filter filter, SplitType splitType, bool trim, bool single, string root) + Filter filter, SplitType splitType) { // Iterate over the files foreach (string file in inputFileNames) @@ -2176,7 +2170,7 @@ namespace SabreTools.Library.DatFiles Globals.Logger.User("Processing '{0}'", Path.GetFileName(file.Split('¬')[0])); innerDatdata.Parse(file, 0, 0, splitType, keep: true, clean: clean, remUnicode: remUnicode, descAsName: descAsName, keepext: ((innerDatdata.DatFormat & DatFormat.TSV) != 0 || (innerDatdata.DatFormat & DatFormat.CSV) != 0)); - innerDatdata.Filter(filter, trim, single, root); + filter.FilterDatFile(innerDatdata); // Get the correct output path string realOutDir = Utilities.GetOutputPath(outDir, file, inplace); @@ -2251,66 +2245,6 @@ namespace SabreTools.Library.DatFiles #region Filtering - /// - /// Filter a DAT based on input parameters and modify the items - /// - /// Filter object for passing to the DatItem level - /// True if we are supposed to trim names to NTFS length, false otherwise - /// True if all games should be replaced by '!', false otherwise - /// String representing root directory to compare against for length calculation - public void Filter(Filter filter, bool single, bool trim, string root) - { - try - { - // Loop over every key in the dictionary - List keys = Keys; - foreach (string key in keys) - { - // For every item in the current key - List items = this[key]; - List newitems = new List(); - foreach (DatItem item in items) - { - // If the rom passes the filter, include it - if (filter.ItemPasses(item)) - { - // If we are in single game mode, rename all games - if (single) - { - item.MachineName = "!"; - } - - // If we are in NTFS trim mode, trim the game name - if (trim) - { - // Windows max name length is 260 - int usableLength = 260 - item.MachineName.Length - root.Length; - if (item.Name.Length > usableLength) - { - string ext = Path.GetExtension(item.Name); - item.Name = item.Name.Substring(0, usableLength - ext.Length); - item.Name += ext; - } - } - - // Lock the list and add the item back - lock (newitems) - { - newitems.Add(item); - } - } - } - - Remove(key); - AddRange(key, newitems); - } - } - catch (Exception ex) - { - Globals.Logger.Error(ex.ToString()); - } - } - /// /// Use game descriptions as names in the DAT, updating cloneof/romof/sampleof /// diff --git a/SabreTools.Library/DatFiles/Filter.cs b/SabreTools.Library/DatFiles/Filter.cs index 1344b8ae..4049a872 100644 --- a/SabreTools.Library/DatFiles/Filter.cs +++ b/SabreTools.Library/DatFiles/Filter.cs @@ -2,6 +2,12 @@ using System.Collections.Generic; using System.Text.RegularExpressions; +#if MONO +using System.IO; +#else +using Alphaleonis.Win32.Filesystem; +#endif + using SabreTools.Library.Data; using SabreTools.Library.DatItems; @@ -53,6 +59,9 @@ namespace SabreTools.Library.DatFiles private long _sizeEqualTo; private bool _includeOfInGame; private bool? _runnable; + private bool _single; + private bool _trim; + private string _root; #endregion @@ -207,6 +216,21 @@ namespace SabreTools.Library.DatFiles get { return _runnable; } set { _runnable = value; } } + public bool Single + { + get { return _single; } + set { _single = value; } + } + public bool Trim + { + get { return _trim; } + set { _trim = value; } + } + public string Root + { + get { return _root; } + set { _root = value; } + } #endregion @@ -251,12 +275,76 @@ namespace SabreTools.Library.DatFiles _sizeEqualTo = -1; _includeOfInGame = false; _runnable = null; + _single = false; + _trim = false; + _root = null; } #endregion #region Instance methods + /// + /// Filter a DatFile using the inputs + /// + /// + /// True if the DatFile was filtered, false on error + public bool FilterDatFile(DatFile datFile) + { + try + { + // Loop over every key in the dictionary + List keys = datFile.Keys; + foreach (string key in keys) + { + // For every item in the current key + List items = datFile[key]; + List newitems = new List(); + foreach (DatItem item in items) + { + // If the rom passes the filter, include it + if (ItemPasses(item)) + { + // If we are in single game mode, rename all games + if (_single) + { + item.MachineName = "!"; + } + + // If we are in NTFS trim mode, trim the game name + if (_trim) + { + // Windows max name length is 260 + int usableLength = 260 - item.MachineName.Length - _root.Length; + if (item.Name.Length > usableLength) + { + string ext = Path.GetExtension(item.Name); + item.Name = item.Name.Substring(0, usableLength - ext.Length); + item.Name += ext; + } + } + + // Lock the list and add the item back + lock (newitems) + { + newitems.Add(item); + } + } + } + + datFile.Remove(key); + datFile.AddRange(key, newitems); + } + } + catch (Exception ex) + { + Globals.Logger.Error(ex.ToString()); + return false; + } + + return true; + } + /// /// Check to see if a DatItem passes the filter /// diff --git a/SabreTools/SabreTools.Inits.cs b/SabreTools/SabreTools.Inits.cs index 4cab77df..8945d6fc 100644 --- a/SabreTools/SabreTools.Inits.cs +++ b/SabreTools/SabreTools.Inits.cs @@ -306,11 +306,7 @@ namespace SabreTools /// True if the date should not be appended to the default name, false otherwise [OBSOLETE] /// /* Filtering info */ /// Pre-populated filter object for DAT filtering - /// /* Trimming info */ /// Type of the split that should be performed (split, merged, fully merged) - /// True if we are supposed to trim names to NTFS length, false otherwise - /// True if all games should be replaced by '!', false otherwise - /// String representing root directory to compare against for length calculation /// /* Output DAT info */ /// Optional param for output directory /// True to clean the game names to WoD standard, false otherwise (default) @@ -363,12 +359,7 @@ namespace SabreTools /* Filtering info */ Filter filter, - - /* Trimming info */ SplitType splitType, - bool trim, - bool single, - string root, /* Output DAT info */ string outDir, @@ -455,7 +446,7 @@ namespace SabreTools }; userInputDat.DetermineUpdateType(inputPaths, basePaths, outDir, updateMode, inplace, skip, bare, clean, - remUnicode, descAsName, filter, splitType, trim, single, root); + remUnicode, descAsName, filter, splitType); } /// diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index 668b774f..33d400a7 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -109,9 +109,7 @@ namespace SabreTools showBaddumpColumn = false, showNodumpColumn = false, shortname = false, - single = false, superdat = false, - trim = false, skip = false, updateDat = false, usegame = true; @@ -581,7 +579,7 @@ namespace SabreTools break; case "-si": case "--single": - single = true; + filter.Single = true; break; case "-ska": case "--skiparc": @@ -617,7 +615,7 @@ namespace SabreTools break; case "-trim": case "--trim": - trim = true; + filter.Trim = true; break; case "-ts": case "--type": @@ -851,7 +849,7 @@ namespace SabreTools break; case "-rd": case "--root-dir": - root = args[++i]; + filter.Root = args[++i]; break; case "-rep": case "--rep-ext": @@ -1293,7 +1291,7 @@ namespace SabreTools // Get statistics on input files else if (stats) { - InitStats(inputs, filename, outDir, single, showBaddumpColumn, showNodumpColumn, statDatFormat); + InitStats(inputs, filename, outDir, filter.Single, showBaddumpColumn, showNodumpColumn, statDatFormat); } // Convert, update, merge, diff, and filter a DAT or folder of DATs @@ -1301,8 +1299,8 @@ namespace SabreTools { InitUpdate(inputs, basePaths, filename, name, description, rootdir, category, version, date, author, email, homepage, url, comment, header, superdat, forcemerge, forcend, forcepack, excludeOf, sceneDateStrip, datFormat, usegame, prefix, postfix, quotes, repext, addext, remext, - datPrefix, romba, updateMode, inplace, skip, removeDateFromAutomaticName, filter, splitType, trim, single, root, outDir, - cleanGameNames, removeUnicode, descAsName, dedup, stripHash); + datPrefix, romba, updateMode, inplace, skip, removeDateFromAutomaticName, filter, splitType, outDir, cleanGameNames, removeUnicode, + descAsName, dedup, stripHash); } // If we're using the verifier