Compare commits

...

17 Commits
3.1.0 ... 3.2.0

Author SHA1 Message Date
Matt Nadareski
3798dbcb47 Bump version 2026-08-31 19:15:36 -04:00
Matt Nadareski
2a70a9a20e Update IO to 2.3.0 2026-08-28 13:11:31 -04:00
Matt Nadareski
6f92f85f5d Convert BFPK writing to use GrindCore zlib 2026-08-27 14:01:50 -04:00
Matt Nadareski
b7851601a4 Convert GCZ writing to use GrindCore zlib 2026-08-27 13:59:38 -04:00
Matt Nadareski
cb2a96c413 Convert GCZ to use GrindCore zlib 2026-08-27 13:57:49 -04:00
Matt Nadareski
69c0843a0d Convert GZip to use GrindCore zlib 2026-08-27 13:56:09 -04:00
Matt Nadareski
0171ea9da7 Convert IS-CAB to use GrindCore zlib 2026-08-27 13:53:23 -04:00
Matt Nadareski
e493af25e0 Convert CExe to use GrindCore zlib 2026-08-27 12:37:26 -04:00
Matt Nadareski
62427576e9 Convert SGA to use GrindCore zlib 2026-08-27 12:30:01 -04:00
Matt Nadareski
e80ea00872 Update packages 2026-08-27 09:36:42 -04:00
Matt Nadareski
ce1cd15978 Fix locking issues with item dictionary implementation 2026-08-11 22:04:32 -04:00
HeroponRikiBestest
2a604bd73a Ensure that the data being read is actually large enough to have a debug directory entry parsed from it (#96) 2026-07-30 20:44:49 -04:00
Matt Nadareski
bcc0a5bd1e Add set type RomVault game extension field 2026-07-23 17:03:14 -04:00
Matt Nadareski
32d9e8a09d Add dir RomVault header extension field 2026-07-23 16:45:12 -04:00
Matt Nadareski
d0f5ac322d Add subset RomVault header extension field 2026-07-23 16:15:27 -04:00
Matt Nadareski
05c86e4c24 Add support for BLAKE3 2026-07-23 11:36:54 -04:00
Matt Nadareski
1d76967a08 Ignore bad IS-CAB group names 2026-07-19 21:09:59 -04:00
89 changed files with 1085 additions and 263 deletions

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
</PropertyGroup>
<!-- Support All Frameworks -->
@@ -49,8 +49,8 @@
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="1.5.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.9" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.11" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup>
</Project>

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
</PropertyGroup>
<!-- Support All Frameworks -->
@@ -33,8 +33,8 @@
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="1.5.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@@ -361,6 +361,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -380,6 +381,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.PartialEquals(other);
@@ -406,6 +408,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = string.Empty,
SpamSum = "spamsum",
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -424,6 +427,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = "sha512",
SpamSum = string.Empty,
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -449,6 +453,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
var other = new Rom
{
@@ -467,6 +472,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -493,6 +499,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
var other = new Rom
{
@@ -510,6 +517,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -536,6 +544,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -554,6 +563,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -580,6 +590,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -598,6 +609,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -624,6 +636,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -642,6 +655,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -668,6 +682,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -686,6 +701,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -712,6 +728,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -730,6 +747,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -756,6 +774,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -774,6 +793,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -800,6 +820,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -818,6 +839,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -844,6 +866,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -862,6 +885,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -888,6 +912,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -906,6 +931,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -932,6 +958,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -950,6 +977,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -976,6 +1004,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -994,6 +1023,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -1020,6 +1050,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = "sha512",
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -1038,6 +1069,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -1064,6 +1096,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = "spamsum",
BLAKE3 = string.Empty,
};
var other = new Rom
{
@@ -1082,6 +1115,53 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
Assert.True(actual);
}
[Fact]
public void PartialEquals_Rom_PartialBLAKE3_True()
{
var self = new Rom
{
Name = "name1",
Size = 12345,
CRC16 = string.Empty,
CRC32 = string.Empty,
CRC64 = string.Empty,
MD2 = string.Empty,
MD4 = string.Empty,
MD5 = string.Empty,
RIPEMD128 = string.Empty,
RIPEMD160 = string.Empty,
SHA1 = string.Empty,
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = "blake3",
};
var other = new Rom
{
Name = "name2",
Size = 12345,
CRC16 = "crc16",
CRC32 = "crc32",
CRC64 = "crc64",
MD2 = "md2",
MD4 = "md4",
MD5 = "md5",
RIPEMD128 = "ripemd128",
RIPEMD160 = "ripemd160",
SHA1 = "sha1",
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -1108,6 +1188,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
var other = new Rom
{
@@ -1126,6 +1207,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.PartialEquals(other);
@@ -1392,6 +1474,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = string.Empty,
SpamSum = "spamsum",
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1408,6 +1491,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = "sha512",
SpamSum = string.Empty,
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1432,6 +1516,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1448,6 +1533,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1472,6 +1558,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1488,6 +1575,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1512,6 +1600,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1528,6 +1617,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1552,6 +1642,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1568,6 +1659,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1592,6 +1684,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1608,6 +1701,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1632,6 +1726,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1648,6 +1743,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1672,6 +1768,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1688,6 +1785,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1712,6 +1810,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1728,6 +1827,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1752,6 +1852,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1768,6 +1869,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1792,6 +1894,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1808,6 +1911,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1832,6 +1936,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1848,6 +1953,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1872,6 +1978,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = "sha512",
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1888,6 +1995,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1912,6 +2020,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = "spamsum",
BLAKE3 = string.Empty,
};
Rom other = new Rom
{
@@ -1928,6 +2037,49 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
Assert.True(actual);
}
[Fact]
public void HashMatch_Rom_PartialBLAKE3_True()
{
Rom self = new Rom
{
CRC16 = string.Empty,
CRC32 = string.Empty,
CRC64 = string.Empty,
MD2 = string.Empty,
MD4 = string.Empty,
MD5 = string.Empty,
RIPEMD128 = string.Empty,
RIPEMD160 = string.Empty,
SHA1 = string.Empty,
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = "blake3",
};
Rom other = new Rom
{
CRC16 = "crc16",
CRC32 = "crc32",
CRC64 = "crc64",
MD2 = "md2",
MD4 = "md4",
MD5 = "md5",
RIPEMD128 = "ripemd128",
RIPEMD160 = "ripemd160",
SHA1 = "sha1",
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -1952,6 +2104,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
Rom other = new Rom
{
@@ -1968,6 +2121,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HashMatch(other);
@@ -2162,6 +2316,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HasZeroHash();
@@ -2186,6 +2341,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2210,6 +2366,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2234,6 +2391,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2258,6 +2416,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2282,6 +2441,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2306,6 +2466,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2330,6 +2491,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2354,6 +2516,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2378,6 +2541,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2402,6 +2566,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2426,6 +2591,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = HashType.SHA384.ZeroString,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2450,6 +2616,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = HashType.SHA512.ZeroString,
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -2474,6 +2641,32 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = HashType.SpamSum.ZeroString,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
Assert.True(actual);
}
[Fact]
public void HasZeroHash_Rom_ZeroBLAKE3_True()
{
var self = new Rom
{
CRC16 = string.Empty,
CRC32 = string.Empty,
CRC64 = string.Empty,
MD2 = string.Empty,
MD4 = string.Empty,
MD5 = string.Empty,
RIPEMD128 = string.Empty,
RIPEMD160 = string.Empty,
SHA1 = string.Empty,
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = HashType.BLAKE3.ZeroString,
};
bool actual = self.HasZeroHash();
@@ -2498,6 +2691,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = HashType.SHA384.ZeroString,
SHA512 = HashType.SHA512.ZeroString,
SpamSum = HashType.SpamSum.ZeroString,
BLAKE3 = HashType.BLAKE3.ZeroString,
};
bool actual = self.HasZeroHash();
@@ -2583,6 +2777,7 @@ namespace SabreTools.Data.Extensions.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
self.FillMissingHashes(other);

View File

@@ -9,9 +9,9 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -296,6 +296,10 @@ namespace SabreTools.Data.Extensions
string? otherSpamSum = other.SpamSum;
bool conditionalSpamSum = ConditionalHashEquals(selfSpamSum, otherSpamSum);
string? selfBlake3 = self.BLAKE3;
string? otherBlake3 = other.BLAKE3;
bool conditionalBlake3 = ConditionalHashEquals(selfBlake3, otherBlake3);
return conditionalCrc16
&& conditionalCrc
&& conditionalCrc64
@@ -308,7 +312,8 @@ namespace SabreTools.Data.Extensions
&& conditionalSha256
&& conditionalSha384
&& conditionalSha512
&& conditionalSpamSum;
&& conditionalSpamSum
&& conditionalBlake3;
}
/// <summary>
@@ -357,6 +362,7 @@ namespace SabreTools.Data.Extensions
bool sha384Null = string.IsNullOrEmpty(rom.SHA384);
bool sha512Null = string.IsNullOrEmpty(rom.SHA512);
bool spamsumNull = string.IsNullOrEmpty(rom.SpamSum);
bool blake3Null = string.IsNullOrEmpty(rom.BLAKE3);
return !crc16Null
|| !crc32Null
@@ -370,7 +376,8 @@ namespace SabreTools.Data.Extensions
|| !sha256Null
|| !sha384Null
|| !sha512Null
|| !spamsumNull;
|| !spamsumNull
|| !blake3Null;
}
/// <summary>
@@ -455,6 +462,9 @@ namespace SabreTools.Data.Extensions
string? spamsum = rom.SpamSum;
bool spamsumNull = string.IsNullOrEmpty(spamsum) || string.Equals(spamsum, HashType.SpamSum.ZeroString, StringComparison.OrdinalIgnoreCase);
string? blake3 = rom.BLAKE3;
bool blake3Null = string.IsNullOrEmpty(blake3) || string.Equals(blake3, HashType.BLAKE3.ZeroString, StringComparison.OrdinalIgnoreCase);
return crc16Null
&& crc32Null
&& crc64Null
@@ -467,7 +477,8 @@ namespace SabreTools.Data.Extensions
&& sha256Null
&& sha384Null
&& sha512Null
&& spamsumNull;
&& spamsumNull
&& blake3Null;
}
/// <summary>
@@ -552,6 +563,9 @@ namespace SabreTools.Data.Extensions
bool spamsumNull = string.IsNullOrEmpty(self.SpamSum);
spamsumNull ^= string.IsNullOrEmpty(other.SpamSum);
bool blake3Null = string.IsNullOrEmpty(self.BLAKE3);
blake3Null ^= string.IsNullOrEmpty(other.BLAKE3);
return !crc16Null
|| !crc32Null
|| !crc64Null
@@ -564,7 +578,8 @@ namespace SabreTools.Data.Extensions
|| !sha256Null
|| !sha384Null
|| !sha512Null
|| !spamsumNull;
|| !spamsumNull
|| !blake3Null;
}
#endregion
@@ -696,6 +711,11 @@ namespace SabreTools.Data.Extensions
string? otherSpamSum = other.SpamSum;
if (string.IsNullOrEmpty(selfSpamSum) && !string.IsNullOrEmpty(otherSpamSum))
self.SpamSum = otherSpamSum;
string? selfBlake3 = self.BLAKE3;
string? otherBlake3 = other.BLAKE3;
if (string.IsNullOrEmpty(selfBlake3) && !string.IsNullOrEmpty(otherBlake3))
self.BLAKE3 = otherBlake3;
}
#endregion

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -32,7 +32,7 @@
<ItemGroup>
<PackageReference Include="NetLegacySupport.Numerics" Version="1.0.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -68,6 +68,9 @@ namespace SabreTools.Data.Models.ClrMamePro
/// <remarks>spamsum; Appears after SHA512</remarks>
public string? SpamSum { get; set; }
/// <remarks>blake3; Appears after SHA512</remarks>
public string? BLAKE3 { get; set; }
#endregion
#region DiscImgeCreator Extensions

View File

@@ -0,0 +1,15 @@
namespace SabreTools.Data.Models.Hashfile
{
/// <summary>
/// BLAKE3 File
/// </summary>
public class BLAKE3
{
[Required]
public string? Hash { get; set; }
[Required]
public string? File { get; set; }
}
}

View File

@@ -24,5 +24,7 @@ namespace SabreTools.Data.Models.Hashfile
public SHA512[]? SHA512 { get; set; }
public SpamSum[]? SpamSum { get; set; }
public BLAKE3[]? BLAKE3 { get; set; }
}
}

