diff --git a/SabreTools.DatItems.Test/Formats/DiskTests.cs b/SabreTools.DatItems.Test/Formats/DiskTests.cs index ef94f277..8ad3c7a5 100644 --- a/SabreTools.DatItems.Test/Formats/DiskTests.cs +++ b/SabreTools.DatItems.Test/Formats/DiskTests.cs @@ -1,4 +1,5 @@ using SabreTools.DatItems.Formats; +using SabreTools.Hashing; using Xunit; namespace SabreTools.DatItems.Test.Formats @@ -47,6 +48,10 @@ namespace SabreTools.DatItems.Test.Formats Assert.Equal("XXXXXX", actual.GetStringFieldValue(Models.Metadata.Rom.SHA1Key)); Assert.Equal(DupeType.All | DupeType.External, actual.GetFieldValue(DatItem.DupeTypeKey)); + DataArea? actualDataArea = actual.GetFieldValue(Rom.DataAreaKey); + Assert.NotNull(actualDataArea); + Assert.Equal("XXXXXX", actualDataArea.GetStringFieldValue(Models.Metadata.DataArea.NameKey)); + Machine? actualMachine = actual.GetFieldValue(DatItem.MachineKey); Assert.NotNull(actualMachine); Assert.Equal("XXXXXX", actualMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey)); @@ -130,6 +135,107 @@ namespace SabreTools.DatItems.Test.Formats #endregion + #region HasHashes + + [Fact] + public void HasHashes_NoHash_False() + { + Disk self = new Disk(); + bool actual = self.HasHashes(); + Assert.False(actual); + } + + [Fact] + public void HasHashes_MD5_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, "XXXXXX"); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, string.Empty); + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_SHA1_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, string.Empty); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, "XXXXXX"); + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_All_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, "XXXXXX"); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, "XXXXXX"); + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + #endregion + + #region HasZeroHash + + [Fact] + public void HasZeroHash_NoHash_True() + { + Disk self = new Disk(); + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_NonZeroHash_False() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, "DEADBEEF"); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, "DEADBEEF"); + + bool actual = self.HasZeroHash(); + Assert.False(actual); + } + + [Fact] + public void HasZeroHash_ZeroMD5_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, ZeroHash.MD5Str); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, string.Empty); + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroSHA1_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, string.Empty); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, ZeroHash.SHA1Str); + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroAll_True() + { + Disk self = new Disk(); + self.SetFieldValue(Models.Metadata.Disk.MD5Key, ZeroHash.MD5Str); + self.SetFieldValue(Models.Metadata.Disk.SHA1Key, ZeroHash.SHA1Str); + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + #endregion + #region GetKey [Theory] diff --git a/SabreTools.DatItems.Test/Formats/FileTests.cs b/SabreTools.DatItems.Test/Formats/FileTests.cs new file mode 100644 index 00000000..ee693722 --- /dev/null +++ b/SabreTools.DatItems.Test/Formats/FileTests.cs @@ -0,0 +1,462 @@ +using SabreTools.DatItems.Formats; +using SabreTools.Hashing; +using Xunit; + +namespace SabreTools.DatItems.Test.Formats +{ + public class FileTests + { + #region ConvertToRom + + [Fact] + public void ConvertToRomTest() + { + Machine machine = new Machine(); + machine.SetFieldValue(Models.Metadata.Machine.NameKey, "XXXXXX"); + + Source source = new Source(0, "XXXXXX"); + + File file = new File(); + file.Id = "XXXXXX"; + file.Extension = "XXXXXX"; + file.Size = 12345; + file.CRC = "DEADBEEF"; + file.MD5 = "DEADBEEF"; + file.SHA1 = "DEADBEEF"; + file.SHA256 = "DEADBEEF"; + file.Format = "XXXXXX"; + file.SetFieldValue(DatItem.DupeTypeKey, DupeType.All | DupeType.External); + file.SetFieldValue(DatItem.MachineKey, machine); + file.SetFieldValue(DatItem.RemoveKey, (bool?)false); + file.SetFieldValue(DatItem.SourceKey, source); + + Rom actual = file.ConvertToRom(); + + Assert.Equal("XXXXXX.XXXXXX", actual.GetName()); + Assert.Equal(12345, actual.GetInt64FieldValue(Models.Metadata.Rom.SizeKey)); + Assert.Equal("deadbeef", actual.GetStringFieldValue(Models.Metadata.Rom.CRCKey)); + Assert.Equal("000000000000000000000000deadbeef", actual.GetStringFieldValue(Models.Metadata.Rom.MD5Key)); + Assert.Equal("00000000000000000000000000000000deadbeef", actual.GetStringFieldValue(Models.Metadata.Rom.SHA1Key)); + Assert.Equal("00000000000000000000000000000000000000000000000000000000deadbeef", actual.GetStringFieldValue(Models.Metadata.Rom.SHA256Key)); + Assert.Equal(DupeType.All | DupeType.External, actual.GetFieldValue(DatItem.DupeTypeKey)); + + Machine? actualMachine = actual.GetFieldValue(DatItem.MachineKey); + Assert.NotNull(actualMachine); + Assert.Equal("XXXXXX", actualMachine.GetStringFieldValue(Models.Metadata.Machine.NameKey)); + + Assert.Equal(false, actual.GetBoolFieldValue(DatItem.RemoveKey)); + + Source? actualSource = actual.GetFieldValue(DatItem.SourceKey); + Assert.NotNull(actualSource); + Assert.Equal(0, actualSource.Index); + Assert.Equal("XXXXXX", actualSource.Name); + } + + #endregion + + #region FillMissingInformation + + [Fact] + public void FillMissingInformation_BothEmpty() + { + File self = new File(); + File other = new File(); + + self.FillMissingInformation(other); + + Assert.Null(self.Size); + Assert.Null(self.CRC); + Assert.Null(self.MD5); + Assert.Null(self.SHA1); + Assert.Null(self.SHA256); + } + + [Fact] + public void FillMissingInformation_AllMissing() + { + File self = new File(); + + File other = new File + { + Size = 12345, + CRC = "DEADBEEF", + MD5 = "DEADBEEF", + SHA1 = "DEADBEEF", + SHA256 = "DEADBEEF", + }; + + self.FillMissingInformation(other); + + Assert.Equal(12345, self.Size); + Assert.Equal("deadbeef", self.CRC); + Assert.Equal("000000000000000000000000deadbeef", self.MD5); + Assert.Equal("00000000000000000000000000000000deadbeef", self.SHA1); + Assert.Equal("00000000000000000000000000000000000000000000000000000000deadbeef", self.SHA256); + } + + #endregion + + #region GetDuplicateSuffix + + [Fact] + public void GetDuplicateSuffix_NoHash_Generic() + { + File self = new File(); + string actual = self.GetDuplicateSuffix(); + Assert.Equal("_1", actual); + } + + [Fact] + public void GetDuplicateSuffix_CRC() + { + string hash = "deadbeef"; + File self = new File { CRC = hash }; + + string actual = self.GetDuplicateSuffix(); + Assert.Equal($"_{hash}", actual); + } + + [Fact] + public void GetDuplicateSuffix_MD5() + { + string hash = "000000000000000000000000deadbeef"; + File self = new File { MD5 = hash }; + + string actual = self.GetDuplicateSuffix(); + Assert.Equal($"_{hash}", actual); + } + + [Fact] + public void GetDuplicateSuffix_SHA1() + { + string hash = "00000000000000000000000000000000deadbeef"; + File self = new File { SHA1 = hash }; + + string actual = self.GetDuplicateSuffix(); + Assert.Equal($"_{hash}", actual); + } + + [Fact] + public void GetDuplicateSuffix_SHA256() + { + string hash = "00000000000000000000000000000000000000000000000000000000deadbeef"; + File self = new File { SHA256 = hash }; + + string actual = self.GetDuplicateSuffix(); + Assert.Equal($"_{hash}", actual); + } + + #endregion + + #region HasHashes + + [Fact] + public void HasHashes_NoHash_False() + { + File self = new File(); + bool actual = self.HasHashes(); + Assert.False(actual); + } + + [Fact] + public void HasHashes_CRC_True() + { + File self = new File + { + CRC = "deadbeef", + MD5 = string.Empty, + SHA1 = string.Empty, + SHA256 = string.Empty, + }; + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_MD5_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = "deadbeef", + SHA1 = string.Empty, + SHA256 = string.Empty, + }; + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_SHA1_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = string.Empty, + SHA1 = "deadbeef", + SHA256 = string.Empty, + }; + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_SHA256_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = string.Empty, + SHA1 = string.Empty, + SHA256 = "deadbeef", + }; + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + [Fact] + public void HasHashes_All_True() + { + File self = new File + { + CRC = "deadbeef", + MD5 = "deadbeef", + SHA1 = "deadbeef", + SHA256 = "deadbeef", + }; + + bool actual = self.HasHashes(); + Assert.True(actual); + } + + #endregion + + #region HasZeroHash + + [Fact] + public void HasZeroHash_NoHash_True() + { + File self = new File(); + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_NonZeroHash_False() + { + File self = new File + { + CRC = "deadbeef", + MD5 = "deadbeef", + SHA1 = "deadbeef", + SHA256 = "deadbeef", + }; + + bool actual = self.HasZeroHash(); + Assert.False(actual); + } + + [Fact] + public void HasZeroHash_ZeroCRC_True() + { + File self = new File + { + CRC = ZeroHash.CRC32Str, + MD5 = string.Empty, + SHA1 = string.Empty, + SHA256 = string.Empty, + }; + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroMD5_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = ZeroHash.MD5Str, + SHA1 = string.Empty, + SHA256 = string.Empty, + }; + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroSHA1_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = string.Empty, + SHA1 = ZeroHash.SHA1Str, + SHA256 = string.Empty, + }; + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroSHA256_True() + { + File self = new File + { + CRC = string.Empty, + MD5 = string.Empty, + SHA1 = string.Empty, + SHA256 = ZeroHash.SHA256Str, + }; + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + [Fact] + public void HasZeroHash_ZeroAll_True() + { + File self = new File + { + CRC = ZeroHash.CRC32Str, + MD5 = ZeroHash.MD5Str, + SHA1 = ZeroHash.SHA1Str, + SHA256 = ZeroHash.SHA256Str, + }; + + bool actual = self.HasZeroHash(); + Assert.True(actual); + } + + #endregion + + #region GetKey + + [Theory] + [InlineData(ItemKey.NULL, false, false, "")] + [InlineData(ItemKey.NULL, false, true, "")] + [InlineData(ItemKey.NULL, true, false, "")] + [InlineData(ItemKey.NULL, true, true, "")] + [InlineData(ItemKey.Machine, false, false, "0000000000-Machine")] + [InlineData(ItemKey.Machine, false, true, "Machine")] + [InlineData(ItemKey.Machine, true, false, "0000000000-machine")] + [InlineData(ItemKey.Machine, true, true, "machine")] + [InlineData(ItemKey.CRC, false, false, "deadbeef")] + [InlineData(ItemKey.CRC, false, true, "deadbeef")] + [InlineData(ItemKey.CRC, true, false, "deadbeef")] + [InlineData(ItemKey.CRC, true, true, "deadbeef")] + [InlineData(ItemKey.MD5, false, false, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, false, true, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, true, false, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, true, true, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, false, false, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, false, true, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, true, false, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, true, true, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, false, false, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, false, true, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, true, false, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, true, true, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA384, false, false, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, false, true, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, true, false, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, true, true, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA512, false, false, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, false, true, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, true, false, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, true, true, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SpamSum, false, false, "3::")] + [InlineData(ItemKey.SpamSum, false, true, "3::")] + [InlineData(ItemKey.SpamSum, true, false, "3::")] + [InlineData(ItemKey.SpamSum, true, true, "3::")] + public void GetKeyTest(ItemKey bucketedBy, bool lower, bool norename, string expected) + { + Machine machine = new Machine(); + machine.SetFieldValue(Models.Metadata.Machine.NameKey, "Machine"); + + DatItem datItem = new File + { + CRC = "DEADBEEF", + MD5 = "DEADBEEF", + SHA1 = "DEADBEEF", + SHA256 = "DEADBEEF", + }; + datItem.SetFieldValue(DatItem.SourceKey, new Source(0)); + datItem.SetFieldValue(DatItem.MachineKey, machine); + + string actual = datItem.GetKey(bucketedBy, lower, norename); + Assert.Equal(expected, actual); + } + + #endregion + + // TODO: Change when Machine retrieval gets fixed + #region GetKeyDB + + [Theory] + [InlineData(ItemKey.NULL, false, false, "")] + [InlineData(ItemKey.NULL, false, true, "")] + [InlineData(ItemKey.NULL, true, false, "")] + [InlineData(ItemKey.NULL, true, true, "")] + [InlineData(ItemKey.Machine, false, false, "0000000000-Machine")] + [InlineData(ItemKey.Machine, false, true, "Machine")] + [InlineData(ItemKey.Machine, true, false, "0000000000-machine")] + [InlineData(ItemKey.Machine, true, true, "machine")] + [InlineData(ItemKey.CRC, false, false, "deadbeef")] + [InlineData(ItemKey.CRC, false, true, "deadbeef")] + [InlineData(ItemKey.CRC, true, false, "deadbeef")] + [InlineData(ItemKey.CRC, true, true, "deadbeef")] + [InlineData(ItemKey.MD5, false, false, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, false, true, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, true, false, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.MD5, true, true, "000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, false, false, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, false, true, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, true, false, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA1, true, true, "00000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, false, false, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, false, true, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, true, false, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA256, true, true, "00000000000000000000000000000000000000000000000000000000deadbeef")] + [InlineData(ItemKey.SHA384, false, false, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, false, true, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, true, false, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA384, true, true, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")] + [InlineData(ItemKey.SHA512, false, false, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, false, true, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, true, false, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SHA512, true, true, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")] + [InlineData(ItemKey.SpamSum, false, false, "3::")] + [InlineData(ItemKey.SpamSum, false, true, "3::")] + [InlineData(ItemKey.SpamSum, true, false, "3::")] + [InlineData(ItemKey.SpamSum, true, true, "3::")] + public void GetKeyDBTest(ItemKey bucketedBy, bool lower, bool norename, string expected) + { + Source source = new Source(0); + + Machine machine = new Machine(); + machine.SetFieldValue(Models.Metadata.Machine.NameKey, "Machine"); + + DatItem datItem = new File + { + CRC = "DEADBEEF", + MD5 = "DEADBEEF", + SHA1 = "DEADBEEF", + SHA256 = "DEADBEEF", + }; + datItem.SetFieldValue(DatItem.MachineKey, machine); + + string actual = datItem.GetKeyDB(bucketedBy, source, lower, norename); + Assert.Equal(expected, actual); + } + + #endregion + } +} \ No newline at end of file diff --git a/SabreTools.DatItems/Formats/Disk.cs b/SabreTools.DatItems/Formats/Disk.cs index 56c55f79..8fc8cc37 100644 --- a/SabreTools.DatItems/Formats/Disk.cs +++ b/SabreTools.DatItems/Formats/Disk.cs @@ -120,6 +120,18 @@ namespace SabreTools.DatItems.Formats /// String representing the suffix public string GetDuplicateSuffix() => _internal.GetDuplicateSuffix(); + /// + /// Returns if the Rom contains any hashes + /// + /// True if any hash exists, false otherwise + public bool HasHashes() => _internal.HasHashes(); + + /// + /// Returns if all of the hashes are set to their 0-byte values + /// + /// True if any hash matches the 0-byte value, false otherwise + public bool HasZeroHash() => _internal.HasZeroHash(); + #endregion #region Sorting and Merging diff --git a/SabreTools.DatItems/Formats/File.cs b/SabreTools.DatItems/Formats/File.cs index 952df4e4..e76f2009 100644 --- a/SabreTools.DatItems/Formats/File.cs +++ b/SabreTools.DatItems/Formats/File.cs @@ -1,7 +1,7 @@ +using System; using System.Linq; using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Core; using SabreTools.Core.Tools; using SabreTools.Hashing; using SabreTools.IO.Extensions; @@ -138,14 +138,17 @@ namespace SabreTools.DatItems.Formats public Rom ConvertToRom() { var rom = new Rom(); + rom.SetName($"{Id}.{Extension}"); + rom.SetFieldValue(Models.Metadata.Rom.SizeKey, Size); rom.SetFieldValue(Models.Metadata.Rom.CRCKey, CRC); - rom.SetFieldValue(DatItem.DupeTypeKey, GetFieldValue(DatItem.DupeTypeKey)); - rom.SetFieldValue(DatItem.MachineKey, GetFieldValue(DatItem.MachineKey)!.Clone() as Machine ?? new Machine()); rom.SetFieldValue(Models.Metadata.Rom.MD5Key, MD5); - rom.SetFieldValue(DatItem.RemoveKey, GetBoolFieldValue(DatItem.RemoveKey)); rom.SetFieldValue(Models.Metadata.Rom.SHA1Key, SHA1); rom.SetFieldValue(Models.Metadata.Rom.SHA256Key, SHA256); + + rom.SetFieldValue(DatItem.DupeTypeKey, GetFieldValue(DatItem.DupeTypeKey)); + rom.SetFieldValue(DatItem.MachineKey, GetFieldValue(DatItem.MachineKey)?.Clone() as Machine); + rom.SetFieldValue(DatItem.RemoveKey, GetBoolFieldValue(DatItem.RemoveKey)); rom.SetFieldValue(DatItem.SourceKey, GetFieldValue(DatItem.SourceKey)); return rom; @@ -155,36 +158,6 @@ namespace SabreTools.DatItems.Formats #region Comparision Methods - /// - public override bool Equals(ModelBackedItem? other) - { - // If other is null - if (other == null) - return false; - - // If the type is mismatched - if (other is not DatItem otherItem) - return false; - - // Compare internal models - return Equals(otherItem); - } - - /// - public override bool Equals(ModelBackedItem? other) - { - // If other is null - if (other == null) - return false; - - // If the type is mismatched - if (other is not DatItem otherItem) - return false; - - // Compare internal models - return Equals(otherItem); - } - /// public override bool Equals(DatItem? other) { @@ -276,10 +249,12 @@ namespace SabreTools.DatItems.Formats /// True if any hash matches the 0-byte value, false otherwise public bool HasZeroHash() { - return (_crc != null && _crc.SequenceEqual(ZeroHash.CRC32Arr)) - || (_md5 != null && _md5.SequenceEqual(ZeroHash.MD5Arr)) - || (_sha1 != null && _sha1.SequenceEqual(ZeroHash.SHA1Arr)) - || (_sha256 != null && _sha256.SequenceEqual(ZeroHash.SHA256Arr)); + bool crcNull = string.IsNullOrEmpty(CRC) || string.Equals(CRC, ZeroHash.CRC32Str, StringComparison.OrdinalIgnoreCase); + bool md5Null = string.IsNullOrEmpty(MD5) || string.Equals(MD5, ZeroHash.MD5Str, StringComparison.OrdinalIgnoreCase); + bool sha1Null = string.IsNullOrEmpty(SHA1) || string.Equals(SHA1, ZeroHash.SHA1Str, StringComparison.OrdinalIgnoreCase); + bool sha256Null = string.IsNullOrEmpty(SHA256) || string.Equals(SHA256, ZeroHash.SHA256Str, StringComparison.OrdinalIgnoreCase); + + return crcNull && md5Null && sha1Null && sha256Null; } /// diff --git a/SabreTools.DatItems/Formats/Media.cs b/SabreTools.DatItems/Formats/Media.cs index efd1dd60..d5e63428 100644 --- a/SabreTools.DatItems/Formats/Media.cs +++ b/SabreTools.DatItems/Formats/Media.cs @@ -68,6 +68,18 @@ namespace SabreTools.DatItems.Formats /// String representing the suffix public string GetDuplicateSuffix() => _internal.GetDuplicateSuffix(); + /// + /// Returns if the Rom contains any hashes + /// + /// True if any hash exists, false otherwise + public bool HasHashes() => _internal.HasHashes(); + + /// + /// Returns if all of the hashes are set to their 0-byte values + /// + /// True if any hash matches the 0-byte value, false otherwise + public bool HasZeroHash() => _internal.HasZeroHash(); + #endregion #region Sorting and Merging