[SabreTools.Helper] Move some files around

This commit is contained in:
Matt Nadareski
2016-10-24 13:43:55 -07:00
parent b44b2739dd
commit ddb6d69c8b
14 changed files with 13 additions and 13 deletions

View File

@@ -0,0 +1,41 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class Archive : DatItem
{
#region Constructors
/// <summary>
/// Create a default, empty Archive object
/// </summary>
public Archive()
{
_name = "";
_itemType = ItemType.Archive;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have an archive, return false
if (_itemType != other.Type)
{
return false;
}
// Otherwise, treat it as an archive
Archive newOther = (Archive)other;
// If the archive information matches
return (_name == newOther.Name);
}
#endregion
}
}

View File

@@ -0,0 +1,63 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class BiosSet : DatItem
{
#region Private instance variables
private string _description;
private bool? _default;
#endregion
#region Publicly facing variables
public string Description
{
get { return _description; }
set { _description = value; }
}
public bool? Default
{
get { return _default; }
set { _default = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Sample object
/// </summary>
public BiosSet()
{
_name = "";
_itemType = ItemType.BiosSet;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a biosset, return false
if (_itemType != other.Type)
{
return false;
}
// Otherwise, treat it as a biosset
BiosSet newOther = (BiosSet)other;
// If the archive information matches
return (_name == newOther.Name && _description == newOther.Description && _default == newOther.Default);
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,902 @@
using System;
using System.Collections.Generic;
using System.IO;
using SabreTools.Helper.Data;
using SabreTools.Helper.Tools;
using NaturalSort;
namespace SabreTools.Helper.Dats
{
[Serializable]
public abstract class DatItem : IEquatable<DatItem>, IComparable<DatItem>
{
#region Protected instance variables
// Standard item information
protected string _name;
protected ItemType _itemType;
protected DupeType _dupeType;
// Machine information
protected Machine _machine;
// Software list information
protected bool? _supported;
protected string _publisher;
protected List<Tuple<string, string>> _infos;
protected string _partName;
protected string _partInterface;
protected List<Tuple<string, string>> _features;
protected string _areaName;
protected long? _areaSize;
// Source metadata information
protected int _systemId;
protected string _systemName;
protected int _sourceId;
protected string _sourceName;
#endregion
#region Publicly facing variables
// Standard item information
public string Name
{
get { return _name; }
set { _name = value; }
}
public ItemType Type
{
get { return _itemType; }
set { _itemType = value; }
}
public DupeType Dupe
{
get { return _dupeType; }
set { _dupeType = value; }
}
// Machine information
public Machine Machine
{
get { return _machine; }
set { _machine = value; }
}
// Software list information
public bool? Supported
{
get { return _supported; }
set { _supported = value; }
}
public string Publisher
{
get { return _publisher; }
set { _publisher = value; }
}
public List<Tuple<string, string>> Infos
{
get { return _infos; }
set { _infos = value; }
}
public string PartName
{
get { return _partName; }
set { _partName = value; }
}
public string PartInterface
{
get { return _partInterface; }
set { _partInterface = value; }
}
public List<Tuple<string, string>> Features
{
get { return _features; }
set { _features = value; }
}
public string AreaName
{
get { return _areaName; }
set { _areaName = value; }
}
public long? AreaSize
{
get { return _areaSize; }
set { _areaSize = value; }
}
// Source metadata information
public int SystemID
{
get { return _systemId; }
set { _systemId = value; }
}
public string System
{
get { return _systemName; }
set { _systemName = value; }
}
public int SourceID
{
get { return _sourceId; }
set { _sourceId = value; }
}
public string Source
{
get { return _sourceName; }
set { _sourceName = value; }
}
#endregion
#region Comparision Methods
public int CompareTo(DatItem other)
{
int ret = 0;
try
{
if (_name == other.Name)
{
ret = (this.Equals(other) ? 0 : 1);
}
ret = String.Compare(_name, other.Name);
}
catch
{
ret = 1;
}
return ret;
}
public abstract bool Equals(DatItem other);
/// <summary>
/// Determine if an item is a duplicate using partial matching logic
/// </summary>
/// <param name="lastItem">DatItem to use as a baseline</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>True if the roms are duplicates, false otherwise</returns>
public bool IsDuplicate(DatItem lastItem, Logger logger)
{
bool dupefound = this.Equals(lastItem);
// More wonderful SHA-1 logging that has to be done
if (_itemType == ItemType.Rom)
{
if (((Rom)this).SHA1 == ((Rom)lastItem).SHA1 && ((Rom)this).Size != ((Rom)lastItem).Size)
{
logger.User("SHA-1 mismatch - Hash: " + ((Rom)this).SHA1);
}
}
return dupefound;
}
/// <summary>
/// Return the duplicate status of two items
/// </summary>
/// <param name="lastItem">DatItem to check against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>The DupeType corresponding to the relationship between the two</returns>
public DupeType GetDuplicateStatus(DatItem lastItem, Logger logger)
{
DupeType output = 0x00;
// If we don't have a duplicate at all, return none
if (!this.IsDuplicate(lastItem, logger))
{
return output;
}
// If the duplicate is external already or should be, set it
if ((lastItem.Dupe & DupeType.External) != 0 || lastItem.SystemID != this.SystemID || lastItem.SourceID != this.SourceID)
{
if (lastItem.Machine.Name == this.Machine.Name && lastItem.Name == this.Name)
{
output = DupeType.External | DupeType.All;
}
else
{
output = DupeType.External | DupeType.Hash;
}
}
// Otherwise, it's considered an internal dupe
else
{
if (lastItem.Machine.Name == this.Machine.Name && lastItem.Name == this.Name)
{
output = DupeType.Internal | DupeType.All;
}
else
{
output = DupeType.Internal | DupeType.Hash;
}
}
return output;
}
#endregion
#region Instance Methods
#region Sorting and Merging
/// <summary>
/// Determine if a rom should be included based on filters
/// </summary>
/// <param name="gamename">Name of the game to match (can use asterisk-partials)</param>
/// <param name="romname">Name of the rom to match (can use asterisk-partials)</param>
/// <param name="romtype">Type of the rom to match</param>
/// <param name="sgt">Find roms greater than or equal to this size</param>
/// <param name="slt">Find roms less than or equal to this size</param>
/// <param name="seq">Find roms equal to this size</param>
/// <param name="crc">CRC of the rom to match (can use asterisk-partials)</param>
/// <param name="md5">MD5 of the rom to match (can use asterisk-partials)</param>
/// <param name="sha1">SHA-1 of the rom to match (can use asterisk-partials)</param>
/// <param name="itemStatus">Select roms with the given status</param>
/// <param name="logger">Logging object for console and file output</param>
/// <returns>Returns true if it should be included, false otherwise</returns>
public bool Filter(string gamename, string romname, string romtype, long sgt,
long slt, long seq, string crc, string md5, string sha1, ItemStatus itemStatus, Logger logger)
{
// Take care of Rom and Disk specific differences
if (Type == ItemType.Rom)
{
Rom rom = (Rom)this;
// Filter on status
if (itemStatus != ItemStatus.NULL)
{
if (itemStatus == ItemStatus.NotNodump && rom.ItemStatus == ItemStatus.Nodump)
{
return false;
}
else if (itemStatus != ItemStatus.NotNodump && rom.ItemStatus != itemStatus)
{
return false;
}
}
// Filter on rom size
if (seq != -1 && rom.Size != seq)
{
return false;
}
else
{
if (sgt != -1 && rom.Size < sgt)
{
return false;
}
if (slt != -1 && rom.Size > slt)
{
return false;
}
}
// Filter on crc
if (!String.IsNullOrEmpty(crc))
{
if (crc.StartsWith("*") && crc.EndsWith("*"))
{
if (!rom.CRC.ToLowerInvariant().Contains(crc.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (crc.StartsWith("*"))
{
if (!rom.CRC.EndsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (crc.EndsWith("*"))
{
if (!rom.CRC.StartsWith(crc.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(rom.CRC, crc, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on md5
if (!String.IsNullOrEmpty(md5))
{
if (md5.StartsWith("*") && md5.EndsWith("*"))
{
if (!rom.MD5.ToLowerInvariant().Contains(md5.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (md5.StartsWith("*"))
{
if (!rom.MD5.EndsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (md5.EndsWith("*"))
{
if (!rom.MD5.StartsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(rom.MD5, md5, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on sha1
if (!String.IsNullOrEmpty(sha1))
{
if (sha1.StartsWith("*") && sha1.EndsWith("*"))
{
if (!rom.SHA1.ToLowerInvariant().Contains(sha1.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (sha1.StartsWith("*"))
{
if (!rom.SHA1.EndsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (sha1.EndsWith("*"))
{
if (!rom.SHA1.StartsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(rom.SHA1, sha1, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
}
else if (Type == ItemType.Disk)
{
Disk rom = (Disk)this;
// Filter on status
if (itemStatus != ItemStatus.NULL && rom.ItemStatus != itemStatus)
{
if (itemStatus == ItemStatus.NotNodump && rom.ItemStatus == ItemStatus.Nodump)
{
return false;
}
else if (itemStatus != ItemStatus.NotNodump && rom.ItemStatus != itemStatus)
{
return false;
}
}
// Filter on md5
if (!String.IsNullOrEmpty(md5))
{
if (md5.StartsWith("*") && md5.EndsWith("*"))
{
if (!rom.MD5.ToLowerInvariant().Contains(md5.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (md5.StartsWith("*"))
{
if (!rom.MD5.EndsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (md5.EndsWith("*"))
{
if (!rom.MD5.StartsWith(md5.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(rom.MD5, md5, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on sha1
if (!String.IsNullOrEmpty(sha1))
{
if (sha1.StartsWith("*") && sha1.EndsWith("*"))
{
if (!rom.SHA1.ToLowerInvariant().Contains(sha1.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (sha1.StartsWith("*"))
{
if (!rom.SHA1.EndsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (sha1.EndsWith("*"))
{
if (!rom.SHA1.StartsWith(sha1.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(rom.SHA1, sha1, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
}
// Filter on game name
if (!String.IsNullOrEmpty(gamename))
{
if (gamename.StartsWith("*") && gamename.EndsWith("*"))
{
if (!Machine.Name.ToLowerInvariant().Contains(gamename.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (gamename.StartsWith("*"))
{
if (!Machine.Name.EndsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (gamename.EndsWith("*"))
{
if (!Machine.Name.StartsWith(gamename.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(Machine.Name, gamename, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on rom name
if (!String.IsNullOrEmpty(romname))
{
if (romname.StartsWith("*") && romname.EndsWith("*"))
{
if (!Name.ToLowerInvariant().Contains(romname.ToLowerInvariant().Replace("*", "")))
{
return false;
}
}
else if (romname.StartsWith("*"))
{
if (!Name.EndsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else if (romname.EndsWith("*"))
{
if (!Name.StartsWith(romname.Replace("*", ""), StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
else
{
if (!String.Equals(Name, romname, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
}
}
// Filter on rom type
if (String.IsNullOrEmpty(romtype) && Type != ItemType.Rom && Type != ItemType.Disk)
{
return false;
}
if (!String.IsNullOrEmpty(romtype) && !String.Equals(Type.ToString(), romtype, StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
return true;
}
/// <summary>
/// Check if a DAT contains the given rom
/// </summary>
/// <param name="datdata">Dat to match against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>True if it contains the rom, false otherwise</returns>
public bool HasDuplicates(DatFile datdata, Logger logger)
{
// Check for an empty rom list first
if (datdata.Files == null || datdata.Files.Count == 0)
{
return false;
}
// Get the correct dictionary based on what is available
string key = "";
if (_itemType == ItemType.Rom && ((Rom)this).CRC != null)
{
key = ((Rom)this).CRC;
datdata.BucketByCRC(false, logger, false);
}
else if (_itemType == ItemType.Rom && ((Rom)this).MD5 != null)
{
key = ((Rom)this).MD5;
datdata.BucketByMD5(false, logger, false);
}
else if (_itemType == ItemType.Disk && ((Disk)this).MD5 != null)
{
key = ((Disk)this).MD5;
datdata.BucketByMD5(false, logger, false);
}
else if (_itemType == ItemType.Rom && ((Rom)this).SHA1 != null)
{
key = ((Rom)this).SHA1;
datdata.BucketBySHA1(false, logger, false);
}
else if (_itemType == ItemType.Disk && ((Disk)this).SHA1 != null)
{
key = ((Disk)this).SHA1;
datdata.BucketBySHA1(false, logger, false);
}
else if (_itemType == ItemType.Rom)
{
key = ((Rom)this).Size.ToString();
datdata.BucketBySize(false, logger, false);
}
else
{
key = "-1";
datdata.BucketBySize(false, logger, false);
}
// If the key doesn't exist, return the empty list
if (!datdata.Files.ContainsKey(key))
{
return false;
}
// Try to find duplicates
List<DatItem> roms = datdata.Files[key];
foreach (DatItem rom in roms)
{
if (IsDuplicate(rom, logger))
{
return true;
}
}
return false;
}
/// <summary>
/// List all duplicates found in a DAT based on a rom
/// </summary>
/// <param name="datdata">Dat to match against</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <param name="remove">True to remove matched roms from the input, false otherwise (default)</param>
/// <returns>List of matched DatItem objects</returns>
public List<DatItem> GetDuplicates(DatFile datdata, Logger logger, bool remove = false)
{
List<DatItem> output = new List<DatItem>();
// Check for an empty rom list first
if (datdata.Files == null || datdata.Files.Count == 0)
{
return output;
}
// Get the correct dictionary based on what is available
string key = "";
if (_itemType == ItemType.Rom && ((Rom)this).CRC != null)
{
key = ((Rom)this).CRC;
datdata.BucketByCRC(false, logger, false);
}
else if (_itemType == ItemType.Rom && ((Rom)this).MD5 != null)
{
key = ((Rom)this).MD5;
datdata.BucketByMD5(false, logger, false);
}
else if (_itemType == ItemType.Disk && ((Disk)this).MD5 != null)
{
key = ((Disk)this).MD5;
datdata.BucketByMD5(false, logger, false);
}
else if (_itemType == ItemType.Rom && ((Rom)this).SHA1 != null)
{
key = ((Rom)this).SHA1;
datdata.BucketBySHA1(false, logger, false);
}
else if (_itemType == ItemType.Disk && ((Disk)this).SHA1 != null)
{
key = ((Disk)this).SHA1;
datdata.BucketBySHA1(false, logger, false);
}
else if (_itemType == ItemType.Rom)
{
key = ((Rom)this).Size.ToString();
datdata.BucketBySize(false, logger, false);
}
else
{
key = "-1";
datdata.BucketBySize(false, logger, false);
}
// If the key doesn't exist, return the empty list
if (!datdata.Files.ContainsKey(key))
{
return output;
}
// Try to find duplicates
List<DatItem> roms = datdata.Files[key];
List<DatItem> left = new List<DatItem>();
foreach (DatItem rom in roms)
{
if (IsDuplicate(rom, logger))
{
output.Add(rom);
}
else
{
left.Add(rom);
}
}
// If we're in removal mode, replace the list with the new one
if (remove)
{
datdata.Files[key] = left;
}
return output;
}
#endregion
#endregion // Instance Methods
#region Static Methods
#region Sorting and Merging
/// <summary>
/// Merge an arbitrary set of ROMs based on the supplied information
/// </summary>
/// <param name="infiles">List of File objects representing the roms to be merged</param>
/// <param name="logger">Logger object for console and/or file output</param>
/// <returns>A List of RomData objects representing the merged roms</returns>
public static List<DatItem> Merge(List<DatItem> infiles, Logger logger)
{
// Check for null or blank roms first
if (infiles == null || infiles.Count == 0)
{
return new List<DatItem>();
}
// Create output list
List<DatItem> outfiles = new List<DatItem>();
// Then deduplicate them by checking to see if data matches previous saved roms
foreach (DatItem file in infiles)
{
// If it's a nodump, add and skip
if (file.Type == ItemType.Rom && ((Rom)file).ItemStatus == ItemStatus.Nodump)
{
outfiles.Add(file);
continue;
}
else if (file.Type == ItemType.Disk && ((Disk)file).ItemStatus == ItemStatus.Nodump)
{
outfiles.Add(file);
continue;
}
// If it's the first rom in the list, don't touch it
if (outfiles.Count != 0)
{
// Check if the rom is a duplicate
DupeType dupetype = 0x00;
DatItem saveditem = new Rom();
int pos = -1;
for (int i = 0; i < outfiles.Count; i++)
{
DatItem lastrom = outfiles[i];
// Get the duplicate status
dupetype = file.GetDuplicateStatus(lastrom, logger);
// If it's a duplicate, skip adding it to the output but add any missing information
if (dupetype != 0x00)
{
// If we don't have a rom or disk, then just skip adding
if (file.Type != ItemType.Rom && file.Type != ItemType.Disk)
{
continue;
}
saveditem = lastrom;
pos = i;
// Roms have more infomration to save
if (file.Type == ItemType.Rom)
{
((Rom)saveditem).Size = ((Rom)saveditem).Size;
((Rom)saveditem).CRC = (String.IsNullOrEmpty(((Rom)saveditem).CRC) && !String.IsNullOrEmpty(((Rom)file).CRC)
? ((Rom)file).CRC
: ((Rom)saveditem).CRC);
((Rom)saveditem).MD5 = (String.IsNullOrEmpty(((Rom)saveditem).MD5) && !String.IsNullOrEmpty(((Rom)file).MD5)
? ((Rom)file).MD5
: ((Rom)saveditem).MD5);
((Rom)saveditem).SHA1 = (String.IsNullOrEmpty(((Rom)saveditem).SHA1) && !String.IsNullOrEmpty(((Rom)file).SHA1)
? ((Rom)file).SHA1
: ((Rom)saveditem).SHA1);
}
else
{
((Disk)saveditem).MD5 = (String.IsNullOrEmpty(((Disk)saveditem).MD5) && !String.IsNullOrEmpty(((Disk)file).MD5)
? ((Disk)file).MD5
: ((Disk)saveditem).MD5);
((Disk)saveditem).SHA1 = (String.IsNullOrEmpty(((Disk)saveditem).SHA1) && !String.IsNullOrEmpty(((Disk)file).SHA1)
? ((Disk)file).SHA1
: ((Disk)saveditem).SHA1);
}
saveditem.Dupe = dupetype;
// If the current system has a lower ID than the previous, set the system accordingly
if (file.SystemID < saveditem.SystemID)
{
saveditem.SystemID = file.SystemID;
saveditem.System = file.System;
saveditem.Machine.Name = file.Machine.Name;
saveditem.Name = file.Name;
}
// If the current source has a lower ID than the previous, set the source accordingly
if (file.SourceID < saveditem.SourceID)
{
saveditem.SourceID = file.SourceID;
saveditem.Source = file.Source;
saveditem.Machine.Name = file.Machine.Name;
saveditem.Name = file.Name;
}
break;
}
}
// If no duplicate is found, add it to the list
if (dupetype == 0x00)
{
outfiles.Add(file);
}
// Otherwise, if a new rom information is found, add that
else
{
outfiles.RemoveAt(pos);
outfiles.Insert(pos, saveditem);
}
}
else
{
outfiles.Add(file);
}
}
// Then return the result
return outfiles;
}
/// <summary>
/// Sort a list of File objects by SystemID, SourceID, Game, and Name (in order)
/// </summary>
/// <param name="roms">List of File objects representing the roms to be sorted</param>
/// <param name="norename">True if files are not renamed, false otherwise</param>
/// <returns>True if it sorted correctly, false otherwise</returns>
public static bool Sort(ref List<DatItem> roms, bool norename)
{
try
{
roms.Sort(delegate (DatItem x, DatItem y)
{
NaturalComparer nc = new NaturalComparer();
if (x.SystemID == y.SystemID)
{
if (x.SourceID == y.SourceID)
{
if (x.Machine.Name == y.Machine.Name)
{
if ((x.Type == ItemType.Rom || x.Type == ItemType.Disk) && (y.Type == ItemType.Rom || y.Type == ItemType.Disk))
{
if (Path.GetDirectoryName(Style.RemovePathUnsafeCharacters(x.Name)) == Path.GetDirectoryName(Style.RemovePathUnsafeCharacters(y.Name)))
{
return nc.Compare(Path.GetFileName(Style.RemovePathUnsafeCharacters(x.Name)), Path.GetFileName(Style.RemovePathUnsafeCharacters(y.Name)));
}
return nc.Compare(Path.GetDirectoryName(Style.RemovePathUnsafeCharacters(x.Name)), Path.GetDirectoryName(Style.RemovePathUnsafeCharacters(y.Name)));
}
else if ((x.Type == ItemType.Rom || x.Type == ItemType.Disk) && (y.Type != ItemType.Rom && y.Type != ItemType.Disk))
{
return -1;
}
else if ((x.Type != ItemType.Rom && x.Type != ItemType.Disk) && (y.Type == ItemType.Rom || y.Type == ItemType.Disk))
{
return 1;
}
else
{
if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name))
{
return nc.Compare(Path.GetFileName(x.Name), Path.GetFileName(y.Name));
}
return nc.Compare(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name));
}
}
return nc.Compare(x.Machine.Name, y.Machine.Name);
}
return (norename ? nc.Compare(x.Machine.Name, y.Machine.Name) : x.SourceID - y.SourceID);
}
return (norename ? nc.Compare(x.Machine.Name, y.Machine.Name) : x.SystemID - y.SystemID);
});
return true;
}
catch (Exception)
{
// Absorb the error
return false;
}
}
#endregion
#endregion // Static Methods
}
}

View File

@@ -0,0 +1,185 @@
using System;
using System.Collections.Specialized;
using System.Linq;
namespace SabreTools.Helper.Dats
{
public class DatItemKV : IEquatable<DatItemKV>
{
// Private instance variables
private string _name;
private NameValueCollection _attributes;
private NameValueCollection _machineAttributes;
private NameValueCollection _machineElements;
// Public instance variables
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Type
{
get { return _name; }
set { _name = value; }
}
public string[] this[string s]
{
get
{
if (_attributes == null)
{
_attributes = new NameValueCollection();
}
return _attributes.GetValues(s);
}
}
// Constructors
public DatItemKV(string name)
{
_name = name;
_attributes = new NameValueCollection();
_machineAttributes = new NameValueCollection();
_machineElements = new NameValueCollection();
}
// Comparison methods
public bool Equals(DatItemKV other)
{
// If the types don't match, then it's not the same
if (_name != other.Type)
{
return false;
}
// Otherwise, loop through and compare against what you can
bool success = true;
foreach (string key in _attributes.Keys)
{
string[] vals = _attributes.GetValues(key);
string[] ovals = other.GetValues(key);
// Special case for "rom"
if (_name == "rom")
{
// If either is a nodump, it's never a match
if (Get("status") == "nodump" || other.Get("status") == "nodump")
{
success = false;
}
// If the size is the same and any combination of metadata matches
if ((Get("size") == other.Get("size")) &&
((String.IsNullOrEmpty(Get("crc")) || String.IsNullOrEmpty(other.Get("crc"))) || Get("crc") == other.Get("crc")) &&
((String.IsNullOrEmpty(Get("md5")) || String.IsNullOrEmpty(other.Get("md5"))) || Get("md5") == other.Get("md5")) &&
((String.IsNullOrEmpty(Get("sha1")) || String.IsNullOrEmpty(other.Get("sha1"))) || Get("sha1") == other.Get("sha1")))
{
success = true;
}
else
{
success = false;
}
}
// Special case for "disk"
else if (_name == "disk")
{
// If either is a nodump, it's never a match
if (Get("status") == "nodump" || other.Get("status") == "nodump")
{
success = false;
}
// If any combination of metadata matches
if (((String.IsNullOrEmpty(Get("md5")) || String.IsNullOrEmpty(other.Get("md5"))) || Get("md5") == other.Get("md5")) &&
((String.IsNullOrEmpty(Get("sha1")) || String.IsNullOrEmpty(other.Get("sha1"))) || Get("sha1") == other.Get("sha1")))
{
success = true;
}
else
{
success = false;
}
}
// For everything else
else
{
// http://stackoverflow.com/questions/649444/testing-equality-of-arrays-in-c-sharp
var q = from a in vals
join b in ovals on a equals b
select a;
success &= vals.Length == ovals.Length && q.Count() == vals.Length;
}
}
return success;
}
// Instance methods
public void Add(string name, string value)
{
_attributes.Add(name, value);
}
public string Get(string name)
{
return _attributes.Get(name);
}
public string Get(int index)
{
return _attributes.Get(index);
}
public string[] GetValues(string name)
{
return _attributes.GetValues(name);
}
public string[] GetValues(int index)
{
return _attributes.GetValues(index);
}
public void MachineAttributesAdd(string name, string value)
{
_machineAttributes.Add(name, value);
}
public string MachineAttributesGet(string name)
{
return _attributes.Get(name);
}
public string MachineAttributesGet(int index)
{
return _attributes.Get(index);
}
public string[] MachineAttributesGetValues(string name)
{
return _attributes.GetValues(name);
}
public string[] MachineAttributesGetValues(int index)
{
return _attributes.GetValues(index);
}
public void MachineElementsAdd(string name, string value)
{
_machineAttributes.Add(name, value);
}
public string MachineElementsGet(string name)
{
return _attributes.Get(name);
}
public string MachineElementsGet(int index)
{
return _attributes.Get(index);
}
public string[] MachineElementsGetValues(string name)
{
return _attributes.GetValues(name);
}
public string[] MachineElementsGetValues(int index)
{
return _attributes.GetValues(index);
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class Disk : DatItem
{
#region Private instance variables
// Disk information
protected string _md5;
protected string _sha1;
// private string _merge;
protected ItemStatus _itemStatus;
#endregion
#region Publicly facing variables
// Disk information
public string MD5
{
get { return _md5; }
set { _md5 = value; }
}
public string SHA1
{
get { return _sha1; }
set { _sha1 = value; }
}
public ItemStatus ItemStatus
{
get { return _itemStatus; }
set { _itemStatus = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Disk object
/// </summary>
public Disk()
{
_name = "";
_itemType = ItemType.Disk;
_dupeType = 0x00;
_itemStatus = ItemStatus.None;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
bool dupefound = false;
// If we don't have a rom, return false
if (_itemType != other.Type)
{
return dupefound;
}
// Otherwise, treat it as a rom
Disk newOther = (Disk)other;
// If either is a nodump, it's never a match
if (_itemStatus == ItemStatus.Nodump || newOther.ItemStatus == ItemStatus.Nodump)
{
return dupefound;
}
if (((String.IsNullOrEmpty(_md5) || String.IsNullOrEmpty(newOther.MD5)) || this.MD5 == newOther.MD5) &&
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(newOther.SHA1)) || this.SHA1 == newOther.SHA1))
{
dupefound = true;
}
return dupefound;
}
#endregion
}
}

View File

@@ -0,0 +1,113 @@
namespace SabreTools.Helper.Dats
{
public class Machine
{
#region Protected instance variables
// Machine information
protected string _name;
protected string _comment;
protected string _description;
protected string _year;
protected string _manufacturer;
protected string _romOf;
protected string _cloneOf;
protected string _sampleOf;
protected string _sourceFile;
protected bool _isBios;
protected string _board;
protected string _rebuildTo;
#endregion
#region Publicly facing variables
// Machine information
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Comment
{
get { return _comment; }
set { _comment = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public string Year
{
get { return _year; }
set { _year = value; }
}
public string Manufacturer
{
get { return _manufacturer; }
set { _manufacturer = value; }
}
public string RomOf
{
get { return _romOf; }
set { _romOf = value; }
}
public string CloneOf
{
get { return _cloneOf; }
set { _cloneOf = value; }
}
public string SampleOf
{
get { return _sampleOf; }
set { _sampleOf = value; }
}
public string SourceFile
{
get { return _sourceFile; }
set { _sourceFile = value; }
}
public bool IsBios
{
get { return _isBios; }
set { _isBios = value; }
}
public string Board
{
get { return _board; }
set { _board = value; }
}
public string RebuildTo
{
get { return _rebuildTo; }
set { _rebuildTo = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Machine object
/// </summary>
public Machine()
{
_name = "";
_description = "";
}
/// <summary>
/// Create a new Machine object with the included information
/// </summary>
/// <param name="name">Name of the machine</param>
/// <param name="description">Description of the machine</param>
public Machine(string name, string description)
{
_name = name;
_description = description;
}
#endregion
}
}

View File

@@ -0,0 +1,83 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class Release : DatItem
{
#region Private instance variables
private string _region;
private string _language;
private string _date;
private bool? _default;
#endregion
#region Publicly facing variables
public string Region
{
get { return _region; }
set { _region = value; }
}
public string Language
{
get { return _language; }
set { _language = value; }
}
public string Date
{
get { return _date; }
set { _date = value; }
}
public bool? Default
{
get { return _default; }
set { _default = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Release object
/// </summary>
public Release()
{
_name = "";
_itemType = ItemType.Release;
_region = "";
_language = "";
_date = "";
_default = null;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a release return false
if (_itemType != other.Type)
{
return false;
}
// Otherwise, treat it as a reease
Release newOther = (Release)other;
// If the archive information matches
return (_name == newOther.Name
&& _region == newOther.Region
&& _language == newOther.Language
&& _date == newOther.Date
&& _default == newOther.Default);
}
#endregion
}
}

View File

@@ -0,0 +1,111 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class Rom : Disk
{
#region Private instance variables
// Rom information
protected long _size;
protected string _crc;
private string _date;
#endregion
#region Publicly facing variables
// Rom information
public long Size
{
get { return _size; }
set { _size = value; }
}
public string CRC
{
get { return _crc; }
set { _crc = value; }
}
public string Date
{
get { return _date; }
set { _date = value; }
}
#endregion
#region Constructors
/// <summary>
/// Create a default, empty Rom object
/// </summary>
public Rom()
{
_name = "";
_itemType = ItemType.Rom;
_dupeType = 0x00;
_itemStatus = ItemStatus.None;
_date = "";
}
/// <summary>
/// Create a "blank" Rom object
/// </summary>
/// <param name="name"></param>
/// <param name="machineName"></param>
public Rom(string name, string machineName)
{
_name = name;
_itemType = ItemType.Rom;
_size = -1;
_crc = "null";
_md5 = "null";
_sha1 = "null";
_itemStatus = ItemStatus.None;
_machine = new Machine
{
Name = machineName,
Description = machineName,
};
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
bool dupefound = false;
// If we don't have a rom, return false
if (_itemType != other.Type)
{
return dupefound;
}
// Otherwise, treat it as a rom
Rom newOther = (Rom)other;
// If either is a nodump, it's never a match
if (_itemStatus == ItemStatus.Nodump || newOther.ItemStatus == ItemStatus.Nodump)
{
return dupefound;
}
if ((this.Size == newOther.Size) &&
((String.IsNullOrEmpty(this.CRC) || String.IsNullOrEmpty(newOther.CRC)) || this.CRC == newOther.CRC) &&
((String.IsNullOrEmpty(this.MD5) || String.IsNullOrEmpty(newOther.MD5)) || this.MD5 == newOther.MD5) &&
((String.IsNullOrEmpty(this.SHA1) || String.IsNullOrEmpty(newOther.SHA1)) || this.SHA1 == newOther.SHA1))
{
dupefound = true;
}
return dupefound;
}
#endregion
}
}

View File

@@ -0,0 +1,41 @@
using System;
using SabreTools.Helper.Data;
namespace SabreTools.Helper.Dats
{
[Serializable]
public class Sample : DatItem
{
#region Constructors
/// <summary>
/// Create a default, empty Sample object
/// </summary>
public Sample()
{
_name = "";
_itemType = ItemType.Sample;
}
#endregion
#region Comparision Methods
public override bool Equals(DatItem other)
{
// If we don't have a sample, return false
if (_itemType != other.Type)
{
return false;
}
// Otherwise, treat it as a sample
Sample newOther = (Sample)other;
// If the archive information matches
return (_name == newOther.Name);
}
#endregion
}
}