View File

@@ -55,6 +55,11 @@ namespace SabreTools.Data.Models.Logiqx
[XmlAttribute("runnable")]
public Runnable? Runnable { get; set; }
/// <remarks>(dir|zip|7z), RomVault extension</remarks>
/// TODO: Turn this into an enum like the other flags
[XmlAttribute("type")]
public string? SetType { get; set; }
[XmlElement("comment")]
public string[]? Comment { get; set; }

View File

@@ -48,6 +48,10 @@ namespace SabreTools.Data.Models.Logiqx
[XmlElement("comment")]
public string? Comment { get; set; }
/// <remarks>RomVault extension</remarks>
[XmlElement("subset")]
public string? Subset { get; set; }
/// <remarks>Trurip extension</remarks>
[XmlElement("type")]
public string? Type { get; set; }

View File

@@ -65,6 +65,10 @@ namespace SabreTools.Data.Models.Logiqx
[XmlAttribute("spamsum")]
public string? SpamSum { get; set; }
/// <remarks>Hash extension</remarks>
[XmlAttribute("blake3")]
public string? BLAKE3 { get; set; }
/// <remarks>DiscImgeCreator extension</remarks>
[XmlAttribute("xxh3_64")]
public string? xxHash364 { get; set; }

View File

@@ -21,5 +21,10 @@ namespace SabreTools.Data.Models.Logiqx
/// <remarks>(zip|unzip) "zip"</remarks>
[XmlAttribute("forcepacking")]
public PackingFlag ForcePacking { get; set; }
/// <remarks>(noautodir|nogame)</remarks>
/// TODO: Turn this into an enum like the other flags
[XmlAttribute("dir")]
public string? Dir { get; set; }
}
}

View File

@@ -33,6 +33,8 @@ namespace SabreTools.Data.Models.Metadata
public string? Description { get; set; }
public string? DirHandling { get; set; }
public string? Email { get; set; }
public string? EmulatorVersion { get; set; }
@@ -108,6 +110,8 @@ namespace SabreTools.Data.Models.Metadata
/// TODO: This needs an internal model OR mapping to fields
public OfflineList.Search? Search { get; set; }
public string? Subset { get; set; }
public string? System { get; set; }
public string? Timestamp { get; set; }
@@ -135,6 +139,7 @@ namespace SabreTools.Data.Models.Metadata
obj.DatVersion = DatVersion;
obj.Debug = Debug;
obj.Description = Description;
obj.DirHandling = DirHandling;
obj.Email = Email;
obj.EmulatorVersion = EmulatorVersion;
obj.FileName = FileName;
@@ -166,6 +171,7 @@ namespace SabreTools.Data.Models.Metadata
obj.ScreenshotsHeight = ScreenshotsHeight;
obj.ScreenshotsWidth = ScreenshotsWidth;
obj.Search = Search;
obj.Subset = Subset;
obj.System = System;
obj.Timestamp = Timestamp;
obj.Type = Type;
@@ -224,6 +230,11 @@ namespace SabreTools.Data.Models.Metadata
else if (Description is not null && !Description.Equals(other.Description, StringComparison.OrdinalIgnoreCase))
return false;
if ((DirHandling is null) ^ (other.DirHandling is null))
return false;
else if (DirHandling is not null && !DirHandling.Equals(other.DirHandling, StringComparison.OrdinalIgnoreCase))
return false;
if ((Email is null) ^ (other.Email is null))
return false;
else if (Email is not null && !Email.Equals(other.Email, StringComparison.OrdinalIgnoreCase))
@@ -336,6 +347,11 @@ namespace SabreTools.Data.Models.Metadata
else if (ScreenshotsWidth is not null && !ScreenshotsWidth.Equals(other.ScreenshotsWidth, StringComparison.OrdinalIgnoreCase))
return false;
if ((Subset is null) ^ (other.Subset is null))
return false;
else if (Subset is not null && !Subset.Equals(other.Subset, StringComparison.OrdinalIgnoreCase))
return false;
if ((System is null) ^ (other.System is null))
return false;
else if (System is not null && !System.Equals(other.System, StringComparison.OrdinalIgnoreCase))

View File

@@ -159,6 +159,9 @@ namespace SabreTools.Data.Models.Metadata
public string? Serial { get; set; }
/// <remarks>(dir|zip|7z), RomVault extension</remarks>
public string? SetType { get; set; }
public SharedFeat[]? SharedFeat { get; set; }
public Slot[]? Slot { get; set; }
@@ -298,6 +301,7 @@ namespace SabreTools.Data.Models.Metadata
obj.SaveType = SaveType;
obj.Score = Score;
obj.Serial = Serial;
obj.SetType = SetType;
if (SharedFeat is not null)
obj.SharedFeat = Array.ConvertAll(SharedFeat, i => (SharedFeat)i.Clone());
if (Slot is not null)
@@ -569,6 +573,11 @@ namespace SabreTools.Data.Models.Metadata
else if (Serial is not null && !Serial.Equals(other.Serial, StringComparison.OrdinalIgnoreCase))
return false;
if ((SetType is null) ^ (other.SetType is null))
return false;
else if (SetType is not null && !SetType.Equals(other.SetType, StringComparison.OrdinalIgnoreCase))
return false;
if ((Source is null) ^ (other.Source is null))
return false;
else if (Source is not null && !Source.Equals(other.Source, StringComparison.OrdinalIgnoreCase))

View File

@@ -39,6 +39,8 @@ namespace SabreTools.Data.Models.Metadata
/// <remarks>ArchiveDotOrg.File</remarks>
public string? BitTorrentMagnetHash { get; set; }
public string? BLAKE3 { get; set; }
/// <remarks>ArchiveDotOrg.File</remarks>
public string? ClothCoverDetectionModuleVersion { get; set; }
@@ -293,6 +295,7 @@ namespace SabreTools.Data.Models.Metadata
obj.Bios = Bios;
obj.Bitrate = Bitrate;
obj.BitTorrentMagnetHash = BitTorrentMagnetHash;
obj.BLAKE3 = BLAKE3;
obj.ClothCoverDetectionModuleVersion = ClothCoverDetectionModuleVersion;
obj.CollectionCatalogNumber = CollectionCatalogNumber;
obj.Comment = Comment;

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -32,7 +32,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@@ -212,6 +212,7 @@ namespace SabreTools.Metadata.DatFiles.Test
DatVersion = "datversion",
Debug = true,
Description = "description",
DirHandling = "noautodir",
Email = "email",
EmulatorVersion = "emulatorversion",
FileName = "filename",
@@ -243,6 +244,7 @@ namespace SabreTools.Metadata.DatFiles.Test
ScreenshotsHeight = "screenshotsheight",
ScreenshotsWidth = "screenshotsWidth",
Search = search,
Subset = "subset",
System = "system",
Timestamp = "timestamp",
Type = "type",
@@ -327,6 +329,7 @@ namespace SabreTools.Metadata.DatFiles.Test
SaveType = "savetype",
Score = "score",
Serial = "serial",
SetType = "dir",
SharedFeat = [CreateMetadataSharedFeat()],
Slot = [CreateMetadataSlot()],
SoftwareList = [CreateMetadataSoftwareList()],
@@ -778,6 +781,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Bios = "bios",
Bitrate = "bitrate",
BitTorrentMagnetHash = "btih",
BLAKE3 = HashType.BLAKE3.ZeroString,
ClothCoverDetectionModuleVersion = "cloth_cover_detection_module_version",
CollectionCatalogNumber = "collection-catalog-number",
Comment = "comment",
@@ -1004,6 +1008,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("datversion", datHeader.DatVersion);
Assert.True(datHeader.Debug);
Assert.Equal("description", datHeader.Description);
Assert.Equal("noautodir", datHeader.DirHandling);
Assert.Equal("email", datHeader.Email);
Assert.Equal("emulatorversion", datHeader.EmulatorVersion);
Assert.Equal(Data.Models.Metadata.MergingFlag.Merged, datHeader.ForceMerging);
@@ -1033,6 +1038,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("screenshotsheight", datHeader.ScreenshotsHeight);
Assert.Equal("screenshotsWidth", datHeader.ScreenshotsWidth);
Assert.NotNull(datHeader.Search);
Assert.Equal("subset", datHeader.Subset);
Assert.Equal("system", datHeader.System);
Assert.Equal("timestamp", datHeader.Timestamp);
Assert.Equal("type", datHeader.Type);
@@ -1090,6 +1096,8 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("sampleof", machine.SampleOf);
Assert.Equal("savetype", machine.SaveType);
Assert.Equal("score", machine.Score);
Assert.Equal("serial", machine.Serial);
Assert.Equal("dir", machine.SetType);
Assert.Equal("source", machine.Source);
Assert.Equal("sourcefile", machine.SourceFile);
Assert.Equal("sourcerom", machine.SourceRom);
@@ -1450,6 +1458,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("bios", rom.Bios);
Assert.Equal("bitrate", rom.Bitrate);
Assert.Equal("btih", rom.BitTorrentMagnetHash);
Assert.Equal(HashType.BLAKE3.ZeroString, rom.BLAKE3);
Assert.Equal("cloth_cover_detection_module_version", rom.ClothCoverDetectionModuleVersion);
Assert.Equal("collection-catalog-number", rom.CollectionCatalogNumber);
Assert.Equal("comment", rom.Comment);

View File

@@ -344,6 +344,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("datversion", header.DatVersion);
Assert.True(header.Debug);
Assert.Equal("description", header.Description);
Assert.Equal("noautodir", header.DirHandling);
Assert.Equal("email", header.Email);
Assert.Equal("emulatorversion", header.EmulatorVersion);
Assert.Equal("filename", header.FileName);
@@ -374,6 +375,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("screenshotsheight", header.ScreenshotsHeight);
Assert.Equal("screenshotsWidth", header.ScreenshotsWidth);
Assert.NotNull(header.Search);
Assert.Equal("subset", header.Subset);
Assert.Equal("system", header.System);
Assert.Equal("timestamp", header.Timestamp);
Assert.Equal("type", header.Type);
@@ -436,6 +438,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("savetype", machine.SaveType);
Assert.Equal("score", machine.Score);
Assert.Equal("serial", machine.Serial);
Assert.Equal("dir", machine.SetType);
Assert.Equal("source", machine.Source);
Assert.Equal("sourcefile", machine.SourceFile);
Assert.Equal("sourcerom", machine.SourceRom);
@@ -1005,6 +1008,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal("bios", rom.Bios);
Assert.Equal("bitrate", rom.Bitrate);
Assert.Equal("btih", rom.BitTorrentMagnetHash);
Assert.Equal(HashType.BLAKE3.ZeroString, rom.BLAKE3);
Assert.Equal("cloth_cover_detection_module_version", rom.ClothCoverDetectionModuleVersion);
Assert.Equal("collection-catalog-number", rom.CollectionCatalogNumber);
Assert.Equal("comment", rom.Comment);

View File

