diff --git a/SabreTools.Library/DatFiles/Enums.cs b/SabreTools.Library/DatFiles/Enums.cs
index aa98ca9f..517e0ea6 100644
--- a/SabreTools.Library/DatFiles/Enums.cs
+++ b/SabreTools.Library/DatFiles/Enums.cs
@@ -5,6 +5,7 @@ namespace SabreTools.Library.DatFiles
///
/// Determines how the current dictionary is bucketed by
///
+ /// TODO: Can we use "Field" instead of this? How much more stupidly complex would that make things?
public enum BucketedBy
{
Default = 0,
diff --git a/SabreTools.Library/DatItems/Archive.cs b/SabreTools.Library/DatItems/Archive.cs
index aee0343e..ea6deca2 100644
--- a/SabreTools.Library/DatItems/Archive.cs
+++ b/SabreTools.Library/DatItems/Archive.cs
@@ -1,6 +1,4 @@
-using SabreTools.Library.Data;
-
-namespace SabreTools.Library.DatItems
+namespace SabreTools.Library.DatItems
{
///
/// Represents generic archive files to be included in a set
diff --git a/SabreTools.Library/DatItems/BiosSet.cs b/SabreTools.Library/DatItems/BiosSet.cs
index 1f745bab..b5f4d547 100644
--- a/SabreTools.Library/DatItems/BiosSet.cs
+++ b/SabreTools.Library/DatItems/BiosSet.cs
@@ -1,4 +1,5 @@
-using SabreTools.Library.Data;
+using System.Collections.Generic;
+using System.Security.Permissions;
using Newtonsoft.Json;
namespace SabreTools.Library.DatItems
@@ -24,6 +25,42 @@ namespace SabreTools.Library.DatItems
#endregion
+ #region Accessors
+
+ ///
+ /// Get the value of that field as a string, if possible
+ ///
+ public override string GetField(Field field, List excludeFields)
+ {
+ // If the field is to be excluded, return empty string
+ if (excludeFields.Contains(field))
+ return string.Empty;
+
+ // Handle BiosSet-specific fields
+ string fieldValue;
+ switch (field)
+ {
+ case Field.Default:
+ fieldValue = Default?.ToString();
+ break;
+ case Field.BiosDescription:
+ fieldValue = Description;
+ break;
+
+ // For everything else, use the base method
+ default:
+ return base.GetField(field, excludeFields);
+ }
+
+ // Make sure we don't return null
+ if (string.IsNullOrEmpty(fieldValue))
+ fieldValue = string.Empty;
+
+ return fieldValue;
+ }
+
+ #endregion
+
#region Constructors
///
diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs
index ec77e282..6c482ba5 100644
--- a/SabreTools.Library/DatItems/DatItem.cs
+++ b/SabreTools.Library/DatItems/DatItem.cs
@@ -615,7 +615,7 @@ namespace SabreTools.Library.DatItems
///
/// Get the value of that field as a string, if possible
///
- public string GetField(Field field, List excludeFields)
+ public virtual string GetField(Field field, List excludeFields)
{
// If the field is to be excluded, return empty string
if (excludeFields.Contains(field))
@@ -625,196 +625,80 @@ namespace SabreTools.Library.DatItems
switch (field)
{
case Field.Name:
- fieldValue = this.Name;
+ fieldValue = Name;
break;
case Field.PartName:
- fieldValue = this.PartName;
+ fieldValue = PartName;
break;
case Field.PartInterface:
- fieldValue = this.PartInterface;
+ fieldValue = PartInterface;
break;
case Field.Features:
- fieldValue = string.Join(";", (this.Features ?? new List>()).Select(f => $"{f.Key}={f.Value}"));
+ fieldValue = string.Join(";", (Features ?? new List>()).Select(f => $"{f.Key}={f.Value}"));
break;
case Field.AreaName:
- fieldValue = this.AreaName;
+ fieldValue = AreaName;
break;
case Field.AreaSize:
- fieldValue = this.AreaSize?.ToString();
+ fieldValue = AreaSize?.ToString();
break;
case Field.MachineName:
- fieldValue = this.MachineName;
+ fieldValue = MachineName;
break;
case Field.Comment:
- fieldValue = this.Comment;
+ fieldValue = Comment;
break;
case Field.Description:
- fieldValue = this.MachineDescription;
+ fieldValue = MachineDescription;
break;
case Field.Year:
- fieldValue = this.Year;
+ fieldValue = Year;
break;
case Field.Manufacturer:
- fieldValue = this.Manufacturer;
+ fieldValue = Manufacturer;
break;
case Field.Publisher:
- fieldValue = this.Publisher;
+ fieldValue = Publisher;
break;
case Field.Category:
- fieldValue = this.Category;
+ fieldValue = Category;
break;
case Field.RomOf:
- fieldValue = this.RomOf;
+ fieldValue = RomOf;
break;
case Field.CloneOf:
- fieldValue = this.CloneOf;
+ fieldValue = CloneOf;
break;
case Field.SampleOf:
- fieldValue = this.SampleOf;
+ fieldValue = SampleOf;
break;
case Field.Supported:
- fieldValue = this.Supported?.ToString();
+ fieldValue = Supported?.ToString();
break;
case Field.SourceFile:
- fieldValue = this.SourceFile;
+ fieldValue = SourceFile;
break;
case Field.Runnable:
- fieldValue = this.Runnable?.ToString();
+ fieldValue = Runnable?.ToString();
break;
case Field.Board:
- fieldValue = this.Board;
+ fieldValue = Board;
break;
case Field.RebuildTo:
- fieldValue = this.RebuildTo;
+ fieldValue = RebuildTo;
break;
case Field.Devices:
- fieldValue = string.Join(";", this.Devices ?? new List());
+ fieldValue = string.Join(";", Devices ?? new List());
break;
case Field.SlotOptions:
- fieldValue = string.Join(";", this.SlotOptions ?? new List());
+ fieldValue = string.Join(";", SlotOptions ?? new List());
break;
case Field.Infos:
- fieldValue = string.Join(";", (this.Infos ?? new List>()).Select(i => $"{i.Key}={i.Value}"));
+ fieldValue = string.Join(";", (Infos ?? new List>()).Select(i => $"{i.Key}={i.Value}"));
break;
case Field.MachineType:
- fieldValue = this.MachineType.ToString();
- break;
-
- case Field.Default:
- if (ItemType == ItemType.BiosSet)
- fieldValue = (this as BiosSet).Default?.ToString();
- else if (ItemType == ItemType.Release)
- fieldValue = (this as Release).Default?.ToString();
- break;
- case Field.BiosDescription:
- if (ItemType == ItemType.BiosSet)
- fieldValue = (this as BiosSet).Description;
- break;
-
- case Field.MD5:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).MD5;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).MD5;
- break;
-#if NET_FRAMEWORK
- case Field.RIPEMD160:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).RIPEMD160;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).RIPEMD160;
- break;
-#endif
- case Field.SHA1:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).SHA1;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).SHA1;
- break;
- case Field.SHA256:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).SHA256;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).SHA256;
- break;
- case Field.SHA384:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).SHA384;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).SHA384;
- break;
- case Field.SHA512:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).SHA512;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).SHA512;
- break;
- case Field.Merge:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).MergeTag;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).MergeTag;
- break;
- case Field.Region:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).Region;
- else if (ItemType == ItemType.Release)
- fieldValue = (this as Release).Region;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Region;
- break;
- case Field.Index:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).Index;
- break;
- case Field.Writable:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).Writable?.ToString();
- break;
- case Field.Optional:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).Optional?.ToString();
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Optional?.ToString();
- break;
- case Field.Status:
- if (ItemType == ItemType.Disk)
- fieldValue = (this as Disk).ItemStatus.ToString();
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).ItemStatus.ToString();
- break;
-
- case Field.Language:
- if (ItemType == ItemType.Release)
- fieldValue = (this as Release).Language;
- break;
- case Field.Date:
- if (ItemType == ItemType.Release)
- fieldValue = (this as Release).Date;
- else if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Date;
- break;
-
- case Field.Bios:
- if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Bios;
- break;
- case Field.Size:
- if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Size.ToString();
- break;
- case Field.CRC:
- if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).CRC;
- break;
- case Field.Offset:
- if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Offset;
- break;
- case Field.Inverted:
- if (ItemType == ItemType.Rom)
- fieldValue = (this as Rom).Inverted?.ToString();
+ fieldValue = MachineType.ToString();
break;
case Field.NULL:
@@ -949,10 +833,10 @@ namespace SabreTools.Library.DatItems
{
try
{
- if (this.Name == other.Name)
- return this.Equals(other) ? 0 : 1;
+ if (Name == other.Name)
+ return Equals(other) ? 0 : 1;
- return String.Compare(this.Name, other.Name);
+ return string.Compare(Name, other.Name);
}
catch
{
@@ -977,13 +861,13 @@ namespace SabreTools.Library.DatItems
DupeType output = 0x00;
// If we don't have a duplicate at all, return none
- if (!this.Equals(lastItem))
+ if (!Equals(lastItem))
return output;
// If the duplicate is external already or should be, set it
- if (lastItem.DupeType.HasFlag(DupeType.External) || lastItem.IndexId != this.IndexId)
+ if (lastItem.DupeType.HasFlag(DupeType.External) || lastItem.IndexId != IndexId)
{
- if (lastItem.MachineName == this.MachineName && lastItem.Name == this.Name)
+ if (lastItem.MachineName == MachineName && lastItem.Name == Name)
output = DupeType.External | DupeType.All;
else
output = DupeType.External | DupeType.Hash;
@@ -992,7 +876,7 @@ namespace SabreTools.Library.DatItems
// Otherwise, it's considered an internal dupe
else
{
- if (lastItem.MachineName == this.MachineName && lastItem.Name == this.Name)
+ if (lastItem.MachineName == MachineName && lastItem.Name == Name)
output = DupeType.Internal | DupeType.All;
else
output = DupeType.Internal | DupeType.Hash;
@@ -1012,7 +896,7 @@ namespace SabreTools.Library.DatItems
/// True if the key should be lowercased (default), false otherwise
/// True if games should only be compared on game and file name, false if system and source are counted
/// String representing the key to be used for the DatItem
- public string GetKey(BucketedBy bucketedBy, bool lower = true, bool norename = true)
+ public virtual string GetKey(BucketedBy bucketedBy, bool lower = true, bool norename = true)
{
// Set the output key as the default blank string
string key = string.Empty;
@@ -1021,16 +905,16 @@ namespace SabreTools.Library.DatItems
switch (bucketedBy)
{
case BucketedBy.CRC:
- key = (this.ItemType == ItemType.Rom ? ((Rom)this).CRC : Constants.CRCZero);
+ key = Constants.CRCZero;
break;
case BucketedBy.Game:
key = (norename ? string.Empty
- : this.IndexId.ToString().PadLeft(10, '0')
+ : IndexId.ToString().PadLeft(10, '0')
+ "-")
- + (string.IsNullOrWhiteSpace(this.MachineName)
+ + (string.IsNullOrWhiteSpace(MachineName)
? "Default"
- : this.MachineName);
+ : MachineName);
if (lower)
key = key.ToLowerInvariant();
@@ -1041,53 +925,29 @@ namespace SabreTools.Library.DatItems
break;
case BucketedBy.MD5:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).MD5
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).MD5
- : Constants.MD5Zero));
+ key = Constants.MD5Zero;
break;
#if NET_FRAMEWORK
case BucketedBy.RIPEMD160:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).RIPEMD160
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).RIPEMD160
- : Constants.RIPEMD160Zero));
+ key = Constants.RIPEMD160Zero;
break;
#endif
case BucketedBy.SHA1:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).SHA1
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).SHA1
- : Constants.SHA1Zero));
+ key = Constants.SHA1Zero;
break;
case BucketedBy.SHA256:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).SHA256
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).SHA256
- : Constants.SHA256Zero));
+ key = Constants.SHA256Zero;
break;
case BucketedBy.SHA384:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).SHA384
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).SHA384
- : Constants.SHA384Zero));
+ key = Constants.SHA384Zero;
break;
case BucketedBy.SHA512:
- key = (this.ItemType == ItemType.Rom
- ? ((Rom)this).SHA512
- : (this.ItemType == ItemType.Disk
- ? ((Disk)this).SHA512
- : Constants.SHA512Zero));
+ key = Constants.SHA512Zero;
break;
}
@@ -1151,13 +1011,13 @@ namespace SabreTools.Library.DatItems
continue;
// If it's a nodump, add and skip
- if (file.ItemType == ItemType.Rom && ((Rom)file).ItemStatus == ItemStatus.Nodump)
+ if (file.ItemType == ItemType.Rom && (file as Rom).ItemStatus == ItemStatus.Nodump)
{
outfiles.Add(file);
nodumpCount++;
continue;
}
- else if (file.ItemType == ItemType.Disk && ((Disk)file).ItemStatus == ItemStatus.Nodump)
+ else if (file.ItemType == ItemType.Disk && (file as Disk).ItemStatus == ItemStatus.Nodump)
{
outfiles.Add(file);
nodumpCount++;
@@ -1172,7 +1032,7 @@ namespace SabreTools.Library.DatItems
// Check if the rom is a duplicate
DupeType dupetype = 0x00;
- DatItem saveditem = new Rom();
+ DatItem saveditem = new Blank();
int pos = -1;
for (int i = 0; i < outfiles.Count; i++)
{
@@ -1187,59 +1047,11 @@ namespace SabreTools.Library.DatItems
saveditem = lastrom;
pos = i;
- // Roms have more infomration to save
- if (file.ItemType == ItemType.Rom)
- {
- ((Rom)saveditem).Size = (((Rom)saveditem).Size == -1 && ((Rom)file).Size != -1
- ? ((Rom)file).Size
- : ((Rom)saveditem).Size);
- ((Rom)saveditem).CRC = (string.IsNullOrWhiteSpace(((Rom)saveditem).CRC) && !string.IsNullOrWhiteSpace(((Rom)file).CRC)
- ? ((Rom)file).CRC
- : ((Rom)saveditem).CRC);
- ((Rom)saveditem).MD5 = (string.IsNullOrWhiteSpace(((Rom)saveditem).MD5) && !string.IsNullOrWhiteSpace(((Rom)file).MD5)
- ? ((Rom)file).MD5
- : ((Rom)saveditem).MD5);
-#if NET_FRAMEWORK
- ((Rom)saveditem).RIPEMD160 = (string.IsNullOrWhiteSpace(((Rom)saveditem).RIPEMD160) && !string.IsNullOrWhiteSpace(((Rom)file).RIPEMD160)
- ? ((Rom)file).RIPEMD160
- : ((Rom)saveditem).RIPEMD160);
-#endif
- ((Rom)saveditem).SHA1 = (string.IsNullOrWhiteSpace(((Rom)saveditem).SHA1) && !string.IsNullOrWhiteSpace(((Rom)file).SHA1)
- ? ((Rom)file).SHA1
- : ((Rom)saveditem).SHA1);
- ((Rom)saveditem).SHA256 = (string.IsNullOrWhiteSpace(((Rom)saveditem).SHA256) && !string.IsNullOrWhiteSpace(((Rom)file).SHA256)
- ? ((Rom)file).SHA256
- : ((Rom)saveditem).SHA256);
- ((Rom)saveditem).SHA384 = (string.IsNullOrWhiteSpace(((Rom)saveditem).SHA384) && !string.IsNullOrWhiteSpace(((Rom)file).SHA384)
- ? ((Rom)file).SHA384
- : ((Rom)saveditem).SHA384);
- ((Rom)saveditem).SHA512 = (string.IsNullOrWhiteSpace(((Rom)saveditem).SHA512) && !string.IsNullOrWhiteSpace(((Rom)file).SHA512)
- ? ((Rom)file).SHA512
- : ((Rom)saveditem).SHA512);
- }
- else if (file.ItemType == ItemType.Disk)
- {
- ((Disk)saveditem).MD5 = (string.IsNullOrWhiteSpace(((Disk)saveditem).MD5) && !string.IsNullOrWhiteSpace(((Disk)file).MD5)
- ? ((Disk)file).MD5
- : ((Disk)saveditem).MD5);
-#if NET_FRAMEWORK
- ((Disk)saveditem).RIPEMD160 = (string.IsNullOrWhiteSpace(((Disk)saveditem).RIPEMD160) && !string.IsNullOrWhiteSpace(((Disk)file).RIPEMD160)
- ? ((Disk)file).RIPEMD160
- : ((Disk)saveditem).RIPEMD160);
-#endif
- ((Disk)saveditem).SHA1 = (string.IsNullOrWhiteSpace(((Disk)saveditem).SHA1) && !string.IsNullOrWhiteSpace(((Disk)file).SHA1)
- ? ((Disk)file).SHA1
- : ((Disk)saveditem).SHA1);
- ((Disk)saveditem).SHA256 = (string.IsNullOrWhiteSpace(((Disk)saveditem).SHA256) && !string.IsNullOrWhiteSpace(((Disk)file).SHA256)
- ? ((Disk)file).SHA256
- : ((Disk)saveditem).SHA256);
- ((Disk)saveditem).SHA384 = (string.IsNullOrWhiteSpace(((Disk)saveditem).SHA384) && !string.IsNullOrWhiteSpace(((Disk)file).SHA384)
- ? ((Disk)file).SHA384
- : ((Disk)saveditem).SHA384);
- ((Disk)saveditem).SHA512 = (string.IsNullOrWhiteSpace(((Disk)saveditem).SHA512) && !string.IsNullOrWhiteSpace(((Disk)file).SHA512)
- ? ((Disk)file).SHA512
- : ((Disk)saveditem).SHA512);
- }
+ // Disks and Roms have more information to fill
+ if (file.ItemType == ItemType.Disk)
+ (saveditem as Disk).FillMissingInformation(file as Disk);
+ else if (file.ItemType == ItemType.Rom)
+ (saveditem as Rom).FillMissingInformation(file as Rom);
saveditem.DupeType = dupetype;
@@ -1370,29 +1182,9 @@ namespace SabreTools.Library.DatItems
private static string GetDuplicateSuffix(DatItem datItem)
{
if (datItem.ItemType == ItemType.Disk)
- {
- Disk disk = datItem as Disk;
-
- if (string.IsNullOrWhiteSpace(disk.MD5))
- return $"_{disk.MD5}";
- else if (string.IsNullOrWhiteSpace(disk.SHA1))
- return $"_{disk.SHA1}";
- else
- return "_1";
- }
+ return (datItem as Disk).GetDuplicateSuffix();
else if (datItem.ItemType == ItemType.Rom)
- {
- Rom rom = datItem as Rom;
-
- if (string.IsNullOrWhiteSpace(rom.CRC))
- return $"_{rom.CRC}";
- else if (string.IsNullOrWhiteSpace(rom.MD5))
- return $"_{rom.MD5}";
- else if (string.IsNullOrWhiteSpace(rom.SHA1))
- return $"_{rom.SHA1}";
- else
- return "_1";
- }
+ return (datItem as Rom).GetDuplicateSuffix();
return "_1";
}
@@ -1414,31 +1206,22 @@ namespace SabreTools.Library.DatItems
{
if (x.MachineName == y.MachineName)
{
- if ((x.ItemType == ItemType.Rom || x.ItemType == ItemType.Disk) && (y.ItemType == ItemType.Rom || y.ItemType == ItemType.Disk))
+ // Special case for comparing a Disk or Rom to another item type
+ if ((x.ItemType == ItemType.Disk || x.ItemType == ItemType.Rom) ^ (y.ItemType == ItemType.Disk || y.ItemType == ItemType.Rom))
{
- if (Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)) == Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name)))
- {
- return nc.Compare(Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(y.Name)));
- }
+ if (x.ItemType == ItemType.Disk || x.ItemType == ItemType.Rom)
+ return -1;
+ else
+ return 1;
+ }
- return nc.Compare(Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name)));
- }
- else if ((x.ItemType == ItemType.Rom || x.ItemType == ItemType.Disk) && (y.ItemType != ItemType.Rom && y.ItemType != ItemType.Disk))
- {
- return -1;
- }
- else if ((x.ItemType != ItemType.Rom && x.ItemType != ItemType.Disk) && (y.ItemType == ItemType.Rom || y.ItemType == ItemType.Disk))
- {
- return 1;
- }
+ // Otherwise, we compare names naturally
else
{
- if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name))
- {
- return nc.Compare(Path.GetFileName(x.Name), Path.GetFileName(y.Name));
- }
+ if (Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)) == Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name)))
+ return nc.Compare(Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(y.Name)));
- return nc.Compare(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name));
+ return nc.Compare(Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name)));
}
}
diff --git a/SabreTools.Library/DatItems/Disk.cs b/SabreTools.Library/DatItems/Disk.cs
index 45134063..2633b905 100644
--- a/SabreTools.Library/DatItems/Disk.cs
+++ b/SabreTools.Library/DatItems/Disk.cs
@@ -1,5 +1,5 @@
-using System.Linq;
-
+using System.Collections.Generic;
+using SabreTools.Library.DatFiles;
using SabreTools.Library.FileTypes;
using SabreTools.Library.Tools;
using Newtonsoft.Json;
@@ -126,6 +126,74 @@ namespace SabreTools.Library.DatItems
#endregion
+ #region Accessors
+
+ ///
+ /// Get the value of that field as a string, if possible
+ ///
+ public override string GetField(Field field, List excludeFields)
+ {
+ // If the field is to be excluded, return empty string
+ if (excludeFields.Contains(field))
+ return string.Empty;
+
+ // Handle Disk-specific fields
+ string fieldValue;
+ switch (field)
+ {
+ case Field.MD5:
+ fieldValue = MD5;
+ break;
+#if NET_FRAMEWORK
+ case Field.RIPEMD160:
+ fieldValue = RIPEMD160;
+ break;
+#endif
+ case Field.SHA1:
+ fieldValue = SHA1;
+ break;
+ case Field.SHA256:
+ fieldValue = SHA256;
+ break;
+ case Field.SHA384:
+ fieldValue = SHA384;
+ break;
+ case Field.SHA512:
+ fieldValue = SHA512;
+ break;
+ case Field.Merge:
+ fieldValue = MergeTag;
+ break;
+ case Field.Region:
+ fieldValue = Region;
+ break;
+ case Field.Index:
+ fieldValue = Index;
+ break;
+ case Field.Writable:
+ fieldValue = Writable?.ToString();
+ break;
+ case Field.Optional:
+ fieldValue = Optional?.ToString();
+ break;
+ case Field.Status:
+ fieldValue = ItemStatus.ToString();
+ break;
+
+ // For everything else, use the base method
+ default:
+ return base.GetField(field, excludeFields);
+ }
+
+ // Make sure we don't return null
+ if (string.IsNullOrEmpty(fieldValue))
+ fieldValue = string.Empty;
+
+ return fieldValue;
+ }
+
+ #endregion
+
#region Constructors
///
@@ -305,6 +373,53 @@ namespace SabreTools.Library.DatItems
return dupefound;
}
+ ///
+ /// Fill any missing size and hash information from another Disk
+ ///
+ /// Disk to fill information from
+ public void FillMissingInformation(Disk other)
+ {
+ if (_md5.IsNullOrEmpty() && !other._md5.IsNullOrEmpty())
+ _md5 = other._md5;
+
+#if NET_FRAMEWORK
+ if (_ripemd160.IsNullOrEmpty() && !other._ripemd160.IsNullOrEmpty())
+ _ripemd160 = other._ripemd160;
+#endif
+
+ if (_sha1.IsNullOrEmpty() && !other._sha1.IsNullOrEmpty())
+ _sha1 = other._sha1;
+
+ if (_sha256.IsNullOrEmpty() && !other._sha256.IsNullOrEmpty())
+ _sha256 = other._sha256;
+
+ if (_sha384.IsNullOrEmpty() && !other._sha384.IsNullOrEmpty())
+ _sha384 = other._sha384;
+
+ if (_sha512.IsNullOrEmpty() && !other._sha512.IsNullOrEmpty())
+ _sha512 = other._sha512;
+ }
+
+ ///
+ /// Get unique duplicate suffix on name collision
+ ///
+ /// String representing the suffix
+ public string GetDuplicateSuffix()
+ {
+ if (!_md5.IsNullOrEmpty())
+ return $"_{MD5}";
+ else if (!_sha1.IsNullOrEmpty())
+ return $"_{SHA1}";
+ else if (!_sha256.IsNullOrEmpty())
+ return $"_{SHA256}";
+ else if (!_sha384.IsNullOrEmpty())
+ return $"_{SHA384}";
+ else if (!_sha512.IsNullOrEmpty())
+ return $"_{SHA512}";
+ else
+ return "_1";
+ }
+
///
/// Returns if there are no, non-empty hashes in common with another Disk
///
@@ -365,5 +480,62 @@ namespace SabreTools.Library.DatItems
}
#endregion
+
+ #region Sorting and Merging
+
+ ///
+ /// Get the dictionary key that should be used for a given item and bucketing type
+ ///
+ /// BucketedBy enum representing what key to get
+ /// True if the key should be lowercased (default), false otherwise
+ /// True if games should only be compared on game and file name, false if system and source are counted
+ /// String representing the key to be used for the DatItem
+ public override string GetKey(BucketedBy bucketedBy, bool lower = true, bool norename = true)
+ {
+ // Set the output key as the default blank string
+ string key = string.Empty;
+
+ // Now determine what the key should be based on the bucketedBy value
+ switch (bucketedBy)
+ {
+ case BucketedBy.MD5:
+ key = MD5;
+ break;
+
+#if NET_FRAMEWORK
+ case BucketedBy.RIPEMD160:
+ key = RIPEMD160;
+ break;
+#endif
+
+ case BucketedBy.SHA1:
+ key = SHA1;
+ break;
+
+ case BucketedBy.SHA256:
+ key = SHA256;
+ break;
+
+ case BucketedBy.SHA384:
+ key = SHA384;
+ break;
+
+ case BucketedBy.SHA512:
+ key = SHA512;
+ break;
+
+ // Let the base handle generic stuff
+ default:
+ return base.GetKey(bucketedBy, lower, norename);
+ }
+
+ // Double and triple check the key for corner cases
+ if (key == null)
+ key = string.Empty;
+
+ return key;
+ }
+
+ #endregion
}
}
diff --git a/SabreTools.Library/DatItems/Release.cs b/SabreTools.Library/DatItems/Release.cs
index fb848720..98650736 100644
--- a/SabreTools.Library/DatItems/Release.cs
+++ b/SabreTools.Library/DatItems/Release.cs
@@ -1,4 +1,4 @@
-using SabreTools.Library.Data;
+using System.Collections.Generic;
using Newtonsoft.Json;
namespace SabreTools.Library.DatItems
@@ -36,6 +36,48 @@ namespace SabreTools.Library.DatItems
#endregion
+ #region Accessors
+
+ ///
+ /// Get the value of that field as a string, if possible
+ ///
+ public override string GetField(Field field, List excludeFields)
+ {
+ // If the field is to be excluded, return empty string
+ if (excludeFields.Contains(field))
+ return string.Empty;
+
+ // Handle Release-specific fields
+ string fieldValue;
+ switch (field)
+ {
+ case Field.Region:
+ fieldValue = Region;
+ break;
+ case Field.Language:
+ fieldValue = Language;
+ break;
+ case Field.Date:
+ fieldValue = Date;
+ break;
+ case Field.Default:
+ fieldValue = Default?.ToString();
+ break;
+
+ // For everything else, use the base method
+ default:
+ return base.GetField(field, excludeFields);
+ }
+
+ // Make sure we don't return null
+ if (string.IsNullOrEmpty(fieldValue))
+ fieldValue = string.Empty;
+
+ return fieldValue;
+ }
+
+ #endregion
+
#region Constructors
///
diff --git a/SabreTools.Library/DatItems/Rom.cs b/SabreTools.Library/DatItems/Rom.cs
index a055ba12..bf345906 100644
--- a/SabreTools.Library/DatItems/Rom.cs
+++ b/SabreTools.Library/DatItems/Rom.cs
@@ -1,6 +1,6 @@
-using System.Linq;
-
+using System.Collections.Generic;
using SabreTools.Library.Data;
+using SabreTools.Library.DatFiles;
using SabreTools.Library.FileTypes;
using SabreTools.Library.Tools;
using Newtonsoft.Json;
@@ -156,6 +156,86 @@ namespace SabreTools.Library.DatItems
#endregion
+ #region Accessors
+
+ ///
+ /// Get the value of that field as a string, if possible
+ ///
+ public override string GetField(Field field, List excludeFields)
+ {
+ // If the field is to be excluded, return empty string
+ if (excludeFields.Contains(field))
+ return string.Empty;
+
+ // Handle Rom-specific fields
+ string fieldValue;
+ switch (field)
+ {
+ case Field.Bios:
+ fieldValue = Bios;
+ break;
+ case Field.Size:
+ fieldValue = Size.ToString();
+ break;
+ case Field.CRC:
+ fieldValue = CRC;
+ break;
+ case Field.MD5:
+ fieldValue = MD5;
+ break;
+#if NET_FRAMEWORK
+ case Field.RIPEMD160:
+ fieldValue = RIPEMD160;
+ break;
+#endif
+ case Field.SHA1:
+ fieldValue = SHA1;
+ break;
+ case Field.SHA256:
+ fieldValue = SHA256;
+ break;
+ case Field.SHA384:
+ fieldValue = SHA384;
+ break;
+ case Field.SHA512:
+ fieldValue = SHA512;
+ break;
+ case Field.Merge:
+ fieldValue = MergeTag;
+ break;
+ case Field.Region:
+ fieldValue = Region;
+ break;
+ case Field.Offset:
+ fieldValue = Offset;
+ break;
+ case Field.Date:
+ fieldValue = Date;
+ break;
+ case Field.Status:
+ fieldValue = ItemStatus.ToString();
+ break;
+ case Field.Optional:
+ fieldValue = Optional?.ToString();
+ break;
+ case Field.Inverted:
+ fieldValue = Inverted?.ToString();
+ break;
+
+ // For everything else, use the base method
+ default:
+ return base.GetField(field, excludeFields);
+ }
+
+ // Make sure we don't return null
+ if (string.IsNullOrEmpty(fieldValue))
+ fieldValue = string.Empty;
+
+ return fieldValue;
+ }
+
+ #endregion
+
#region Constructors
///
@@ -307,6 +387,61 @@ namespace SabreTools.Library.DatItems
return dupefound;
}
+ ///
+ /// Fill any missing size and hash information from another Rom
+ ///
+ /// Rom to fill information from
+ public void FillMissingInformation(Rom other)
+ {
+ if (Size == -1 && other.Size != -1)
+ Size = other.Size;
+
+ if (_crc.IsNullOrEmpty() && !other._crc.IsNullOrEmpty())
+ _crc = other._crc;
+
+ if (_md5.IsNullOrEmpty() && !other._md5.IsNullOrEmpty())
+ _md5 = other._md5;
+
+#if NET_FRAMEWORK
+ if (_ripemd160.IsNullOrEmpty() && !other._ripemd160.IsNullOrEmpty())
+ _ripemd160 = other._ripemd160;
+#endif
+
+ if (_sha1.IsNullOrEmpty() && !other._sha1.IsNullOrEmpty())
+ _sha1 = other._sha1;
+
+ if (_sha256.IsNullOrEmpty() && !other._sha256.IsNullOrEmpty())
+ _sha256 = other._sha256;
+
+ if (_sha384.IsNullOrEmpty() && !other._sha384.IsNullOrEmpty())
+ _sha384 = other._sha384;
+
+ if (_sha512.IsNullOrEmpty() && !other._sha512.IsNullOrEmpty())
+ _sha512 = other._sha512;
+ }
+
+ ///
+ /// Get unique duplicate suffix on name collision
+ ///
+ /// String representing the suffix
+ public string GetDuplicateSuffix()
+ {
+ if (!_crc.IsNullOrEmpty())
+ return $"_{CRC}";
+ else if (!_md5.IsNullOrEmpty())
+ return $"_{MD5}";
+ else if (!_sha1.IsNullOrEmpty())
+ return $"_{SHA1}";
+ else if (!_sha256.IsNullOrEmpty())
+ return $"_{SHA256}";
+ else if (!_sha384.IsNullOrEmpty())
+ return $"_{SHA384}";
+ else if (!_sha512.IsNullOrEmpty())
+ return $"_{SHA512}";
+ else
+ return "_1";
+ }
+
///
/// Returns if there are no, non-empty hashes in common with another Rom
///
@@ -370,5 +505,66 @@ namespace SabreTools.Library.DatItems
}
#endregion
+
+ #region Sorting and Merging
+
+ ///
+ /// Get the dictionary key that should be used for a given item and bucketing type
+ ///
+ /// BucketedBy enum representing what key to get
+ /// True if the key should be lowercased (default), false otherwise
+ /// True if games should only be compared on game and file name, false if system and source are counted
+ /// String representing the key to be used for the DatItem
+ public override string GetKey(BucketedBy bucketedBy, bool lower = true, bool norename = true)
+ {
+ // Set the output key as the default blank string
+ string key = string.Empty;
+
+ // Now determine what the key should be based on the bucketedBy value
+ switch (bucketedBy)
+ {
+ case BucketedBy.CRC:
+ key = CRC;
+ break;
+
+ case BucketedBy.MD5:
+ key = MD5;
+ break;
+
+#if NET_FRAMEWORK
+ case BucketedBy.RIPEMD160:
+ key = RIPEMD160;
+ break;
+#endif
+
+ case BucketedBy.SHA1:
+ key = SHA1;
+ break;
+
+ case BucketedBy.SHA256:
+ key = SHA256;
+ break;
+
+ case BucketedBy.SHA384:
+ key = SHA384;
+ break;
+
+ case BucketedBy.SHA512:
+ key = SHA512;
+ break;
+
+ // Let the base handle generic stuff
+ default:
+ return base.GetKey(bucketedBy, lower, norename);
+ }
+
+ // Double and triple check the key for corner cases
+ if (key == null)
+ key = string.Empty;
+
+ return key;
+ }
+
+ #endregion
}
}
diff --git a/SabreTools.Library/DatItems/Sample.cs b/SabreTools.Library/DatItems/Sample.cs
index ad036ad7..e15d3d73 100644
--- a/SabreTools.Library/DatItems/Sample.cs
+++ b/SabreTools.Library/DatItems/Sample.cs
@@ -1,6 +1,4 @@
-using SabreTools.Library.Data;
-
-namespace SabreTools.Library.DatItems
+namespace SabreTools.Library.DatItems
{
///
/// Represents a (usually WAV-formatted) sample to be included for use in the set