diff --git a/SabreTools.Library/DatFiles/Filter.cs b/SabreTools.Library/DatFiles/Filter.cs index 3ed01fb5..aa23d769 100644 --- a/SabreTools.Library/DatFiles/Filter.cs +++ b/SabreTools.Library/DatFiles/Filter.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; +using SabreTools.Library.Data; +using SabreTools.Library.DatItems; #if MONO using System.IO; @@ -8,761 +10,531 @@ using System.IO; using Alphaleonis.Win32.Filesystem; #endif -using SabreTools.Library.Data; -using SabreTools.Library.DatItems; - namespace SabreTools.Library.DatFiles { - /// - /// Represents the filtering operations that need to be performed on a set of items, usually a DAT - /// - public class Filter - { - #region Private instance variables - - #region Positive - - private List _gameNames; - private List _gameDescriptions; - private List _romNames; - private List _romTypes; - private List _crcs; - private List _md5s; - private List _sha1s; - private List _sha256s; - private List _sha384s; - private List _sha512s; - private ItemStatus _itemStatuses; - private MachineType _machineTypes; - - #endregion - - #region Negative - - private List _notGameNames; - private List _notGameDescriptions; - private List _notRomNames; - private List _notRomTypes; - private List _notCrcs; - private List _notMd5s; - private List _notSha1s; - private List _notSha256s; - private List _notSha384s; - private List _notSha512s; - private ItemStatus _itemNotStatuses; - private MachineType _machineNotTypes; - - #endregion - - #region Neutral - - private long _sizeGreaterThanOrEqual; - private long _sizeLessThanOrEqual; - private long _sizeEqualTo; - private bool _includeOfInGame; - private bool? _runnable; - private bool _single; - private bool _trim; - private string _root; - - #endregion - - #endregion // Private instance variables - - #region Pubically facing variables - - #region Positive - - public List MachineNames - { - get { return _gameNames; } - set { _gameNames = value; } - } - public List MachineDescriptions - { - get { return _gameDescriptions; } - set { _gameDescriptions = value; } - } - public List ItemNames - { - get { return _romNames; } - set { _romNames = value; } - } - public List ItemTypes - { - get { return _romTypes; } - set { _romTypes = value; } - } - public List CRCs - { - get { return _crcs; } - set { _crcs = value; } - } - public List MD5s - { - get { return _md5s; } - set { _md5s = value; } - } - public List SHA1s - { - get { return _sha1s; } - set { _sha1s = value; } - } - public List SHA256s - { - get { return _sha256s; } - set { _sha256s = value; } - } - public List SHA384s - { - get { return _sha384s; } - set { _sha384s = value; } - } - public List SHA512s - { - get { return _sha512s; } - set { _sha512s = value; } - } - public ItemStatus ItemStatuses - { - get { return _itemStatuses; } - set { _itemStatuses = value; } - } - public MachineType MachineTypes - { - get { return _machineTypes; } - set { _machineTypes = value; } - } - - #endregion - - #region Negative - - public List NotMachineNames - { - get { return _notGameNames; } - set { _notGameNames = value; } - } - public List NotMachineDescriptions - { - get { return _notGameDescriptions; } - set { _notGameDescriptions = value; } - } - public List NotItemNames - { - get { return _notRomNames; } - set { _notRomNames = value; } - } - public List NotItemTypes - { - get { return _notRomTypes; } - set { _notRomTypes = value; } - } - public List NotCRCs - { - get { return _notCrcs; } - set { _notCrcs = value; } - } - public List NotMD5s - { - get { return _notMd5s; } - set { _notMd5s = value; } - } - public List NotSHA1s - { - get { return _notSha1s; } - set { _notSha1s = value; } - } - public List NotSHA256s - { - get { return _notSha256s; } - set { _notSha256s = value; } - } - public List NotSHA384s - { - get { return _notSha384s; } - set { _notSha384s = value; } - } - public List NotSHA512s - { - get { return _notSha512s; } - set { _notSha512s = value; } - } - public ItemStatus NotItemStatuses - { - get { return _itemNotStatuses; } - set { _itemNotStatuses = value; } - } - public MachineType NotMachineTypes - { - get { return _machineNotTypes; } - set { _machineNotTypes = value; } - } - - #endregion - - #region Neutral - - public long SizeGreaterThanOrEqual - { - get { return _sizeGreaterThanOrEqual; } - set { _sizeGreaterThanOrEqual = value; } - } - public long SizeLessThanOrEqual - { - get { return _sizeLessThanOrEqual; } - set { _sizeLessThanOrEqual = value; } - } - public long SizeEqualTo - { - get { return _sizeEqualTo; } - set { _sizeEqualTo = value; } - } - public bool IncludeOfInGame - { - get { return _includeOfInGame; } - set { _includeOfInGame = value; } - } - public bool? Runnable - { - 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 - - #endregion // Pubically facing variables - - #region Constructors - - /// - /// Create an empty Filter object - /// - public Filter() - { - // Positive - _gameNames = new List(); - _gameDescriptions = new List(); - _romNames = new List(); - _romTypes = new List(); - _crcs = new List(); - _md5s = new List(); - _sha1s = new List(); - _sha256s = new List(); - _sha384s = new List(); - _sha512s = new List(); - _itemStatuses = ItemStatus.NULL; - _machineTypes = MachineType.NULL; - - // Negative - _notGameNames = new List(); - _notGameDescriptions = new List(); - _notRomNames = new List(); - _notRomTypes = new List(); - _notCrcs = new List(); - _notMd5s = new List(); - _notSha1s = new List(); - _notSha256s = new List(); - _notSha384s = new List(); - _notSha512s = new List(); - _itemNotStatuses = ItemStatus.NULL; - _machineNotTypes = MachineType.NULL; - - // Neutral - _sizeGreaterThanOrEqual = -1; - _sizeLessThanOrEqual = -1; - _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 - /// - /// DatItem to check - /// True if the file passed the filter, false otherwise - public bool ItemPasses(DatItem item) - { - // If the item is null, we automatically fail it - if (item == null) - { - return false; - } - - // Filter on machine type - if (_machineTypes != MachineType.NULL && (item.MachineType & _machineTypes) == 0) - { - return false; - } - if (_machineNotTypes != MachineType.NULL && (item.MachineType & _machineNotTypes) != 0) - { - return false; - } - - // Filter on machine runability - if (_runnable != null && item.Runnable != _runnable) - { - return false; - } - - // Take care of Rom and Disk specific differences - if (item.ItemType == ItemType.Rom) - { - Rom rom = (Rom)item; - - // Filter on status - if (_itemStatuses != ItemStatus.NULL && (rom.ItemStatus & _itemStatuses) == 0) - { - return false; - } - if (_itemNotStatuses != ItemStatus.NULL && (rom.ItemStatus & _itemNotStatuses) != 0) - { - return false; - } - - // Filter on rom size - if (_sizeEqualTo != -1 && rom.Size != _sizeEqualTo) - { - return false; - } - else - { - if (_sizeGreaterThanOrEqual != -1 && rom.Size < _sizeGreaterThanOrEqual) - { - return false; - } - if (_sizeLessThanOrEqual != -1 && rom.Size > _sizeLessThanOrEqual) - { - return false; - } - } - - // Filter on CRC - if (_crcs.Count > 0) - { - // If the CRC isn't in the list, return false - if (!FindValueInList(_crcs, rom.CRC)) - { - return false; - } - } - if (_notCrcs.Count > 0) - { - // If the CRC is in the list, return false - if (FindValueInList(_notCrcs, rom.CRC)) - { - return false; - } - } - - // Filter on MD5 - if (_md5s.Count > 0) - { - // If the MD5 isn't in the list, return false - if (!FindValueInList(_md5s, rom.MD5)) - { - return false; - } - } - if (_notMd5s.Count > 0) - { - // If the MD5 is in the list, return false - if (FindValueInList(_notMd5s, rom.MD5)) - { - return false; - } - } - - // Filter on SHA1 - if (_sha1s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha1s, rom.SHA1)) - { - return false; - } - } - if (_notSha1s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha1s, rom.SHA1)) - { - return false; - } - } - - // Filter on SHA256 - if (_sha256s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha256s, rom.SHA256)) - { - return false; - } - } - if (_notSha256s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha256s, rom.SHA256)) - { - return false; - } - } - - // Filter on SHA384 - if (_sha384s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha384s, rom.SHA384)) - { - return false; - } - } - if (_notSha384s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha384s, rom.SHA384)) - { - return false; - } - } - - // Filter on SHA512 - if (_sha512s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha512s, rom.SHA512)) - { - return false; - } - } - if (_notSha512s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha512s, rom.SHA512)) - { - return false; - } - } - } - else if (item.ItemType == ItemType.Disk) - { - Disk rom = (Disk)item; - - // Filter on status - if (_itemStatuses != ItemStatus.NULL && (rom.ItemStatus & _itemStatuses) == 0) - { - return false; - } - if (_itemNotStatuses != ItemStatus.NULL && (rom.ItemStatus & _itemNotStatuses) != 0) - { - return false; - } - - // Filter on MD5 - if (_md5s.Count > 0) - { - // If the MD5 isn't in the list, return false - if (!FindValueInList(_md5s, rom.MD5)) - { - return false; - } - } - if (_notMd5s.Count > 0) - { - // If the MD5 is in the list, return false - if (FindValueInList(_notMd5s, rom.MD5)) - { - return false; - } - } - - // Filter on SHA1 - if (_sha1s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha1s, rom.SHA1)) - { - return false; - } - } - if (_notSha1s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha1s, rom.SHA1)) - { - return false; - } - } - - // Filter on SHA256 - if (_sha256s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha256s, rom.SHA256)) - { - return false; - } - } - if (_notSha256s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha256s, rom.SHA256)) - { - return false; - } - } - - // Filter on SHA384 - if (_sha384s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha384s, rom.SHA384)) - { - return false; - } - } - if (_notSha384s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha384s, rom.SHA384)) - { - return false; - } - } - - // Filter on SHA512 - if (_sha512s.Count > 0) - { - // If the SHA-1 isn't in the list, return false - if (!FindValueInList(_sha512s, rom.SHA512)) - { - return false; - } - } - if (_notSha512s.Count > 0) - { - // If the SHA-1 is in the list, return false - if (FindValueInList(_notSha512s, rom.SHA512)) - { - return false; - } - } - } - - // Filter on game name - if (_gameNames.Count > 0) - { - bool found = FindValueInList(_gameNames, item.MachineName); - - // If we are checking CloneOf and RomOf, add them in as well - if (_includeOfInGame) - { - found |= FindValueInList(_gameNames, item.CloneOf); - found |= FindValueInList(_gameNames, item.RomOf); - } - - // If the game name was not found in the list, return false - if (!found) - { - return false; - } - } - if (_notGameNames.Count > 0) - { - bool found = FindValueInList(_notGameNames, item.MachineName); - - // If we are checking CloneOf and RomOf, add them in as well - if (_includeOfInGame) - { - found |= FindValueInList(_notGameNames, item.CloneOf); - found |= FindValueInList(_notGameNames, item.RomOf); - } - - // If the game name was found in the list, return false - if (found) - { - return false; - } - } - - // Filter on game description - if (_gameDescriptions.Count > 0) - { - bool found = FindValueInList(_gameDescriptions, item.MachineDescription); - - // If the game description was not found in the list, return false - if (!found) - { - return false; - } - } - if (_notGameDescriptions.Count > 0) - { - bool found = FindValueInList(_notGameDescriptions, item.MachineDescription); - - // If the game description was found in the list, return false - if (found) - { - return false; - } - } - - // Filter on rom name - if (_romNames.Count > 0) - { - // If the rom name was not found in the list, return false - if (!FindValueInList(_romNames, item.Name)) - { - return false; - } - } - if (_notRomNames.Count > 0) - { - // If the rom name was found in the list, return false - if (FindValueInList(_notRomNames, item.Name)) - { - return false; - } - } - - // Filter on rom type - if (_romTypes.Count == 0 && _notRomTypes.Count == 0 && item.ItemType != ItemType.Rom && item.ItemType != ItemType.Disk && item.ItemType != ItemType.Blank) - { - return false; - } - if (_romTypes.Count > 0) - { - // If the rom type was not found in the list, return false - if (!FindValueInList(_romTypes, item.ItemType.ToString())) - { - return false; - } - } - if (_notRomTypes.Count > 0) - { - // If the rom type was found in the list, return false - if (FindValueInList(_notRomTypes, item.ItemType.ToString())) - { - return false; - } - } - - return true; - } - - /// - /// Generic code to check if a specific value is in the list given - /// - /// List to search for the value in - /// Value to search the list for - /// True if the value could be found, false otherwise - private bool FindValueInList(List haystack, string needle) - { - bool found = false; - foreach (string straw in haystack) - { - if (!String.IsNullOrWhiteSpace(straw)) - { - string regexStraw = straw; - - // If the straw has no special characters at all, treat it as an exact match - if (regexStraw == Regex.Escape(regexStraw)) - { - regexStraw = "^" + regexStraw + "$"; - } - - // Check if a match is found with the regex - found |= Regex.IsMatch(needle, regexStraw, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - } - } - - return found; - } - - #endregion - } + /// + /// Represents the filtering operations that need to be performed on a set of items, usually a DAT + /// + public class Filter + { + #region Pubically facing variables + + #region Positive + + public List MachineNames { get; set; } = new List(); + public List MachineDescriptions { get; set; } = new List(); + public List ItemNames { get; set; } = new List(); + public List ItemTypes { get; set; } = new List(); + public List CRCs { get; set; } = new List(); + public List MD5s { get; set; } = new List(); + public List SHA1s { get; set; } = new List(); + public List SHA256s { get; set; } = new List(); + public List SHA384s { get; set; } = new List(); + public List SHA512s { get; set; } = new List(); + public ItemStatus ItemStatuses { get; set; } = ItemStatus.NULL; + public MachineType MachineTypes { get; set; } = MachineType.NULL; + + #endregion + + #region Negative + + public List NotMachineNames { get; set; } = new List(); + public List NotMachineDescriptions { get; set; } = new List(); + public List NotItemNames { get; set; } = new List(); + public List NotItemTypes { get; set; } = new List(); + public List NotCRCs { get; set; } = new List(); + public List NotMD5s { get; set; } = new List(); + public List NotSHA1s { get; set; } = new List(); + public List NotSHA256s { get; set; } = new List(); + public List NotSHA384s { get; set; } = new List(); + public List NotSHA512s { get; set; } = new List(); + public ItemStatus NotItemStatuses { get; set; } = ItemStatus.NULL; + public MachineType NotMachineTypes { get; set; } = MachineType.NULL; + + #endregion + + #region Neutral + + public long SizeGreaterThanOrEqual { get; set; } = -1; + public long SizeLessThanOrEqual { get; set; } = -1; + public long SizeEqualTo { get; set; } = -1; + public bool IncludeOfInGame { get; set; } = false; + public bool? Runnable { get; set; } = null; + public bool Single { get; set; } = false; + public bool Trim { get; set; } = false; + public string Root { get; set; } = null; + + #endregion + + #endregion // Pubically facing variables + + #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 (this.Single) + { + item.MachineName = "!"; + } + + // If we are in NTFS trim mode, trim the game name + if (this.Trim) + { + // Windows max name length is 260 + int usableLength = 260 - item.MachineName.Length - this.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 + /// + /// DatItem to check + /// True if the file passed the filter, false otherwise + public bool ItemPasses(DatItem item) + { + // If the item is null, we automatically fail it + if (item == null) + { + return false; + } + + // Filter on machine type + if (this.MachineTypes != MachineType.NULL && (item.MachineType & this.MachineTypes) == 0) + { + return false; + } + if (this.NotMachineTypes != MachineType.NULL && (item.MachineType & this.NotMachineTypes) != 0) + { + return false; + } + + // Filter on machine runability + if (this.Runnable != null && item.Runnable != this.Runnable) + { + return false; + } + + // Take care of Rom and Disk specific differences + if (item.ItemType == ItemType.Rom) + { + Rom rom = (Rom)item; + + // Filter on status + if (this.ItemStatuses != ItemStatus.NULL && (rom.ItemStatus & this.ItemStatuses) == 0) + { + return false; + } + if (this.NotItemStatuses != ItemStatus.NULL && (rom.ItemStatus & this.NotItemStatuses) != 0) + { + return false; + } + + // Filter on rom size + if (this.SizeEqualTo != -1 && rom.Size != this.SizeEqualTo) + { + return false; + } + else + { + if (this.SizeGreaterThanOrEqual != -1 && rom.Size < this.SizeGreaterThanOrEqual) + { + return false; + } + if (this.SizeLessThanOrEqual != -1 && rom.Size > this.SizeLessThanOrEqual) + { + return false; + } + } + + // Filter on CRC + if (this.CRCs.Count > 0) + { + // If the CRC isn't in the list, return false + if (!FindValueInList(this.CRCs, rom.CRC)) + { + return false; + } + } + if (this.NotCRCs.Count > 0) + { + // If the CRC is in the list, return false + if (FindValueInList(this.NotCRCs, rom.CRC)) + { + return false; + } + } + + // Filter on MD5 + if (this.MD5s.Count > 0) + { + // If the MD5 isn't in the list, return false + if (!FindValueInList(this.MD5s, rom.MD5)) + { + return false; + } + } + if (this.NotMD5s.Count > 0) + { + // If the MD5 is in the list, return false + if (FindValueInList(this.NotMD5s, rom.MD5)) + { + return false; + } + } + + // Filter on SHA-1 + if (this.SHA1s.Count > 0) + { + // If the SHA-1 isn't in the list, return false + if (!FindValueInList(this.SHA1s, rom.SHA1)) + { + return false; + } + } + if (this.NotSHA1s.Count > 0) + { + // If the SHA-1 is in the list, return false + if (FindValueInList(this.NotSHA1s, rom.SHA1)) + { + return false; + } + } + + // Filter on SHA-256 + if (this.SHA256s.Count > 0) + { + // If the SHA-256 isn't in the list, return false + if (!FindValueInList(this.SHA256s, rom.SHA256)) + { + return false; + } + } + if (this.NotSHA256s.Count > 0) + { + // If the SHA-256 is in the list, return false + if (FindValueInList(this.NotSHA256s, rom.SHA256)) + { + return false; + } + } + + // Filter on SHA-384 + if (this.SHA384s.Count > 0) + { + // If the SHA-384 isn't in the list, return false + if (!FindValueInList(this.SHA384s, rom.SHA384)) + { + return false; + } + } + if (this.NotSHA384s.Count > 0) + { + // If the SHA-384 is in the list, return false + if (FindValueInList(this.NotSHA384s, rom.SHA384)) + { + return false; + } + } + + // Filter on SHA-512 + if (this.SHA512s.Count > 0) + { + // If the SHA-512 isn't in the list, return false + if (!FindValueInList(this.SHA512s, rom.SHA512)) + { + return false; + } + } + if (this.NotSHA512s.Count > 0) + { + // If the SHA-512 is in the list, return false + if (FindValueInList(this.NotSHA512s, rom.SHA512)) + { + return false; + } + } + } + else if (item.ItemType == ItemType.Disk) + { + Disk rom = (Disk)item; + + // Filter on status + if (this.ItemStatuses != ItemStatus.NULL && (rom.ItemStatus & this.ItemStatuses) == 0) + { + return false; + } + if (this.NotItemStatuses != ItemStatus.NULL && (rom.ItemStatus & this.NotItemStatuses) != 0) + { + return false; + } + + // Filter on MD5 + if (this.MD5s.Count > 0) + { + // If the MD5 isn't in the list, return false + if (!FindValueInList(this.MD5s, rom.MD5)) + { + return false; + } + } + if (this.NotMD5s.Count > 0) + { + // If the MD5 is in the list, return false + if (FindValueInList(this.NotMD5s, rom.MD5)) + { + return false; + } + } + + // Filter on SHA-1 + if (this.SHA1s.Count > 0) + { + // If the SHA-1 isn't in the list, return false + if (!FindValueInList(this.SHA1s, rom.SHA1)) + { + return false; + } + } + if (this.NotSHA1s.Count > 0) + { + // If the SHA-1 is in the list, return false + if (FindValueInList(this.NotSHA1s, rom.SHA1)) + { + return false; + } + } + + // Filter on SHA-256 + if (this.SHA256s.Count > 0) + { + // If the SHA-256 isn't in the list, return false + if (!FindValueInList(this.SHA256s, rom.SHA256)) + { + return false; + } + } + if (this.NotSHA256s.Count > 0) + { + // If the SHA-256 is in the list, return false + if (FindValueInList(this.NotSHA256s, rom.SHA256)) + { + return false; + } + } + + // Filter on SHA-384 + if (this.SHA384s.Count > 0) + { + // If the SHA-384 isn't in the list, return false + if (!FindValueInList(this.SHA384s, rom.SHA384)) + { + return false; + } + } + if (this.NotSHA384s.Count > 0) + { + // If the SHA-384 is in the list, return false + if (FindValueInList(this.NotSHA384s, rom.SHA384)) + { + return false; + } + } + + // Filter on SHA-512 + if (this.SHA512s.Count > 0) + { + // If the SHA-512 isn't in the list, return false + if (!FindValueInList(this.SHA512s, rom.SHA512)) + { + return false; + } + } + if (this.NotSHA512s.Count > 0) + { + // If the SHA-512 is in the list, return false + if (FindValueInList(this.NotSHA512s, rom.SHA512)) + { + return false; + } + } + } + + // Filter on machine name + if (this.MachineNames.Count > 0) + { + bool found = FindValueInList(this.MachineNames, item.MachineName); + + // If we are checking CloneOf and RomOf, add them in as well + if (this.IncludeOfInGame) + { + found |= FindValueInList(this.MachineNames, item.CloneOf); + found |= FindValueInList(this.MachineNames, item.RomOf); + } + + // If the game name was not found in the list, return false + if (!found) + { + return false; + } + } + if (this.NotMachineNames.Count > 0) + { + bool found = FindValueInList(this.NotMachineNames, item.MachineName); + + // If we are checking CloneOf and RomOf, add them in as well + if (this.IncludeOfInGame) + { + found |= FindValueInList(this.NotMachineNames, item.CloneOf); + found |= FindValueInList(this.NotMachineNames, item.RomOf); + } + + // If the machine name was found in the list, return false + if (found) + { + return false; + } + } + + // Filter on machine description + if (this.MachineDescriptions.Count > 0) + { + bool found = FindValueInList(this.MachineDescriptions, item.MachineDescription); + + // If the machine description was not found in the list, return false + if (!found) + { + return false; + } + } + if (this.NotMachineDescriptions.Count > 0) + { + bool found = FindValueInList(this.NotMachineDescriptions, item.MachineDescription); + + // If the machine description was found in the list, return false + if (found) + { + return false; + } + } + + // Filter on item name + if (this.ItemNames.Count > 0) + { + // If the item name was not found in the list, return false + if (!FindValueInList(this.ItemNames, item.Name)) + { + return false; + } + } + if (this.NotItemNames.Count > 0) + { + // If the item name was found in the list, return false + if (FindValueInList(this.NotItemNames, item.Name)) + { + return false; + } + } + + // Filter on item type + if (this.ItemTypes.Count == 0 && this.NotItemTypes.Count == 0 && item.ItemType != ItemType.Rom && item.ItemType != ItemType.Disk && item.ItemType != ItemType.Blank) + { + return false; + } + if (this.ItemTypes.Count > 0) + { + // If the item type was not found in the list, return false + if (!FindValueInList(this.ItemTypes, item.ItemType.ToString())) + { + return false; + } + } + if (this.NotItemTypes.Count > 0) + { + // If the item type was found in the list, return false + if (FindValueInList(this.NotItemTypes, item.ItemType.ToString())) + { + return false; + } + } + + return true; + } + + /// + /// Generic code to check if a specific value is in the list given + /// + /// List to search for the value in + /// Value to search the list for + /// True if the value could be found, false otherwise + private bool FindValueInList(List haystack, string needle) + { + bool found = false; + foreach (string straw in haystack) + { + if (!String.IsNullOrWhiteSpace(straw)) + { + string regexStraw = straw; + + // If the straw has no special characters at all, treat it as an exact match + if (regexStraw == Regex.Escape(regexStraw)) + { + regexStraw = "^" + regexStraw + "$"; + } + + // Check if a match is found with the regex + found |= Regex.IsMatch(needle, regexStraw, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + } + } + + return found; + } + + #endregion + } }