@@ -1396,7 +1396,8 @@ namespace SabreTools.Metadata.DatFiles.Test
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
string actual = DatFile.FormatPrefixPostfix(item, machine, fix);
@@ -1514,7 +1515,8 @@ namespace SabreTools.Metadata.DatFiles.Test
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
string actual = DatFile.FormatPrefixPostfix(item, machine, fix);
@@ -1550,6 +1552,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Null(rom.SHA384);
Assert.Null(rom.SHA512);
Assert.Null(rom.SpamSum);
Assert.Null(rom.BLAKE3);
}
[Fact]
@@ -1575,6 +1578,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Null(rom.SHA384);
Assert.Null(rom.SHA512);
Assert.Null(rom.SpamSum);
Assert.Null(rom.BLAKE3);
}
[Fact]
@@ -1594,7 +1598,8 @@ namespace SabreTools.Metadata.DatFiles.Test
SHA256 = "null",
SHA384 = "null",
SHA512 = "null",
SpamSum = "null"
SpamSum = "null",
BLAKE3 = "null",
};
DatItem actual = DatFile.ProcessNullifiedItem(item);
@@ -1614,6 +1619,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(HashType.SHA384.ZeroString, rom.SHA384);
Assert.Equal(HashType.SHA512.ZeroString, rom.SHA512);
Assert.Equal(HashType.SpamSum.ZeroString, rom.SpamSum);
Assert.Equal(HashType.BLAKE3.ZeroString, rom.BLAKE3);
}
#endregion
@@ -1955,6 +1961,19 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal($"_{hash}", actual);
}
[Fact]
public void GetDuplicateSuffix_Rom_BLAKE3()
{
string hash = "hash";
DatItem datItem = new Rom
{
BLAKE3 = hash
};
string actual = DatFile.GetDuplicateSuffix(datItem);
Assert.Equal($"_{hash}", actual);
}
[Fact]
public void GetDuplicateSuffix_Other_Generic()
{
@@ -2434,7 +2453,8 @@ namespace SabreTools.Metadata.DatFiles.Test
SHA256 = "crc",
SHA384 = "crc",
SHA512 = "crc",
SpamSum = "crc"
SpamSum = "crc",
BLAKE3 = "crc",
};
DatFile datFile = new Logiqx(null, useGame: false);

View File

@@ -60,6 +60,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(0, stats.GetHashCount(HashType.SHA384));
Assert.Equal(0, stats.GetHashCount(HashType.SHA512));
Assert.Equal(0, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(0, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -88,6 +89,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(1, stats.GetHashCount(HashType.SHA384));
Assert.Equal(1, stats.GetHashCount(HashType.SHA512));
Assert.Equal(2, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(1, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -116,6 +118,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(0, stats.GetHashCount(HashType.SHA384));
Assert.Equal(0, stats.GetHashCount(HashType.SHA512));
Assert.Equal(0, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(0, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -151,6 +154,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(0, stats.GetHashCount(HashType.SHA384));
Assert.Equal(0, stats.GetHashCount(HashType.SHA512));
Assert.Equal(0, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(0, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -179,6 +183,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(1, stats.GetHashCount(HashType.SHA384));
Assert.Equal(1, stats.GetHashCount(HashType.SHA512));
Assert.Equal(2, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(1, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(1, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -203,6 +208,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(0, stats.GetHashCount(HashType.SHA384));
Assert.Equal(0, stats.GetHashCount(HashType.SHA512));
Assert.Equal(0, stats.GetHashCount(HashType.SpamSum));
Assert.Equal(0, stats.GetHashCount(HashType.BLAKE3));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Disk));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.File));
Assert.Equal(0, stats.GetItemCount(Data.Models.Metadata.ItemType.Media));
@@ -238,6 +244,7 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.Equal(1, newStats.GetHashCount(HashType.SHA384));
Assert.Equal(1, newStats.GetHashCount(HashType.SHA512));
Assert.Equal(1, newStats.GetHashCount(HashType.SpamSum));
Assert.Equal(1, newStats.GetHashCount(HashType.BLAKE3));
Assert.Equal(1, newStats.GetItemCount(Data.Models.Metadata.ItemType.Rom));
Assert.Equal(1, newStats.GetStatusCount(ItemStatus.Good));
}
@@ -317,6 +324,7 @@ namespace SabreTools.Metadata.DatFiles.Test
rom.SHA384 = HashType.SHA384.ZeroString;
rom.SHA512 = HashType.SHA512.ZeroString;
rom.SpamSum = HashType.SpamSum.ZeroString;
rom.BLAKE3 = HashType.BLAKE3.ZeroString;
return rom;
}

View File

@@ -700,6 +700,31 @@ namespace SabreTools.Metadata.DatFiles.Test
]));
}
[Fact]
public void Blake3File_SupportedTypes()
{
var datFile = new Blake3File(null);
var actual = datFile.SupportedTypes;
Assert.True(actual.SequenceEqual([
Data.Models.Metadata.ItemType.Rom,
]));
}
[Fact]
public void Blake3File_GetMissingRequiredFields_Rom()
{
var datItem = new Rom();
var datFile = new Blake3File(null);
var actual = datFile.GetMissingRequiredFields(datItem);
Assert.NotNull(actual);
Assert.True(actual.SequenceEqual([
nameof(Data.Models.Metadata.Rom.Name),
nameof(Data.Models.Metadata.Rom.BLAKE3),
]));
}
#endregion
#region Listrom

View File

@@ -9,10 +9,10 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -104,6 +104,8 @@ namespace SabreTools.Metadata.DatFiles
Header.Debug = header.Debug;
if (Header.Description is null)
Header.Description = header.Description;
if (Header.DirHandling is null)
Header.DirHandling = header.DirHandling;
if (Header.Email is null)
Header.Email = header.Email;
if (Header.EmulatorVersion is null)
@@ -156,6 +158,8 @@ namespace SabreTools.Metadata.DatFiles
Header.ScreenshotsWidth = header.ScreenshotsWidth;
if (Header.System is null)
Header.System = header.System;
if (Header.Subset is null)
Header.Subset = header.Subset;
if (Header.Timestamp is null)
Header.Timestamp = header.Timestamp;
if (Header.Type is null)

View File

@@ -593,7 +593,8 @@ namespace SabreTools.Metadata.DatFiles
sha384 = string.Empty,
sha512 = string.Empty,
size = string.Empty,
spamsum = string.Empty;
spamsum = string.Empty,
blake3 = string.Empty;
// Ensure we have the proper values for replacement
if (item is Disk disk)
@@ -633,6 +634,7 @@ namespace SabreTools.Metadata.DatFiles
sha512 = rom.SHA512 ?? string.Empty;
size = rom.Size.ToString() ?? string.Empty;
spamsum = rom.SpamSum ?? string.Empty;
blake3 = rom.BLAKE3 ?? string.Empty;
}
// Now do bulk replacement where possible
@@ -657,7 +659,8 @@ namespace SabreTools.Metadata.DatFiles
.Replace("%sha384%", sha384)
.Replace("%sha512%", sha512)
.Replace("%size%", size)
.Replace("%spamsum%", spamsum);
.Replace("%spamsum%", spamsum)
.Replace("%blake3%", blake3);
return fix;
}
@@ -697,6 +700,7 @@ namespace SabreTools.Metadata.DatFiles
rom.SHA384 = rom.SHA384 == "null" ? HashType.SHA384.ZeroString : null;
rom.SHA512 = rom.SHA512 == "null" ? HashType.SHA512.ZeroString : null;
rom.SpamSum = rom.SpamSum == "null" ? HashType.SpamSum.ZeroString : null;
rom.BLAKE3 = rom.BLAKE3 == "null" ? HashType.BLAKE3.ZeroString : null;
return rom;
}
@@ -1127,6 +1131,10 @@ namespace SabreTools.Metadata.DatFiles
if (!string.IsNullOrEmpty(spamSum))
return $"_{spamSum}";
string? blake3 = datItem.BLAKE3;
if (!string.IsNullOrEmpty(blake3))
return $"_{blake3}";
return "_1";
}

View File

@@ -84,6 +84,12 @@ namespace SabreTools.Metadata.DatFiles
set => _internal.Description = value;
}
public string? DirHandling
{
get => _internal.DirHandling;
set => _internal.DirHandling = value;
}
public string? Email
{
get => _internal.Email;
@@ -282,6 +288,12 @@ namespace SabreTools.Metadata.DatFiles
[JsonIgnore]
public bool SearchSpecified => Search is not null;
public string? Subset
{
get => _internal.Subset;
set => _internal.Subset = value;
}
public string? System
{
get => _internal.System;

View File

@@ -353,6 +353,12 @@ namespace SabreTools.Metadata.DatFiles
ModifyHashCount(HashType.SHA384, string.IsNullOrEmpty(rom.SHA384) ? 0 : 1);
ModifyHashCount(HashType.SHA512, string.IsNullOrEmpty(rom.SHA512) ? 0 : 1);
ModifyHashCount(HashType.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : 1);
#if NET7_0_OR_GREATER
ModifyHashCount(HashType.BLAKE3, string.IsNullOrEmpty(rom.BLAKE3) ? 0 : 1);
#else
// HACK because BLAKE3 is not supported below .NET 7
ModifyHashCount(HashType.CRC1_ZERO, string.IsNullOrEmpty(rom.BLAKE3) ? 0 : 1);
#endif
}
ModifyStatusCount(ItemStatus.BadDump, status == ItemStatus.BadDump ? 1 : 0);
@@ -430,6 +436,12 @@ namespace SabreTools.Metadata.DatFiles
ModifyHashCount(HashType.SHA384, string.IsNullOrEmpty(rom.SHA384) ? 0 : -1);
ModifyHashCount(HashType.SHA512, string.IsNullOrEmpty(rom.SHA512) ? 0 : -1);
ModifyHashCount(HashType.SpamSum, string.IsNullOrEmpty(rom.SpamSum) ? 0 : -1);
#if NET7_0_OR_GREATER
ModifyHashCount(HashType.BLAKE3, string.IsNullOrEmpty(rom.BLAKE3) ? 0 : -1);
#else
// HACK because BLAKE3 is not supported below .NET 7
ModifyHashCount(HashType.CRC1_ZERO, string.IsNullOrEmpty(rom.BLAKE3) ? 0 : -1);
#endif
}
ModifyStatusCount(ItemStatus.BadDump, status == ItemStatus.BadDump ? -1 : 0);

View File

@@ -169,6 +169,11 @@ namespace SabreTools.Metadata.DatFiles
/// </summary>
RedumpSpamSum,
/// <summary>
/// BLAKE3 hash list
/// </summary>
RedumpBLAKE3,
#endregion
}
}

View File

@@ -0,0 +1,56 @@
using System.Collections.Generic;
using SabreTools.Hashing;
using SabreTools.Metadata.DatItems;
using SabreTools.Metadata.DatItems.Formats;
namespace SabreTools.Metadata.DatFiles.Formats
{
/// <summary>
/// Represents an BLAKE3 hashfile
/// </summary>
public sealed class Blake3File : Hashfile
{
/// <inheritdoc/>
public override Data.Models.Metadata.ItemType[] SupportedTypes
=> [
Data.Models.Metadata.ItemType.Rom,
];
/// <summary>
/// Constructor designed for casting a base DatFile
/// </summary>
/// <param name="datFile">Parent DatFile to copy from</param>
public Blake3File(DatFile? datFile) : base(datFile)
{
#if NET7_0_OR_GREATER
_hash = HashType.BLAKE3;
#else
// HACK because BLAKE3 is not supported below .NET 7
_hash = HashType.CRC1_ZERO;
#endif
Header.DatFormat = DatFormat.RedumpBLAKE3;
}
/// <inheritdoc/>
protected internal override List<string>? GetMissingRequiredFields(DatItem datItem)
{
List<string> missingFields = [];
switch (datItem)
{
case Rom rom:
if (string.IsNullOrEmpty(rom.Name))
missingFields.Add(nameof(Data.Models.Metadata.Rom.Name));
if (string.IsNullOrEmpty(rom.BLAKE3))
missingFields.Add(nameof(Data.Models.Metadata.Rom.BLAKE3));
break;
default:
// Item type is not supported
break;
}
return missingFields;
}
}
}

View File

