DatItems of destiny

This commit is contained in:
Matt Nadareski
2020-08-17 17:28:32 -07:00
parent fafac31ea8
commit 5660da7b0e
8 changed files with 521 additions and 294 deletions

View File

@@ -5,6 +5,7 @@ namespace SabreTools.Library.DatFiles
/// <summary>
/// Determines how the current dictionary is bucketed by
/// </summary>
/// TODO: Can we use "Field" instead of this? How much more stupidly complex would that make things?
public enum BucketedBy
{
Default = 0,

View File

@@ -1,6 +1,4 @@
using SabreTools.Library.Data;
namespace SabreTools.Library.DatItems
namespace SabreTools.Library.DatItems
{
/// <summary>
/// Represents generic archive files to be included in a set

View File

@@ -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
/// <summary>
/// Get the value of that field as a string, if possible
/// </summary>
public override string GetField(Field field, List<Field> 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
/// <summary>

View File

@@ -615,7 +615,7 @@ namespace SabreTools.Library.DatItems
/// <summary>
/// Get the value of that field as a string, if possible
/// </summary>
public string GetField(Field field, List<Field> excludeFields)
public virtual string GetField(Field field, List<Field> 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<KeyValuePair<string, string>>()).Select(f => $"{f.Key}={f.Value}"));
fieldValue = string.Join(";", (Features ?? new List<KeyValuePair<string, string>>()).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<string>());
fieldValue = string.Join(";", Devices ?? new List<string>());
break;
case Field.SlotOptions:
fieldValue = string.Join(";", this.SlotOptions ?? new List<string>());
fieldValue = string.Join(";", SlotOptions ?? new List<string>());
break;
case Field.Infos:
fieldValue = string.Join(";", (this.Infos ?? new List<KeyValuePair<string, string>>()).Select(i => $"{i.Key}={i.Value}"));
fieldValue = string.Join(";", (Infos ?? new List<KeyValuePair<string, string>>()).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
/// <param name="lower">True if the key should be lowercased (default), false otherwise</param>
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
/// <returns>String representing the key to be used for the DatItem</returns>
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))
{
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(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))
// 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 (x.ItemType == ItemType.Disk || x.ItemType == ItemType.Rom)
return -1;
}
else if ((x.ItemType != ItemType.Rom && x.ItemType != ItemType.Disk) && (y.ItemType == ItemType.Rom || y.ItemType == ItemType.Disk))
{
else
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)));
}
}

View File

@@ -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
/// <summary>
/// Get the value of that field as a string, if possible
/// </summary>
public override string GetField(Field field, List<Field> 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
/// <summary>
@@ -305,6 +373,53 @@ namespace SabreTools.Library.DatItems
return dupefound;
}
/// <summary>
/// Fill any missing size and hash information from another Disk
/// </summary>
/// <param name="other">Disk to fill information from</param>
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;
}
/// <summary>
/// Get unique duplicate suffix on name collision
/// </summary>
/// <returns>String representing the suffix</returns>
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";
}
/// <summary>
/// Returns if there are no, non-empty hashes in common with another Disk
/// </summary>
@@ -365,5 +480,62 @@ namespace SabreTools.Library.DatItems
}
#endregion
#region Sorting and Merging
/// <summary>
/// Get the dictionary key that should be used for a given item and bucketing type
/// </summary>
/// <param name="bucketedBy">BucketedBy enum representing what key to get</param>
/// <param name="lower">True if the key should be lowercased (default), false otherwise</param>
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
/// <returns>String representing the key to be used for the DatItem</returns>
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
}
}

View File

@@ -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
/// <summary>
/// Get the value of that field as a string, if possible
/// </summary>
public override string GetField(Field field, List<Field> 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
/// <summary>

View File

@@ -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
/// <summary>
/// Get the value of that field as a string, if possible
/// </summary>
public override string GetField(Field field, List<Field> 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
/// <summary>
@@ -307,6 +387,61 @@ namespace SabreTools.Library.DatItems
return dupefound;
}
/// <summary>
/// Fill any missing size and hash information from another Rom
/// </summary>
/// <param name="other">Rom to fill information from</param>
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;
}
/// <summary>
/// Get unique duplicate suffix on name collision
/// </summary>
/// <returns>String representing the suffix</returns>
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";
}
/// <summary>
/// Returns if there are no, non-empty hashes in common with another Rom
/// </summary>
@@ -370,5 +505,66 @@ namespace SabreTools.Library.DatItems
}
#endregion
#region Sorting and Merging
/// <summary>
/// Get the dictionary key that should be used for a given item and bucketing type
/// </summary>
/// <param name="bucketedBy">BucketedBy enum representing what key to get</param>
/// <param name="lower">True if the key should be lowercased (default), false otherwise</param>
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
/// <returns>String representing the key to be used for the DatItem</returns>
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
}
}

View File

@@ -1,6 +1,4 @@
using SabreTools.Library.Data;
namespace SabreTools.Library.DatItems
namespace SabreTools.Library.DatItems
{
/// <summary>
/// Represents a (usually WAV-formatted) sample to be included for use in the set