@@ -90,7 +90,8 @@ namespace SabreTools.Metadata.DatFiles.Formats
missingFields.Add(nameof(Data.Models.Metadata.Rom.Name));
if (rom.Size is null || rom.Size < 0)
missingFields.Add(nameof(Data.Models.Metadata.Rom.Size));
if (string.IsNullOrEmpty(rom.CRC16)
if (string.IsNullOrEmpty(rom.BLAKE3)
&& string.IsNullOrEmpty(rom.CRC16)
&& string.IsNullOrEmpty(rom.CRC32)
&& string.IsNullOrEmpty(rom.CRC64)
&& string.IsNullOrEmpty(rom.MD2)

View File

@@ -284,7 +284,8 @@ namespace SabreTools.Metadata.DatFiles.Formats
missingFields.Add(nameof(Data.Models.Metadata.Rom.Name));
if (rom.Size is null || rom.Size < 0)
missingFields.Add(nameof(Data.Models.Metadata.Rom.Size));
if (string.IsNullOrEmpty(rom.CRC16)
if (string.IsNullOrEmpty(rom.BLAKE3)
&& string.IsNullOrEmpty(rom.CRC16)
&& string.IsNullOrEmpty(rom.CRC32)
&& string.IsNullOrEmpty(rom.CRC64)
&& string.IsNullOrEmpty(rom.MD2)

View File

@@ -482,6 +482,7 @@ namespace SabreTools.Metadata.DatFiles
rom.SHA384 = null; // HashType.SHA384.ZeroString;
rom.SHA512 = null; // HashType.SHA512.ZeroString;
rom.SpamSum = null; // HashType.SpamSum.ZeroString;
rom.BLAKE3 = null; // HashType.BLAKE3.ZeroString;
}
// If the file has no size and it's not the above case, skip and log

View File

@@ -40,6 +40,15 @@ namespace SabreTools.Metadata.DatFiles
private readonly Dictionary<string, List<DatItem>?> _items = [];
#endif
/// <summary>
/// Internal dictionary for the class
/// </summary>
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
private readonly ConcurrentDictionary<string, object> _itemsLocks = [];
#else
private readonly Dictionary<string, object> _itemsLocks = [];
#endif
/// <summary>
/// Logging object
/// </summary>
@@ -163,6 +172,7 @@ namespace SabreTools.Metadata.DatFiles
rom.SHA384 = null; // HashType.SHA384.ZeroString;
rom.SHA512 = null; // HashType.SHA512.ZeroString;
rom.SpamSum = null; // HashType.SpamSum.ZeroString;
rom.BLAKE3 = null; // HashType.BLAKE3.ZeroString;
}
// If the file has no size and it's not the above case, skip and log
@@ -190,7 +200,14 @@ namespace SabreTools.Metadata.DatFiles
// If only adding statistics, we add an empty key for games and then just item stats
if (statsOnly)
{
EnsureBucketingKey(key);
// Add an empty key
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
_items.GetOrAdd(key, []);
#else
if (!_items.ContainsKey(key))
_items[key] = [];
#endif
DatStatistics.AddItemStatistics(item);
}
else
@@ -293,7 +310,16 @@ namespace SabreTools.Metadata.DatFiles
public bool RemoveItem(string key, DatItem value, int index)
{
// Explicit lock for some weird corner cases
lock (key)
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
object lockObj = _itemsLocks.GetOrAdd(key, _ => new object());
#else
if (!_itemsLocks.ContainsKey(key))
_itemsLocks[key] = new object();
object lockObj = _itemsLocks[key];
#endif
lock (lockObj)
{
// If the key doesn't exist, return
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
@@ -337,10 +363,24 @@ namespace SabreTools.Metadata.DatFiles
internal void AddItem(string key, DatItem value)
{
// Explicit lock for some weird corner cases
lock (key)
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
object lockObj = _itemsLocks.GetOrAdd(key, _ => new object());
#else
if (!_itemsLocks.ContainsKey(key))
_itemsLocks[key] = new object();
object lockObj = _itemsLocks[key];
#endif
lock (lockObj)
{
// Ensure the key exists
EnsureBucketingKey(key);
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
_items.GetOrAdd(key, []);
#else
if (!_items.ContainsKey(key))
_items[key] = [];
#endif
// If item is null, don't add it
if (value is null)
@@ -639,21 +679,6 @@ namespace SabreTools.Metadata.DatFiles
return roms.FindIndex(datItem.Equals) > -1;
}
/// <summary>
/// Ensure the key exists in the items dictionary
/// </summary>
/// <param name="key">Key to ensure</param>
private void EnsureBucketingKey(string key)
{
// If the key is missing from the dictionary, add it
#if NET40_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
_items.GetOrAdd(key, []);
#else
if (!_items.ContainsKey(key))
_items[key] = [];
#endif
}
/// <summary>
/// Get the highest-order Field value that represents the statistics
/// </summary>

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -46,8 +46,8 @@
<ItemGroup>
<PackageReference Include="MinValueTupleBridge" Version="0.2.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="$(TargetFramework.StartsWith(`net40`)) OR $(TargetFramework.StartsWith(`net45`))" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" Condition="$(TargetFramework.StartsWith(`net46`)) OR $(TargetFramework.StartsWith(`net47`)) OR $(TargetFramework.StartsWith(`net48`))" />
</ItemGroup>

View File

@@ -290,6 +290,10 @@ namespace SabreTools.Metadata.DatItems.Test
[InlineData(ItemKey.SpamSum, false, true, "3::")]
[InlineData(ItemKey.SpamSum, true, false, "3::")]
[InlineData(ItemKey.SpamSum, true, true, "3::")]
[InlineData(ItemKey.BLAKE3, false, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, false, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
public void GetKeyDB_DefaultImplementation(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);
@@ -363,6 +367,10 @@ namespace SabreTools.Metadata.DatItems.Test
[InlineData(ItemKey.SpamSum, false, true, "BASE64")]
[InlineData(ItemKey.SpamSum, true, false, "base64")]
[InlineData(ItemKey.SpamSum, true, true, "base64")]
[InlineData(ItemKey.BLAKE3, false, false, "DEADBEEF")]
[InlineData(ItemKey.BLAKE3, false, true, "DEADBEEF")]
[InlineData(ItemKey.BLAKE3, true, false, "deadbeef")]
[InlineData(ItemKey.BLAKE3, true, true, "deadbeef")]
public void GetKeyDB_CustomImplementation(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);
@@ -383,7 +391,8 @@ namespace SabreTools.Metadata.DatItems.Test
SHA256 = "DEADBEEF",
SHA384 = "DEADBEEF",
SHA512 = "DEADBEEF",
SpamSum = "BASE64"
SpamSum = "BASE64",
BLAKE3 = "DEADBEEF",
};
string actual = datItem.GetKey(bucketedBy, machine, source, lower, norename);

View File

@@ -260,6 +260,10 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
[InlineData(ItemKey.SpamSum, false, true, "3::")]
[InlineData(ItemKey.SpamSum, true, false, "3::")]
[InlineData(ItemKey.SpamSum, true, true, "3::")]
[InlineData(ItemKey.BLAKE3, false, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, false, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
public void GetKeyDBTest(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);

View File

@@ -337,6 +337,10 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
[InlineData(ItemKey.SpamSum, false, true, "3::")]
[InlineData(ItemKey.SpamSum, true, false, "3::")]
[InlineData(ItemKey.SpamSum, true, true, "3::")]
[InlineData(ItemKey.BLAKE3, false, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, false, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
public void GetKeyDBTest(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);

View File

@@ -330,6 +330,10 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
[InlineData(ItemKey.SpamSum, false, true, "DEADBEEF")]
[InlineData(ItemKey.SpamSum, true, false, "deadbeef")]
[InlineData(ItemKey.SpamSum, true, true, "deadbeef")]
[InlineData(ItemKey.BLAKE3, false, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, false, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, false, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData(ItemKey.BLAKE3, true, true, "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
public void GetKeyDBTest(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);

View File

@@ -28,6 +28,7 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
Assert.Null(self.SHA384);
Assert.Null(self.SHA512);
Assert.Null(self.SpamSum);
Assert.Null(self.BLAKE3);
}
[Fact]
@@ -49,7 +50,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
self.FillMissingInformation(other);
@@ -67,6 +69,7 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
Assert.Equal("sha384", self.SHA384);
Assert.Equal("sha512", self.SHA512);
Assert.Equal("spamsum", self.SpamSum);
Assert.Equal("blake3", self.BLAKE3);
}
#endregion
@@ -98,7 +101,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -122,7 +126,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -146,7 +151,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -170,7 +176,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -194,7 +201,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -218,7 +226,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -242,7 +251,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -266,7 +276,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -290,7 +301,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -314,7 +326,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = "sha256",
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -338,7 +351,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = "sha384",
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -362,7 +376,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = "sha512",
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
@@ -386,7 +401,33 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = string.Empty,
};
bool actual = self.HasHashes();
Assert.True(actual);
}
[Fact]
public void HasHashes_BLAKE3_True()
{
Rom self = new Rom
{
CRC16 = string.Empty,
CRC32 = string.Empty,
CRC64 = string.Empty,
MD2 = string.Empty,
MD4 = string.Empty,
MD5 = string.Empty,
RIPEMD128 = string.Empty,
RIPEMD160 = string.Empty,
SHA1 = string.Empty,
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = "blake3",
};
bool actual = self.HasHashes();
@@ -410,7 +451,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HasHashes();
@@ -446,7 +488,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = "sha256",
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum"
SpamSum = "spamsum",
BLAKE3 = "blake3",
};
bool actual = self.HasZeroHash();
@@ -470,7 +513,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -494,7 +538,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -518,7 +563,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -542,7 +588,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -566,7 +613,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -590,7 +638,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -614,7 +663,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -638,7 +688,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -662,7 +713,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -686,7 +738,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = HashType.SHA256.ZeroString,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -710,7 +763,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = HashType.SHA384.ZeroString,
SHA512 = string.Empty,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -734,7 +788,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = HashType.SHA512.ZeroString,
SpamSum = string.Empty
SpamSum = string.Empty,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
@@ -758,7 +813,33 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = HashType.SpamSum.ZeroString
SpamSum = HashType.SpamSum.ZeroString,
BLAKE3 = string.Empty,
};
bool actual = self.HasZeroHash();
Assert.True(actual);
}
[Fact]
public void HasZeroHash_ZeroBLAKE3_True()
{
Rom self = new Rom
{
CRC16 = string.Empty,
CRC32 = string.Empty,
CRC64 = string.Empty,
MD2 = string.Empty,
MD4 = string.Empty,
MD5 = string.Empty,
RIPEMD128 = string.Empty,
RIPEMD160 = string.Empty,
SHA1 = string.Empty,
SHA256 = string.Empty,
SHA384 = string.Empty,
SHA512 = string.Empty,
SpamSum = string.Empty,
BLAKE3 = HashType.BLAKE3.ZeroString,
};
bool actual = self.HasZeroHash();
@@ -782,7 +863,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = HashType.SHA256.ZeroString,
SHA384 = HashType.SHA384.ZeroString,
SHA512 = HashType.SHA512.ZeroString,
SpamSum = HashType.SpamSum.ZeroString
SpamSum = HashType.SpamSum.ZeroString,
BLAKE3 = HashType.BLAKE3.ZeroString,
};
bool actual = self.HasZeroHash();
@@ -855,6 +937,10 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
[InlineData(ItemKey.SpamSum, false, true, "DEADBEEF")]
[InlineData(ItemKey.SpamSum, true, false, "deadbeef")]
[InlineData(ItemKey.SpamSum, true, true, "deadbeef")]
[InlineData(ItemKey.BLAKE3, false, false, "DEADBEEF")]
[InlineData(ItemKey.BLAKE3, false, true, "DEADBEEF")]
[InlineData(ItemKey.BLAKE3, true, false, "deadbeef")]
[InlineData(ItemKey.BLAKE3, true, true, "deadbeef")]
public void GetKeyDBTest(ItemKey bucketedBy, bool lower, bool norename, string expected)
{
Source source = new Source(0);
@@ -875,7 +961,8 @@ namespace SabreTools.Metadata.DatItems.Formats.Test
SHA256 = "DEADBEEF",
SHA384 = "DEADBEEF",
SHA512 = "DEADBEEF",
SpamSum = "DEADBEEF"
SpamSum = "DEADBEEF",
BLAKE3 = "DEADBEEF",
};
string actual = datItem.GetKey(bucketedBy, machine, source, lower, norename);

View File

@@ -9,10 +9,10 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -191,6 +191,10 @@ namespace SabreTools.Metadata.DatItems
// Now determine what the key should be based on the bucketedBy value
switch (bucketedBy)
{
case ItemKey.BLAKE3:
key = HashType.BLAKE3.ZeroString;
break;
case ItemKey.CRC16:
key = HashType.CRC16.ZeroString;
break;

View File

@@ -26,6 +26,7 @@ namespace SabreTools.Metadata.DatItems
Machine,
BLAKE3,
CRC16,
CRC32,
CRC64,

View File

@@ -74,6 +74,12 @@ namespace SabreTools.Metadata.DatItems.Formats
set => _internal.BitTorrentMagnetHash = value;
}
public string? BLAKE3
{
get => _internal.BLAKE3;
set => _internal.BLAKE3 = value;
}
public string? ClothCoverDetectionModuleVersion
{
get => _internal.ClothCoverDetectionModuleVersion;
@@ -858,6 +864,10 @@ namespace SabreTools.Metadata.DatItems.Formats
// Now determine what the key should be based on the bucketedBy value
switch (bucketedBy)
{
case ItemKey.BLAKE3:
key = BLAKE3;
break;
case ItemKey.CRC16:
key = CRC16;
break;

View File

@@ -320,6 +320,12 @@ namespace SabreTools.Metadata.DatItems
set => _internal.Serial = value;
}
public string? SetType
{
get => _internal.SetType;
set => _internal.SetType = value;
}
public string? Source
{
get => _internal.Source;

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -32,8 +32,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1103,6 +1103,7 @@ namespace SabreTools.Metadata.Filter.Test
[InlineData("header.datversion", "datversion")]
[InlineData("header.debug", "yes")]
[InlineData("header.description", "description")]
[InlineData("header.dir", "noautodir")]
[InlineData("header.email", "email")]
[InlineData("header.emulatorversion", "emulatorversion")]
[InlineData("header.filename", "filename")]
@@ -1131,6 +1132,7 @@ namespace SabreTools.Metadata.Filter.Test
[InlineData("header.schemalocation", "schemalocation")]
[InlineData("header.screenshotsheight", "screenshotsheight")]
[InlineData("header.screenshotswidth", "screenshotswidth")]
[InlineData("header.subset", "subset")]
[InlineData("header.system", "system")]
[InlineData("header.timestamp", "timestamp")]
[InlineData("header.type", "type")]
@@ -1150,6 +1152,7 @@ namespace SabreTools.Metadata.Filter.Test
DatVersion = "datversion",
Debug = true,
Description = "description",
DirHandling = "noautodir",
Email = "email",
EmulatorVersion = "emulatorversion",
FileName = "filename",
@@ -1176,6 +1179,7 @@ namespace SabreTools.Metadata.Filter.Test
SchemaLocation = "schemalocation",
ScreenshotsHeight = "screenshotsheight",
ScreenshotsWidth = "screenshotswidth",
Subset = "subset",
System = "system",
Timestamp = "timestamp",
Type = "type",
@@ -1290,6 +1294,8 @@ namespace SabreTools.Metadata.Filter.Test
[InlineData("machine.sampleof", "sampleof")]
[InlineData("machine.savetype", "savetype")]
[InlineData("machine.score", "score")]
[InlineData("machine.serial", "serial")]
[InlineData("machine.settype", "dir")]
[InlineData("machine.source", "source")]
[InlineData("machine.sourcefile", "sourcefile")]
[InlineData("machine.sourcerom", "sourcerom")]
@@ -1360,6 +1366,7 @@ namespace SabreTools.Metadata.Filter.Test
SaveType = "savetype",
Score = "score",
Serial = "serial",
SetType = "dir",
Source = "source",
SourceFile = "sourcefile",
SourceRom = "sourcerom",
@@ -1582,6 +1589,7 @@ namespace SabreTools.Metadata.Filter.Test
[InlineData("rom.bitrate", "bitrate")]
[InlineData("rom.bittorrentmagnethash", "btih")]
[InlineData("rom.btih", "btih")]
[InlineData("rom.blake3", "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262")]
[InlineData("rom.cloth_cover_detection_module_version", "cloth_cover_detection_module_version")]
[InlineData("rom.clothcoverdetectionmoduleversion", "cloth_cover_detection_module_version")]
[InlineData("rom.collection-catalog-number", "collection-catalog-number")]
@@ -1719,6 +1727,7 @@ namespace SabreTools.Metadata.Filter.Test
Bios = "bios",
Bitrate = "bitrate",
BitTorrentMagnetHash = "btih",
BLAKE3 = HashType.BLAKE3.ZeroString,
ClothCoverDetectionModuleVersion = "cloth_cover_detection_module_version",
CollectionCatalogNumber = "collection-catalog-number",
Comment = "comment",

View File

@@ -19,9 +19,9 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -309,6 +309,8 @@ namespace SabreTools.Metadata.Filter
"datversion",
"debug",
"description",
"dir",
"dirhandling",
"email",
"emulatorversion",
"filename",
@@ -337,6 +339,7 @@ namespace SabreTools.Metadata.Filter
"screenshotsheight",
"screenshotswidth",
"skipper",
"subset",
"system",
"timestamp",
"type",
@@ -421,6 +424,8 @@ namespace SabreTools.Metadata.Filter
"sampleof",
"savetype",
"score",
"serial",
"settype",
"source",
"sourcefile",
"sourcerom",
@@ -540,6 +545,7 @@ namespace SabreTools.Metadata.Filter
"bitrate",
"bittorrentmagnethash",
"btih",
"blake3",
"cloth_cover_detection_module_version",
"clothcoverdetectionmoduleversion",
"collection-catalog-number",

View File

@@ -1280,6 +1280,10 @@ namespace SabreTools.Metadata.Filter
case "description":
checkValue = obj.Description;
return true;
case "dir":
case "dirhandling":
checkValue = obj.DirHandling;
return true;
case "email":
checkValue = obj.Email;
return true;
@@ -1365,6 +1369,9 @@ namespace SabreTools.Metadata.Filter
checkValue = obj.ScreenshotsWidth;
return true;
// Header.Search is intentionally skipped
case "subset":
checkValue = obj.Subset;
return true;
case "system":
checkValue = obj.System;
return true;
@@ -1603,6 +1610,9 @@ namespace SabreTools.Metadata.Filter
case "serial":
checkValue = obj.Serial;
return true;
case "settype":
checkValue = obj.SetType;
return true;
case "source":
checkValue = obj.Source;
return true;
@@ -1901,6 +1911,9 @@ namespace SabreTools.Metadata.Filter
case "bittorrentmagnethash":
checkValue = obj.BitTorrentMagnetHash;
return true;
case "blake3":
checkValue = obj.BLAKE3;
return true;
case "cloth_cover_detection_module_version":
case "clothcoverdetectionmoduleversion":
checkValue = obj.ClothCoverDetectionModuleVersion;

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -36,7 +36,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@@ -13,7 +13,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -37,8 +37,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
</Project>

View File

@@ -9,9 +9,9 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>

View File

@@ -115,6 +115,7 @@ namespace SabreTools.Serialization.CrossModel.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
xxHash364 = "xxhash364",
xxHash3128 = "xxhash3128",
Region = "region",
@@ -378,6 +379,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal("sha384", rom.SHA384);
Assert.Equal("sha512", rom.SHA512);
Assert.Equal("spamsum", rom.SpamSum);
Assert.Equal("blake3", rom.BLAKE3);
Assert.Equal("xxhash364", rom.xxHash364);
Assert.Equal("xxhash3128", rom.xxHash3128);
Assert.Equal("region", rom.Region);

View File

@@ -213,6 +213,29 @@ namespace SabreTools.Serialization.CrossModel.Test
Validate(newSpamsum);
}
[Fact]
public void RoundTripBLAKE3Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.BLAKE3);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.BLAKE3);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.BLAKE3);
var newBlake3 = Assert.Single(newHf.BLAKE3);
Validate(newBlake3);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
@@ -236,6 +259,8 @@ namespace SabreTools.Serialization.CrossModel.Test
return new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "hash", File = "file" }] };
else if (hashType == HashType.SpamSum)
return new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "hash", File = "file" }] };
else if (hashType == HashType.BLAKE3)
return new Data.Models.Hashfile.Hashfile { BLAKE3 = [new Data.Models.Hashfile.BLAKE3 { Hash = "hash", File = "file" }] };
else
throw new ArgumentOutOfRangeException(nameof(hashType));
}
@@ -329,5 +354,15 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal("hash", spamsum.Hash);
Assert.Equal("file", spamsum.File);
}
/// <summary>
/// Validate a BLAKE3
/// </summary>
private static void Validate(Data.Models.Hashfile.BLAKE3? blake3)
{
Assert.NotNull(blake3);
Assert.Equal("hash", blake3.Hash);
Assert.Equal("file", blake3.File);
}
}
}

View File

@@ -79,6 +79,7 @@ namespace SabreTools.Serialization.CrossModel.Test
ForceMerging = Data.Models.Metadata.MergingFlag.Merged,
ForceNodump = Data.Models.Metadata.NodumpFlag.Required,
ForcePacking = Data.Models.Metadata.PackingFlag.Zip,
Dir = "noautodir",
};
var clrmamepro = new Data.Models.Logiqx.ClrMamePro
@@ -115,6 +116,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Url = "url",
Comment = "comment",
Type = "type",
Subset = "subset",
RomVault = romvault,
ClrMamePro = clrmamepro,
RomCenter = romcenter,
@@ -171,6 +173,7 @@ namespace SabreTools.Serialization.CrossModel.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
xxHash364 = "xxhash364",
xxHash3128 = "xxhash3128",
Merge = "merge",
@@ -252,6 +255,7 @@ namespace SabreTools.Serialization.CrossModel.Test
gameBase.Id = "id";
gameBase.CloneOfId = "cloneofid";
gameBase.Runnable = Data.Models.Metadata.Runnable.Yes;
gameBase.SetType = "dir";
gameBase.Comment = ["comment"];
gameBase.Description = "description";
gameBase.Year = "year";
@@ -314,6 +318,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal("url", header.Url);
Assert.Equal("comment", header.Comment);
Assert.Equal("type", header.Type);
Assert.Equal("subset", header.Subset);
Validate(header.RomVault);
Validate(header.ClrMamePro);
Validate(header.RomCenter);
@@ -329,6 +334,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal(Data.Models.Metadata.MergingFlag.Merged, rv.ForceMerging);
Assert.Equal(Data.Models.Metadata.NodumpFlag.Required, rv.ForceNodump);
Assert.Equal(Data.Models.Metadata.PackingFlag.Zip, rv.ForcePacking);
Assert.Equal("noautodir", rv.Dir);
}
/// <summary>
@@ -380,6 +386,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal("id", gb.Id);
Assert.Equal("cloneofid", gb.CloneOfId);
Assert.Equal(Data.Models.Metadata.Runnable.Yes, gb.Runnable);
Assert.Equal("dir", gb.SetType);
Assert.NotNull(gb.Comment);
string comment = Assert.Single(gb.Comment);
@@ -504,6 +511,7 @@ namespace SabreTools.Serialization.CrossModel.Test
Assert.Equal("sha384", rom.SHA384);
Assert.Equal("sha512", rom.SHA512);
Assert.Equal("spamsum", rom.SpamSum);
Assert.Equal("blake3", rom.BLAKE3);
Assert.Equal("xxhash364", rom.xxHash364);
Assert.Equal("xxhash3128", rom.xxHash3128);
Assert.Equal("merge", rom.Merge);

View File

@@ -9,10 +9,10 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -290,6 +290,7 @@ namespace SabreTools.Serialization.CrossModel
SHA384 = item.SHA384,
SHA512 = item.SHA512,
SpamSum = item.SpamSum,
BLAKE3 = item.BLAKE3,
xxHash364 = item.xxHash364,
xxHash3128 = item.xxHash3128,
Merge = item.Merge,

View File

@@ -270,6 +270,7 @@ namespace SabreTools.Serialization.CrossModel
SHA384 = item.SHA384,
SHA512 = item.SHA512,
SpamSum = item.SpamSum,
BLAKE3 = item.BLAKE3,
xxHash364 = item.xxHash364,
xxHash3128 = item.xxHash3128,
Merge = item.Merge,

View File

@@ -36,6 +36,7 @@ namespace SabreTools.Serialization.CrossModel
var sha384s = new List<SHA384>();
var sha512s = new List<SHA512>();
var spamsums = new List<SpamSum>();
var blake3s = new List<BLAKE3>();
foreach (var hashfile in hashfiles)
{
@@ -61,6 +62,8 @@ namespace SabreTools.Serialization.CrossModel
sha512s.AddRange(hashfile.SHA512);
if (hashfile.SpamSum is not null && hashfile.SpamSum.Length > 0)
spamsums.AddRange(hashfile.SpamSum);
if (hashfile.BLAKE3 is not null && hashfile.BLAKE3.Length > 0)
blake3s.AddRange(hashfile.BLAKE3);
}
var hashfileItem = new Data.Models.Hashfile.Hashfile();
@@ -87,6 +90,8 @@ namespace SabreTools.Serialization.CrossModel
hashfileItem.SHA512 = [.. sha512s];
if (spamsums.Count > 0)
hashfileItem.SpamSum = [.. spamsums];
if (blake3s.Count > 0)
hashfileItem.BLAKE3 = [.. blake3s];
return hashfileItem;
}
@@ -135,6 +140,14 @@ namespace SabreTools.Serialization.CrossModel
SpamSum = hash == HashType.SpamSum
? Array.ConvertAll(roms, ConvertToSpamSum)
: null,
#if NET7_0_OR_GREATER
BLAKE3 = hash == HashType.BLAKE3
#else
// HACK because BLAKE3 is not supported below .NET 7
BLAKE3 = hash == HashType.CRC1_ZERO
#endif
? Array.ConvertAll(roms, ConvertToBLAKE3)
: null,
};
}
@@ -280,5 +293,18 @@ namespace SabreTools.Serialization.CrossModel
};
return spamsum;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Rom"/> to <see cref="BLAKE3"/>
/// </summary>
private static BLAKE3 ConvertToBLAKE3(Data.Models.Metadata.Rom item)
{
var spamsum = new BLAKE3
{
Hash = item.BLAKE3,
File = item.Name,
};
return spamsum;
}
}
}

View File

@@ -29,7 +29,7 @@ namespace SabreTools.Serialization.CrossModel
{
var header = new Data.Models.Metadata.Header
{
Name = "Hashfile",
Name = "Hashfile",
};
return header;
}
@@ -63,6 +63,8 @@ namespace SabreTools.Serialization.CrossModel
machine.Rom = Array.ConvertAll(item.SHA512, ConvertToInternalModel);
else if (item.SpamSum is not null && item.SpamSum.Length > 0)
machine.Rom = Array.ConvertAll(item.SpamSum, ConvertToInternalModel);
else if (item.BLAKE3 is not null && item.BLAKE3.Length > 0)
machine.Rom = Array.ConvertAll(item.BLAKE3, ConvertToInternalModel);
return machine;
}
@@ -209,5 +211,18 @@ namespace SabreTools.Serialization.CrossModel
};
return rom;
}
/// <summary>
/// Convert from <see cref="BLAKE3"/> to <see cref="Models.Metadata.Rom"/>
/// </summary>
private static Data.Models.Metadata.Rom ConvertToInternalModel(BLAKE3 item)
{
var rom = new Data.Models.Metadata.Rom
{
BLAKE3 = item.Hash,
Name = item.File,
};
return rom;
}
}
}

View File

@@ -54,6 +54,7 @@ namespace SabreTools.Serialization.CrossModel
Url = item.Url,
Comment = item.Comment,
Type = item.Type,
Subset = item.Subset,
};
if (item.HeaderSkipper is not null
@@ -70,6 +71,8 @@ namespace SabreTools.Serialization.CrossModel
header.RomVault.ForceNodump = item.ForceNodump;
if (item.ForcePacking is not Data.Models.Metadata.PackingFlag.None)
header.RomVault.ForcePacking = item.ForcePacking;
if (item.DirHandling is not null)
header.RomVault.Dir = item.DirHandling;
header.ClrMamePro = new Data.Models.Logiqx.ClrMamePro();
if (item.HeaderSkipper is not null)
@@ -130,6 +133,7 @@ namespace SabreTools.Serialization.CrossModel
gameBase.Id = item.Id;
gameBase.CloneOfId = item.CloneOfId;
gameBase.Runnable = item.Runnable;
gameBase.SetType = item.SetType;
gameBase.Comment = item.Comment;
gameBase.Description = item.Description;
gameBase.Year = item.Year;
@@ -352,6 +356,7 @@ namespace SabreTools.Serialization.CrossModel
SHA384 = item.SHA384,
SHA512 = item.SHA512,
SpamSum = item.SpamSum,
BLAKE3 = item.BLAKE3,
xxHash364 = item.xxHash364,
xxHash3128 = item.xxHash3128,
Merge = item.Merge,

View File

@@ -66,8 +66,18 @@ namespace SabreTools.Serialization.CrossModel
Url = item.Url,
Comment = item.Comment,
Type = item.Type,
Subset = item.Subset,
};
if (item.RomVault is not null)
{
header.HeaderSkipper = item.RomVault.Header;
header.ForceMerging = item.RomVault.ForceMerging;
header.ForceNodump = item.RomVault.ForceNodump;
header.ForcePacking = item.RomVault.ForcePacking;
header.DirHandling = item.RomVault.Dir;
}
if (item.ClrMamePro is not null)
{
header.HeaderSkipper = item.ClrMamePro.Header;
@@ -153,6 +163,7 @@ namespace SabreTools.Serialization.CrossModel
Runnable = item.Runnable,
SampleOf = item.SampleOf,
Score = item.Trurip?.Score,
SetType = item.SetType,
Source = item.Trurip?.Source,
SourceFile = item.SourceFile,
Subgenre = item.Trurip?.Subgenre,
@@ -321,6 +332,7 @@ namespace SabreTools.Serialization.CrossModel
SHA384 = item.SHA384,
SHA512 = item.SHA512,
SpamSum = item.SpamSum,
BLAKE3 = item.BLAKE3,
xxHash364 = item.xxHash364,
xxHash3128 = item.xxHash3128,
Merge = item.Merge,

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -31,7 +31,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -232,6 +232,7 @@ namespace SabreTools.Serialization.Readers.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
xxHash364 = "xxhash364",
xxHash3128 = "xxhash3128",
Region = "region",
@@ -495,6 +496,7 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal("sha384", rom.SHA384);
Assert.Equal("sha512", rom.SHA512);
Assert.Equal("spamsum", rom.SpamSum);
Assert.Equal("blake3", rom.BLAKE3);
Assert.Equal("xxhash364", rom.xxHash364);
Assert.Equal("xxhash3128", rom.xxHash3128);
Assert.Equal("region", rom.Region);

View File

@@ -287,6 +287,30 @@ namespace SabreTools.Serialization.Readers.Test
Validate(newSpamsum);
}
[Fact]
public void RoundTripBLAKE3Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.BLAKE3);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.BLAKE3);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.BLAKE3);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.BLAKE3);
var newBlake3 = Assert.Single(newHf.BLAKE3);
Validate(newBlake3);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
@@ -310,6 +334,8 @@ namespace SabreTools.Serialization.Readers.Test
return new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "hash", File = "file" }] };
else if (hashType == HashType.SpamSum)
return new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "hash", File = "file" }] };
else if (hashType == HashType.BLAKE3)
return new Data.Models.Hashfile.Hashfile { BLAKE3 = [new Data.Models.Hashfile.BLAKE3 { Hash = "hash", File = "file" }] };
else
throw new ArgumentOutOfRangeException(nameof(hashType));
}
@@ -403,5 +429,15 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal("hash", spamsum.Hash);
Assert.Equal("file", spamsum.File);
}
/// <summary>
/// Validate a BLAKE3
/// </summary>
private static void Validate(Data.Models.Hashfile.BLAKE3? blake3)
{
Assert.NotNull(blake3);
Assert.Equal("hash", blake3.Hash);
Assert.Equal("file", blake3.File);
}
}
}

View File

@@ -144,6 +144,7 @@ namespace SabreTools.Serialization.Readers.Test
ForceMerging = Data.Models.Metadata.MergingFlag.Merged,
ForceNodump = Data.Models.Metadata.NodumpFlag.Required,
ForcePacking = Data.Models.Metadata.PackingFlag.Zip,
Dir = "noautodir",
};
var clrmamepro = new Data.Models.Logiqx.ClrMamePro
@@ -180,6 +181,7 @@ namespace SabreTools.Serialization.Readers.Test
Url = "url",
Comment = "comment",
Type = "type",
Subset = "subset",
RomVault = romvault,
ClrMamePro = clrmamepro,
RomCenter = romcenter,
@@ -236,6 +238,7 @@ namespace SabreTools.Serialization.Readers.Test
SHA384 = "sha384",
SHA512 = "sha512",
SpamSum = "spamsum",
BLAKE3 = "blake3",
xxHash364 = "xxhash364",
xxHash3128 = "xxhash3128",
Merge = "merge",
@@ -317,6 +320,7 @@ namespace SabreTools.Serialization.Readers.Test
gameBase.Id = "id";
gameBase.CloneOfId = "cloneofid";
gameBase.Runnable = Data.Models.Metadata.Runnable.Yes;
gameBase.SetType = "dir";
gameBase.Comment = ["comment"];
gameBase.Description = "description";
gameBase.Year = "year";
@@ -367,6 +371,7 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal("url", header.Url);
Assert.Equal("comment", header.Comment);
Assert.Equal("type", header.Type);
Assert.Equal("subset", header.Subset);
Validate(header.RomVault);
Validate(header.ClrMamePro);
Validate(header.RomCenter);
@@ -382,6 +387,7 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal(Data.Models.Metadata.MergingFlag.Merged, rv.ForceMerging);
Assert.Equal(Data.Models.Metadata.NodumpFlag.Required, rv.ForceNodump);
Assert.Equal(Data.Models.Metadata.PackingFlag.Zip, rv.ForcePacking);
Assert.Equal("noautodir", rv.Dir);
}
/// <summary>
@@ -430,6 +436,7 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal("id", gb.Id);
Assert.Equal("cloneofid", gb.CloneOfId);
Assert.Equal(Data.Models.Metadata.Runnable.Yes, gb.Runnable);
Assert.Equal("dir", gb.SetType);
Assert.NotNull(gb.Comment);
string comment = Assert.Single(gb.Comment);
@@ -552,6 +559,7 @@ namespace SabreTools.Serialization.Readers.Test
Assert.Equal("sha384", rom.SHA384);
Assert.Equal("sha512", rom.SHA512);
Assert.Equal("spamsum", rom.SpamSum);
Assert.Equal("blake3", rom.BLAKE3);
Assert.Equal("xxhash364", rom.xxHash364);
Assert.Equal("xxhash3128", rom.xxHash3128);
Assert.Equal("merge", rom.Merge);

View File

@@ -9,9 +9,9 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -568,6 +568,9 @@ namespace SabreTools.Serialization.Readers
case "spamsum":
rom.SpamSum = kvp.Value;
break;
case "blake3":
rom.BLAKE3 = kvp.Value;
break;
case "xxh3_64":
rom.xxHash364 = kvp.Value;
break;

View File

@@ -91,6 +91,13 @@ namespace SabreTools.Serialization.Readers
return DeserializeSHA512(data);
else if (hash == HashType.SpamSum)
return DeserializeSpamSum(data);
#if NET7_0_OR_GREATER
else if (hash == HashType.BLAKE3)
#else
// HACK because BLAKE3 is not supported below .NET 7
else if (hash == HashType.CRC1_ZERO)
#endif
return DeserializeBLAKE3(data);
else
return null;
}
@@ -558,6 +565,50 @@ namespace SabreTools.Serialization.Readers
}
}
/// <inheritdoc cref="Deserialize(Stream)"/>
public Data.Models.Hashfile.Hashfile? DeserializeBLAKE3(Stream? data)
{
// If the data is invalid
if (data is null || !data.CanRead)
return default;
try
{
// Setup the reader and output
var reader = new StreamReader(data);
var blake3List = new List<BLAKE3>();
// Loop through the rows and parse out values
while (!reader.EndOfStream)
{
// Read and split the line
string? line = reader.ReadLine();
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
if (lineParts is null || lineParts.Length < 2)
continue;
// Parse the line into a hash
var blake3 = new BLAKE3
{
Hash = lineParts[0],
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
};
blake3List.Add(blake3);
}
// Assign the hashes to the hashfile and return
if (blake3List.Count > 0)
return new Data.Models.Hashfile.Hashfile { BLAKE3 = [.. blake3List] };
return null;
}
catch
{
// Ignore the actual error
return null;
}
}
#endregion
}
}

View File

@@ -270,6 +270,12 @@ namespace SabreTools.Serialization.Readers
obj.Type = reader.ReadElementContentAsString();
break;
case "subset":
if (obj.Subset is not null && Debug)
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
obj.Subset = reader.ReadElementContentAsString();
break;
case "romvault":
if (obj.RomVault is not null && Debug)
Console.WriteLine($"'{reader.Name}' element already found, overwriting");
@@ -335,6 +341,7 @@ namespace SabreTools.Serialization.Readers
obj.ForceMerging = reader.GetAttribute("forcemerging").AsMergingFlag();
obj.ForceNodump = reader.GetAttribute("forcenodump").AsNodumpFlag();
obj.ForcePacking = reader.GetAttribute("forcepacking").AsPackingFlag();
obj.Dir = reader.GetAttribute("dir");
return obj;
}
@@ -517,6 +524,7 @@ namespace SabreTools.Serialization.Readers
obj.Id = reader.GetAttribute("id");
obj.CloneOfId = reader.GetAttribute("cloneofid");
obj.Runnable = reader.GetAttribute("runnable").AsRunnable();
obj.SetType = reader.GetAttribute("type");
// Handle empty elements
if (reader.IsEmptyElement)
@@ -788,6 +796,7 @@ namespace SabreTools.Serialization.Readers
obj.SHA384 = reader.GetAttribute("sha384");
obj.SHA512 = reader.GetAttribute("sha512");
obj.SpamSum = reader.GetAttribute("spamsum");
obj.BLAKE3 = reader.GetAttribute("blake3");
obj.xxHash364 = reader.GetAttribute("xxh3_64");
obj.xxHash3128 = reader.GetAttribute("xxh3_128");
obj.Merge = reader.GetAttribute("merge");

View File

@@ -749,7 +749,7 @@ namespace SabreTools.Serialization.Readers
var table = new List<Data.Models.PortableExecutable.DebugData.Entry>();
int offset = 0;
while (offset < data.Length)
while (offset < data.Length && data.Length - offset >= 28)
{
var entry = ParseDebugDirectoryEntry(data, ref offset);
table.Add(entry);

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -36,8 +36,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -9,9 +9,9 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -275,6 +275,7 @@ namespace SabreTools.Serialization.Writers
writer.WriteOptionalAttributeString("sha384", rom.SHA384);
writer.WriteOptionalAttributeString("sha512", rom.SHA512);
writer.WriteOptionalAttributeString("spamsum", rom.SpamSum);
writer.WriteOptionalAttributeString("blake3", rom.BLAKE3);
writer.WriteOptionalAttributeString("xxh3_64", rom.xxHash364);
writer.WriteOptionalAttributeString("xxh3_128", rom.xxHash3128);
writer.WriteOptionalAttributeString("merge", rom.Merge);

View File

@@ -101,6 +101,13 @@ namespace SabreTools.Serialization.Writers
WriteSHA512(obj.SHA512, writer);
else if (hash == HashType.SpamSum)
WriteSpamSum(obj.SpamSum, writer);
#if NET7_0_OR_GREATER
else if (hash == HashType.BLAKE3)
#else
// HACK because BLAKE3 is not supported below .NET 7
else if (hash == HashType.CRC1_ZERO)
#endif
WriteBLAKE3(obj.BLAKE3, writer);
else
throw new ArgumentOutOfRangeException(nameof(hash));
@@ -351,6 +358,28 @@ namespace SabreTools.Serialization.Writers
}
}
/// <summary>
/// Write BLAKE3 information to the current writer
/// </summary>
/// <param name="blake3s">Array of BLAKE3 objects representing the files</param>
/// <param name="writer">Writer representing the output</param>
private static void WriteBLAKE3(BLAKE3[]? blake3s, Writer writer)
{
// If the item information is missing, we can't do anything
if (blake3s is null || blake3s.Length == 0)
return;
// Loop through and write out the items
foreach (var blake3 in blake3s)
{
if (string.IsNullOrEmpty(blake3.Hash) || string.IsNullOrEmpty(blake3.File))
continue;
writer.WriteValues([blake3.Hash!, blake3.File!]);
writer.Flush();
}
}
#endregion
}
}

View File

@@ -158,6 +158,7 @@ namespace SabreTools.Serialization.Writers
writer.WriteOptionalElementString("url", obj.Url);
writer.WriteOptionalElementString("comment", obj.Comment);
writer.WriteOptionalElementString("type", obj.Type);
writer.WriteOptionalElementString("subset", obj.Subset);
if (obj.RomVault is not null)
WriteRomVault(obj.RomVault, writer);
@@ -211,6 +212,7 @@ namespace SabreTools.Serialization.Writers
writer.WriteOptionalAttributeString("forcenodump", obj.ForceNodump.AsStringValue());
if (obj.ForcePacking != Data.Models.Metadata.PackingFlag.None)
writer.WriteOptionalAttributeString("forcepacking", obj.ForcePacking.AsStringValue());
writer.WriteOptionalAttributeString("dir", obj.Dir);
writer.WriteEndElement();
}
@@ -360,6 +362,7 @@ namespace SabreTools.Serialization.Writers
writer.WriteOptionalAttributeString("id", obj.Id);
writer.WriteOptionalAttributeString("cloneofid", obj.CloneOfId);
writer.WriteOptionalAttributeString("runnable", obj.Runnable?.AsStringValue());
writer.WriteOptionalAttributeString("type", obj.SetType);
if (obj.Comment is not null && obj.Comment.Length > 0)
{
@@ -528,6 +531,7 @@ namespace SabreTools.Serialization.Writers
writer.WriteOptionalAttributeString("sha384", obj.SHA384);
writer.WriteOptionalAttributeString("sha512", obj.SHA512);
writer.WriteOptionalAttributeString("spamsum", obj.SpamSum);
writer.WriteOptionalAttributeString("blake3", obj.BLAKE3);
writer.WriteOptionalAttributeString("xxh3_64", obj.xxHash364);
writer.WriteOptionalAttributeString("xxh3_128", obj.xxHash3128);
writer.WriteOptionalAttributeString("merge", obj.Merge);

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -32,8 +32,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -58,14 +58,14 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GrindCore" Version="0.7.1" />
<PackageReference Include="GrindCore.SharpCompress" Version="0.48.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="GrindCore" Version="0.9.0" />
<PackageReference Include="GrindCore.SharpCompress" Version="0.50.5" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="MinValueTupleBridge" Version="0.2.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
<PackageReference Include="Net30.LinqBridge" Version="1.6.0.2" Condition="$(TargetFramework.StartsWith(`net2`))" />
<PackageReference Include="NetLegacySupport.Numerics" Version="1.0.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="$(TargetFramework.StartsWith(`net40`)) OR $(TargetFramework.StartsWith(`net45`))" />
<PackageReference Include="System.ValueTuple" Version="4.6.2" Condition="$(TargetFramework.StartsWith(`net46`)) OR $(TargetFramework.StartsWith(`net47`)) OR $(TargetFramework.StartsWith(`net48`))" />
</ItemGroup>

View File

@@ -19,10 +19,10 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using SabreTools.IO.Compression.Deflate;
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
using SabreTools.IO.Extensions;
namespace SabreTools.Wrappers
@@ -95,7 +96,7 @@ namespace SabreTools.Wrappers
else
{
using var ms = new MemoryStream(data);
using var zs = new ZlibStream(ms, CompressionMode.Decompress);
using var zs = new ZLibStream(ms, new CompressionOptions { Type = CompressionType.Decompress });
zs.BlockCopy(fs);
fs.Flush();
}

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using SabreTools.IO.Compression.BZip2;
using Nanook.GrindCore;
using Nanook.GrindCore.BZip2;
using SabreTools.IO.Extensions;
namespace SabreTools.Wrappers
@@ -21,7 +22,7 @@ namespace SabreTools.Wrappers
try
{
// Try opening the stream
using var bz2File = new BZip2InputStream(_dataSource, true);
using var bz2File = new BZip2Stream(_dataSource, new CompressionOptions { LeaveOpen = true, Type = CompressionType.Decompress});
// Ensure directory separators are consistent
string filename = Guid.NewGuid().ToString();

View File

@@ -1,5 +1,6 @@
using System.IO;
using SabreTools.IO.Compression.Deflate;
using Nanook.GrindCore;
using Nanook.GrindCore.DeflateZLib;
using SabreTools.IO.Extensions;
using static SabreTools.Data.Models.GCZ.Constants;
@@ -61,7 +62,8 @@ namespace SabreTools.Wrappers
// Verify Adler-32 checksum on the compressed (raw) data before decompressing
if (BlockHashes is not null && blockIndex < BlockHashes.Length)
{
uint actual = Adler.Adler32(1, raw, 0, raw.Length);
// TODO: Replace with call to Hashing library
uint actual = IO.Compression.Deflate.Adler.Adler32(1, raw, 0, raw.Length);
if (actual != BlockHashes[blockIndex])
return null;
}
@@ -78,7 +80,7 @@ namespace SabreTools.Wrappers
try
{
using var cs = new MemoryStream(raw, 2, raw.Length - 6);
using var ds = new DeflateStream(cs, CompressionMode.Decompress);
using var ds = new DeflateStream(cs, new CompressionOptions { Type = CompressionType.Decompress });
using var os = new MemoryStream();
ds.BlockCopy(os, blockSize: 4096);

View File

@@ -1,7 +1,8 @@
using System;
using System.IO;
using Nanook.GrindCore;
using Nanook.GrindCore.DeflateZLib;
using SabreTools.Data.Models.GCZ;
using SabreTools.IO.Compression.Deflate;
using SabreTools.IO.Extensions;
using SabreTools.Numerics.Extensions;
@@ -122,13 +123,13 @@ namespace SabreTools.Wrappers
{
blockPointers[i] = blockPointer;
destination.Write(compressBuf, 0, compressedSize);
blockHashes[i] = Adler.Adler32(1, compressBuf, 0, compressedSize);
blockHashes[i] = IO.Compression.Deflate.Adler.Adler32(1, compressBuf, 0, compressedSize);
}
else
{
blockPointers[i] = blockPointer | Constants.UncompressedFlag;
destination.Write(readBuf, 0, blockDataSize);
blockHashes[i] = Adler.Adler32(1, readBuf, 0, blockDataSize);
blockHashes[i] = IO.Compression.Deflate.Adler.Adler32(1, readBuf, 0, blockDataSize);
}
}
@@ -175,12 +176,12 @@ namespace SabreTools.Wrappers
ms.WriteByte(0x78);
ms.WriteByte(0x9C);
using (var ds = new DeflateStream(ms, CompressionMode.Compress, leaveOpen: true))
using (var ds = new DeflateStream(ms, new CompressionOptions { LeaveOpen = true, Type = CompressionType.Level5 }))
{
ds.Write(input, 0, inputSize);
}
uint adler = Adler.Adler32(1, input, 0, inputSize);
uint adler = IO.Compression.Deflate.Adler.Adler32(1, input, 0, inputSize);
ms.WriteByte((byte)(adler >> 24));
ms.WriteByte((byte)(adler >> 16));
ms.WriteByte((byte)(adler >> 8));

View File

@@ -1,7 +1,8 @@
using System;
using System.IO;
using Nanook.GrindCore;
using Nanook.GrindCore.DeflateZLib;
using SabreTools.Data.Models.GZIP;
using SabreTools.IO.Compression.Deflate;
using SabreTools.IO.Extensions;
namespace SabreTools.Wrappers
@@ -53,7 +54,7 @@ namespace SabreTools.Wrappers
Directory.CreateDirectory(directoryName);
// Open the source as a DEFLATE stream
var deflateStream = new DeflateStream(_dataSource, CompressionMode.Decompress, leaveOpen: true);
var deflateStream = new DeflateStream(_dataSource, new CompressionOptions { LeaveOpen = true, Type = CompressionType.Decompress});
// Write the file
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);

View File

@@ -1,9 +1,10 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using Nanook.GrindCore;
using Nanook.GrindCore.DeflateZLib;
using SabreTools.Data.Models.InstallShieldCabinet;
using SabreTools.Hashing;
using SabreTools.IO.Compression.zlib;
using SabreTools.IO.Extensions;
using static SabreTools.Data.Models.InstallShieldCabinet.Constants;
@@ -50,11 +51,6 @@ namespace SabreTools.Wrappers
/// </summary>
private const int BUFFER_SIZE = 64 * 1024;
/// <summary>
/// Maximum size of the window in bits
/// </summary>
private const int MAX_WBITS = 15;
/// <summary>
/// Characters that should be replaced by an underscore for filenames
/// </summary>
@@ -245,7 +241,7 @@ namespace SabreTools.Wrappers
string filename = cabinet.GetFileName(i) ?? $"BAD_FILENAME{i}";
uint dirIndex = cabinet.GetDirectoryIndexFromFile(i);
string dir = cabinet.GetDirectoryName((int)dirIndex) ?? $"BAD_DIRNAME{dirIndex}";
string group = cabinet.GetFileGroupNameFromFile(i) ?? $"BAD_GROUPNAME{dirIndex}";
string? group = cabinet.GetFileGroupNameFromFile(i);
// Consistently replace problematic path characters
foreach (char c in PathReplacementCharacters)
@@ -253,17 +249,19 @@ namespace SabreTools.Wrappers
dir = dir.Replace(c, '_');
}
foreach (char c in PathReplacementCharacters)
// Only process the group if it's valid
if (group is not null)
{
group = group.Replace(c, '_');
foreach (char c in PathReplacementCharacters)
{
group = group.Replace(c, '_');
}
}
// Build the full path
#if NET20 || NET35
filename = Path.Combine(Path.Combine(group, dir), filename);
#else
filename = Path.Combine(group, dir, filename);
#endif
filename = Path.Combine(dir, filename);
if (group is not null)
filename = Path.Combine(group, filename);
// Ensure directory separators are consistent
filename = filename.TrimStart(['\\', '/']);
@@ -315,7 +313,7 @@ namespace SabreTools.Wrappers
// Create the output file and hasher
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
var md5 = new HashWrapper(HashType.MD5);
var md5 = new HashWrapper(Hashing.HashType.MD5);
ulong readBytesLeft = GetReadableBytes(fileDescriptor);
ulong writeBytesLeft = GetWritableBytes(fileDescriptor);
@@ -329,7 +327,7 @@ namespace SabreTools.Wrappers
while (readBytesLeft > 0 && readBytesLeft <= storedSize)
{
uint bytesToWrite = BUFFER_SIZE;
int result;
bool result;
// Handle compressed files
#if NET20 || NET35
@@ -366,9 +364,9 @@ namespace SabreTools.Wrappers
result = Uncompress(outputBuffer, ref bytesToWrite, inputBuffer, ref bytesToRead);
// If we didn't get a positive result that's not a data error (false positives)
if (result != zlibConst.Z_OK && result != zlibConst.Z_DATA_ERROR)
if (!result)
{
Console.Error.WriteLine($"Decompression failed with code {result.ToZlibConstName()}. bytes_to_read={bytesToRead}, volume={fileDescriptor.Volume}, read_bytes={bytesToRead}");
Console.Error.WriteLine($"Decompression failed. bytes_to_read={bytesToRead}, volume={fileDescriptor.Volume}, read_bytes={bytesToRead}");
reader.Dispose();
fs?.Close();
return false;
@@ -482,73 +480,42 @@ namespace SabreTools.Wrappers
/// <summary>
/// Uncompress a source byte array to a destination
/// </summary>
private static unsafe int Uncompress(byte[] dest, ref uint destLen, byte[] source, ref uint sourceLen)
private static bool Uncompress(byte[] dest, ref uint destLen, byte[] source, ref uint sourceLen)
{
fixed (byte* sourcePtr = source, destPtr = dest)
{
var stream = new ZLib.z_stream_s
{
next_in = sourcePtr,
avail_in = sourceLen,
next_out = destPtr,
avail_out = destLen,
};
// Prepare the streams
using var sourceStream = new MemoryStream(source, index: 0, (int)sourceLen, false);
using var deflateStream = new DeflateStream(sourceStream, new CompressionOptions { Type = CompressionType.Decompress });
using var destStream = new MemoryStream(dest);
// make second parameter negative to disable checksum verification
int err = ZLib.inflateInit2_(stream, -MAX_WBITS, ZLib.zlibVersion(), source.Length);
if (err != zlibConst.Z_OK)
return err;
// Copy the source to the destination
bool copied = deflateStream.BlockCopy(destStream);
err = ZLib.inflate(stream, zlibConst.Z_FINISH);
if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END)
{
ZLib.inflateEnd(stream);
return err;
}
destLen = stream.total_out;
sourceLen = stream.total_in;
return ZLib.inflateEnd(stream);
}
destLen = (uint)destStream.Position;
sourceLen = (uint)deflateStream.Position;
return copied;
}
/// <summary>
/// Uncompress a source byte array to a destination (old version)
/// </summary>
private static unsafe int UncompressOld(byte[] dest, ref uint destLen, byte[] source, ref uint sourceLen)
private static bool UncompressOld(byte[] dest, ref uint destLen, byte[] source, ref uint sourceLen)
{
fixed (byte* sourcePtr = source, destPtr = dest)
// Prepare the streams
using var sourceStream = new MemoryStream(source, 0, (int)sourceLen, false);
using var deflateStream = new DeflateStream(sourceStream, new CompressionOptions { Type = CompressionType.Decompress });
using var destStream = new MemoryStream(dest);
// Copy the source to the destination
while (deflateStream.Position < sourceLen)
{
var stream = new ZLib.z_stream_s
{
next_in = sourcePtr,
avail_in = sourceLen,
next_out = destPtr,
avail_out = destLen,
};
destLen = 0;
sourceLen = 0;
// make second parameter negative to disable checksum verification
int err = ZLib.inflateInit2_(stream, -MAX_WBITS, ZLib.zlibVersion(), source.Length);
if (err != zlibConst.Z_OK)
return err;
while (stream.avail_in > 1)
{
err = ZLib.inflate(stream, zlibConst.Z_BLOCK);
if (err != zlibConst.Z_OK)
{
ZLib.inflateEnd(stream);
return err;
}
}
destLen = stream.total_out;
sourceLen = stream.total_in;
return ZLib.inflateEnd(stream);
bool copied = deflateStream.BlockCopy(destStream);
if (!copied)
return false;
}
destLen = (uint)destStream.Position;
sourceLen = (uint)deflateStream.Position;
return true;
}
#endregion

View File

@@ -1,7 +1,8 @@
using System;
using System.IO;
using SabreTools.IO.Compression.BZip2;
using SabreTools.IO.Compression.zlib;
using Nanook.GrindCore;
using Nanook.GrindCore.BZip2;
using Nanook.GrindCore.ZLib;
using SabreTools.IO.Extensions;
using SabreTools.Matching;
using SabreTools.Numerics.Extensions;
@@ -595,7 +596,7 @@ namespace SabreTools.Wrappers
// Try opening the stream
using var ms = new MemoryStream(bz2Data);
using var bz2File = new BZip2InputStream(ms, false);
using var bz2File = new BZip2Stream(ms, new CompressionOptions { LeaveOpen = false, Type = CompressionType.Decompress});
// Try to read the decompressed data
byte[] data = bz2File.ReadBytes(extracted);
@@ -736,35 +737,15 @@ namespace SabreTools.Wrappers
{
try
{
// Open the input stream as ZLib-compressed
using var inputStream = new MemoryStream(resource);
var zlibStream = new ZLibStream(inputStream, new CompressionOptions { Type = CompressionType.Decompress });
// Inflate the data into the buffer
var zstream = new ZLib.z_stream_s();
byte[] data = new byte[resource.Length * 4];
unsafe
{
fixed (byte* payloadPtr = resource, dataPtr = data)
{
zstream.next_in = payloadPtr;
zstream.avail_in = (uint)resource.Length;
zstream.total_in = (uint)resource.Length;
zstream.next_out = dataPtr;
zstream.avail_out = (uint)data.Length;
zstream.total_out = 0;
using var outputStream = new MemoryStream();
zlibStream.BlockCopy(outputStream);
byte[] data = outputStream.ToArray();
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), resource.Length);
int zret = ZLib.inflate(zstream, 1);
ZLib.inflateEnd(zstream);
}
}
// Trim the buffer to the proper size
uint read = zstream.total_out;
#if NETFRAMEWORK
var temp = new byte[read];
Array.Copy(data, temp, read);
data = temp;
#else
data = new ReadOnlySpan<byte>(data, 0, (int)read).ToArray();
#endif
return data;
}
catch

View File

@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using SabreTools.IO.Compression.zlib;
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
using SabreTools.IO.Extensions;
using SabreTools.Numerics.Extensions;
namespace SabreTools.Wrappers
@@ -94,25 +96,14 @@ namespace SabreTools.Wrappers
}
else
{
// Inflate the data into the buffer
var zstream = new ZLib.z_stream_s();
data = new byte[outputFileSize];
unsafe
{
fixed (byte* payloadPtr = compressedData, dataPtr = data)
{
zstream.next_in = payloadPtr;
zstream.avail_in = (uint)compressedData.Length;
zstream.total_in = (uint)compressedData.Length;
zstream.next_out = dataPtr;
zstream.avail_out = (uint)data.Length;
zstream.total_out = 0;
// Open the input stream as ZLib-compressed
using var inputStream = new MemoryStream(compressedData);
var zlibStream = new ZLibStream(inputStream, new CompressionOptions { Type = CompressionType.Decompress });
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), compressedData.Length);
int zret = ZLib.inflate(zstream, 1);
ZLib.inflateEnd(zstream);
}
}
// Inflate the data into the buffer
using var outputStream = new MemoryStream();
zlibStream.BlockCopy(outputStream);
data = outputStream.ToArray();
}
// If we have an invalid output directory

View File

@@ -12,7 +12,7 @@
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -43,11 +43,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GrindCore" Version="0.7.1" />
<PackageReference Include="GrindCore.SharpCompress" Version="0.48.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="GrindCore" Version="0.9.0" />
<PackageReference Include="GrindCore.SharpCompress" Version="0.50.5" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="SabreTools.Hashing" Version="2.0.0" />
<PackageReference Include="SabreTools.IO" Version="2.2.0" />
<PackageReference Include="SabreTools.Hashing" Version="2.1.0" />
<PackageReference Include="SabreTools.IO" Version="2.3.0" />
</ItemGroup>
<ItemGroup>