mirror of
https://github.com/claunia/romrepomgr.git
synced 2025-12-16 19:24:51 +00:00
Compare commits
3 Commits
c5da48fa47
...
55a6af0c74
| Author | SHA1 | Date | |
|---|---|---|---|
|
55a6af0c74
|
|||
|
69fb3c768b
|
|||
|
b0e0ba4502
|
@@ -4,6 +4,7 @@
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
<LangVersion>default</LangVersion>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project ToolsVersion="15.0">
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Aaru.Checksums.Native" Version="6.0.0-alpha.10"/>
|
||||
<PackageVersion Include="AsyncFixer" Version="1.6.0"/>
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.2"/>
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.2"/>
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.2"/>
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.3.2"/>
|
||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.3.0"/>
|
||||
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.3.2"/>
|
||||
<PackageVersion Include="Avalonia" Version="11.3.2"/>
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||
<PackageVersion Include="DotNetZip" Version="1.16.0"/>
|
||||
<PackageVersion Include="EFCore.BulkExtensions" Version="9.0.1"/>
|
||||
<PackageVersion Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2"/>
|
||||
@@ -28,22 +29,22 @@
|
||||
<PackageVersion Include="Roslynator.CodeAnalysis.Analyzers" Version="4.13.1"/>
|
||||
<PackageVersion Include="Roslynator.Formatting.Analyzers" Version="4.13.1"/>
|
||||
<PackageVersion Include="SabreTools.Models" Version="1.5.8"/>
|
||||
<PackageVersion Include="Serilog" Version="4.3.0"/>
|
||||
<PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.2"/>
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0"/>
|
||||
<PackageVersion Include="SharpCompress" Version="0.39.0"/>
|
||||
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31"/>
|
||||
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0"/>
|
||||
<PackageVersion Include="Text.Analyzers" Version="4.14.0"/>
|
||||
<PackageVersion Include="winfsp.net" Version="2.1.25156"/>
|
||||
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
|
||||
<PackageVersion Include="SabreTools.Hashing" Version="1.2.3"/>
|
||||
<PackageVersion Include="SabreTools.IO" Version="1.4.13"/>
|
||||
<PackageVersion Include="SabreTools.Matching" Version="1.3.4"/>
|
||||
<PackageVersion Include="SabreTools.Skippers" Version="1.1.3"/>
|
||||
|
||||
<PackageVersion Include="System.IO.Compression" Version="4.3.0"/>
|
||||
<PackageVersion Include="SharpCompress" Version="0.38.0"/>
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="8.0.0"/>
|
||||
<PackageVersion Include="ZstdSharp.Port" Version="0.8.1"/>
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
37
RomRepoMgr.Core/Checksums/Authors.cs
Normal file
37
RomRepoMgr.Core/Checksums/Authors.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Authors.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Aaru.Checksums.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
static class Authors
|
||||
{
|
||||
internal const string NataliaPortillo = "Natalia Portillo";
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Aaru.Helpers;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <summary>
|
||||
/// Converts base data types to an array of bytes, and an array of bytes to base data types. All info taken from
|
||||
|
||||
132
RomRepoMgr.Core/Checksums/CRC32/arm_simd.cs
Normal file
132
RomRepoMgr.Core/Checksums/CRC32/arm_simd.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : arm_simd.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// The Chromium Authors
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute CRC32 checksum using ARM special instructions..
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums.CRC32;
|
||||
|
||||
static class ArmSimd
|
||||
{
|
||||
internal static uint Step64(byte[] buf, long len, uint crc)
|
||||
{
|
||||
uint c = crc;
|
||||
|
||||
var bufPos = 0;
|
||||
|
||||
while(len >= 64)
|
||||
{
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
while(len >= 8)
|
||||
{
|
||||
c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
|
||||
bufPos += 8;
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
while(len-- > 0) c = Crc32.ComputeCrc32(c, buf[bufPos++]);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
internal static uint Step32(byte[] buf, long len, uint crc)
|
||||
{
|
||||
uint c = crc;
|
||||
|
||||
var bufPos = 0;
|
||||
|
||||
while(len >= 32)
|
||||
{
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
len -= 32;
|
||||
}
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
|
||||
bufPos += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
while(len-- > 0) c = Crc32.ComputeCrc32(c, buf[bufPos++]);
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
229
RomRepoMgr.Core/Checksums/CRC32/clmul.cs
Normal file
229
RomRepoMgr.Core/Checksums/CRC32/clmul.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : clmul.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
// Wajdi Feghali <wajdi.k.feghali@intel.com>
|
||||
// Jim Guilford <james.guilford@intel.com>
|
||||
// Vinodh Gopal <vinodh.gopal@intel.com>
|
||||
// Erdinc Ozturk <erdinc.ozturk@intel.com>
|
||||
// Jim Kukunas <james.t.kukunas@linux.intel.com>
|
||||
// Marian Beermann
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ
|
||||
// instruction.
|
||||
//
|
||||
// A white paper describing this algorithm can be found at:
|
||||
// http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from
|
||||
// the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// Copyright (c) 2016 Marian Beermann (add support for initial value, restructuring)
|
||||
// Copyright (C) 2013 Intel Corporation. All rights reserved.
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums.CRC32;
|
||||
|
||||
static class Clmul
|
||||
{
|
||||
static readonly uint[] _crcK =
|
||||
[
|
||||
0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
|
||||
0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
|
||||
];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static void Fold4(ref Vector128<uint> xmmCRC0, ref Vector128<uint> xmmCRC1, ref Vector128<uint> xmmCRC2,
|
||||
ref Vector128<uint> xmmCRC3)
|
||||
{
|
||||
var xmmFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001);
|
||||
|
||||
Vector128<uint> xTmp0 = xmmCRC0;
|
||||
Vector128<uint> xTmp1 = xmmCRC1;
|
||||
Vector128<uint> xTmp2 = xmmCRC2;
|
||||
Vector128<uint> xTmp3 = xmmCRC3;
|
||||
|
||||
xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
|
||||
xTmp0 = Pclmulqdq.CarrylessMultiply(xTmp0.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
|
||||
Vector128<float> psCRC0 = xmmCRC0.AsSingle();
|
||||
Vector128<float> psT0 = xTmp0.AsSingle();
|
||||
Vector128<float> psRes0 = Sse.Xor(psCRC0, psT0);
|
||||
|
||||
xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
|
||||
xTmp1 = Pclmulqdq.CarrylessMultiply(xTmp1.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
|
||||
Vector128<float> psCRC1 = xmmCRC1.AsSingle();
|
||||
Vector128<float> psT1 = xTmp1.AsSingle();
|
||||
Vector128<float> psRes1 = Sse.Xor(psCRC1, psT1);
|
||||
|
||||
xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
|
||||
xTmp2 = Pclmulqdq.CarrylessMultiply(xTmp2.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
|
||||
Vector128<float> psCRC2 = xmmCRC2.AsSingle();
|
||||
Vector128<float> psT2 = xTmp2.AsSingle();
|
||||
Vector128<float> psRes2 = Sse.Xor(psCRC2, psT2);
|
||||
|
||||
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
|
||||
xTmp3 = Pclmulqdq.CarrylessMultiply(xTmp3.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
|
||||
Vector128<float> psCRC3 = xmmCRC3.AsSingle();
|
||||
Vector128<float> psT3 = xTmp3.AsSingle();
|
||||
Vector128<float> psRes3 = Sse.Xor(psCRC3, psT3);
|
||||
|
||||
xmmCRC0 = psRes0.AsUInt32();
|
||||
xmmCRC1 = psRes1.AsUInt32();
|
||||
xmmCRC2 = psRes2.AsUInt32();
|
||||
xmmCRC3 = psRes3.AsUInt32();
|
||||
}
|
||||
|
||||
internal static uint Step(byte[] src, long len, uint initialCRC)
|
||||
{
|
||||
Vector128<uint> xmmInitial = Sse2.ConvertScalarToVector128UInt32(initialCRC);
|
||||
Vector128<uint> xmmCRC0 = Sse2.ConvertScalarToVector128UInt32(0x9db42487);
|
||||
Vector128<uint> xmmCRC1 = Vector128<uint>.Zero;
|
||||
Vector128<uint> xmmCRC2 = Vector128<uint>.Zero;
|
||||
Vector128<uint> xmmCRC3 = Vector128<uint>.Zero;
|
||||
var bufPos = 0;
|
||||
|
||||
var first = true;
|
||||
|
||||
/* fold 512 to 32 step variable declarations for ISO-C90 compat. */
|
||||
var xmmMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
|
||||
var xmmMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
|
||||
while((len -= 64) >= 0)
|
||||
{
|
||||
var xmmT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
|
||||
BitConverter.ToUInt32(src, bufPos + 4),
|
||||
BitConverter.ToUInt32(src, bufPos + 8),
|
||||
BitConverter.ToUInt32(src, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var xmmT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
|
||||
BitConverter.ToUInt32(src, bufPos + 4),
|
||||
BitConverter.ToUInt32(src, bufPos + 8),
|
||||
BitConverter.ToUInt32(src, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var xmmT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
|
||||
BitConverter.ToUInt32(src, bufPos + 4),
|
||||
BitConverter.ToUInt32(src, bufPos + 8),
|
||||
BitConverter.ToUInt32(src, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
var xmmT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
|
||||
BitConverter.ToUInt32(src, bufPos + 4),
|
||||
BitConverter.ToUInt32(src, bufPos + 8),
|
||||
BitConverter.ToUInt32(src, bufPos + 12));
|
||||
|
||||
bufPos += 16;
|
||||
|
||||
if(first)
|
||||
{
|
||||
first = false;
|
||||
xmmT0 = Sse2.Xor(xmmT0, xmmInitial);
|
||||
}
|
||||
|
||||
Fold4(ref xmmCRC0, ref xmmCRC1, ref xmmCRC2, ref xmmCRC3);
|
||||
|
||||
xmmCRC0 = Sse2.Xor(xmmCRC0, xmmT0);
|
||||
xmmCRC1 = Sse2.Xor(xmmCRC1, xmmT1);
|
||||
xmmCRC2 = Sse2.Xor(xmmCRC2, xmmT2);
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmT3);
|
||||
}
|
||||
|
||||
/* fold 512 to 32 */
|
||||
|
||||
/*
|
||||
* k1
|
||||
*/
|
||||
var crcFold = Vector128.Create(_crcK[0], _crcK[1], _crcK[2], _crcK[3]);
|
||||
|
||||
Vector128<uint> xTmp0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
|
||||
|
||||
xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
|
||||
xmmCRC1 = Sse2.Xor(xmmCRC1, xTmp0);
|
||||
xmmCRC1 = Sse2.Xor(xmmCRC1, xmmCRC0);
|
||||
|
||||
Vector128<uint> xTmp1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
|
||||
|
||||
xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
|
||||
xmmCRC2 = Sse2.Xor(xmmCRC2, xTmp1);
|
||||
xmmCRC2 = Sse2.Xor(xmmCRC2, xmmCRC1);
|
||||
|
||||
Vector128<uint> xTmp2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
|
||||
|
||||
xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xTmp2);
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
|
||||
|
||||
/*
|
||||
* k5
|
||||
*/
|
||||
crcFold = Vector128.Create(_crcK[4], _crcK[5], _crcK[6], _crcK[7]);
|
||||
|
||||
xmmCRC0 = xmmCRC3;
|
||||
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
|
||||
xmmCRC0 = Sse2.ShiftRightLogical128BitLane(xmmCRC0, 8);
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
|
||||
|
||||
xmmCRC0 = xmmCRC3;
|
||||
xmmCRC3 = Sse2.ShiftLeftLogical128BitLane(xmmCRC3, 4);
|
||||
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
|
||||
xmmCRC3 = Sse2.And(xmmCRC3, xmmMask2);
|
||||
|
||||
/*
|
||||
* k7
|
||||
*/
|
||||
xmmCRC1 = xmmCRC3;
|
||||
xmmCRC2 = xmmCRC3;
|
||||
crcFold = Vector128.Create(_crcK[8], _crcK[9], _crcK[10], _crcK[11]);
|
||||
|
||||
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
|
||||
xmmCRC3 = Sse2.And(xmmCRC3, xmmMask);
|
||||
|
||||
xmmCRC2 = xmmCRC3;
|
||||
xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
|
||||
xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC1);
|
||||
|
||||
/*
|
||||
* could just as well write xmm_crc3[2], doing a movaps and truncating, but
|
||||
* no real advantage - it's a tiny bit slower per call, while no additional CPUs
|
||||
* would be supported by only requiring SSSE3 and CLMUL instead of SSE4.1 + CLMUL
|
||||
*/
|
||||
return ~Sse41.Extract(xmmCRC3, 2);
|
||||
}
|
||||
}
|
||||
@@ -27,48 +27,326 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Helpers;
|
||||
using RomRepoMgr.Core.Checksums.CRC32;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements a CRC32 algorithm</summary>
|
||||
public sealed class Crc32Context : IChecksum
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
public sealed partial class Crc32Context : IChecksum
|
||||
{
|
||||
const uint CRC32_ISO_POLY = 0xEDB88320;
|
||||
const uint CRC32_ISO_SEED = 0xFFFFFFFF;
|
||||
|
||||
readonly uint _finalSeed;
|
||||
readonly uint[] _table;
|
||||
uint _hashInt;
|
||||
internal static readonly uint[][] ISOCrc32Table =
|
||||
[
|
||||
[
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
],
|
||||
[
|
||||
0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,
|
||||
0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,
|
||||
0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,
|
||||
0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A, 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E,
|
||||
0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761, 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265,
|
||||
0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D,
|
||||
0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034,
|
||||
0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C,
|
||||
0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,
|
||||
0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA,
|
||||
0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97, 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93,
|
||||
0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F, 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B,
|
||||
0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864, 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60,
|
||||
0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C, 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768,
|
||||
0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31,
|
||||
0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539,
|
||||
0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C,
|
||||
0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,
|
||||
0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD,
|
||||
0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1, 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5,
|
||||
0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A, 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E,
|
||||
0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522, 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026,
|
||||
0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B, 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F,
|
||||
0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277,
|
||||
0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189,
|
||||
0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81,
|
||||
0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,
|
||||
0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0,
|
||||
0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F, 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B,
|
||||
0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27, 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23,
|
||||
0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E, 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A,
|
||||
0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876, 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72
|
||||
],
|
||||
[
|
||||
0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685,
|
||||
0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D,
|
||||
0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29, 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5,
|
||||
0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91, 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D,
|
||||
0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9, 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065,
|
||||
0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD,
|
||||
0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315,
|
||||
0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD,
|
||||
0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,
|
||||
0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD,
|
||||
0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835,
|
||||
0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151, 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D,
|
||||
0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579, 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5,
|
||||
0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1, 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D,
|
||||
0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5,
|
||||
0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D,
|
||||
0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05,
|
||||
0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,
|
||||
0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75,
|
||||
0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711, 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD,
|
||||
0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339, 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5,
|
||||
0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281, 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D,
|
||||
0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049, 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895,
|
||||
0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D,
|
||||
0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5,
|
||||
0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D,
|
||||
0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,
|
||||
0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D,
|
||||
0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9, 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625,
|
||||
0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41, 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D,
|
||||
0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89, 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555,
|
||||
0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31, 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED
|
||||
],
|
||||
[
|
||||
0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9,
|
||||
0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701, 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056,
|
||||
0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871, 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26,
|
||||
0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E, 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9,
|
||||
0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0, 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787,
|
||||
0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68,
|
||||
0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018,
|
||||
0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7,
|
||||
0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,
|
||||
0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B,
|
||||
0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C, 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B,
|
||||
0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3, 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4,
|
||||
0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED, 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA,
|
||||
0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002, 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755,
|
||||
0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825,
|
||||
0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA,
|
||||
0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82,
|
||||
0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,
|
||||
0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D,
|
||||
0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2,
|
||||
0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB, 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC,
|
||||
0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04, 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953,
|
||||
0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174, 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623,
|
||||
0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC,
|
||||
0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF,
|
||||
0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50,
|
||||
0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,
|
||||
0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF,
|
||||
0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981,
|
||||
0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,
|
||||
0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,
|
||||
0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1
|
||||
],
|
||||
[
|
||||
0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0, 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,
|
||||
0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111, 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,
|
||||
0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52, 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,
|
||||
0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693, 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053,
|
||||
0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4, 0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314,
|
||||
0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15, 0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5,
|
||||
0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256, 0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496,
|
||||
0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997, 0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57,
|
||||
0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299, 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,
|
||||
0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958, 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98,
|
||||
0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B, 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB,
|
||||
0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA, 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A,
|
||||
0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D, 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D,
|
||||
0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C, 0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C,
|
||||
0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F, 0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF,
|
||||
0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE, 0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E,
|
||||
0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42, 0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82,
|
||||
0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183, 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,
|
||||
0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0, 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00,
|
||||
0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601, 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1,
|
||||
0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546, 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386,
|
||||
0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87, 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847,
|
||||
0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4, 0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404,
|
||||
0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905, 0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5,
|
||||
0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B, 0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB,
|
||||
0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA, 0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A,
|
||||
0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589, 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,
|
||||
0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48, 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888,
|
||||
0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F, 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF,
|
||||
0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE, 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E,
|
||||
0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D, 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D,
|
||||
0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C, 0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C
|
||||
],
|
||||
[
|
||||
0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE, 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8,
|
||||
0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3, 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5,
|
||||
0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035, 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223,
|
||||
0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258, 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E,
|
||||
0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798, 0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E,
|
||||
0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5, 0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3,
|
||||
0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503, 0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715,
|
||||
0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E, 0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578,
|
||||
0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2, 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,
|
||||
0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF, 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9,
|
||||
0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59, 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F,
|
||||
0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834, 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22,
|
||||
0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4, 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2,
|
||||
0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99, 0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F,
|
||||
0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F, 0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79,
|
||||
0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02, 0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14,
|
||||
0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676, 0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460,
|
||||
0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B, 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,
|
||||
0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED, 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB,
|
||||
0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680, 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496,
|
||||
0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340, 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156,
|
||||
0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D, 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B,
|
||||
0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB, 0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD,
|
||||
0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6, 0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0,
|
||||
0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A, 0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C,
|
||||
0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77, 0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61,
|
||||
0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81, 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,
|
||||
0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC, 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA,
|
||||
0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C, 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A,
|
||||
0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41, 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957,
|
||||
0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7, 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1,
|
||||
0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA, 0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC
|
||||
],
|
||||
[
|
||||
0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D, 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E,
|
||||
0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA, 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9,
|
||||
0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653, 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240,
|
||||
0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834, 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27,
|
||||
0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301, 0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712,
|
||||
0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66, 0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975,
|
||||
0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF, 0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC,
|
||||
0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8, 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB,
|
||||
0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4, 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,
|
||||
0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183, 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590,
|
||||
0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A, 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739,
|
||||
0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D, 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E,
|
||||
0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678, 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B,
|
||||
0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F, 0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C,
|
||||
0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6, 0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5,
|
||||
0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1, 0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2,
|
||||
0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F, 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C,
|
||||
0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08, 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,
|
||||
0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1, 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2,
|
||||
0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6, 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5,
|
||||
0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3, 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0,
|
||||
0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794, 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387,
|
||||
0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D, 0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E,
|
||||
0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A, 0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49,
|
||||
0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516, 0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105,
|
||||
0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71, 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62,
|
||||
0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8, 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,
|
||||
0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF, 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC,
|
||||
0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A, 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899,
|
||||
0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED, 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE,
|
||||
0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044, 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457,
|
||||
0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23, 0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30
|
||||
],
|
||||
[
|
||||
0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3, 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919,
|
||||
0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56, 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC,
|
||||
0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8, 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832,
|
||||
0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D, 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387,
|
||||
0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5, 0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F,
|
||||
0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00, 0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA,
|
||||
0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E, 0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64,
|
||||
0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B, 0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1,
|
||||
0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E, 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,
|
||||
0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB, 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041,
|
||||
0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425, 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF,
|
||||
0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90, 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A,
|
||||
0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758, 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2,
|
||||
0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED, 0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217,
|
||||
0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673, 0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889,
|
||||
0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6, 0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C,
|
||||
0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239, 0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3,
|
||||
0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C, 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,
|
||||
0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312, 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8,
|
||||
0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7, 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D,
|
||||
0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F, 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95,
|
||||
0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA, 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520,
|
||||
0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144, 0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE,
|
||||
0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1, 0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B,
|
||||
0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4, 0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E,
|
||||
0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61, 0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B,
|
||||
0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF, 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,
|
||||
0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A, 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0,
|
||||
0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282, 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78,
|
||||
0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937, 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,
|
||||
0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9, 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,
|
||||
0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C, 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6
|
||||
]
|
||||
];
|
||||
|
||||
readonly uint _finalSeed;
|
||||
readonly IntPtr _nativeContext;
|
||||
readonly uint[][] _table;
|
||||
readonly bool _useIso;
|
||||
readonly bool _useNative;
|
||||
uint _hashInt;
|
||||
|
||||
/// <summary>Initializes the CRC32 table and seed as CRC32-ISO</summary>
|
||||
public Crc32Context()
|
||||
{
|
||||
_hashInt = CRC32_ISO_SEED;
|
||||
_finalSeed = CRC32_ISO_SEED;
|
||||
_table = ISOCrc32Table;
|
||||
_useIso = true;
|
||||
|
||||
_table = new uint[256];
|
||||
if(!Native.IsSupported) return;
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
{
|
||||
var entry = (uint)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ CRC32_ISO_POLY;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
_table[i] = entry;
|
||||
}
|
||||
_nativeContext = crc32_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>Initializes the CRC32 table with a custom polynomial and seed</summary>
|
||||
@@ -76,8 +354,34 @@ public sealed class Crc32Context : IChecksum
|
||||
{
|
||||
_hashInt = seed;
|
||||
_finalSeed = seed;
|
||||
_useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
|
||||
|
||||
_table = new uint[256];
|
||||
if(Native.IsSupported && _useIso)
|
||||
{
|
||||
_nativeContext = crc32_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
_table = GenerateTable(polynomial);
|
||||
}
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial IntPtr crc32_init();
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial int crc32_update(IntPtr ctx, byte[] data, uint len);
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial int crc32_final(IntPtr ctx, ref uint crc);
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial void crc32_free(IntPtr ctx);
|
||||
|
||||
static uint[][] GenerateTable(uint polynomial)
|
||||
{
|
||||
var table = new uint[8][];
|
||||
|
||||
for(var i = 0; i < 8; i++) table[i] = new uint[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
{
|
||||
@@ -91,42 +395,103 @@ public sealed class Crc32Context : IChecksum
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
_table[i] = entry;
|
||||
table[0][i] = entry;
|
||||
}
|
||||
|
||||
for(var slice = 1; slice < 8; slice++)
|
||||
{
|
||||
for(var i = 0; i < 256; i++)
|
||||
table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len)
|
||||
static void Step(ref uint previousCrc, uint[][] table, byte[] data, uint len, bool useIso, bool useNative,
|
||||
IntPtr nativeContext)
|
||||
{
|
||||
for(var i = 0; i < len; i++) _hashInt = _hashInt >> 8 ^ _table[data[i] ^ _hashInt & 0xff];
|
||||
}
|
||||
if(useNative && useIso)
|
||||
{
|
||||
crc32_update(nativeContext, data, len);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final() => BigEndianBitConverter.GetBytes(_hashInt ^ _finalSeed);
|
||||
var currentPos = 0;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
var crc32Output = new StringBuilder();
|
||||
if(useIso)
|
||||
{
|
||||
if(Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
|
||||
{
|
||||
// Only works in blocks of 16 bytes
|
||||
uint blocks = len / 64;
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(_hashInt ^ _finalSeed).Length; i++)
|
||||
crc32Output.Append(BigEndianBitConverter.GetBytes(_hashInt ^ _finalSeed)[i].ToString("x2"));
|
||||
if(blocks > 0)
|
||||
{
|
||||
previousCrc = ~Clmul.Step(data, blocks * 64, ~previousCrc);
|
||||
|
||||
return crc32Output.ToString();
|
||||
currentPos = (int)(blocks * 64);
|
||||
len -= blocks * 64;
|
||||
}
|
||||
|
||||
if(len == 0) return;
|
||||
}
|
||||
|
||||
if(Crc32.Arm64.IsSupported)
|
||||
{
|
||||
previousCrc = ArmSimd.Step64(data, len, previousCrc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(Crc32.IsSupported)
|
||||
{
|
||||
previousCrc = ArmSimd.Step32(data, len, previousCrc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unroll according to Intel slicing by uint8_t
|
||||
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
// http://sourceforge.net/projects/slicing-by-8/
|
||||
const int unroll = 4;
|
||||
const int bytesAtOnce = 8 * unroll;
|
||||
uint crc = previousCrc;
|
||||
|
||||
while(len >= bytesAtOnce)
|
||||
{
|
||||
int unrolling;
|
||||
|
||||
for(unrolling = 0; unrolling < unroll; unrolling++)
|
||||
{
|
||||
uint one = BitConverter.ToUInt32(data, currentPos) ^ crc;
|
||||
currentPos += 4;
|
||||
var two = BitConverter.ToUInt32(data, currentPos);
|
||||
currentPos += 4;
|
||||
|
||||
crc = table[0][two >> 24 & 0xFF] ^
|
||||
table[1][two >> 16 & 0xFF] ^
|
||||
table[2][two >> 8 & 0xFF] ^
|
||||
table[3][two & 0xFF] ^
|
||||
table[4][one >> 24 & 0xFF] ^
|
||||
table[5][one >> 16 & 0xFF] ^
|
||||
table[6][one >> 8 & 0xFF] ^
|
||||
table[7][one & 0xFF];
|
||||
}
|
||||
|
||||
len -= bytesAtOnce;
|
||||
}
|
||||
|
||||
while(len-- != 0) crc = crc >> 8 ^ table[0][crc & 0xFF ^ data[currentPos++]];
|
||||
|
||||
previousCrc = crc;
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
|
||||
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
File(filename, out byte[] hash);
|
||||
@@ -147,32 +512,41 @@ public sealed class Crc32Context : IChecksum
|
||||
/// <param name="seed">CRC seed</param>
|
||||
public static string File(string filename, out byte[] hash, uint polynomial, uint seed)
|
||||
{
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
uint localhashInt = seed;
|
||||
|
||||
var localTable = new uint[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
if(useNative && useIso)
|
||||
{
|
||||
var entry = (uint)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ polynomial;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
localTable[i] = entry;
|
||||
nativeContext = crc32_init();
|
||||
useNative = nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
for(var i = 0; i < fileStream.Length; i++)
|
||||
localhashInt = localhashInt >> 8 ^ localTable[fileStream.ReadByte() ^ localhashInt & 0xff];
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
|
||||
localhashInt ^= seed;
|
||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||
uint localHashInt = seed;
|
||||
|
||||
uint[][] localTable = GenerateTable(polynomial);
|
||||
|
||||
var buffer = new byte[65536];
|
||||
int read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
|
||||
while(read > 0)
|
||||
{
|
||||
Step(ref localHashInt, localTable, buffer, (uint)read, useIso, useNative, nativeContext);
|
||||
|
||||
read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
}
|
||||
|
||||
localHashInt ^= seed;
|
||||
|
||||
if(useNative && useIso)
|
||||
{
|
||||
crc32_final(nativeContext, ref localHashInt);
|
||||
crc32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(localHashInt);
|
||||
|
||||
var crc32Output = new StringBuilder();
|
||||
|
||||
@@ -198,29 +572,31 @@ public sealed class Crc32Context : IChecksum
|
||||
/// <param name="seed">CRC seed</param>
|
||||
public static string Data(byte[] data, uint len, out byte[] hash, uint polynomial, uint seed)
|
||||
{
|
||||
uint localhashInt = seed;
|
||||
bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
var localTable = new uint[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
if(useNative && useIso)
|
||||
{
|
||||
var entry = (uint)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ polynomial;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
localTable[i] = entry;
|
||||
nativeContext = crc32_init();
|
||||
useNative = nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
for(var i = 0; i < len; i++) localhashInt = localhashInt >> 8 ^ localTable[data[i] ^ localhashInt & 0xff];
|
||||
uint localHashInt = seed;
|
||||
|
||||
localhashInt ^= seed;
|
||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||
uint[][] localTable = GenerateTable(polynomial);
|
||||
|
||||
Step(ref localHashInt, localTable, data, len, useIso, useNative, nativeContext);
|
||||
|
||||
localHashInt ^= seed;
|
||||
|
||||
if(useNative && useIso)
|
||||
{
|
||||
crc32_final(nativeContext, ref localHashInt);
|
||||
crc32_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(localHashInt);
|
||||
|
||||
var crc32Output = new StringBuilder();
|
||||
|
||||
@@ -233,4 +609,63 @@ public sealed class Crc32Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.CRC32_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("BCC4E18A-79CD-4B52-8A57-2B599E5176B3");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) =>
|
||||
Step(ref _hashInt, _table, data, len, _useIso, _useNative, _nativeContext);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
uint crc = _hashInt ^ _finalSeed;
|
||||
|
||||
if(!_useNative || !_useIso) return BigEndianBitConverter.GetBytes(crc);
|
||||
|
||||
crc32_final(_nativeContext, ref crc);
|
||||
crc32_free(_nativeContext);
|
||||
|
||||
return BigEndianBitConverter.GetBytes(crc);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
uint crc = _hashInt ^ _finalSeed;
|
||||
|
||||
var crc32Output = new StringBuilder();
|
||||
|
||||
if(_useNative && _useIso)
|
||||
{
|
||||
crc32_final(_nativeContext, ref crc);
|
||||
crc32_free(_nativeContext);
|
||||
}
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
|
||||
crc32Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
|
||||
|
||||
return crc32Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
122
RomRepoMgr.Core/Checksums/CRC64/clmul.cs
Normal file
122
RomRepoMgr.Core/Checksums/CRC64/clmul.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : clmul.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Compute the CRC64 using a parallelized folding approach with the PCLMULQDQ
|
||||
// instruction.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This file is under the public domain:
|
||||
// https://github.com/rawrunprotected/crc
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums.CRC64;
|
||||
|
||||
static class Clmul
|
||||
{
|
||||
static readonly byte[] _shuffleMasks =
|
||||
[
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x8f, 0x8e,
|
||||
0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80
|
||||
];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static void ShiftRight128(Vector128<ulong> initial, uint n, out Vector128<ulong> outLeft,
|
||||
out Vector128<ulong> outRight)
|
||||
{
|
||||
uint maskPos = 16 - n;
|
||||
|
||||
var maskA = Vector128.Create(_shuffleMasks[maskPos],
|
||||
_shuffleMasks[maskPos + 1],
|
||||
_shuffleMasks[maskPos + 2],
|
||||
_shuffleMasks[maskPos + 3],
|
||||
_shuffleMasks[maskPos + 4],
|
||||
_shuffleMasks[maskPos + 5],
|
||||
_shuffleMasks[maskPos + 6],
|
||||
_shuffleMasks[maskPos + 7],
|
||||
_shuffleMasks[maskPos + 8],
|
||||
_shuffleMasks[maskPos + 9],
|
||||
_shuffleMasks[maskPos + 10],
|
||||
_shuffleMasks[maskPos + 11],
|
||||
_shuffleMasks[maskPos + 12],
|
||||
_shuffleMasks[maskPos + 13],
|
||||
_shuffleMasks[maskPos + 14],
|
||||
_shuffleMasks[maskPos + 15]);
|
||||
|
||||
Vector128<byte> maskB = Sse2.Xor(maskA, Sse2.CompareEqual(Vector128<byte>.Zero, Vector128<byte>.Zero));
|
||||
|
||||
outLeft = Ssse3.Shuffle(initial.AsByte(), maskB).AsUInt64();
|
||||
outRight = Ssse3.Shuffle(initial.AsByte(), maskA).AsUInt64();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
static Vector128<ulong> Fold(Vector128<ulong> input, Vector128<ulong> foldConstants) =>
|
||||
Sse2.Xor(Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x00),
|
||||
Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x11));
|
||||
|
||||
internal static ulong Step(ulong crc, byte[] data, uint length)
|
||||
{
|
||||
var bufPos = 16;
|
||||
const ulong k1 = 0xe05dd497ca393ae4;
|
||||
const ulong k2 = 0xdabe95afc7875f40;
|
||||
const ulong mu = 0x9c3e466c172963d5;
|
||||
const ulong pol = 0x92d8af2baf0e1e85;
|
||||
var foldConstants1 = Vector128.Create(k1, k2);
|
||||
var foldConstants2 = Vector128.Create(mu, pol);
|
||||
var initialCrc = Vector128.Create(~crc, 0);
|
||||
length -= 16;
|
||||
|
||||
// Initial CRC can simply be added to data
|
||||
ShiftRight128(initialCrc, 0, out Vector128<ulong> crc0, out Vector128<ulong> crc1);
|
||||
|
||||
Vector128<ulong> accumulator =
|
||||
Sse2.Xor(Fold(Sse2.Xor(crc0,
|
||||
Vector128.Create(BitConverter.ToUInt64(data, 0), BitConverter.ToUInt64(data, 8))),
|
||||
foldConstants1),
|
||||
crc1);
|
||||
|
||||
while(length >= 32)
|
||||
{
|
||||
accumulator =
|
||||
Fold(Sse2.Xor(Vector128.Create(BitConverter.ToUInt64(data, bufPos),
|
||||
BitConverter.ToUInt64(data, bufPos + 8)),
|
||||
accumulator),
|
||||
foldConstants1);
|
||||
|
||||
length -= 16;
|
||||
bufPos += 16;
|
||||
}
|
||||
|
||||
Vector128<ulong> p = Sse2.Xor(accumulator,
|
||||
Vector128.Create(BitConverter.ToUInt64(data, bufPos),
|
||||
BitConverter.ToUInt64(data, bufPos + 8)));
|
||||
|
||||
Vector128<ulong> r = Sse2.Xor(Pclmulqdq.CarrylessMultiply(p, foldConstants1, 0x10),
|
||||
Sse2.ShiftRightLogical128BitLane(p, 8));
|
||||
|
||||
// Final Barrett reduction
|
||||
Vector128<ulong> t1 = Pclmulqdq.CarrylessMultiply(r, foldConstants2, 0x00);
|
||||
|
||||
Vector128<ulong> t2 = Sse2.Xor(Sse2.Xor(Pclmulqdq.CarrylessMultiply(t1, foldConstants2, 0x10),
|
||||
Sse2.ShiftLeftLogical128BitLane(t1, 8)),
|
||||
r);
|
||||
|
||||
return ~((ulong)Sse41.Extract(t2.AsUInt32(), 3) << 32 | Sse41.Extract(t2.AsUInt32(), 2));
|
||||
}
|
||||
}
|
||||
@@ -27,57 +27,306 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Helpers;
|
||||
using RomRepoMgr.Core.Checksums.CRC64;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements a CRC64 algorithm</summary>
|
||||
public sealed class Crc64Context : IChecksum
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
public sealed partial class Crc64Context : IChecksum
|
||||
{
|
||||
/// <summary>ECMA CRC64 polynomial</summary>
|
||||
const ulong CRC64_ECMA_POLY = 0xC96C5795D7870F42;
|
||||
/// <summary>ECMA CRC64 seed</summary>
|
||||
const ulong CRC64_ECMA_SEED = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
readonly ulong _finalSeed;
|
||||
readonly ulong[] _table;
|
||||
ulong _hashInt;
|
||||
static readonly ulong[][] _ecmaCrc64Table =
|
||||
[
|
||||
[
|
||||
0x0000000000000000, 0xB32E4CBE03A75F6F, 0xF4843657A840A05B, 0x47AA7AE9ABE7FF34, 0x7BD0C384FF8F5E33,
|
||||
0xC8FE8F3AFC28015C, 0x8F54F5D357CFFE68, 0x3C7AB96D5468A107, 0xF7A18709FF1EBC66, 0x448FCBB7FCB9E309,
|
||||
0x0325B15E575E1C3D, 0xB00BFDE054F94352, 0x8C71448D0091E255, 0x3F5F08330336BD3A, 0x78F572DAA8D1420E,
|
||||
0xCBDB3E64AB761D61, 0x7D9BA13851336649, 0xCEB5ED8652943926, 0x891F976FF973C612, 0x3A31DBD1FAD4997D,
|
||||
0x064B62BCAEBC387A, 0xB5652E02AD1B6715, 0xF2CF54EB06FC9821, 0x41E11855055BC74E, 0x8A3A2631AE2DDA2F,
|
||||
0x39146A8FAD8A8540, 0x7EBE1066066D7A74, 0xCD905CD805CA251B, 0xF1EAE5B551A2841C, 0x42C4A90B5205DB73,
|
||||
0x056ED3E2F9E22447, 0xB6409F5CFA457B28, 0xFB374270A266CC92, 0x48190ECEA1C193FD, 0x0FB374270A266CC9,
|
||||
0xBC9D3899098133A6, 0x80E781F45DE992A1, 0x33C9CD4A5E4ECDCE, 0x7463B7A3F5A932FA, 0xC74DFB1DF60E6D95,
|
||||
0x0C96C5795D7870F4, 0xBFB889C75EDF2F9B, 0xF812F32EF538D0AF, 0x4B3CBF90F69F8FC0, 0x774606FDA2F72EC7,
|
||||
0xC4684A43A15071A8, 0x83C230AA0AB78E9C, 0x30EC7C140910D1F3, 0x86ACE348F355AADB, 0x3582AFF6F0F2F5B4,
|
||||
0x7228D51F5B150A80, 0xC10699A158B255EF, 0xFD7C20CC0CDAF4E8, 0x4E526C720F7DAB87, 0x09F8169BA49A54B3,
|
||||
0xBAD65A25A73D0BDC, 0x710D64410C4B16BD, 0xC22328FF0FEC49D2, 0x85895216A40BB6E6, 0x36A71EA8A7ACE989,
|
||||
0x0ADDA7C5F3C4488E, 0xB9F3EB7BF06317E1, 0xFE5991925B84E8D5, 0x4D77DD2C5823B7BA, 0x64B62BCAEBC387A1,
|
||||
0xD7986774E864D8CE, 0x90321D9D438327FA, 0x231C512340247895, 0x1F66E84E144CD992, 0xAC48A4F017EB86FD,
|
||||
0xEBE2DE19BC0C79C9, 0x58CC92A7BFAB26A6, 0x9317ACC314DD3BC7, 0x2039E07D177A64A8, 0x67939A94BC9D9B9C,
|
||||
0xD4BDD62ABF3AC4F3, 0xE8C76F47EB5265F4, 0x5BE923F9E8F53A9B, 0x1C4359104312C5AF, 0xAF6D15AE40B59AC0,
|
||||
0x192D8AF2BAF0E1E8, 0xAA03C64CB957BE87, 0xEDA9BCA512B041B3, 0x5E87F01B11171EDC, 0x62FD4976457FBFDB,
|
||||
0xD1D305C846D8E0B4, 0x96797F21ED3F1F80, 0x2557339FEE9840EF, 0xEE8C0DFB45EE5D8E, 0x5DA24145464902E1,
|
||||
0x1A083BACEDAEFDD5, 0xA9267712EE09A2BA, 0x955CCE7FBA6103BD, 0x267282C1B9C65CD2, 0x61D8F8281221A3E6,
|
||||
0xD2F6B4961186FC89, 0x9F8169BA49A54B33, 0x2CAF25044A02145C, 0x6B055FEDE1E5EB68, 0xD82B1353E242B407,
|
||||
0xE451AA3EB62A1500, 0x577FE680B58D4A6F, 0x10D59C691E6AB55B, 0xA3FBD0D71DCDEA34, 0x6820EEB3B6BBF755,
|
||||
0xDB0EA20DB51CA83A, 0x9CA4D8E41EFB570E, 0x2F8A945A1D5C0861, 0x13F02D374934A966, 0xA0DE61894A93F609,
|
||||
0xE7741B60E174093D, 0x545A57DEE2D35652, 0xE21AC88218962D7A, 0x5134843C1B317215, 0x169EFED5B0D68D21,
|
||||
0xA5B0B26BB371D24E, 0x99CA0B06E7197349, 0x2AE447B8E4BE2C26, 0x6D4E3D514F59D312, 0xDE6071EF4CFE8C7D,
|
||||
0x15BB4F8BE788911C, 0xA6950335E42FCE73, 0xE13F79DC4FC83147, 0x521135624C6F6E28, 0x6E6B8C0F1807CF2F,
|
||||
0xDD45C0B11BA09040, 0x9AEFBA58B0476F74, 0x29C1F6E6B3E0301B, 0xC96C5795D7870F42, 0x7A421B2BD420502D,
|
||||
0x3DE861C27FC7AF19, 0x8EC62D7C7C60F076, 0xB2BC941128085171, 0x0192D8AF2BAF0E1E, 0x4638A2468048F12A,
|
||||
0xF516EEF883EFAE45, 0x3ECDD09C2899B324, 0x8DE39C222B3EEC4B, 0xCA49E6CB80D9137F, 0x7967AA75837E4C10,
|
||||
0x451D1318D716ED17, 0xF6335FA6D4B1B278, 0xB199254F7F564D4C, 0x02B769F17CF11223, 0xB4F7F6AD86B4690B,
|
||||
0x07D9BA1385133664, 0x4073C0FA2EF4C950, 0xF35D8C442D53963F, 0xCF273529793B3738, 0x7C0979977A9C6857,
|
||||
0x3BA3037ED17B9763, 0x888D4FC0D2DCC80C, 0x435671A479AAD56D, 0xF0783D1A7A0D8A02, 0xB7D247F3D1EA7536,
|
||||
0x04FC0B4DD24D2A59, 0x3886B22086258B5E, 0x8BA8FE9E8582D431, 0xCC0284772E652B05, 0x7F2CC8C92DC2746A,
|
||||
0x325B15E575E1C3D0, 0x8175595B76469CBF, 0xC6DF23B2DDA1638B, 0x75F16F0CDE063CE4, 0x498BD6618A6E9DE3,
|
||||
0xFAA59ADF89C9C28C, 0xBD0FE036222E3DB8, 0x0E21AC88218962D7, 0xC5FA92EC8AFF7FB6, 0x76D4DE52895820D9,
|
||||
0x317EA4BB22BFDFED, 0x8250E80521188082, 0xBE2A516875702185, 0x0D041DD676D77EEA, 0x4AAE673FDD3081DE,
|
||||
0xF9802B81DE97DEB1, 0x4FC0B4DD24D2A599, 0xFCEEF8632775FAF6, 0xBB44828A8C9205C2, 0x086ACE348F355AAD,
|
||||
0x34107759DB5DFBAA, 0x873E3BE7D8FAA4C5, 0xC094410E731D5BF1, 0x73BA0DB070BA049E, 0xB86133D4DBCC19FF,
|
||||
0x0B4F7F6AD86B4690, 0x4CE50583738CB9A4, 0xFFCB493D702BE6CB, 0xC3B1F050244347CC, 0x709FBCEE27E418A3,
|
||||
0x3735C6078C03E797, 0x841B8AB98FA4B8F8, 0xADDA7C5F3C4488E3, 0x1EF430E13FE3D78C, 0x595E4A08940428B8,
|
||||
0xEA7006B697A377D7, 0xD60ABFDBC3CBD6D0, 0x6524F365C06C89BF, 0x228E898C6B8B768B, 0x91A0C532682C29E4,
|
||||
0x5A7BFB56C35A3485, 0xE955B7E8C0FD6BEA, 0xAEFFCD016B1A94DE, 0x1DD181BF68BDCBB1, 0x21AB38D23CD56AB6,
|
||||
0x9285746C3F7235D9, 0xD52F0E859495CAED, 0x6601423B97329582, 0xD041DD676D77EEAA, 0x636F91D96ED0B1C5,
|
||||
0x24C5EB30C5374EF1, 0x97EBA78EC690119E, 0xAB911EE392F8B099, 0x18BF525D915FEFF6, 0x5F1528B43AB810C2,
|
||||
0xEC3B640A391F4FAD, 0x27E05A6E926952CC, 0x94CE16D091CE0DA3, 0xD3646C393A29F297, 0x604A2087398EADF8,
|
||||
0x5C3099EA6DE60CFF, 0xEF1ED5546E415390, 0xA8B4AFBDC5A6ACA4, 0x1B9AE303C601F3CB, 0x56ED3E2F9E224471,
|
||||
0xE5C372919D851B1E, 0xA26908783662E42A, 0x114744C635C5BB45, 0x2D3DFDAB61AD1A42, 0x9E13B115620A452D,
|
||||
0xD9B9CBFCC9EDBA19, 0x6A978742CA4AE576, 0xA14CB926613CF817, 0x1262F598629BA778, 0x55C88F71C97C584C,
|
||||
0xE6E6C3CFCADB0723, 0xDA9C7AA29EB3A624, 0x69B2361C9D14F94B, 0x2E184CF536F3067F, 0x9D36004B35545910,
|
||||
0x2B769F17CF112238, 0x9858D3A9CCB67D57, 0xDFF2A94067518263, 0x6CDCE5FE64F6DD0C, 0x50A65C93309E7C0B,
|
||||
0xE388102D33392364, 0xA4226AC498DEDC50, 0x170C267A9B79833F, 0xDCD7181E300F9E5E, 0x6FF954A033A8C131,
|
||||
0x28532E49984F3E05, 0x9B7D62F79BE8616A, 0xA707DB9ACF80C06D, 0x14299724CC279F02, 0x5383EDCD67C06036,
|
||||
0xE0ADA17364673F59
|
||||
],
|
||||
[
|
||||
0x0000000000000000, 0x54E979925CD0F10D, 0xA9D2F324B9A1E21A, 0xFD3B8AB6E5711317, 0xC17D4962DC4DDAB1,
|
||||
0x959430F0809D2BBC, 0x68AFBA4665EC38AB, 0x3C46C3D4393CC9A6, 0x10223DEE1795ABE7, 0x44CB447C4B455AEA,
|
||||
0xB9F0CECAAE3449FD, 0xED19B758F2E4B8F0, 0xD15F748CCBD87156, 0x85B60D1E9708805B, 0x788D87A87279934C,
|
||||
0x2C64FE3A2EA96241, 0x20447BDC2F2B57CE, 0x74AD024E73FBA6C3, 0x899688F8968AB5D4, 0xDD7FF16ACA5A44D9,
|
||||
0xE13932BEF3668D7F, 0xB5D04B2CAFB67C72, 0x48EBC19A4AC76F65, 0x1C02B80816179E68, 0x3066463238BEFC29,
|
||||
0x648F3FA0646E0D24, 0x99B4B516811F1E33, 0xCD5DCC84DDCFEF3E, 0xF11B0F50E4F32698, 0xA5F276C2B823D795,
|
||||
0x58C9FC745D52C482, 0x0C2085E60182358F, 0x4088F7B85E56AF9C, 0x14618E2A02865E91, 0xE95A049CE7F74D86,
|
||||
0xBDB37D0EBB27BC8B, 0x81F5BEDA821B752D, 0xD51CC748DECB8420, 0x28274DFE3BBA9737, 0x7CCE346C676A663A,
|
||||
0x50AACA5649C3047B, 0x0443B3C41513F576, 0xF9783972F062E661, 0xAD9140E0ACB2176C, 0x91D78334958EDECA,
|
||||
0xC53EFAA6C95E2FC7, 0x380570102C2F3CD0, 0x6CEC098270FFCDDD, 0x60CC8C64717DF852, 0x3425F5F62DAD095F,
|
||||
0xC91E7F40C8DC1A48, 0x9DF706D2940CEB45, 0xA1B1C506AD3022E3, 0xF558BC94F1E0D3EE, 0x086336221491C0F9,
|
||||
0x5C8A4FB0484131F4, 0x70EEB18A66E853B5, 0x2407C8183A38A2B8, 0xD93C42AEDF49B1AF, 0x8DD53B3C839940A2,
|
||||
0xB193F8E8BAA58904, 0xE57A817AE6757809, 0x18410BCC03046B1E, 0x4CA8725E5FD49A13, 0x8111EF70BCAD5F38,
|
||||
0xD5F896E2E07DAE35, 0x28C31C54050CBD22, 0x7C2A65C659DC4C2F, 0x406CA61260E08589, 0x1485DF803C307484,
|
||||
0xE9BE5536D9416793, 0xBD572CA48591969E, 0x9133D29EAB38F4DF, 0xC5DAAB0CF7E805D2, 0x38E121BA129916C5,
|
||||
0x6C0858284E49E7C8, 0x504E9BFC77752E6E, 0x04A7E26E2BA5DF63, 0xF99C68D8CED4CC74, 0xAD75114A92043D79,
|
||||
0xA15594AC938608F6, 0xF5BCED3ECF56F9FB, 0x088767882A27EAEC, 0x5C6E1E1A76F71BE1, 0x6028DDCE4FCBD247,
|
||||
0x34C1A45C131B234A, 0xC9FA2EEAF66A305D, 0x9D135778AABAC150, 0xB177A9428413A311, 0xE59ED0D0D8C3521C,
|
||||
0x18A55A663DB2410B, 0x4C4C23F46162B006, 0x700AE020585E79A0, 0x24E399B2048E88AD, 0xD9D81304E1FF9BBA,
|
||||
0x8D316A96BD2F6AB7, 0xC19918C8E2FBF0A4, 0x9570615ABE2B01A9, 0x684BEBEC5B5A12BE, 0x3CA2927E078AE3B3,
|
||||
0x00E451AA3EB62A15, 0x540D28386266DB18, 0xA936A28E8717C80F, 0xFDDFDB1CDBC73902, 0xD1BB2526F56E5B43,
|
||||
0x85525CB4A9BEAA4E, 0x7869D6024CCFB959, 0x2C80AF90101F4854, 0x10C66C44292381F2, 0x442F15D675F370FF,
|
||||
0xB9149F60908263E8, 0xEDFDE6F2CC5292E5, 0xE1DD6314CDD0A76A, 0xB5341A8691005667, 0x480F903074714570,
|
||||
0x1CE6E9A228A1B47D, 0x20A02A76119D7DDB, 0x744953E44D4D8CD6, 0x8972D952A83C9FC1, 0xDD9BA0C0F4EC6ECC,
|
||||
0xF1FF5EFADA450C8D, 0xA51627688695FD80, 0x582DADDE63E4EE97, 0x0CC4D44C3F341F9A, 0x308217980608D63C,
|
||||
0x646B6E0A5AD82731, 0x9950E4BCBFA93426, 0xCDB99D2EE379C52B, 0x90FB71CAD654A0F5, 0xC41208588A8451F8,
|
||||
0x392982EE6FF542EF, 0x6DC0FB7C3325B3E2, 0x518638A80A197A44, 0x056F413A56C98B49, 0xF854CB8CB3B8985E,
|
||||
0xACBDB21EEF686953, 0x80D94C24C1C10B12, 0xD43035B69D11FA1F, 0x290BBF007860E908, 0x7DE2C69224B01805,
|
||||
0x41A405461D8CD1A3, 0x154D7CD4415C20AE, 0xE876F662A42D33B9, 0xBC9F8FF0F8FDC2B4, 0xB0BF0A16F97FF73B,
|
||||
0xE4567384A5AF0636, 0x196DF93240DE1521, 0x4D8480A01C0EE42C, 0x71C2437425322D8A, 0x252B3AE679E2DC87,
|
||||
0xD810B0509C93CF90, 0x8CF9C9C2C0433E9D, 0xA09D37F8EEEA5CDC, 0xF4744E6AB23AADD1, 0x094FC4DC574BBEC6,
|
||||
0x5DA6BD4E0B9B4FCB, 0x61E07E9A32A7866D, 0x350907086E777760, 0xC8328DBE8B066477, 0x9CDBF42CD7D6957A,
|
||||
0xD073867288020F69, 0x849AFFE0D4D2FE64, 0x79A1755631A3ED73, 0x2D480CC46D731C7E, 0x110ECF10544FD5D8,
|
||||
0x45E7B682089F24D5, 0xB8DC3C34EDEE37C2, 0xEC3545A6B13EC6CF, 0xC051BB9C9F97A48E, 0x94B8C20EC3475583,
|
||||
0x698348B826364694, 0x3D6A312A7AE6B799, 0x012CF2FE43DA7E3F, 0x55C58B6C1F0A8F32, 0xA8FE01DAFA7B9C25,
|
||||
0xFC177848A6AB6D28, 0xF037FDAEA72958A7, 0xA4DE843CFBF9A9AA, 0x59E50E8A1E88BABD, 0x0D0C771842584BB0,
|
||||
0x314AB4CC7B648216, 0x65A3CD5E27B4731B, 0x989847E8C2C5600C, 0xCC713E7A9E159101, 0xE015C040B0BCF340,
|
||||
0xB4FCB9D2EC6C024D, 0x49C73364091D115A, 0x1D2E4AF655CDE057, 0x216889226CF129F1, 0x7581F0B03021D8FC,
|
||||
0x88BA7A06D550CBEB, 0xDC53039489803AE6, 0x11EA9EBA6AF9FFCD, 0x4503E72836290EC0, 0xB8386D9ED3581DD7,
|
||||
0xECD1140C8F88ECDA, 0xD097D7D8B6B4257C, 0x847EAE4AEA64D471, 0x794524FC0F15C766, 0x2DAC5D6E53C5366B,
|
||||
0x01C8A3547D6C542A, 0x5521DAC621BCA527, 0xA81A5070C4CDB630, 0xFCF329E2981D473D, 0xC0B5EA36A1218E9B,
|
||||
0x945C93A4FDF17F96, 0x6967191218806C81, 0x3D8E608044509D8C, 0x31AEE56645D2A803, 0x65479CF41902590E,
|
||||
0x987C1642FC734A19, 0xCC956FD0A0A3BB14, 0xF0D3AC04999F72B2, 0xA43AD596C54F83BF, 0x59015F20203E90A8,
|
||||
0x0DE826B27CEE61A5, 0x218CD888524703E4, 0x7565A11A0E97F2E9, 0x885E2BACEBE6E1FE, 0xDCB7523EB73610F3,
|
||||
0xE0F191EA8E0AD955, 0xB418E878D2DA2858, 0x492362CE37AB3B4F, 0x1DCA1B5C6B7BCA42, 0x5162690234AF5051,
|
||||
0x058B1090687FA15C, 0xF8B09A268D0EB24B, 0xAC59E3B4D1DE4346, 0x901F2060E8E28AE0, 0xC4F659F2B4327BED,
|
||||
0x39CDD344514368FA, 0x6D24AAD60D9399F7, 0x414054EC233AFBB6, 0x15A92D7E7FEA0ABB, 0xE892A7C89A9B19AC,
|
||||
0xBC7BDE5AC64BE8A1, 0x803D1D8EFF772107, 0xD4D4641CA3A7D00A, 0x29EFEEAA46D6C31D, 0x7D0697381A063210,
|
||||
0x712612DE1B84079F, 0x25CF6B4C4754F692, 0xD8F4E1FAA225E585, 0x8C1D9868FEF51488, 0xB05B5BBCC7C9DD2E,
|
||||
0xE4B2222E9B192C23, 0x1989A8987E683F34, 0x4D60D10A22B8CE39, 0x61042F300C11AC78, 0x35ED56A250C15D75,
|
||||
0xC8D6DC14B5B04E62, 0x9C3FA586E960BF6F, 0xA0796652D05C76C9, 0xF4901FC08C8C87C4, 0x09AB957669FD94D3,
|
||||
0x5D42ECE4352D65DE
|
||||
],
|
||||
[
|
||||
0x0000000000000000, 0x3F0BE14A916A6DCB, 0x7E17C29522D4DB96, 0x411C23DFB3BEB65D, 0xFC2F852A45A9B72C,
|
||||
0xC3246460D4C3DAE7, 0x823847BF677D6CBA, 0xBD33A6F5F6170171, 0x6A87A57F245D70DD, 0x558C4435B5371D16,
|
||||
0x149067EA0689AB4B, 0x2B9B86A097E3C680, 0x96A8205561F4C7F1, 0xA9A3C11FF09EAA3A, 0xE8BFE2C043201C67,
|
||||
0xD7B4038AD24A71AC, 0xD50F4AFE48BAE1BA, 0xEA04ABB4D9D08C71, 0xAB18886B6A6E3A2C, 0x94136921FB0457E7,
|
||||
0x2920CFD40D135696, 0x162B2E9E9C793B5D, 0x57370D412FC78D00, 0x683CEC0BBEADE0CB, 0xBF88EF816CE79167,
|
||||
0x80830ECBFD8DFCAC, 0xC19F2D144E334AF1, 0xFE94CC5EDF59273A, 0x43A76AAB294E264B, 0x7CAC8BE1B8244B80,
|
||||
0x3DB0A83E0B9AFDDD, 0x02BB49749AF09016, 0x38C63AD73E7BDDF1, 0x07CDDB9DAF11B03A, 0x46D1F8421CAF0667,
|
||||
0x79DA19088DC56BAC, 0xC4E9BFFD7BD26ADD, 0xFBE25EB7EAB80716, 0xBAFE7D685906B14B, 0x85F59C22C86CDC80,
|
||||
0x52419FA81A26AD2C, 0x6D4A7EE28B4CC0E7, 0x2C565D3D38F276BA, 0x135DBC77A9981B71, 0xAE6E1A825F8F1A00,
|
||||
0x9165FBC8CEE577CB, 0xD079D8177D5BC196, 0xEF72395DEC31AC5D, 0xEDC9702976C13C4B, 0xD2C29163E7AB5180,
|
||||
0x93DEB2BC5415E7DD, 0xACD553F6C57F8A16, 0x11E6F50333688B67, 0x2EED1449A202E6AC, 0x6FF1379611BC50F1,
|
||||
0x50FAD6DC80D63D3A, 0x874ED556529C4C96, 0xB845341CC3F6215D, 0xF95917C370489700, 0xC652F689E122FACB,
|
||||
0x7B61507C1735FBBA, 0x446AB136865F9671, 0x057692E935E1202C, 0x3A7D73A3A48B4DE7, 0x718C75AE7CF7BBE2,
|
||||
0x4E8794E4ED9DD629, 0x0F9BB73B5E236074, 0x30905671CF490DBF, 0x8DA3F084395E0CCE, 0xB2A811CEA8346105,
|
||||
0xF3B432111B8AD758, 0xCCBFD35B8AE0BA93, 0x1B0BD0D158AACB3F, 0x2400319BC9C0A6F4, 0x651C12447A7E10A9,
|
||||
0x5A17F30EEB147D62, 0xE72455FB1D037C13, 0xD82FB4B18C6911D8, 0x9933976E3FD7A785, 0xA6387624AEBDCA4E,
|
||||
0xA4833F50344D5A58, 0x9B88DE1AA5273793, 0xDA94FDC5169981CE, 0xE59F1C8F87F3EC05, 0x58ACBA7A71E4ED74,
|
||||
0x67A75B30E08E80BF, 0x26BB78EF533036E2, 0x19B099A5C25A5B29, 0xCE049A2F10102A85, 0xF10F7B65817A474E,
|
||||
0xB01358BA32C4F113, 0x8F18B9F0A3AE9CD8, 0x322B1F0555B99DA9, 0x0D20FE4FC4D3F062, 0x4C3CDD90776D463F,
|
||||
0x73373CDAE6072BF4, 0x494A4F79428C6613, 0x7641AE33D3E60BD8, 0x375D8DEC6058BD85, 0x08566CA6F132D04E,
|
||||
0xB565CA530725D13F, 0x8A6E2B19964FBCF4, 0xCB7208C625F10AA9, 0xF479E98CB49B6762, 0x23CDEA0666D116CE,
|
||||
0x1CC60B4CF7BB7B05, 0x5DDA28934405CD58, 0x62D1C9D9D56FA093, 0xDFE26F2C2378A1E2, 0xE0E98E66B212CC29,
|
||||
0xA1F5ADB901AC7A74, 0x9EFE4CF390C617BF, 0x9C4505870A3687A9, 0xA34EE4CD9B5CEA62, 0xE252C71228E25C3F,
|
||||
0xDD592658B98831F4, 0x606A80AD4F9F3085, 0x5F6161E7DEF55D4E, 0x1E7D42386D4BEB13, 0x2176A372FC2186D8,
|
||||
0xF6C2A0F82E6BF774, 0xC9C941B2BF019ABF, 0x88D5626D0CBF2CE2, 0xB7DE83279DD54129, 0x0AED25D26BC24058,
|
||||
0x35E6C498FAA82D93, 0x74FAE74749169BCE, 0x4BF1060DD87CF605, 0xE318EB5CF9EF77C4, 0xDC130A1668851A0F,
|
||||
0x9D0F29C9DB3BAC52, 0xA204C8834A51C199, 0x1F376E76BC46C0E8, 0x203C8F3C2D2CAD23, 0x6120ACE39E921B7E,
|
||||
0x5E2B4DA90FF876B5, 0x899F4E23DDB20719, 0xB694AF694CD86AD2, 0xF7888CB6FF66DC8F, 0xC8836DFC6E0CB144,
|
||||
0x75B0CB09981BB035, 0x4ABB2A430971DDFE, 0x0BA7099CBACF6BA3, 0x34ACE8D62BA50668, 0x3617A1A2B155967E,
|
||||
0x091C40E8203FFBB5, 0x4800633793814DE8, 0x770B827D02EB2023, 0xCA382488F4FC2152, 0xF533C5C265964C99,
|
||||
0xB42FE61DD628FAC4, 0x8B2407574742970F, 0x5C9004DD9508E6A3, 0x639BE59704628B68, 0x2287C648B7DC3D35,
|
||||
0x1D8C270226B650FE, 0xA0BF81F7D0A1518F, 0x9FB460BD41CB3C44, 0xDEA84362F2758A19, 0xE1A3A228631FE7D2,
|
||||
0xDBDED18BC794AA35, 0xE4D530C156FEC7FE, 0xA5C9131EE54071A3, 0x9AC2F254742A1C68, 0x27F154A1823D1D19,
|
||||
0x18FAB5EB135770D2, 0x59E69634A0E9C68F, 0x66ED777E3183AB44, 0xB15974F4E3C9DAE8, 0x8E5295BE72A3B723,
|
||||
0xCF4EB661C11D017E, 0xF045572B50776CB5, 0x4D76F1DEA6606DC4, 0x727D1094370A000F, 0x3361334B84B4B652,
|
||||
0x0C6AD20115DEDB99, 0x0ED19B758F2E4B8F, 0x31DA7A3F1E442644, 0x70C659E0ADFA9019, 0x4FCDB8AA3C90FDD2,
|
||||
0xF2FE1E5FCA87FCA3, 0xCDF5FF155BED9168, 0x8CE9DCCAE8532735, 0xB3E23D8079394AFE, 0x64563E0AAB733B52,
|
||||
0x5B5DDF403A195699, 0x1A41FC9F89A7E0C4, 0x254A1DD518CD8D0F, 0x9879BB20EEDA8C7E, 0xA7725A6A7FB0E1B5,
|
||||
0xE66E79B5CC0E57E8, 0xD96598FF5D643A23, 0x92949EF28518CC26, 0xAD9F7FB81472A1ED, 0xEC835C67A7CC17B0,
|
||||
0xD388BD2D36A67A7B, 0x6EBB1BD8C0B17B0A, 0x51B0FA9251DB16C1, 0x10ACD94DE265A09C, 0x2FA73807730FCD57,
|
||||
0xF8133B8DA145BCFB, 0xC718DAC7302FD130, 0x8604F9188391676D, 0xB90F185212FB0AA6, 0x043CBEA7E4EC0BD7,
|
||||
0x3B375FED7586661C, 0x7A2B7C32C638D041, 0x45209D785752BD8A, 0x479BD40CCDA22D9C, 0x789035465CC84057,
|
||||
0x398C1699EF76F60A, 0x0687F7D37E1C9BC1, 0xBBB45126880B9AB0, 0x84BFB06C1961F77B, 0xC5A393B3AADF4126,
|
||||
0xFAA872F93BB52CED, 0x2D1C7173E9FF5D41, 0x121790397895308A, 0x530BB3E6CB2B86D7, 0x6C0052AC5A41EB1C,
|
||||
0xD133F459AC56EA6D, 0xEE3815133D3C87A6, 0xAF2436CC8E8231FB, 0x902FD7861FE85C30, 0xAA52A425BB6311D7,
|
||||
0x9559456F2A097C1C, 0xD44566B099B7CA41, 0xEB4E87FA08DDA78A, 0x567D210FFECAA6FB, 0x6976C0456FA0CB30,
|
||||
0x286AE39ADC1E7D6D, 0x176102D04D7410A6, 0xC0D5015A9F3E610A, 0xFFDEE0100E540CC1, 0xBEC2C3CFBDEABA9C,
|
||||
0x81C922852C80D757, 0x3CFA8470DA97D626, 0x03F1653A4BFDBBED, 0x42ED46E5F8430DB0, 0x7DE6A7AF6929607B,
|
||||
0x7F5DEEDBF3D9F06D, 0x40560F9162B39DA6, 0x014A2C4ED10D2BFB, 0x3E41CD0440674630, 0x83726BF1B6704741,
|
||||
0xBC798ABB271A2A8A, 0xFD65A96494A49CD7, 0xC26E482E05CEF11C, 0x15DA4BA4D78480B0, 0x2AD1AAEE46EEED7B,
|
||||
0x6BCD8931F5505B26, 0x54C6687B643A36ED, 0xE9F5CE8E922D379C, 0xD6FE2FC403475A57, 0x97E20C1BB0F9EC0A,
|
||||
0xA8E9ED51219381C1
|
||||
],
|
||||
[
|
||||
0x0000000000000000, 0x1DEE8A5E222CA1DC, 0x3BDD14BC445943B8, 0x26339EE26675E264, 0x77BA297888B28770,
|
||||
0x6A54A326AA9E26AC, 0x4C673DC4CCEBC4C8, 0x5189B79AEEC76514, 0xEF7452F111650EE0, 0xF29AD8AF3349AF3C,
|
||||
0xD4A9464D553C4D58, 0xC947CC137710EC84, 0x98CE7B8999D78990, 0x8520F1D7BBFB284C, 0xA3136F35DD8ECA28,
|
||||
0xBEFDE56BFFA26BF4, 0x4C300AC98DC40345, 0x51DE8097AFE8A299, 0x77ED1E75C99D40FD, 0x6A03942BEBB1E121,
|
||||
0x3B8A23B105768435, 0x2664A9EF275A25E9, 0x0057370D412FC78D, 0x1DB9BD5363036651, 0xA34458389CA10DA5,
|
||||
0xBEAAD266BE8DAC79, 0x98994C84D8F84E1D, 0x8577C6DAFAD4EFC1, 0xD4FE714014138AD5, 0xC910FB1E363F2B09,
|
||||
0xEF2365FC504AC96D, 0xF2CDEFA2726668B1, 0x986015931B88068A, 0x858E9FCD39A4A756, 0xA3BD012F5FD14532,
|
||||
0xBE538B717DFDE4EE, 0xEFDA3CEB933A81FA, 0xF234B6B5B1162026, 0xD4072857D763C242, 0xC9E9A209F54F639E,
|
||||
0x771447620AED086A, 0x6AFACD3C28C1A9B6, 0x4CC953DE4EB44BD2, 0x5127D9806C98EA0E, 0x00AE6E1A825F8F1A,
|
||||
0x1D40E444A0732EC6, 0x3B737AA6C606CCA2, 0x269DF0F8E42A6D7E, 0xD4501F5A964C05CF, 0xC9BE9504B460A413,
|
||||
0xEF8D0BE6D2154677, 0xF26381B8F039E7AB, 0xA3EA36221EFE82BF, 0xBE04BC7C3CD22363, 0x9837229E5AA7C107,
|
||||
0x85D9A8C0788B60DB, 0x3B244DAB87290B2F, 0x26CAC7F5A505AAF3, 0x00F95917C3704897, 0x1D17D349E15CE94B,
|
||||
0x4C9E64D30F9B8C5F, 0x5170EE8D2DB72D83, 0x7743706F4BC2CFE7, 0x6AADFA3169EE6E3B, 0xA218840D981E1391,
|
||||
0xBFF60E53BA32B24D, 0x99C590B1DC475029, 0x842B1AEFFE6BF1F5, 0xD5A2AD7510AC94E1, 0xC84C272B3280353D,
|
||||
0xEE7FB9C954F5D759, 0xF391339776D97685, 0x4D6CD6FC897B1D71, 0x50825CA2AB57BCAD, 0x76B1C240CD225EC9,
|
||||
0x6B5F481EEF0EFF15, 0x3AD6FF8401C99A01, 0x273875DA23E53BDD, 0x010BEB384590D9B9, 0x1CE5616667BC7865,
|
||||
0xEE288EC415DA10D4, 0xF3C6049A37F6B108, 0xD5F59A785183536C, 0xC81B102673AFF2B0, 0x9992A7BC9D6897A4,
|
||||
0x847C2DE2BF443678, 0xA24FB300D931D41C, 0xBFA1395EFB1D75C0, 0x015CDC3504BF1E34, 0x1CB2566B2693BFE8,
|
||||
0x3A81C88940E65D8C, 0x276F42D762CAFC50, 0x76E6F54D8C0D9944, 0x6B087F13AE213898, 0x4D3BE1F1C854DAFC,
|
||||
0x50D56BAFEA787B20, 0x3A78919E8396151B, 0x27961BC0A1BAB4C7, 0x01A58522C7CF56A3, 0x1C4B0F7CE5E3F77F,
|
||||
0x4DC2B8E60B24926B, 0x502C32B8290833B7, 0x761FAC5A4F7DD1D3, 0x6BF126046D51700F, 0xD50CC36F92F31BFB,
|
||||
0xC8E24931B0DFBA27, 0xEED1D7D3D6AA5843, 0xF33F5D8DF486F99F, 0xA2B6EA171A419C8B, 0xBF586049386D3D57,
|
||||
0x996BFEAB5E18DF33, 0x848574F57C347EEF, 0x76489B570E52165E, 0x6BA611092C7EB782, 0x4D958FEB4A0B55E6,
|
||||
0x507B05B56827F43A, 0x01F2B22F86E0912E, 0x1C1C3871A4CC30F2, 0x3A2FA693C2B9D296, 0x27C12CCDE095734A,
|
||||
0x993CC9A61F3718BE, 0x84D243F83D1BB962, 0xA2E1DD1A5B6E5B06, 0xBF0F57447942FADA, 0xEE86E0DE97859FCE,
|
||||
0xF3686A80B5A93E12, 0xD55BF462D3DCDC76, 0xC8B57E3CF1F07DAA, 0xD6E9A7309F3239A7, 0xCB072D6EBD1E987B,
|
||||
0xED34B38CDB6B7A1F, 0xF0DA39D2F947DBC3, 0xA1538E481780BED7, 0xBCBD041635AC1F0B, 0x9A8E9AF453D9FD6F,
|
||||
0x876010AA71F55CB3, 0x399DF5C18E573747, 0x24737F9FAC7B969B, 0x0240E17DCA0E74FF, 0x1FAE6B23E822D523,
|
||||
0x4E27DCB906E5B037, 0x53C956E724C911EB, 0x75FAC80542BCF38F, 0x6814425B60905253, 0x9AD9ADF912F63AE2,
|
||||
0x873727A730DA9B3E, 0xA104B94556AF795A, 0xBCEA331B7483D886, 0xED6384819A44BD92, 0xF08D0EDFB8681C4E,
|
||||
0xD6BE903DDE1DFE2A, 0xCB501A63FC315FF6, 0x75ADFF0803933402, 0x6843755621BF95DE, 0x4E70EBB447CA77BA,
|
||||
0x539E61EA65E6D666, 0x0217D6708B21B372, 0x1FF95C2EA90D12AE, 0x39CAC2CCCF78F0CA, 0x24244892ED545116,
|
||||
0x4E89B2A384BA3F2D, 0x536738FDA6969EF1, 0x7554A61FC0E37C95, 0x68BA2C41E2CFDD49, 0x39339BDB0C08B85D,
|
||||
0x24DD11852E241981, 0x02EE8F674851FBE5, 0x1F0005396A7D5A39, 0xA1FDE05295DF31CD, 0xBC136A0CB7F39011,
|
||||
0x9A20F4EED1867275, 0x87CE7EB0F3AAD3A9, 0xD647C92A1D6DB6BD, 0xCBA943743F411761, 0xED9ADD965934F505,
|
||||
0xF07457C87B1854D9, 0x02B9B86A097E3C68, 0x1F5732342B529DB4, 0x3964ACD64D277FD0, 0x248A26886F0BDE0C,
|
||||
0x7503911281CCBB18, 0x68ED1B4CA3E01AC4, 0x4EDE85AEC595F8A0, 0x53300FF0E7B9597C, 0xEDCDEA9B181B3288,
|
||||
0xF02360C53A379354, 0xD610FE275C427130, 0xCBFE74797E6ED0EC, 0x9A77C3E390A9B5F8, 0x879949BDB2851424,
|
||||
0xA1AAD75FD4F0F640, 0xBC445D01F6DC579C, 0x74F1233D072C2A36, 0x691FA96325008BEA, 0x4F2C37814375698E,
|
||||
0x52C2BDDF6159C852, 0x034B0A458F9EAD46, 0x1EA5801BADB20C9A, 0x38961EF9CBC7EEFE, 0x257894A7E9EB4F22,
|
||||
0x9B8571CC164924D6, 0x866BFB923465850A, 0xA05865705210676E, 0xBDB6EF2E703CC6B2, 0xEC3F58B49EFBA3A6,
|
||||
0xF1D1D2EABCD7027A, 0xD7E24C08DAA2E01E, 0xCA0CC656F88E41C2, 0x38C129F48AE82973, 0x252FA3AAA8C488AF,
|
||||
0x031C3D48CEB16ACB, 0x1EF2B716EC9DCB17, 0x4F7B008C025AAE03, 0x52958AD220760FDF, 0x74A614304603EDBB,
|
||||
0x69489E6E642F4C67, 0xD7B57B059B8D2793, 0xCA5BF15BB9A1864F, 0xEC686FB9DFD4642B, 0xF186E5E7FDF8C5F7,
|
||||
0xA00F527D133FA0E3, 0xBDE1D8233113013F, 0x9BD246C15766E35B, 0x863CCC9F754A4287, 0xEC9136AE1CA42CBC,
|
||||
0xF17FBCF03E888D60, 0xD74C221258FD6F04, 0xCAA2A84C7AD1CED8, 0x9B2B1FD69416ABCC, 0x86C59588B63A0A10,
|
||||
0xA0F60B6AD04FE874, 0xBD188134F26349A8, 0x03E5645F0DC1225C, 0x1E0BEE012FED8380, 0x383870E3499861E4,
|
||||
0x25D6FABD6BB4C038, 0x745F4D278573A52C, 0x69B1C779A75F04F0, 0x4F82599BC12AE694, 0x526CD3C5E3064748,
|
||||
0xA0A13C6791602FF9, 0xBD4FB639B34C8E25, 0x9B7C28DBD5396C41, 0x8692A285F715CD9D, 0xD71B151F19D2A889,
|
||||
0xCAF59F413BFE0955, 0xECC601A35D8BEB31, 0xF1288BFD7FA74AED, 0x4FD56E9680052119, 0x523BE4C8A22980C5,
|
||||
0x74087A2AC45C62A1, 0x69E6F074E670C37D, 0x386F47EE08B7A669, 0x2581CDB02A9B07B5, 0x03B253524CEEE5D1,
|
||||
0x1E5CD90C6EC2440D
|
||||
]
|
||||
];
|
||||
|
||||
readonly ulong _finalSeed;
|
||||
readonly IntPtr _nativeContext;
|
||||
readonly ulong[][] _table;
|
||||
readonly bool _useEcma;
|
||||
readonly bool _useNative;
|
||||
ulong _hashInt;
|
||||
|
||||
/// <summary>Initializes the CRC64 table and seed as CRC64-ECMA</summary>
|
||||
public Crc64Context()
|
||||
{
|
||||
_hashInt = CRC64_ECMA_SEED;
|
||||
|
||||
_table = new ulong[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
{
|
||||
var entry = (ulong)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ CRC64_ECMA_POLY;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
_table[i] = entry;
|
||||
}
|
||||
|
||||
_hashInt = CRC64_ECMA_SEED;
|
||||
_table = _ecmaCrc64Table;
|
||||
_finalSeed = CRC64_ECMA_SEED;
|
||||
_useEcma = true;
|
||||
|
||||
if(!Native.IsSupported) return;
|
||||
|
||||
_nativeContext = crc64_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>Initializes the CRC16 table with a custom polynomial and seed</summary>
|
||||
public Crc64Context(ulong polynomial, ulong seed)
|
||||
{
|
||||
_hashInt = seed;
|
||||
_hashInt = seed;
|
||||
_finalSeed = seed;
|
||||
_useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
|
||||
|
||||
_table = new ulong[256];
|
||||
if(Native.IsSupported && _useEcma)
|
||||
{
|
||||
_nativeContext = crc64_init();
|
||||
_useNative = _nativeContext != IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
_table = GenerateTable(polynomial);
|
||||
}
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial IntPtr crc64_init();
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial int crc64_update(IntPtr ctx, byte[] data, uint len);
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial int crc64_final(IntPtr ctx, ref ulong crc);
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial void crc64_free(IntPtr ctx);
|
||||
|
||||
static ulong[][] GenerateTable(ulong polynomial)
|
||||
{
|
||||
var table = new ulong[8][];
|
||||
|
||||
for(var i = 0; i < 8; i++) table[i] = new ulong[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
{
|
||||
@@ -91,44 +340,79 @@ public sealed class Crc64Context : IChecksum
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
_table[i] = entry;
|
||||
table[0][i] = entry;
|
||||
}
|
||||
|
||||
_finalSeed = seed;
|
||||
for(var slice = 1; slice < 4; slice++)
|
||||
{
|
||||
for(var i = 0; i < 256; i++)
|
||||
table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len)
|
||||
static void Step(ref ulong previousCrc, ulong[][] table, byte[] data, uint len, bool useEcma, bool useNative,
|
||||
IntPtr nativeContext)
|
||||
{
|
||||
for(var i = 0; i < len; i++) _hashInt = _hashInt >> 8 ^ _table[data[i] ^ _hashInt & 0xff];
|
||||
}
|
||||
if(useNative && useEcma)
|
||||
{
|
||||
crc64_update(nativeContext, data, len);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final() => BigEndianBitConverter.GetBytes(_hashInt ^= _finalSeed);
|
||||
var dataOff = 0;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
var crc64Output = new StringBuilder();
|
||||
if(useEcma && Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
|
||||
{
|
||||
// Only works in blocks of 32 bytes
|
||||
uint blocks = len / 32;
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(_hashInt ^= _finalSeed).Length; i++)
|
||||
crc64Output.Append(BigEndianBitConverter.GetBytes(_hashInt ^= _finalSeed)[i].ToString("x2"));
|
||||
if(blocks > 0)
|
||||
{
|
||||
previousCrc = ~Clmul.Step(~previousCrc, data, blocks * 32);
|
||||
|
||||
return crc64Output.ToString();
|
||||
dataOff = (int)(blocks * 32);
|
||||
len -= blocks * 32;
|
||||
}
|
||||
|
||||
if(len == 0) return;
|
||||
}
|
||||
|
||||
// Unroll according to Intel slicing by uint8_t
|
||||
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
// http://sourceforge.net/projects/slicing-by-8/
|
||||
|
||||
ulong crc = previousCrc;
|
||||
|
||||
if(len > 4)
|
||||
{
|
||||
long limit = dataOff + (len & ~(uint)3);
|
||||
len &= 3;
|
||||
|
||||
while(dataOff < limit)
|
||||
{
|
||||
var tmp = (uint)(crc ^ BitConverter.ToUInt32(data, dataOff));
|
||||
dataOff += 4;
|
||||
|
||||
crc = table[3][tmp & 0xFF] ^
|
||||
table[2][tmp >> 8 & 0xFF] ^
|
||||
crc >> 32 ^
|
||||
table[1][tmp >> 16 & 0xFF] ^
|
||||
table[0][tmp >> 24];
|
||||
}
|
||||
}
|
||||
|
||||
while(len-- != 0) crc = table[0][data[dataOff++] ^ crc & 0xFF] ^ crc >> 8;
|
||||
|
||||
previousCrc = crc;
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
|
||||
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
File(filename, out byte[] localHash);
|
||||
@@ -149,32 +433,41 @@ public sealed class Crc64Context : IChecksum
|
||||
/// <param name="seed">CRC seed</param>
|
||||
public static string File(string filename, out byte[] hash, ulong polynomial, ulong seed)
|
||||
{
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
ulong localhashInt = seed;
|
||||
|
||||
var localTable = new ulong[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
if(useNative && useEcma)
|
||||
{
|
||||
var entry = (ulong)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ polynomial;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
localTable[i] = entry;
|
||||
nativeContext = crc64_init();
|
||||
useNative = nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
for(var i = 0; i < fileStream.Length; i++)
|
||||
localhashInt = localhashInt >> 8 ^ localTable[(ulong)fileStream.ReadByte() ^ localhashInt & 0xffL];
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
|
||||
localhashInt ^= seed;
|
||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||
ulong localHashInt = seed;
|
||||
|
||||
ulong[][] localTable = GenerateTable(polynomial);
|
||||
|
||||
var buffer = new byte[65536];
|
||||
int read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
|
||||
while(read > 0)
|
||||
{
|
||||
Step(ref localHashInt, localTable, buffer, (uint)read, useEcma, useNative, nativeContext);
|
||||
|
||||
read = fileStream.EnsureRead(buffer, 0, 65536);
|
||||
}
|
||||
|
||||
localHashInt ^= seed;
|
||||
|
||||
if(useNative && useEcma)
|
||||
{
|
||||
crc64_final(nativeContext, ref localHashInt);
|
||||
crc64_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(localHashInt);
|
||||
|
||||
var crc64Output = new StringBuilder();
|
||||
|
||||
@@ -200,29 +493,31 @@ public sealed class Crc64Context : IChecksum
|
||||
/// <param name="seed">CRC seed</param>
|
||||
public static string Data(byte[] data, uint len, out byte[] hash, ulong polynomial, ulong seed)
|
||||
{
|
||||
ulong localhashInt = seed;
|
||||
bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
|
||||
bool useNative = Native.IsSupported;
|
||||
IntPtr nativeContext = IntPtr.Zero;
|
||||
|
||||
var localTable = new ulong[256];
|
||||
|
||||
for(var i = 0; i < 256; i++)
|
||||
if(useNative && useEcma)
|
||||
{
|
||||
var entry = (ulong)i;
|
||||
|
||||
for(var j = 0; j < 8; j++)
|
||||
{
|
||||
if((entry & 1) == 1)
|
||||
entry = entry >> 1 ^ polynomial;
|
||||
else
|
||||
entry >>= 1;
|
||||
}
|
||||
|
||||
localTable[i] = entry;
|
||||
nativeContext = crc64_init();
|
||||
useNative = nativeContext != IntPtr.Zero;
|
||||
}
|
||||
|
||||
for(var i = 0; i < len; i++) localhashInt = localhashInt >> 8 ^ localTable[data[i] ^ localhashInt & 0xff];
|
||||
ulong localHashInt = seed;
|
||||
|
||||
localhashInt ^= seed;
|
||||
hash = BigEndianBitConverter.GetBytes(localhashInt);
|
||||
ulong[][] localTable = GenerateTable(polynomial);
|
||||
|
||||
Step(ref localHashInt, localTable, data, len, useEcma, useNative, nativeContext);
|
||||
|
||||
localHashInt ^= seed;
|
||||
|
||||
if(useNative && useEcma)
|
||||
{
|
||||
crc64_final(nativeContext, ref localHashInt);
|
||||
crc64_free(nativeContext);
|
||||
}
|
||||
|
||||
hash = BigEndianBitConverter.GetBytes(localHashInt);
|
||||
|
||||
var crc64Output = new StringBuilder();
|
||||
|
||||
@@ -235,4 +530,63 @@ public sealed class Crc64Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.CRC64_ECMA_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("D0C0D902-420A-45DA-A235-9D48BEE4B1CE");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) =>
|
||||
Step(ref _hashInt, _table, data, len, _useEcma, _useNative, _nativeContext);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
ulong crc = _hashInt ^ _finalSeed;
|
||||
|
||||
if(!_useNative || !_useEcma) return BigEndianBitConverter.GetBytes(crc);
|
||||
|
||||
crc64_final(_nativeContext, ref crc);
|
||||
crc64_free(_nativeContext);
|
||||
|
||||
return BigEndianBitConverter.GetBytes(crc);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
ulong crc = _hashInt ^ _finalSeed;
|
||||
|
||||
var crc64Output = new StringBuilder();
|
||||
|
||||
if(_useNative && _useEcma)
|
||||
{
|
||||
crc64_final(_nativeContext, ref crc);
|
||||
crc64_free(_nativeContext);
|
||||
}
|
||||
|
||||
for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
|
||||
crc64Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
|
||||
|
||||
return crc64Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
namespace Aaru.CommonTypes.Interfaces;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
public interface IChecksum
|
||||
{
|
||||
|
||||
417
RomRepoMgr.Core/Checksums/Localization/Localization.Designer.cs
generated
Normal file
417
RomRepoMgr.Core/Checksums/Localization/Localization.Designer.cs
generated
Normal file
@@ -0,0 +1,417 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums.Localization {
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Localization {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Localization() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Aaru.Checksums.Localization.Localization", typeof(Localization).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Adler-32.
|
||||
/// </summary>
|
||||
internal static string Adler32_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Adler32_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Assertion failed.
|
||||
/// </summary>
|
||||
internal static string Assertion_failed {
|
||||
get {
|
||||
return ResourceManager.GetString("Assertion_failed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CD-Text Pack 4 CRC 0x{0:X4}, expected 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string CD_Text_Pack_four_CRC_0_expected_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("CD_Text_Pack_four_CRC_0_expected_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CD-Text Pack 1 CRC 0x{0:X4}, expected 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string CD_Text_Pack_one_CRC_0_expected_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("CD_Text_Pack_one_CRC_0_expected_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CD-Text Pack 3 CRC 0x{0:X4}, expected 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string CD_Text_Pack_three_CRC_0_expected_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("CD_Text_Pack_three_CRC_0_expected_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CD-Text Pack 2 CRC 0x{0:X4}, expected 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string CD_Text_Pack_two_CRC_0_expected_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("CD_Text_Pack_two_CRC_0_expected_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CRC-16 (CCITT).
|
||||
/// </summary>
|
||||
internal static string CRC16_CCITT_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("CRC16_CCITT_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CRC-16 (IBM).
|
||||
/// </summary>
|
||||
internal static string CRC16_IBM_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("CRC16_IBM_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CRC-32.
|
||||
/// </summary>
|
||||
internal static string CRC32_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("CRC32_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CRC-64 (ECMA).
|
||||
/// </summary>
|
||||
internal static string CRC64_ECMA_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("CRC64_ECMA_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cyclic CDTP2 0x{0:X4}, Calc CDTP2 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string Cyclic_CDTP2_0_Calc_CDTP2_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("Cyclic_CDTP2_0_Calc_CDTP2_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cyclic CDTP3 0x{0:X4}, Calc CDTP3 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string Cyclic_CDTP3_0_Calc_CDTP3_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("Cyclic_CDTP3_0_Calc_CDTP3_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cyclic CDTP4 0x{0:X4}, Calc CDTP4 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string Cyclic_CDTP4_0_Calc_CDTP4_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("Cyclic_CDTP4_0_Calc_CDTP4_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected CD+EG Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_CD_EG_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_CD_EG_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected CD+G Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_CD_G_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_CD_G_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected CD+MIDI Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_CD_MIDI_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_CD_MIDI_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected CD-TEXT Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_CD_TEXT_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_CD_TEXT_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected Line Graphics Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_Line_Graphics_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_Line_Graphics_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected unknown Pack type in subchannel: mode {0}, item {1}.
|
||||
/// </summary>
|
||||
internal static string Detected_unknown_Pack_type_in_subchannel_mode_0_item_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_unknown_Pack_type_in_subchannel_mode_0_item_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected User Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_User_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_User_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Detected Zero Pack in subchannel.
|
||||
/// </summary>
|
||||
internal static string Detected_Zero_Pack_in_subchannel {
|
||||
get {
|
||||
return ResourceManager.GetString("Detected_Zero_Pack_in_subchannel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// Erasure positions as determined by roots of Eras Loc Poly:
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly {
|
||||
get {
|
||||
return ResourceManager.GetString("Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// ERROR: denominator = 0
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string ERROR_denominator_equals_zero {
|
||||
get {
|
||||
return ResourceManager.GetString("ERROR_denominator_equals_zero", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// Final error positions: .
|
||||
/// </summary>
|
||||
internal static string Final_error_positions {
|
||||
get {
|
||||
return ResourceManager.GetString("Final_error_positions", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Fletcher-16.
|
||||
/// </summary>
|
||||
internal static string Fletcher16_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Fletcher16_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Fletcher-32.
|
||||
/// </summary>
|
||||
internal static string Fletcher32_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("Fletcher32_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// lambda(x) is WRONG
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string lambda_is_wrong {
|
||||
get {
|
||||
return ResourceManager.GetString("lambda_is_wrong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to m must be between 2 and 16 inclusive.
|
||||
/// </summary>
|
||||
internal static string m_must_be_between_2_and_16_inclusive {
|
||||
get {
|
||||
return ResourceManager.GetString("m_must_be_between_2_and_16_inclusive", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to MD5.
|
||||
/// </summary>
|
||||
internal static string MD5_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("MD5_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not yet implemented..
|
||||
/// </summary>
|
||||
internal static string Not_yet_implemented {
|
||||
get {
|
||||
return ResourceManager.GetString("Not_yet_implemented", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Q subchannel CRC 0x{0:X4}, expected 0x{1:X4}.
|
||||
/// </summary>
|
||||
internal static string Q_subchannel_CRC_0_expected_1 {
|
||||
get {
|
||||
return ResourceManager.GetString("Q_subchannel_CRC_0_expected_1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SHA1.
|
||||
/// </summary>
|
||||
internal static string SHA1_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("SHA1_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SHA256.
|
||||
/// </summary>
|
||||
internal static string SHA256_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("SHA256_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SHA384.
|
||||
/// </summary>
|
||||
internal static string SHA384_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("SHA384_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SHA512.
|
||||
/// </summary>
|
||||
internal static string SHA512_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("SHA512_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SpamSum does not have a binary representation..
|
||||
/// </summary>
|
||||
internal static string SpamSum_does_not_have_a_binary_representation {
|
||||
get {
|
||||
return ResourceManager.GetString("SpamSum_does_not_have_a_binary_representation", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SpamSum.
|
||||
/// </summary>
|
||||
internal static string SpamSum_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("SpamSum_Name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The input exceeds data types..
|
||||
/// </summary>
|
||||
internal static string The_input_exceeds_data_types {
|
||||
get {
|
||||
return ResourceManager.GetString("The_input_exceeds_data_types", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Trying to calculate RS without initializing!.
|
||||
/// </summary>
|
||||
internal static string Trying_to_calculate_RS_without_initializing {
|
||||
get {
|
||||
return ResourceManager.GetString("Trying_to_calculate_RS_without_initializing", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
136
RomRepoMgr.Core/Checksums/Localization/Localization.es.resx
Normal file
136
RomRepoMgr.Core/Checksums/Localization/Localization.es.resx
Normal file
@@ -0,0 +1,136 @@
|
||||
<root>
|
||||
<!-- ReSharper disable MarkupTextTypo -->
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<data name="Assertion_failed" xml:space="preserve">
|
||||
<value>Error de aserción</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_four_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CRC del paquete 4 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_one_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CRC del paquete 1 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_three_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CRC del paquete 3 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_two_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CRC del paquete 4 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP2_0_Calc_CDTP2_1" xml:space="preserve">
|
||||
<value>CDTP2 cíclico 0x{0:X4}, CDTP2 calculado 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP3_0_Calc_CDTP3_1" xml:space="preserve">
|
||||
<value>CDTP3 cíclico 0x{0:X4}, CDTP3 calculado 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP4_0_Calc_CDTP4_1" xml:space="preserve">
|
||||
<value>CDTP4 cíclico 0x{0:X4}, CDTP4 calculado 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Detected_CD_EG_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete CD+EG en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_CD_G_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete CD+G en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_CD_MIDI_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete CD+MIDI en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_CD_TEXT_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete CD-TEXT en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_Line_Graphics_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete de gráficos lineales en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_unknown_Pack_type_in_subchannel_mode_0_item_1" xml:space="preserve">
|
||||
<value>Detectado paquete de tipo desconocido en el subcanal: modo {0}, elemento {1}</value>
|
||||
</data>
|
||||
<data name="Detected_User_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete de usuario en el subcanal</value>
|
||||
</data>
|
||||
<data name="Detected_Zero_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detectado paquete cero en el subcanal</value>
|
||||
</data>
|
||||
<data name="Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly" xml:space="preserve">
|
||||
<value>Posiciones de borrado determinadas por el polinomio:</value>
|
||||
</data>
|
||||
<data name="ERROR_denominator_equals_zero" xml:space="preserve">
|
||||
<value>ERROR: denominador = 0</value>
|
||||
</data>
|
||||
<data name="Final_error_positions" xml:space="preserve">
|
||||
<value>Posiciones finales de error:</value>
|
||||
</data>
|
||||
<data name="lambda_is_wrong" xml:space="preserve">
|
||||
<value>lambda(x) es INCORRECTO</value>
|
||||
</data>
|
||||
<data name="m_must_be_between_2_and_16_inclusive" xml:space="preserve">
|
||||
<value>m debe estar entre 2 y 16 inclusivos</value>
|
||||
</data>
|
||||
<data name="Not_yet_implemented" xml:space="preserve">
|
||||
<value>Aún no implementado.</value>
|
||||
</data>
|
||||
<data name="Q_subchannel_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CRC del subcanal Q es 0x{0:X4}, se esperaba 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="SpamSum_does_not_have_a_binary_representation" xml:space="preserve">
|
||||
<value>SpamSum no posee una representación binaria.</value>
|
||||
</data>
|
||||
<data name="The_input_exceeds_data_types" xml:space="preserve">
|
||||
<value>La entrada excede los tipos de datos</value>
|
||||
</data>
|
||||
<data name="Trying_to_calculate_RS_without_initializing" xml:space="preserve">
|
||||
<value>¡Intentando calcular RS sin inicializar!</value>
|
||||
</data>
|
||||
<data name="Adler32_Name" xml:space="preserve">
|
||||
<value>Adler-32</value>
|
||||
</data>
|
||||
<data name="CRC16_CCITT_Name" xml:space="preserve">
|
||||
<value>CRC-16 (CCITT)</value>
|
||||
</data>
|
||||
<data name="CRC16_IBM_Name" xml:space="preserve">
|
||||
<value>CRC-16 (IBM)</value>
|
||||
</data>
|
||||
<data name="CRC32_Name" xml:space="preserve">
|
||||
<value>CRC-32</value>
|
||||
</data>
|
||||
<data name="CRC64_ECMA_Name" xml:space="preserve">
|
||||
<value>CRC-64 (ECMA)</value>
|
||||
</data>
|
||||
<data name="Fletcher32_Name" xml:space="preserve">
|
||||
<value>Fletcher-32</value>
|
||||
</data>
|
||||
<data name="Fletcher16_Name" xml:space="preserve">
|
||||
<value>Fletcher-16</value>
|
||||
</data>
|
||||
<data name="MD5_Name" xml:space="preserve">
|
||||
<value>MD5</value>
|
||||
</data>
|
||||
<data name="SHA1_Name" xml:space="preserve">
|
||||
<value>SHA1</value>
|
||||
</data>
|
||||
<data name="SHA256_Name" xml:space="preserve">
|
||||
<value>SHA256</value>
|
||||
</data>
|
||||
<data name="SHA384_Name" xml:space="preserve">
|
||||
<value>SHA384</value>
|
||||
</data>
|
||||
<data name="SHA512_Name" xml:space="preserve">
|
||||
<value>SHA512</value>
|
||||
</data>
|
||||
<data name="SpamSum_Name" xml:space="preserve">
|
||||
<value>SpamSum</value>
|
||||
</data>
|
||||
</root>
|
||||
148
RomRepoMgr.Core/Checksums/Localization/Localization.resx
Normal file
148
RomRepoMgr.Core/Checksums/Localization/Localization.resx
Normal file
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<root>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
|
||||
id="root" xmlns="">
|
||||
<xsd:element name="root" msdata:IsDataSet="true"></xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=b77a5c561934e089
|
||||
</value>
|
||||
</resheader>
|
||||
<data name="Detected_Zero_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected Zero Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_Line_Graphics_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected Line Graphics Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_CD_G_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected CD+G Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_CD_EG_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected CD+EG Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_CD_TEXT_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected CD-TEXT Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_CD_MIDI_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected CD+MIDI Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_User_Pack_in_subchannel" xml:space="preserve">
|
||||
<value>Detected User Pack in subchannel</value>
|
||||
</data>
|
||||
<data name="Detected_unknown_Pack_type_in_subchannel_mode_0_item_1" xml:space="preserve">
|
||||
<value>Detected unknown Pack type in subchannel: mode {0}, item {1}</value>
|
||||
</data>
|
||||
<data name="Q_subchannel_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>Q subchannel CRC 0x{0:X4}, expected 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_one_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CD-Text Pack 1 CRC 0x{0:X4}, expected 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP2_0_Calc_CDTP2_1" xml:space="preserve">
|
||||
<value>Cyclic CDTP2 0x{0:X4}, Calc CDTP2 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_two_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CD-Text Pack 2 CRC 0x{0:X4}, expected 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP3_0_Calc_CDTP3_1" xml:space="preserve">
|
||||
<value>Cyclic CDTP3 0x{0:X4}, Calc CDTP3 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_three_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CD-Text Pack 3 CRC 0x{0:X4}, expected 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="Cyclic_CDTP4_0_Calc_CDTP4_1" xml:space="preserve">
|
||||
<value>Cyclic CDTP4 0x{0:X4}, Calc CDTP4 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="CD_Text_Pack_four_CRC_0_expected_1" xml:space="preserve">
|
||||
<value>CD-Text Pack 4 CRC 0x{0:X4}, expected 0x{1:X4}</value>
|
||||
</data>
|
||||
<data name="m_must_be_between_2_and_16_inclusive" xml:space="preserve">
|
||||
<value>m must be between 2 and 16 inclusive</value>
|
||||
</data>
|
||||
<data name="Trying_to_calculate_RS_without_initializing" xml:space="preserve">
|
||||
<value>Trying to calculate RS without initializing!</value>
|
||||
</data>
|
||||
<data name="lambda_is_wrong" xml:space="preserve">
|
||||
<value>
|
||||
lambda(x) is WRONG
|
||||
</value>
|
||||
</data>
|
||||
<data name="Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly" xml:space="preserve">
|
||||
<value>
|
||||
Erasure positions as determined by roots of Eras Loc Poly:
|
||||
</value>
|
||||
</data>
|
||||
<data name="Final_error_positions" xml:space="preserve">
|
||||
<value>
|
||||
Final error positions: </value>
|
||||
</data>
|
||||
<data name="ERROR_denominator_equals_zero" xml:space="preserve">
|
||||
<value>
|
||||
ERROR: denominator = 0
|
||||
</value>
|
||||
</data>
|
||||
<data name="SpamSum_does_not_have_a_binary_representation" xml:space="preserve">
|
||||
<value>SpamSum does not have a binary representation.</value>
|
||||
</data>
|
||||
<data name="Assertion_failed" xml:space="preserve">
|
||||
<value>Assertion failed</value>
|
||||
</data>
|
||||
<data name="The_input_exceeds_data_types" xml:space="preserve">
|
||||
<value>The input exceeds data types.</value>
|
||||
</data>
|
||||
<data name="Not_yet_implemented" xml:space="preserve">
|
||||
<value>Not yet implemented.</value>
|
||||
</data>
|
||||
<data name="Adler32_Name" xml:space="preserve">
|
||||
<value>Adler-32</value>
|
||||
</data>
|
||||
<data name="CRC16_CCITT_Name" xml:space="preserve">
|
||||
<value>CRC-16 (CCITT)</value>
|
||||
</data>
|
||||
<data name="CRC16_IBM_Name" xml:space="preserve">
|
||||
<value>CRC-16 (IBM)</value>
|
||||
</data>
|
||||
<data name="CRC32_Name" xml:space="preserve">
|
||||
<value>CRC-32</value>
|
||||
</data>
|
||||
<data name="CRC64_ECMA_Name" xml:space="preserve">
|
||||
<value>CRC-64 (ECMA)</value>
|
||||
</data>
|
||||
<data name="Fletcher32_Name" xml:space="preserve">
|
||||
<value>Fletcher-32</value>
|
||||
</data>
|
||||
<data name="Fletcher16_Name" xml:space="preserve">
|
||||
<value>Fletcher-16</value>
|
||||
</data>
|
||||
<data name="MD5_Name" xml:space="preserve">
|
||||
<value>MD5</value>
|
||||
</data>
|
||||
<data name="SHA1_Name" xml:space="preserve">
|
||||
<value>SHA1</value>
|
||||
</data>
|
||||
<data name="SHA256_Name" xml:space="preserve">
|
||||
<value>SHA256</value>
|
||||
</data>
|
||||
<data name="SHA384_Name" xml:space="preserve">
|
||||
<value>SHA384</value>
|
||||
</data>
|
||||
<data name="SHA512_Name" xml:space="preserve">
|
||||
<value>SHA512</value>
|
||||
</data>
|
||||
<data name="SpamSum_Name" xml:space="preserve">
|
||||
<value>SpamSum</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -27,16 +27,17 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Wraps up .NET MD5 implementation to a Init(), Update(), Final() context.</summary>
|
||||
public sealed class Md5Context : IChecksum
|
||||
{
|
||||
@@ -45,44 +46,12 @@ public sealed class Md5Context : IChecksum
|
||||
/// <summary>Initializes the MD5 hash provider</summary>
|
||||
public Md5Context() => _provider = MD5.Create();
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var md5Output = new StringBuilder();
|
||||
|
||||
foreach(byte h in _provider.Hash) md5Output.Append(h.ToString("x2"));
|
||||
|
||||
return md5Output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
var localMd5Provider = MD5.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
byte[] result = localMd5Provider.ComputeHash(fileStream);
|
||||
fileStream.Close();
|
||||
|
||||
@@ -95,7 +64,7 @@ public sealed class Md5Context : IChecksum
|
||||
public static string File(string filename, out byte[] hash)
|
||||
{
|
||||
var localMd5Provider = MD5.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
hash = localMd5Provider.ComputeHash(fileStream);
|
||||
var md5Output = new StringBuilder();
|
||||
|
||||
@@ -125,4 +94,51 @@ public sealed class Md5Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.MD5_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("C78674C4-F699-4FAB-A618-1661AF659A7C");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var md5Output = new StringBuilder();
|
||||
|
||||
if(_provider.Hash is null) return null;
|
||||
|
||||
foreach(byte h in _provider.Hash) md5Output.Append(h.ToString("x2"));
|
||||
|
||||
return md5Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
81
RomRepoMgr.Core/Checksums/Native.cs
Normal file
81
RomRepoMgr.Core/Checksums/Native.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Native.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Checksums.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Checks that Aaru.Checksums.Native library is available and usable.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <summary>Handles native implementations of compression algorithms</summary>
|
||||
public static partial class Native
|
||||
{
|
||||
static bool _checked;
|
||||
static bool _supported;
|
||||
|
||||
/// <summary>Set to return native as never supported</summary>
|
||||
public static bool ForceManaged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set to <c>true</c> the native library was found and loaded correctly and its reported version is
|
||||
/// compatible.
|
||||
/// </summary>
|
||||
public static bool IsSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
if(ForceManaged) return false;
|
||||
|
||||
if(_checked) return _supported;
|
||||
|
||||
ulong version;
|
||||
_checked = true;
|
||||
|
||||
try
|
||||
{
|
||||
version = get_acn_version();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_supported = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Check version compatibility
|
||||
_supported = version >= 0x06000000;
|
||||
|
||||
return _supported;
|
||||
}
|
||||
}
|
||||
|
||||
[LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
|
||||
private static partial ulong get_acn_version();
|
||||
}
|
||||
@@ -27,17 +27,22 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Wraps up .NET SHA1 implementation to a Init(), Update(), Final() context.</summary>
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
public sealed class Sha1Context : IChecksum
|
||||
{
|
||||
readonly SHA1 _provider;
|
||||
@@ -45,44 +50,14 @@ public sealed class Sha1Context : IChecksum
|
||||
/// <summary>Initializes the SHA1 hash provider</summary>
|
||||
public Sha1Context() => _provider = SHA1.Create();
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha1Output = new StringBuilder();
|
||||
|
||||
foreach(byte h in _provider.Hash) sha1Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha1Output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
|
||||
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
var localSha1Provider = SHA1.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
byte[] result = localSha1Provider.ComputeHash(fileStream);
|
||||
fileStream.Close();
|
||||
|
||||
@@ -95,7 +70,7 @@ public sealed class Sha1Context : IChecksum
|
||||
public static string File(string filename, out byte[] hash)
|
||||
{
|
||||
var localSha1Provider = SHA1.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
hash = localSha1Provider.ComputeHash(fileStream);
|
||||
var sha1Output = new StringBuilder();
|
||||
|
||||
@@ -125,4 +100,51 @@ public sealed class Sha1Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.SHA1_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("5C28939D-DCBB-4C6E-8498-C509ABD99FC2");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha1Output = new StringBuilder();
|
||||
|
||||
if(_provider.Hash is null) return null;
|
||||
|
||||
foreach(byte h in _provider.Hash) sha1Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha1Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -27,17 +27,22 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Wraps up .NET SHA256 implementation to a Init(), Update(), Final() context.</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
public sealed class Sha256Context : IChecksum
|
||||
{
|
||||
readonly SHA256 _provider;
|
||||
@@ -45,44 +50,14 @@ public sealed class Sha256Context : IChecksum
|
||||
/// <summary>Initializes the SHA256 hash provider</summary>
|
||||
public Sha256Context() => _provider = SHA256.Create();
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha256Output = new StringBuilder();
|
||||
|
||||
foreach(byte h in _provider.Hash) sha256Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha256Output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
|
||||
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
var localSha256Provider = SHA256.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
byte[] result = localSha256Provider.ComputeHash(fileStream);
|
||||
fileStream.Close();
|
||||
|
||||
@@ -95,7 +70,7 @@ public sealed class Sha256Context : IChecksum
|
||||
public static string File(string filename, out byte[] hash)
|
||||
{
|
||||
var localSha256Provider = SHA256.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
hash = localSha256Provider.ComputeHash(fileStream);
|
||||
var sha256Output = new StringBuilder();
|
||||
|
||||
@@ -125,4 +100,51 @@ public sealed class Sha256Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.SHA256_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("A6F0EF52-064D-41D1-8619-240481749B70");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha256Output = new StringBuilder();
|
||||
|
||||
if(_provider.Hash is null) return null;
|
||||
|
||||
foreach(byte h in _provider.Hash) sha256Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha256Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -27,17 +27,23 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Wraps up .NET SHA384 implementation to a Init(), Update(), Final() context.</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
public sealed class Sha384Context : IChecksum
|
||||
{
|
||||
readonly SHA384 _provider;
|
||||
@@ -45,44 +51,14 @@ public sealed class Sha384Context : IChecksum
|
||||
/// <summary>Initializes the SHA384 hash provider</summary>
|
||||
public Sha384Context() => _provider = SHA384.Create();
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha384Output = new StringBuilder();
|
||||
|
||||
foreach(byte h in _provider.Hash) sha384Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha384Output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
|
||||
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
var localSha384Provider = SHA384.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
byte[] result = localSha384Provider.ComputeHash(fileStream);
|
||||
fileStream.Close();
|
||||
|
||||
@@ -95,7 +71,7 @@ public sealed class Sha384Context : IChecksum
|
||||
public static string File(string filename, out byte[] hash)
|
||||
{
|
||||
var localSha384Provider = SHA384.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
hash = localSha384Provider.ComputeHash(fileStream);
|
||||
var sha384Output = new StringBuilder();
|
||||
|
||||
@@ -125,4 +101,51 @@ public sealed class Sha384Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.SHA384_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("4A2A1820-E157-4842-B1E2-0E629FA60DDD");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha384Output = new StringBuilder();
|
||||
|
||||
if(_provider.Hash is null) return null;
|
||||
|
||||
foreach(byte h in _provider.Hash) sha384Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha384Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -27,17 +27,23 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Wraps up .NET SHA512 implementation to a Init(), Update(), Final() context.</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
public sealed class Sha512Context : IChecksum
|
||||
{
|
||||
readonly SHA512 _provider;
|
||||
@@ -45,44 +51,12 @@ public sealed class Sha512Context : IChecksum
|
||||
/// <summary>Initializes the SHA512 hash provider</summary>
|
||||
public Sha512Context() => _provider = SHA512.Create();
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha512Output = new StringBuilder();
|
||||
|
||||
foreach(byte h in _provider.Hash) sha512Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha512Output.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
public static byte[] File(string filename)
|
||||
{
|
||||
var localSha512Provider = SHA512.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
byte[] result = localSha512Provider.ComputeHash(fileStream);
|
||||
fileStream.Close();
|
||||
|
||||
@@ -95,7 +69,7 @@ public sealed class Sha512Context : IChecksum
|
||||
public static string File(string filename, out byte[] hash)
|
||||
{
|
||||
var localSha512Provider = SHA512.Create();
|
||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||
var fileStream = new FileStream(filename, FileMode.Open);
|
||||
hash = localSha512Provider.ComputeHash(fileStream);
|
||||
var sha512Output = new StringBuilder();
|
||||
|
||||
@@ -125,4 +99,51 @@ public sealed class Sha512Context : IChecksum
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.SHA512_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("1E167BCB-2362-44DA-B5B0-B7ED3A22D5A6");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
|
||||
return _provider.Hash;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a hexadecimal representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
_provider.TransformFinalBlock([], 0, 0);
|
||||
var sha512Output = new StringBuilder();
|
||||
|
||||
if(_provider.Hash is null) return null;
|
||||
|
||||
foreach(byte h in _provider.Hash) sha512Output.Append(h.ToString("x2"));
|
||||
|
||||
return sha512Output.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2024 Natalia Portillo
|
||||
// Copyright © 2011-2025 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
// Based on ssdeep
|
||||
@@ -40,14 +40,19 @@
|
||||
// http://ssdeep.sf.net/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using RomRepoMgr.Core.Resources;
|
||||
|
||||
namespace Aaru.Checksums;
|
||||
namespace RomRepoMgr.Core.Checksums;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Implements the SpamSum fuzzy hashing algorithm.</summary>
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
[SuppressMessage("ReSharper", "UnusedParameter.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
[SuppressMessage("ReSharper", "OutParameterValueIsAlwaysDiscarded.Global")]
|
||||
public sealed class SpamSumContext : IChecksum
|
||||
{
|
||||
const uint ROLLING_WINDOW = 7;
|
||||
@@ -59,15 +64,8 @@ public sealed class SpamSumContext : IChecksum
|
||||
const uint FUZZY_MAX_RESULT = 2 * SPAMSUM_LENGTH + 20;
|
||||
|
||||
//"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
readonly byte[] _b64 =
|
||||
[
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
|
||||
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
|
||||
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31,
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
|
||||
];
|
||||
|
||||
FuzzyState _self;
|
||||
readonly byte[] _b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"u8.ToArray();
|
||||
FuzzyState _self;
|
||||
|
||||
/// <summary>Initializes the SpamSum structures</summary>
|
||||
public SpamSumContext()
|
||||
@@ -90,35 +88,6 @@ public sealed class SpamSumContext : IChecksum
|
||||
roll_init();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len)
|
||||
{
|
||||
_self.TotalSize += len;
|
||||
|
||||
for(var i = 0; i < len; i++) fuzzy_engine_step(data[i]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final() => throw new NotImplementedException(Localization.Spamsum_no_binary);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a base64 representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
FuzzyDigest(out byte[] result);
|
||||
|
||||
return CToString(result);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void roll_init() => _self.Roll = new RollState
|
||||
{
|
||||
@@ -167,10 +136,15 @@ public sealed class SpamSumContext : IChecksum
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void fuzzy_try_fork_blockhash()
|
||||
{
|
||||
if(_self.Bhend >= NUM_BLOCKHASHES) return;
|
||||
switch(_self.Bhend)
|
||||
{
|
||||
case >= NUM_BLOCKHASHES:
|
||||
return;
|
||||
|
||||
if(_self.Bhend == 0) // assert
|
||||
throw new Exception(Localization.Assertion_failed);
|
||||
// assert
|
||||
case 0:
|
||||
throw new Exception(Localization.Localization.Assertion_failed);
|
||||
}
|
||||
|
||||
uint obh = _self.Bhend - 1;
|
||||
uint nbh = _self.Bhend;
|
||||
@@ -185,7 +159,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void fuzzy_try_reduce_blockhash()
|
||||
{
|
||||
if(_self.Bhstart >= _self.Bhend) throw new Exception(Localization.Assertion_failed);
|
||||
if(_self.Bhstart >= _self.Bhend) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
if(_self.Bhend - _self.Bhstart < 2)
|
||||
/* Need at least two working hashes. */
|
||||
@@ -271,16 +245,15 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
/* Verify that our elimination was not overeager. */
|
||||
if(!(bi == 0 || (ulong)SSDEEP_BS(bi) / 2 * SPAMSUM_LENGTH < _self.TotalSize))
|
||||
throw new Exception(Localization.Assertion_failed);
|
||||
|
||||
var resultOff = 0;
|
||||
throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
/* Initial blocksize guess. */
|
||||
while((ulong)SSDEEP_BS(bi) * SPAMSUM_LENGTH < _self.TotalSize)
|
||||
{
|
||||
++bi;
|
||||
|
||||
if(bi >= NUM_BLOCKHASHES) throw new OverflowException(Localization.Spamsum_Input_exceeds_data);
|
||||
if(bi >= NUM_BLOCKHASHES)
|
||||
throw new OverflowException(Localization.Localization.The_input_exceeds_data_types);
|
||||
}
|
||||
|
||||
/* Adapt blocksize guess to actual digest length. */
|
||||
@@ -288,26 +261,27 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
while(bi > _self.Bhstart && _self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) --bi;
|
||||
|
||||
if(bi > 0 && _self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) throw new Exception(Localization.Assertion_failed);
|
||||
if(bi > 0 && _self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2)
|
||||
throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
sb.AppendFormat("{0}:", SSDEEP_BS(bi));
|
||||
sb.Append($"{SSDEEP_BS(bi)}:");
|
||||
int i = Encoding.ASCII.GetBytes(sb.ToString()).Length;
|
||||
|
||||
if(i <= 0)
|
||||
/* Maybe snprintf has set errno here? */
|
||||
throw new OverflowException(Localization.Spamsum_Input_exceeds_data);
|
||||
throw new OverflowException(Localization.Localization.The_input_exceeds_data_types);
|
||||
|
||||
if(i >= remain) throw new Exception(Localization.Assertion_failed);
|
||||
if(i >= remain) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
remain -= i;
|
||||
|
||||
Array.Copy(Encoding.ASCII.GetBytes(sb.ToString()), 0, result, 0, i);
|
||||
|
||||
resultOff = i;
|
||||
int resultOff = i;
|
||||
|
||||
i = (int)_self.Bh[bi].Dlen;
|
||||
|
||||
if(i > remain) throw new Exception(Localization.Assertion_failed);
|
||||
if(i > remain) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
|
||||
resultOff += i;
|
||||
@@ -315,7 +289,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
if(h != 0)
|
||||
{
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
result[resultOff] = _b64[_self.Bh[bi].H % 64];
|
||||
|
||||
@@ -330,7 +304,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
}
|
||||
else if(_self.Bh[bi].Digest[i] != 0)
|
||||
{
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
result[resultOff] = _self.Bh[bi].Digest[i];
|
||||
|
||||
@@ -344,7 +318,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
}
|
||||
}
|
||||
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
result[resultOff++] = 0x3A; // ':'
|
||||
--remain;
|
||||
@@ -354,7 +328,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
++bi;
|
||||
i = (int)_self.Bh[bi].Dlen;
|
||||
|
||||
if(i > remain) throw new Exception(Localization.Assertion_failed);
|
||||
if(i > remain) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
|
||||
resultOff += i;
|
||||
@@ -362,7 +336,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
if(h != 0)
|
||||
{
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
h = _self.Bh[bi].Halfh;
|
||||
result[resultOff] = _b64[h % 64];
|
||||
@@ -382,7 +356,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
if(i != 0)
|
||||
{
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
result[resultOff] = (byte)i;
|
||||
|
||||
@@ -399,9 +373,9 @@ public sealed class SpamSumContext : IChecksum
|
||||
}
|
||||
else if(h != 0)
|
||||
{
|
||||
if(_self.Bh[bi].Dlen != 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(_self.Bh[bi].Dlen != 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
if(remain <= 0) throw new Exception(Localization.Assertion_failed);
|
||||
if(remain <= 0) throw new Exception(Localization.Localization.Assertion_failed);
|
||||
|
||||
result[resultOff++] = _b64[_self.Bh[bi].H % 64];
|
||||
/* No need to bother with FUZZY_FLAG_ELIMSEQ, because this
|
||||
@@ -414,13 +388,14 @@ public sealed class SpamSumContext : IChecksum
|
||||
|
||||
/// <summary>Gets the hash of a file</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
public static byte[] File(string filename) => throw new NotImplementedException(Localization.Spamsum_no_binary);
|
||||
public static byte[] File(string filename) =>
|
||||
throw new NotImplementedException(Localization.Localization.SpamSum_does_not_have_a_binary_representation);
|
||||
|
||||
/// <summary>Gets the hash of a file in hexadecimal and as a byte array.</summary>
|
||||
/// <param name="filename">File path.</param>
|
||||
/// <param name="hash">Byte array of the hash value.</param>
|
||||
public static string File(string filename, out byte[] hash) =>
|
||||
throw new NotImplementedException(Localization.Not_yet_implemented);
|
||||
throw new NotImplementedException(Localization.Localization.Not_yet_implemented);
|
||||
|
||||
/// <summary>Gets the hash of the specified data buffer.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
@@ -462,16 +437,7 @@ public sealed class SpamSumContext : IChecksum
|
||||
return Encoding.ASCII.GetString(cString, 0, count);
|
||||
}
|
||||
|
||||
struct RollState
|
||||
{
|
||||
public byte[] Window;
|
||||
|
||||
// ROLLING_WINDOW
|
||||
public uint H1;
|
||||
public uint H2;
|
||||
public uint H3;
|
||||
public uint N;
|
||||
}
|
||||
#region Nested type: BlockhashContext
|
||||
|
||||
/* A blockhash contains a signature state for a specific (implicit) blocksize.
|
||||
* The blocksize is given by SSDEEP_BS(index). The h and halfh members are the
|
||||
@@ -489,6 +455,10 @@ public sealed class SpamSumContext : IChecksum
|
||||
public uint Dlen;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: FuzzyState
|
||||
|
||||
struct FuzzyState
|
||||
{
|
||||
public uint Bhstart;
|
||||
@@ -499,4 +469,64 @@ public sealed class SpamSumContext : IChecksum
|
||||
public ulong TotalSize;
|
||||
public RollState Roll;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: RollState
|
||||
|
||||
struct RollState
|
||||
{
|
||||
public byte[] Window;
|
||||
|
||||
// ROLLING_WINDOW
|
||||
public uint H1;
|
||||
public uint H2;
|
||||
public uint H3;
|
||||
public uint N;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IChecksum Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Localization.SpamSum_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("DA692981-3291-47D8-B8B9-A87F0605F6E9");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NataliaPortillo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
/// <param name="len">Length of buffer to hash.</param>
|
||||
public void Update(byte[] data, uint len)
|
||||
{
|
||||
_self.TotalSize += len;
|
||||
|
||||
for(var i = 0; i < len; i++) fuzzy_engine_step(data[i]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Updates the hash with data.</summary>
|
||||
/// <param name="data">Data buffer.</param>
|
||||
public void Update(byte[] data) => Update(data, (uint)data.Length);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a byte array of the hash value.</summary>
|
||||
public byte[] Final() =>
|
||||
throw new NotImplementedException(Localization.Localization.SpamSum_does_not_have_a_binary_representation);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a base64 representation of the hash value.</summary>
|
||||
public string End()
|
||||
{
|
||||
FuzzyDigest(out byte[] result);
|
||||
|
||||
return CToString(result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aaru.Checksums.Native" />
|
||||
<PackageReference Include="DotNetZip"/>
|
||||
<PackageReference Include="EFCore.BulkExtensions"/>
|
||||
<PackageReference Include="Mono.Fuse.NETStandard"/>
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Aaru.Checksums;
|
||||
using RomRepoMgr.Core.Checksums;
|
||||
using Crc32Context = RomRepoMgr.Core.Checksums.Crc32Context;
|
||||
|
||||
namespace RomRepoMgr.Core.Workers;
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Aaru.Checksums;
|
||||
using EFCore.BulkExtensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RomRepoMgr.Core.Checksums;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Core.Resources;
|
||||
@@ -172,7 +172,7 @@ public sealed class DatImporter
|
||||
Maximum = machineNames.Count
|
||||
});
|
||||
|
||||
int position = 0;
|
||||
var position = 0;
|
||||
var machines = new Dictionary<string, Machine>();
|
||||
|
||||
foreach(string name in machineNames)
|
||||
@@ -220,29 +220,29 @@ public sealed class DatImporter
|
||||
var disks = new List<Disk>();
|
||||
var medias = new List<Media>();
|
||||
|
||||
string tmpRomCrc32Table = Guid.NewGuid().ToString();
|
||||
string tmpRomMd5Table = Guid.NewGuid().ToString();
|
||||
string tmpRomSha1Table = Guid.NewGuid().ToString();
|
||||
string tmpRomSha256Table = Guid.NewGuid().ToString();
|
||||
string tmpRomSha384Table = Guid.NewGuid().ToString();
|
||||
string tmpRomSha512Table = Guid.NewGuid().ToString();
|
||||
string tmpDiskMd5Table = Guid.NewGuid().ToString();
|
||||
string tmpDiskSha1Table = Guid.NewGuid().ToString();
|
||||
string tmpMediaMd5Table = Guid.NewGuid().ToString();
|
||||
string tmpMediaSha1Table = Guid.NewGuid().ToString();
|
||||
string tmpMediaSha256Table = Guid.NewGuid().ToString();
|
||||
var tmpRomCrc32Table = Guid.NewGuid().ToString();
|
||||
var tmpRomMd5Table = Guid.NewGuid().ToString();
|
||||
var tmpRomSha1Table = Guid.NewGuid().ToString();
|
||||
var tmpRomSha256Table = Guid.NewGuid().ToString();
|
||||
var tmpRomSha384Table = Guid.NewGuid().ToString();
|
||||
var tmpRomSha512Table = Guid.NewGuid().ToString();
|
||||
var tmpDiskMd5Table = Guid.NewGuid().ToString();
|
||||
var tmpDiskSha1Table = Guid.NewGuid().ToString();
|
||||
var tmpMediaMd5Table = Guid.NewGuid().ToString();
|
||||
var tmpMediaSha1Table = Guid.NewGuid().ToString();
|
||||
var tmpMediaSha256Table = Guid.NewGuid().ToString();
|
||||
|
||||
bool romsHaveCrc = false;
|
||||
bool romsHaveMd5 = false;
|
||||
bool romsHaveSha1 = false;
|
||||
bool romsHaveSha256 = false;
|
||||
bool romsHaveSha384 = false;
|
||||
bool romsHaveSha512 = false;
|
||||
bool disksHaveMd5 = false;
|
||||
bool disksHaveSha1 = false;
|
||||
bool mediasHaveMd5 = false;
|
||||
bool mediasHaveSha1 = false;
|
||||
bool mediasHaveSha256 = false;
|
||||
var romsHaveCrc = false;
|
||||
var romsHaveMd5 = false;
|
||||
var romsHaveSha1 = false;
|
||||
var romsHaveSha256 = false;
|
||||
var romsHaveSha384 = false;
|
||||
var romsHaveSha512 = false;
|
||||
var disksHaveMd5 = false;
|
||||
var disksHaveSha1 = false;
|
||||
var mediasHaveMd5 = false;
|
||||
var mediasHaveSha1 = false;
|
||||
var mediasHaveSha256 = false;
|
||||
|
||||
DbConnection dbConnection = ctx.Database.GetDbConnection();
|
||||
dbConnection.Open();
|
||||
@@ -623,7 +623,7 @@ public sealed class DatImporter
|
||||
|
||||
foreach(Rom rom in roms)
|
||||
{
|
||||
bool hashCollision = false;
|
||||
var hashCollision = false;
|
||||
|
||||
SetProgress?.Invoke(this,
|
||||
new ProgressEventArgs
|
||||
@@ -645,7 +645,7 @@ public sealed class DatImporter
|
||||
return;
|
||||
}
|
||||
|
||||
ulong uSize = (ulong)rom.GetInt64FieldValue(SabreTools.Models.Metadata.Rom.SizeKey);
|
||||
var uSize = (ulong)rom.GetInt64FieldValue(SabreTools.Models.Metadata.Rom.SizeKey);
|
||||
|
||||
DbFile file = null;
|
||||
|
||||
|
||||
@@ -1,59 +1,29 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Media;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
|
||||
namespace RomRepoMgr.Models;
|
||||
|
||||
public class DatImporter : ReactiveObject
|
||||
public partial class DatImporter : ObservableObject
|
||||
{
|
||||
bool _indeterminate;
|
||||
double _maximum;
|
||||
double _minimum;
|
||||
double _progress;
|
||||
Color _statusColor;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _indeterminate;
|
||||
[ObservableProperty]
|
||||
double _maximum;
|
||||
[ObservableProperty]
|
||||
double _minimum;
|
||||
[ObservableProperty]
|
||||
double _progress;
|
||||
[ObservableProperty]
|
||||
Color _statusColor;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
public string Filename { get; internal init; }
|
||||
public Task Task { get; set; }
|
||||
public bool Running { get; private set; } = true;
|
||||
|
||||
public bool Indeterminate
|
||||
{
|
||||
get => _indeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _indeterminate, value);
|
||||
}
|
||||
|
||||
public double Progress
|
||||
{
|
||||
get => _progress;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress, value);
|
||||
}
|
||||
|
||||
public double Maximum
|
||||
{
|
||||
get => _maximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _maximum, value);
|
||||
}
|
||||
|
||||
public double Minimum
|
||||
{
|
||||
get => _minimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _minimum, value);
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public Color StatusColor
|
||||
{
|
||||
get => _statusColor;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusColor, value);
|
||||
}
|
||||
|
||||
internal void OnErrorOccurred(object sender, ErrorEventArgs e)
|
||||
{
|
||||
StatusMessage = e.Message;
|
||||
|
||||
@@ -1,75 +1,29 @@
|
||||
using System;
|
||||
using Avalonia.Media;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
|
||||
namespace RomRepoMgr.Models;
|
||||
|
||||
public class RomImporter : ReactiveObject
|
||||
public partial class RomImporter : ObservableObject
|
||||
{
|
||||
bool _indeterminate;
|
||||
double _maximum;
|
||||
double _minimum;
|
||||
double _progress;
|
||||
bool _progressVisible = true;
|
||||
Color _statusColor;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _indeterminate;
|
||||
[ObservableProperty]
|
||||
double _maximum;
|
||||
[ObservableProperty]
|
||||
double _minimum;
|
||||
[ObservableProperty]
|
||||
double _progress;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible = true;
|
||||
[ObservableProperty]
|
||||
Color _statusColor;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
public string Filename { get; internal init; }
|
||||
public bool Running { get; private set; } = true;
|
||||
|
||||
public bool Indeterminate
|
||||
{
|
||||
get => _indeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _indeterminate, value);
|
||||
}
|
||||
|
||||
public double Progress
|
||||
{
|
||||
get => _progress;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress, value);
|
||||
}
|
||||
|
||||
public double Maximum
|
||||
{
|
||||
get => _maximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _maximum, value);
|
||||
}
|
||||
|
||||
public double Minimum
|
||||
{
|
||||
get => _minimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _minimum, value);
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public Color StatusColor
|
||||
{
|
||||
get => _statusColor;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusColor, value);
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
internal void OnErrorOccurred(object sender, ErrorEventArgs e)
|
||||
{
|
||||
StatusMessage = e.Message;
|
||||
StatusColor = Colors.Red;
|
||||
|
||||
if(!Indeterminate) return;
|
||||
|
||||
Indeterminate = false;
|
||||
Progress = 0;
|
||||
}
|
||||
|
||||
internal void OnSetIndeterminateProgress(object sender, EventArgs e)
|
||||
{
|
||||
Indeterminate = true;
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
// Copyright © 2020-2024 Natalia Portillo
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Logging;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Serilog;
|
||||
|
||||
namespace RomRepoMgr;
|
||||
|
||||
@@ -34,11 +35,40 @@ internal static class Program
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
#if DEBUG
|
||||
.MinimumLevel.Debug()
|
||||
#else
|
||||
.MinimumLevel.Information()
|
||||
#endif
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
try
|
||||
{
|
||||
Log.Information("Starting up");
|
||||
Log.Debug("Testing debug logging");
|
||||
|
||||
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.Fatal(ex, "Application start-up failed");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
}
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace(LogEventLevel.Debug)
|
||||
.UseReactiveUI();
|
||||
#if DEBUG
|
||||
.LogToSerilog(LogEventLevel.Debug);
|
||||
#else
|
||||
.LogToSerilog(LogEventLevel.Information);
|
||||
#endif
|
||||
}
|
||||
@@ -19,9 +19,9 @@
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid"/>
|
||||
<PackageReference Include="Avalonia.Desktop"/>
|
||||
<PackageReference Include="Avalonia.Diagnostics"/>
|
||||
<PackageReference Include="Avalonia.ReactiveUI"/>
|
||||
<PackageReference Include="Avalonia.Svg.Skia"/>
|
||||
<PackageReference Include="Avalonia.Themes.Fluent"/>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm"/>
|
||||
<PackageReference Include="MessageBox.Avalonia"/>
|
||||
<PackageReference Include="AsyncFixer"/>
|
||||
<PackageReference Include="ErrorProne.NET.CoreAnalyzers"/>
|
||||
@@ -31,6 +31,9 @@
|
||||
<PackageReference Include="Roslynator.Analyzers"/>
|
||||
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers"/>
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers"/>
|
||||
<PackageReference Include="Serilog"/>
|
||||
<PackageReference Include="Serilog.Extensions.Logging"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console"/>
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer"/>
|
||||
<PackageReference Include="Text.Analyzers"/>
|
||||
</ItemGroup>
|
||||
|
||||
49
RomRepoMgr/SerilogSink.cs
Normal file
49
RomRepoMgr/SerilogSink.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Avalonia.Logging;
|
||||
|
||||
namespace RomRepoMgr;
|
||||
|
||||
public class SerilogSink(LogEventLevel minimumLevel, IList<string>? areas = null) : ILogSink
|
||||
{
|
||||
private readonly IList<string>? _areas = areas?.Count > 0 ? areas : null;
|
||||
|
||||
public bool IsEnabled(LogEventLevel level, string area) =>
|
||||
level >= minimumLevel && (_areas?.Contains(area) ?? true);
|
||||
|
||||
public void Log(LogEventLevel level, string area, object? source, string messageTemplate)
|
||||
{
|
||||
if(IsEnabled(level, area))
|
||||
Serilog.Log.Write(LogLevelToSerilogLevel(level),
|
||||
"[{Area} {Source}] {MessageTemplate}",
|
||||
area,
|
||||
source,
|
||||
messageTemplate);
|
||||
}
|
||||
|
||||
public void Log(LogEventLevel level, string area, object? source, string messageTemplate,
|
||||
params object?[] propertyValues)
|
||||
{
|
||||
if(IsEnabled(level, area))
|
||||
Serilog.Log.Write(LogLevelToSerilogLevel(level),
|
||||
"[{Area} {Source}] {MessageTemplate}",
|
||||
propertyValues,
|
||||
area,
|
||||
source,
|
||||
messageTemplate);
|
||||
}
|
||||
|
||||
private static Serilog.Events.LogEventLevel LogLevelToSerilogLevel(LogEventLevel level)
|
||||
{
|
||||
return level switch
|
||||
{
|
||||
LogEventLevel.Verbose => Serilog.Events.LogEventLevel.Verbose,
|
||||
LogEventLevel.Debug => Serilog.Events.LogEventLevel.Debug,
|
||||
LogEventLevel.Information => Serilog.Events.LogEventLevel.Information,
|
||||
LogEventLevel.Warning => Serilog.Events.LogEventLevel.Warning,
|
||||
LogEventLevel.Error => Serilog.Events.LogEventLevel.Error,
|
||||
LogEventLevel.Fatal => Serilog.Events.LogEventLevel.Fatal,
|
||||
_ => Serilog.Events.LogEventLevel.Verbose
|
||||
};
|
||||
}
|
||||
}
|
||||
15
RomRepoMgr/SerilogSinkExtensions.cs
Normal file
15
RomRepoMgr/SerilogSinkExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Logging;
|
||||
|
||||
namespace RomRepoMgr;
|
||||
|
||||
public static class SerilogSinkExtensions
|
||||
{
|
||||
public static AppBuilder LogToSerilog(this AppBuilder builder, LogEventLevel level = LogEventLevel.Warning,
|
||||
params string[] areas)
|
||||
{
|
||||
Logger.Sink = new SerilogSink(level, areas);
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -26,20 +26,22 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class AboutViewModel : ViewModelBase
|
||||
public sealed partial class AboutViewModel : ViewModelBase
|
||||
{
|
||||
readonly About _view;
|
||||
string _versionText;
|
||||
[ObservableProperty]
|
||||
string _versionText;
|
||||
|
||||
public AboutViewModel()
|
||||
{
|
||||
@@ -57,26 +59,20 @@ public sealed class AboutViewModel : ViewModelBase
|
||||
public string SuiteName => "ROM Repository Manager";
|
||||
public string Copyright => "© 2020-2024 Natalia Portillo";
|
||||
public string Website => "https://www.claunia.com";
|
||||
public ReactiveCommand<Unit, Unit> WebsiteCommand { get; private set; }
|
||||
public ReactiveCommand<Unit, Unit> LicenseCommand { get; private set; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; private set; }
|
||||
public ICommand WebsiteCommand { get; private set; }
|
||||
public ICommand LicenseCommand { get; private set; }
|
||||
public ICommand CloseCommand { get; private set; }
|
||||
public ObservableCollection<AssemblyModel> Assemblies { get; private set; }
|
||||
|
||||
public string VersionText
|
||||
{
|
||||
get => _versionText;
|
||||
private set => this.RaiseAndSetIfChanged(ref _versionText, value);
|
||||
}
|
||||
|
||||
void LoadData()
|
||||
{
|
||||
VersionText =
|
||||
(Attribute.GetCustomAttribute(typeof(App).Assembly, typeof(AssemblyInformationalVersionAttribute)) as
|
||||
AssemblyInformationalVersionAttribute)?.InformationalVersion;
|
||||
|
||||
WebsiteCommand = ReactiveCommand.Create(ExecuteWebsiteCommand);
|
||||
LicenseCommand = ReactiveCommand.Create(ExecuteLicenseCommand);
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
WebsiteCommand = new RelayCommand(ExecuteWebsiteCommand);
|
||||
LicenseCommand = new RelayCommand(ExecuteLicenseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
|
||||
Assemblies = [];
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using System.Windows.Input;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Database;
|
||||
@@ -35,7 +36,7 @@ using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public class EditDatViewModel : ViewModelBase
|
||||
public partial class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
readonly RomSetModel _romSet;
|
||||
readonly EditDat _view;
|
||||
@@ -45,9 +46,10 @@ public class EditDatViewModel : ViewModelBase
|
||||
string _date;
|
||||
string _description;
|
||||
string _homepage;
|
||||
bool _modified;
|
||||
string _name;
|
||||
string _version;
|
||||
[ObservableProperty]
|
||||
bool _modified;
|
||||
string _name;
|
||||
string _version;
|
||||
|
||||
// Mock
|
||||
public EditDatViewModel()
|
||||
@@ -96,26 +98,20 @@ public class EditDatViewModel : ViewModelBase
|
||||
_date = romSet.Date;
|
||||
_description = romSet.Description;
|
||||
_homepage = romSet.Homepage;
|
||||
SaveCommand = ReactiveCommand.CreateFromTask(ExecuteSaveCommandAsync);
|
||||
CancelCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
SaveCommand = new AsyncRelayCommand(ExecuteSaveCommandAsync);
|
||||
CancelCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SaveCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CancelCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public long TotalMachines => _romSet.TotalMachines;
|
||||
public long CompleteMachines => _romSet.CompleteMachines;
|
||||
public long IncompleteMachines => _romSet.IncompleteMachines;
|
||||
public long TotalRoms => _romSet.TotalRoms;
|
||||
public long HaveRoms => _romSet.HaveRoms;
|
||||
public long MissRoms => _romSet.MissRoms;
|
||||
|
||||
public bool Modified
|
||||
{
|
||||
get => _modified;
|
||||
set => this.RaiseAndSetIfChanged(ref _modified, value);
|
||||
}
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand CancelCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
public long TotalMachines => _romSet.TotalMachines;
|
||||
public long CompleteMachines => _romSet.CompleteMachines;
|
||||
public long IncompleteMachines => _romSet.IncompleteMachines;
|
||||
public long TotalRoms => _romSet.TotalRoms;
|
||||
public long HaveRoms => _romSet.HaveRoms;
|
||||
public long MissRoms => _romSet.MissRoms;
|
||||
|
||||
public string Name
|
||||
{
|
||||
@@ -124,7 +120,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _name) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _name, value);
|
||||
SetProperty(ref _name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +131,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _version) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _version, value);
|
||||
SetProperty(ref _version, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +142,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _author) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _author, value);
|
||||
SetProperty(ref _author, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +153,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _comment) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _comment, value);
|
||||
SetProperty(ref _comment, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +164,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _category) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _category, value);
|
||||
SetProperty(ref _category, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +175,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _date) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _date, value);
|
||||
SetProperty(ref _date, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +186,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _description) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _description, value);
|
||||
SetProperty(ref _description, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +197,7 @@ public class EditDatViewModel : ViewModelBase
|
||||
{
|
||||
if(value != _homepage) Modified = true;
|
||||
|
||||
this.RaiseAndSetIfChanged(ref _homepage, value);
|
||||
SetProperty(ref _homepage, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,11 @@
|
||||
*******************************************************************************/
|
||||
|
||||
using System.IO;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
@@ -37,17 +38,22 @@ using ErrorEventArgs = RomRepoMgr.Core.EventArgs.ErrorEventArgs;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class ExportDatViewModel : ViewModelBase
|
||||
public sealed partial class ExportDatViewModel : ViewModelBase
|
||||
{
|
||||
readonly string _datHash;
|
||||
readonly string _outPath;
|
||||
readonly ExportDat _view;
|
||||
readonly Compression _worker;
|
||||
bool _canClose;
|
||||
string _errorMessage;
|
||||
bool _errorVisible;
|
||||
bool _progressVisible;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
string _errorMessage;
|
||||
[ObservableProperty]
|
||||
bool _errorVisible;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
|
||||
// Mock
|
||||
public ExportDatViewModel() {}
|
||||
@@ -57,7 +63,7 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
_view = view;
|
||||
_datHash = datHash;
|
||||
_outPath = outPath;
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
ProgressVisible = false;
|
||||
ErrorVisible = false;
|
||||
_worker = new Compression();
|
||||
@@ -65,37 +71,7 @@ public sealed class ExportDatViewModel : ViewModelBase
|
||||
_worker.FailedWithText += OnWorkerOnFailedWithText;
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public bool ErrorVisible
|
||||
{
|
||||
get => _errorVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _errorVisible, value);
|
||||
}
|
||||
|
||||
public string ErrorMessage
|
||||
{
|
||||
get => _errorMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _errorMessage, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
void OnWorkerOnFinishedWithText(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
|
||||
@@ -24,39 +24,59 @@
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class ExportRomsViewModel : ViewModelBase
|
||||
public sealed partial class ExportRomsViewModel : ViewModelBase
|
||||
{
|
||||
readonly long _romSetId;
|
||||
readonly ExportRoms _view;
|
||||
bool _canClose;
|
||||
bool _progress2IsIndeterminate;
|
||||
double _progress2Maximum;
|
||||
double _progress2Minimum;
|
||||
double _progress2Value;
|
||||
bool _progress2Visible;
|
||||
bool _progress3IsIndeterminate;
|
||||
double _progress3Maximum;
|
||||
double _progress3Minimum;
|
||||
double _progress3Value;
|
||||
bool _progress3Visible;
|
||||
bool _progressIsIndeterminate;
|
||||
double _progressMaximum;
|
||||
double _progressMinimum;
|
||||
double _progressValue;
|
||||
bool _progressVisible;
|
||||
string _status2Message;
|
||||
string _status3Message;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
bool _progress2IsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progress2Maximum;
|
||||
[ObservableProperty]
|
||||
double _progress2Minimum;
|
||||
[ObservableProperty]
|
||||
double _progress2Value;
|
||||
[ObservableProperty]
|
||||
bool _progress2Visible;
|
||||
[ObservableProperty]
|
||||
bool _progress3IsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progress3Maximum;
|
||||
[ObservableProperty]
|
||||
double _progress3Minimum;
|
||||
[ObservableProperty]
|
||||
double _progress3Value;
|
||||
[ObservableProperty]
|
||||
bool _progress3Visible;
|
||||
[ObservableProperty]
|
||||
bool _progressIsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progressMaximum;
|
||||
[ObservableProperty]
|
||||
double _progressMinimum;
|
||||
[ObservableProperty]
|
||||
double _progressValue;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
[ObservableProperty]
|
||||
string _status2Message;
|
||||
[ObservableProperty]
|
||||
string _status3Message;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
|
||||
// Mock
|
||||
public ExportRomsViewModel()
|
||||
@@ -71,127 +91,12 @@ public sealed class ExportRomsViewModel : ViewModelBase
|
||||
_view = view;
|
||||
_romSetId = romSetId;
|
||||
FolderPath = folderPath;
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
CanClose = false;
|
||||
}
|
||||
|
||||
public string FolderPath { get; }
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public double ProgressMinimum
|
||||
{
|
||||
get => _progressMinimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMinimum, value);
|
||||
}
|
||||
|
||||
public double ProgressMaximum
|
||||
{
|
||||
get => _progressMaximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMaximum, value);
|
||||
}
|
||||
|
||||
public double ProgressValue
|
||||
{
|
||||
get => _progressValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressValue, value);
|
||||
}
|
||||
|
||||
public bool ProgressIsIndeterminate
|
||||
{
|
||||
get => _progressIsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressIsIndeterminate, value);
|
||||
}
|
||||
|
||||
public bool Progress2Visible
|
||||
{
|
||||
get => _progress2Visible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Visible, value);
|
||||
}
|
||||
|
||||
public string Status2Message
|
||||
{
|
||||
get => _status2Message;
|
||||
set => this.RaiseAndSetIfChanged(ref _status2Message, value);
|
||||
}
|
||||
|
||||
public double Progress2Minimum
|
||||
{
|
||||
get => _progress2Minimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Minimum, value);
|
||||
}
|
||||
|
||||
public double Progress2Maximum
|
||||
{
|
||||
get => _progress2Maximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Maximum, value);
|
||||
}
|
||||
|
||||
public double Progress2Value
|
||||
{
|
||||
get => _progress2Value;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Value, value);
|
||||
}
|
||||
|
||||
public bool Progress2IsIndeterminate
|
||||
{
|
||||
get => _progress2IsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2IsIndeterminate, value);
|
||||
}
|
||||
|
||||
public bool Progress3Visible
|
||||
{
|
||||
get => _progress3Visible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3Visible, value);
|
||||
}
|
||||
|
||||
public string Status3Message
|
||||
{
|
||||
get => _status3Message;
|
||||
set => this.RaiseAndSetIfChanged(ref _status3Message, value);
|
||||
}
|
||||
|
||||
public double Progress3Minimum
|
||||
{
|
||||
get => _progress3Minimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3Minimum, value);
|
||||
}
|
||||
|
||||
public double Progress3Maximum
|
||||
{
|
||||
get => _progress3Maximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3Maximum, value);
|
||||
}
|
||||
|
||||
public double Progress3Value
|
||||
{
|
||||
get => _progress3Value;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3Value, value);
|
||||
}
|
||||
|
||||
public bool Progress3IsIndeterminate
|
||||
{
|
||||
get => _progress3IsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress3IsIndeterminate, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public string FolderPath { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
void ExecuteCloseCommand() => _view.Close();
|
||||
|
||||
|
||||
@@ -4,75 +4,70 @@ using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Models;
|
||||
using RomRepoMgr.Resources;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public class ImportDatFolderViewModel : ViewModelBase
|
||||
public sealed partial class ImportDatFolderViewModel : ViewModelBase
|
||||
{
|
||||
readonly Stopwatch _stopwatch = new();
|
||||
bool _allFilesChecked;
|
||||
bool _canClose;
|
||||
bool _canStart;
|
||||
string _category;
|
||||
string[] _datFiles;
|
||||
string _folderPath;
|
||||
bool _isImporting;
|
||||
bool _isReady;
|
||||
int _listPosition;
|
||||
bool _progressIsIndeterminate;
|
||||
double _progressMaximum;
|
||||
double _progressMinimum;
|
||||
double _progressValue;
|
||||
bool _progressVisible;
|
||||
bool _recursiveChecked;
|
||||
string _statusMessage;
|
||||
int _workers;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
bool _canStart;
|
||||
[ObservableProperty]
|
||||
string _category;
|
||||
string[] _datFiles;
|
||||
[ObservableProperty]
|
||||
string _folderPath;
|
||||
[ObservableProperty]
|
||||
bool _isImporting;
|
||||
[ObservableProperty]
|
||||
bool _isReady;
|
||||
int _listPosition;
|
||||
[ObservableProperty]
|
||||
bool _progressIsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progressMaximum;
|
||||
[ObservableProperty]
|
||||
double _progressMinimum;
|
||||
[ObservableProperty]
|
||||
double _progressValue;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
bool _recursiveChecked;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
int _workers;
|
||||
|
||||
public ImportDatFolderViewModel()
|
||||
{
|
||||
CanClose = true;
|
||||
IsReady = true;
|
||||
SelectFolderCommand = ReactiveCommand.CreateFromTask(SelectFolderAsync);
|
||||
CloseCommand = ReactiveCommand.Create(Close);
|
||||
StartCommand = ReactiveCommand.Create(Start);
|
||||
SelectFolderCommand = new AsyncRelayCommand(SelectFolderAsync);
|
||||
CloseCommand = new RelayCommand(Close);
|
||||
StartCommand = new RelayCommand(Start);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SelectFolderCommand { get; }
|
||||
public Window View { get; init; }
|
||||
|
||||
public bool IsReady
|
||||
{
|
||||
get => _isReady;
|
||||
set => this.RaiseAndSetIfChanged(ref _isReady, value);
|
||||
}
|
||||
|
||||
public string FolderPath
|
||||
{
|
||||
get => _folderPath;
|
||||
set => this.RaiseAndSetIfChanged(ref _folderPath, value);
|
||||
}
|
||||
|
||||
public string Category
|
||||
{
|
||||
get => _category;
|
||||
set => this.RaiseAndSetIfChanged(ref _category, value);
|
||||
}
|
||||
public ICommand SelectFolderCommand { get; }
|
||||
public Window View { get; init; }
|
||||
|
||||
public bool AllFilesChecked
|
||||
{
|
||||
get => _allFilesChecked;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _allFilesChecked, value);
|
||||
SetProperty(ref _allFilesChecked, value);
|
||||
RefreshFiles();
|
||||
}
|
||||
}
|
||||
@@ -82,67 +77,13 @@ public class ImportDatFolderViewModel : ViewModelBase
|
||||
get => _recursiveChecked;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _recursiveChecked, value);
|
||||
SetProperty(ref _recursiveChecked, value);
|
||||
RefreshFiles();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public bool ProgressIsIndeterminate
|
||||
{
|
||||
get => _progressIsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressIsIndeterminate, value);
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public bool CanStart
|
||||
{
|
||||
get => _canStart;
|
||||
set => this.RaiseAndSetIfChanged(ref _canStart, value);
|
||||
}
|
||||
|
||||
public double ProgressMinimum
|
||||
{
|
||||
get => _progressMinimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMinimum, value);
|
||||
}
|
||||
|
||||
public double ProgressMaximum
|
||||
{
|
||||
get => _progressMaximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMaximum, value);
|
||||
}
|
||||
|
||||
public double ProgressValue
|
||||
{
|
||||
get => _progressValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressValue, value);
|
||||
}
|
||||
|
||||
public bool IsImporting
|
||||
{
|
||||
get => _isImporting;
|
||||
set => this.RaiseAndSetIfChanged(ref _isImporting, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> StartCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
public ICommand StartCommand { get; }
|
||||
public ObservableCollection<DatImporter> Importers { get; } = [];
|
||||
|
||||
void Start()
|
||||
|
||||
@@ -24,29 +24,39 @@
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class ImportDatViewModel : ViewModelBase
|
||||
public sealed partial class ImportDatViewModel : ViewModelBase
|
||||
{
|
||||
readonly ImportDat _view;
|
||||
readonly DatImporter _worker;
|
||||
bool _canClose;
|
||||
double _currentValue;
|
||||
string _errorMessage;
|
||||
bool _errorVisible;
|
||||
bool _indeterminateProgress;
|
||||
double _maximumValue;
|
||||
double _minimumValue;
|
||||
bool _progressVisible;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
double _currentValue;
|
||||
[ObservableProperty]
|
||||
string _errorMessage;
|
||||
[ObservableProperty]
|
||||
bool _errorVisible;
|
||||
[ObservableProperty]
|
||||
bool _indeterminateProgress;
|
||||
[ObservableProperty]
|
||||
double _maximumValue;
|
||||
[ObservableProperty]
|
||||
double _minimumValue;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
|
||||
// Mock
|
||||
public ImportDatViewModel() {}
|
||||
@@ -54,7 +64,7 @@ public sealed class ImportDatViewModel : ViewModelBase
|
||||
public ImportDatViewModel(ImportDat view, string datPath)
|
||||
{
|
||||
_view = view;
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
IndeterminateProgress = true;
|
||||
ProgressVisible = false;
|
||||
ErrorVisible = false;
|
||||
@@ -67,61 +77,7 @@ public sealed class ImportDatViewModel : ViewModelBase
|
||||
_worker.WorkFinished += OnWorkerOnWorkFinished;
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public bool IndeterminateProgress
|
||||
{
|
||||
get => _indeterminateProgress;
|
||||
set => this.RaiseAndSetIfChanged(ref _indeterminateProgress, value);
|
||||
}
|
||||
|
||||
public double MaximumValue
|
||||
{
|
||||
get => _maximumValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _maximumValue, value);
|
||||
}
|
||||
|
||||
public double MinimumValue
|
||||
{
|
||||
get => _minimumValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _minimumValue, value);
|
||||
}
|
||||
|
||||
public double CurrentValue
|
||||
{
|
||||
get => _currentValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _currentValue, value);
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public bool ErrorVisible
|
||||
{
|
||||
get => _errorVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _errorVisible, value);
|
||||
}
|
||||
|
||||
public string ErrorMessage
|
||||
{
|
||||
get => _errorMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _errorMessage, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
void OnWorkerOnWorkFinished(object sender, MessageEventArgs args) => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
|
||||
@@ -1,62 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reactive;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Database.Models;
|
||||
using RomRepoMgr.Models;
|
||||
using RomRepoMgr.Resources;
|
||||
using Serilog;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public class ImportRomFolderViewModel : ViewModelBase
|
||||
public sealed partial class ImportRomFolderViewModel : ViewModelBase
|
||||
{
|
||||
readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
||||
readonly ConcurrentBag<DbDisk> _newDisks = [];
|
||||
readonly ConcurrentBag<DbFile> _newFiles = [];
|
||||
readonly ConcurrentBag<DbMedia> _newMedias = [];
|
||||
readonly Stopwatch _stopwatch = new();
|
||||
bool _canClose;
|
||||
bool _canStart;
|
||||
string _folderPath;
|
||||
bool _isImporting;
|
||||
bool _isReady;
|
||||
bool _knownOnlyChecked;
|
||||
int _listPosition;
|
||||
bool _progress2IsIndeterminate;
|
||||
double _progress2Maximum;
|
||||
double _progress2Minimum;
|
||||
double _progress2Value;
|
||||
bool _progress2Visible;
|
||||
bool _progressIsIndeterminate;
|
||||
double _progressMaximum;
|
||||
double _progressMinimum;
|
||||
double _progressValue;
|
||||
bool _progressVisible;
|
||||
bool _recurseArchivesChecked;
|
||||
bool _removeFilesChecked;
|
||||
bool _removeFilesEnabled;
|
||||
FileImporter _rootImporter;
|
||||
string _statusMessage;
|
||||
string _statusMessage2;
|
||||
bool _statusMessage2Visible;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
bool _canStart;
|
||||
[ObservableProperty]
|
||||
string _folderPath;
|
||||
[ObservableProperty]
|
||||
bool _isImporting;
|
||||
[ObservableProperty]
|
||||
bool _isReady;
|
||||
[ObservableProperty]
|
||||
bool _knownOnlyChecked;
|
||||
int _listPosition;
|
||||
[ObservableProperty]
|
||||
bool _progress2IsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progress2Maximum;
|
||||
[ObservableProperty]
|
||||
double _progress2Minimum;
|
||||
[ObservableProperty]
|
||||
double _progress2Value;
|
||||
[ObservableProperty]
|
||||
bool _progress2Visible;
|
||||
[ObservableProperty]
|
||||
bool _progressIsIndeterminate;
|
||||
[ObservableProperty]
|
||||
double _progressMaximum;
|
||||
[ObservableProperty]
|
||||
double _progressMinimum;
|
||||
[ObservableProperty]
|
||||
double _progressValue;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
bool _recurseArchivesChecked;
|
||||
[ObservableProperty]
|
||||
bool _removeFilesChecked;
|
||||
[ObservableProperty]
|
||||
bool _removeFilesEnabled;
|
||||
FileImporter _rootImporter;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
string _statusMessage2;
|
||||
[ObservableProperty]
|
||||
bool _statusMessage2Visible;
|
||||
|
||||
|
||||
public ImportRomFolderViewModel()
|
||||
{
|
||||
SelectFolderCommand = ReactiveCommand.CreateFromTask(SelectFolderAsync);
|
||||
CloseCommand = ReactiveCommand.Create(Close);
|
||||
StartCommand = ReactiveCommand.Create(Start);
|
||||
SelectFolderCommand = new AsyncRelayCommand(SelectFolderAsync);
|
||||
CloseCommand = new RelayCommand(Close);
|
||||
StartCommand = new RelayCommand(Start);
|
||||
CanClose = true;
|
||||
RemoveFilesChecked = false;
|
||||
KnownOnlyChecked = true;
|
||||
@@ -64,31 +88,13 @@ public class ImportRomFolderViewModel : ViewModelBase
|
||||
RemoveFilesEnabled = false;
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> SelectFolderCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> StartCommand { get; }
|
||||
public Window View { get; init; }
|
||||
public ICommand SelectFolderCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
public ICommand StartCommand { get; }
|
||||
public Window View { get; init; }
|
||||
|
||||
public bool RecurseArchivesEnabled => Settings.Settings.UnArUsable;
|
||||
|
||||
public bool RemoveFilesChecked
|
||||
{
|
||||
get => _removeFilesChecked;
|
||||
set => this.RaiseAndSetIfChanged(ref _removeFilesChecked, value);
|
||||
}
|
||||
|
||||
public bool KnownOnlyChecked
|
||||
{
|
||||
get => _knownOnlyChecked;
|
||||
set => this.RaiseAndSetIfChanged(ref _knownOnlyChecked, value);
|
||||
}
|
||||
|
||||
public bool RemoveFilesEnabled
|
||||
{
|
||||
get => _removeFilesEnabled;
|
||||
set => this.RaiseAndSetIfChanged(ref _removeFilesEnabled, value);
|
||||
}
|
||||
|
||||
public bool RecurseArchivesChecked
|
||||
{
|
||||
get => _recurseArchivesChecked;
|
||||
@@ -97,119 +103,10 @@ public class ImportRomFolderViewModel : ViewModelBase
|
||||
if(value) RemoveFilesChecked = false;
|
||||
|
||||
RemoveFilesEnabled = !value;
|
||||
this.RaiseAndSetIfChanged(ref _recurseArchivesChecked, value);
|
||||
SetProperty(ref _recurseArchivesChecked, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReady
|
||||
{
|
||||
get => _isReady;
|
||||
set => this.RaiseAndSetIfChanged(ref _isReady, value);
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public double ProgressMinimum
|
||||
{
|
||||
get => _progressMinimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMinimum, value);
|
||||
}
|
||||
|
||||
public double ProgressMaximum
|
||||
{
|
||||
get => _progressMaximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressMaximum, value);
|
||||
}
|
||||
|
||||
public double ProgressValue
|
||||
{
|
||||
get => _progressValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressValue, value);
|
||||
}
|
||||
|
||||
public bool ProgressIsIndeterminate
|
||||
{
|
||||
get => _progressIsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressIsIndeterminate, value);
|
||||
}
|
||||
|
||||
public bool Progress2Visible
|
||||
{
|
||||
get => _progress2Visible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Visible, value);
|
||||
}
|
||||
|
||||
public bool StatusMessage2Visible
|
||||
{
|
||||
get => _statusMessage2Visible;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage2Visible, value);
|
||||
}
|
||||
|
||||
public string StatusMessage2
|
||||
{
|
||||
get => _statusMessage2;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage2, value);
|
||||
}
|
||||
|
||||
public double Progress2Minimum
|
||||
{
|
||||
get => _progress2Minimum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Minimum, value);
|
||||
}
|
||||
|
||||
public double Progress2Maximum
|
||||
{
|
||||
get => _progress2Maximum;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Maximum, value);
|
||||
}
|
||||
|
||||
public double Progress2Value
|
||||
{
|
||||
get => _progress2Value;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2Value, value);
|
||||
}
|
||||
|
||||
public bool Progress2IsIndeterminate
|
||||
{
|
||||
get => _progress2IsIndeterminate;
|
||||
set => this.RaiseAndSetIfChanged(ref _progress2IsIndeterminate, value);
|
||||
}
|
||||
|
||||
public string FolderPath
|
||||
{
|
||||
get => _folderPath;
|
||||
set => this.RaiseAndSetIfChanged(ref _folderPath, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public bool CanStart
|
||||
{
|
||||
get => _canStart;
|
||||
set => this.RaiseAndSetIfChanged(ref _canStart, value);
|
||||
}
|
||||
|
||||
public bool IsImporting
|
||||
{
|
||||
get => _isImporting;
|
||||
set => this.RaiseAndSetIfChanged(ref _isImporting, value);
|
||||
}
|
||||
|
||||
|
||||
public ObservableCollection<RomImporter> Importers { get; } = [];
|
||||
|
||||
void Start()
|
||||
@@ -339,7 +236,7 @@ public class ImportRomFolderViewModel : ViewModelBase
|
||||
});
|
||||
|
||||
_stopwatch.Stop();
|
||||
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process files.");
|
||||
Log.Debug("Took {TotalSeconds} seconds to process files", _stopwatch.Elapsed.TotalSeconds);
|
||||
|
||||
_rootImporter.SaveChanges();
|
||||
|
||||
@@ -429,7 +326,7 @@ public class ImportRomFolderViewModel : ViewModelBase
|
||||
});
|
||||
|
||||
_stopwatch.Stop();
|
||||
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process archives.");
|
||||
Log.Debug("Took {TotalSeconds} seconds to process archives", _stopwatch.Elapsed.TotalSeconds);
|
||||
|
||||
Progress2Visible = false;
|
||||
StatusMessage2Visible = false;
|
||||
@@ -440,7 +337,7 @@ public class ImportRomFolderViewModel : ViewModelBase
|
||||
void CheckArchivesFinished(object sender, EventArgs e)
|
||||
{
|
||||
_stopwatch.Stop();
|
||||
Console.WriteLine("Took {0} seconds to check archives.", _stopwatch.Elapsed.TotalSeconds);
|
||||
Log.Debug("Took {TotalSeconds} seconds to check archives", _stopwatch.Elapsed.TotalSeconds);
|
||||
|
||||
Progress2Visible = false;
|
||||
StatusMessage2Visible = false;
|
||||
|
||||
@@ -28,29 +28,33 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using MsBox.Avalonia;
|
||||
using MsBox.Avalonia.Enums;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Filesystem;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Resources;
|
||||
using RomRepoMgr.Views;
|
||||
using Serilog;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
public sealed partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
readonly MainWindow _view;
|
||||
RomSetModel _selectedRomSet;
|
||||
Vfs _vfs;
|
||||
[ObservableProperty]
|
||||
RomSetModel _selectedRomSet;
|
||||
[ObservableProperty]
|
||||
Vfs _vfs;
|
||||
|
||||
// Mock
|
||||
public MainWindowViewModel() {}
|
||||
@@ -58,19 +62,19 @@ public class MainWindowViewModel : ViewModelBase
|
||||
public MainWindowViewModel(MainWindow view, List<RomSetModel> romSets)
|
||||
{
|
||||
_view = view;
|
||||
ExitCommand = ReactiveCommand.Create(ExecuteExitCommand);
|
||||
SettingsCommand = ReactiveCommand.CreateFromTask(ExecuteSettingsCommandAsync);
|
||||
AboutCommand = ReactiveCommand.Create(ExecuteAboutCommand);
|
||||
ImportDatCommand = ReactiveCommand.CreateFromTask(ExecuteImportDatCommandAsync);
|
||||
ImportDatFolderCommand = ReactiveCommand.CreateFromTask(ExecuteImportDatFolderCommandAsync);
|
||||
ImportRomFolderCommand = ReactiveCommand.CreateFromTask(ExecuteImportRomFolderCommandAsync);
|
||||
DeleteRomSetCommand = ReactiveCommand.CreateFromTask(ExecuteDeleteRomSetCommandAsync);
|
||||
EditRomSetCommand = ReactiveCommand.Create(ExecuteEditRomSetCommand);
|
||||
ExportDatCommand = ReactiveCommand.CreateFromTask(ExecuteExportDatCommandAsync);
|
||||
ExportRomsCommand = ReactiveCommand.CreateFromTask(ExecuteExportRomsCommandAsync);
|
||||
MountCommand = ReactiveCommand.CreateFromTask(ExecuteMountCommandAsync);
|
||||
UmountCommand = ReactiveCommand.Create(ExecuteUmountCommand);
|
||||
UpdateStatsCommand = ReactiveCommand.CreateFromTask(ExecuteUpdateStatsCommandAsync);
|
||||
ExitCommand = new RelayCommand(ExecuteExitCommand);
|
||||
SettingsCommand = new AsyncRelayCommand(ExecuteSettingsCommandAsync);
|
||||
AboutCommand = new RelayCommand(ExecuteAboutCommand);
|
||||
ImportDatCommand = new AsyncRelayCommand(ExecuteImportDatCommandAsync);
|
||||
ImportDatFolderCommand = new AsyncRelayCommand(ExecuteImportDatFolderCommandAsync);
|
||||
ImportRomFolderCommand = new AsyncRelayCommand(ExecuteImportRomFolderCommandAsync);
|
||||
DeleteRomSetCommand = new AsyncRelayCommand(ExecuteDeleteRomSetCommandAsync);
|
||||
EditRomSetCommand = new RelayCommand(ExecuteEditRomSetCommand);
|
||||
ExportDatCommand = new AsyncRelayCommand(ExecuteExportDatCommandAsync);
|
||||
ExportRomsCommand = new AsyncRelayCommand(ExecuteExportRomsCommandAsync);
|
||||
MountCommand = new AsyncRelayCommand(ExecuteMountCommandAsync);
|
||||
UmountCommand = new RelayCommand(ExecuteUmountCommand);
|
||||
UpdateStatsCommand = new AsyncRelayCommand(ExecuteUpdateStatsCommandAsync);
|
||||
RomSets = new ObservableCollection<RomSetModel>(romSets);
|
||||
}
|
||||
|
||||
@@ -81,31 +85,19 @@ public class MainWindowViewModel : ViewModelBase
|
||||
NativeMenu.GetIsNativeMenuExported((Application.Current.ApplicationLifetime as
|
||||
IClassicDesktopStyleApplicationLifetime)?.MainWindow);
|
||||
|
||||
public ReactiveCommand<Unit, Unit> AboutCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ExitCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> SettingsCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDatCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportDatFolderCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ImportRomFolderCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> DeleteRomSetCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> EditRomSetCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ExportDatCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> ExportRomsCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> MountCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> UmountCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> UpdateStatsCommand { get; }
|
||||
|
||||
public Vfs Vfs
|
||||
{
|
||||
get => _vfs;
|
||||
set => this.RaiseAndSetIfChanged(ref _vfs, value);
|
||||
}
|
||||
|
||||
public RomSetModel SelectedRomSet
|
||||
{
|
||||
get => _selectedRomSet;
|
||||
set => this.RaiseAndSetIfChanged(ref _selectedRomSet, value);
|
||||
}
|
||||
public ICommand AboutCommand { get; }
|
||||
public ICommand ExitCommand { get; }
|
||||
public ICommand SettingsCommand { get; }
|
||||
public ICommand ImportDatCommand { get; }
|
||||
public ICommand ImportDatFolderCommand { get; }
|
||||
public ICommand ImportRomFolderCommand { get; }
|
||||
public ICommand DeleteRomSetCommand { get; }
|
||||
public ICommand EditRomSetCommand { get; }
|
||||
public ICommand ExportDatCommand { get; }
|
||||
public ICommand ExportRomsCommand { get; }
|
||||
public ICommand MountCommand { get; }
|
||||
public ICommand UmountCommand { get; }
|
||||
public ICommand UpdateStatsCommand { get; }
|
||||
|
||||
internal Task ExecuteSettingsCommandAsync()
|
||||
{
|
||||
@@ -279,8 +271,10 @@ public class MainWindowViewModel : ViewModelBase
|
||||
Vfs.Umounted += VfsOnUmounted;
|
||||
Vfs.MountTo(result[0].Path.LocalPath);
|
||||
}
|
||||
catch(Exception)
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error mounting VFS");
|
||||
|
||||
if(Debugger.IsAttached) throw;
|
||||
|
||||
Vfs = null;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using RomRepoMgr.Core;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Database.Models;
|
||||
@@ -35,11 +35,12 @@ using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class RemoveDatViewModel : ViewModelBase
|
||||
public sealed partial class RemoveDatViewModel : ViewModelBase
|
||||
{
|
||||
readonly long _romSetId;
|
||||
readonly RemoveDat _view;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
|
||||
// Mock
|
||||
public RemoveDatViewModel() {}
|
||||
@@ -50,12 +51,6 @@ public sealed class RemoveDatViewModel : ViewModelBase
|
||||
_romSetId = romSetId;
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
internal void OnOpened()
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
|
||||
@@ -26,14 +26,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MsBox.Avalonia;
|
||||
using MsBox.Avalonia.Enums;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Database;
|
||||
@@ -43,7 +44,7 @@ using ErrorEventArgs = RomRepoMgr.Core.EventArgs.ErrorEventArgs;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class SettingsViewModel : ViewModelBase
|
||||
public sealed partial class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
readonly SettingsDialog _view;
|
||||
bool _databaseChanged;
|
||||
@@ -53,8 +54,10 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
bool _temporaryChanged;
|
||||
string _temporaryPath;
|
||||
bool _unArChanged;
|
||||
string _unArPath;
|
||||
string _unArVersion;
|
||||
[ObservableProperty]
|
||||
string _unArPath;
|
||||
[ObservableProperty]
|
||||
string _unArVersion;
|
||||
|
||||
// Mock
|
||||
public SettingsViewModel() {}
|
||||
@@ -67,12 +70,12 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
_temporaryChanged = false;
|
||||
_unArChanged = false;
|
||||
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
UnArCommand = ReactiveCommand.CreateFromTask(ExecuteUnArCommandAsync);
|
||||
TemporaryCommand = ReactiveCommand.CreateFromTask(ExecuteTemporaryCommandAsync);
|
||||
RepositoryCommand = ReactiveCommand.CreateFromTask(ExecuteRepositoryCommandAsync);
|
||||
DatabaseCommand = ReactiveCommand.CreateFromTask(ExecuteDatabaseCommandAsync);
|
||||
SaveCommand = ReactiveCommand.Create(ExecuteSaveCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
UnArCommand = new AsyncRelayCommand(ExecuteUnArCommandAsync);
|
||||
TemporaryCommand = new AsyncRelayCommand(ExecuteTemporaryCommandAsync);
|
||||
RepositoryCommand = new AsyncRelayCommand(ExecuteRepositoryCommandAsync);
|
||||
DatabaseCommand = new AsyncRelayCommand(ExecuteDatabaseCommandAsync);
|
||||
SaveCommand = new RelayCommand(ExecuteSaveCommand);
|
||||
|
||||
DatabasePath = Settings.Settings.Current.DatabasePath;
|
||||
RepositoryPath = Settings.Settings.Current.RepositoryPath;
|
||||
@@ -82,19 +85,19 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
if(!string.IsNullOrWhiteSpace(UnArPath)) CheckUnAr();
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> UnArCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> TemporaryCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> RepositoryCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> DatabaseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ReactiveCommand<Unit, Unit> SaveCommand { get; }
|
||||
public ICommand UnArCommand { get; }
|
||||
public ICommand TemporaryCommand { get; }
|
||||
public ICommand RepositoryCommand { get; }
|
||||
public ICommand DatabaseCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
public ICommand SaveCommand { get; }
|
||||
|
||||
public string DatabasePath
|
||||
{
|
||||
get => _databasePath;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _databasePath, value);
|
||||
SetProperty(ref _databasePath, value);
|
||||
_databaseChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +107,7 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
get => _repositoryPath;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _repositoryPath, value);
|
||||
SetProperty(ref _repositoryPath, value);
|
||||
|
||||
// TODO: Refresh repository existing files
|
||||
_repositoryChanged = true;
|
||||
@@ -116,23 +119,11 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
get => _temporaryPath;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _temporaryPath, value);
|
||||
SetProperty(ref _temporaryPath, value);
|
||||
_temporaryChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
public string UnArPath
|
||||
{
|
||||
get => _unArPath;
|
||||
set => this.RaiseAndSetIfChanged(ref _unArPath, value);
|
||||
}
|
||||
|
||||
public string UnArVersion
|
||||
{
|
||||
get => _unArVersion;
|
||||
set => this.RaiseAndSetIfChanged(ref _unArVersion, value);
|
||||
}
|
||||
|
||||
void CheckUnAr()
|
||||
{
|
||||
var worker = new Compression();
|
||||
@@ -239,7 +230,7 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
var ctx = Context.Create(result);
|
||||
await ctx.Database.MigrateAsync();
|
||||
}
|
||||
catch(Exception)
|
||||
catch
|
||||
{
|
||||
btnResult = await MessageBoxManager
|
||||
.GetMessageBoxStandard(Localization.DatabaseFileUnusableMsgBoxTitle,
|
||||
@@ -254,7 +245,7 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
File.Delete(result);
|
||||
}
|
||||
catch(Exception)
|
||||
catch
|
||||
{
|
||||
await MessageBoxManager
|
||||
.GetMessageBoxStandard(Localization.DatabaseFileCannotDeleteTitle,
|
||||
@@ -263,9 +254,13 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
Icon.Error)
|
||||
.ShowWindowDialogAsync(_view);
|
||||
|
||||
#pragma warning disable ERP022
|
||||
return;
|
||||
#pragma warning restore ERP022
|
||||
}
|
||||
#pragma warning disable ERP022
|
||||
}
|
||||
#pragma warning restore ERP022
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -282,7 +277,7 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
File.Delete(result);
|
||||
}
|
||||
catch(Exception)
|
||||
catch
|
||||
{
|
||||
await MessageBoxManager
|
||||
.GetMessageBoxStandard(Localization.DatabaseFileCannotDeleteTitle,
|
||||
@@ -291,7 +286,9 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
Icon.Error)
|
||||
.ShowWindowDialogAsync(_view);
|
||||
|
||||
#pragma warning disable ERP022
|
||||
return;
|
||||
#pragma warning restore ERP022
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,7 +298,7 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
var ctx = Context.Create(result);
|
||||
await ctx.Database.MigrateAsync();
|
||||
}
|
||||
catch(Exception)
|
||||
catch
|
||||
{
|
||||
await MessageBoxManager
|
||||
.GetMessageBoxStandard(Localization.DatabaseFileUnusableMsgBoxTitle,
|
||||
@@ -310,7 +307,9 @@ public sealed class SettingsViewModel : ViewModelBase
|
||||
Icon.Error)
|
||||
.ShowWindowDialogAsync(_view);
|
||||
|
||||
#pragma warning disable ERP022
|
||||
return;
|
||||
#pragma warning restore ERP022
|
||||
}
|
||||
|
||||
DatabasePath = result;
|
||||
|
||||
@@ -26,42 +26,60 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.EventArgs;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Core.Workers;
|
||||
using RomRepoMgr.Database;
|
||||
using Serilog;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class SplashWindowViewModel : ViewModelBase
|
||||
public sealed partial class SplashWindowViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
bool _checkingUnArError;
|
||||
[ObservableProperty]
|
||||
bool _checkingUnArOk;
|
||||
[ObservableProperty]
|
||||
bool _checkingUnArUnknown;
|
||||
[ObservableProperty]
|
||||
bool _exitVisible;
|
||||
[ObservableProperty]
|
||||
bool _loadingDatabaseError;
|
||||
[ObservableProperty]
|
||||
bool _loadingDatabaseOk;
|
||||
[ObservableProperty]
|
||||
bool _loadingDatabaseUnknown;
|
||||
[ObservableProperty]
|
||||
bool _loadingRomSetsError;
|
||||
[ObservableProperty]
|
||||
bool _loadingRomSetsOk;
|
||||
[ObservableProperty]
|
||||
bool _loadingRomSetsUnknown;
|
||||
[ObservableProperty]
|
||||
bool _loadingSettingsError;
|
||||
[ObservableProperty]
|
||||
bool _loadingSettingsOk;
|
||||
[ObservableProperty]
|
||||
bool _loadingSettingsUnknown;
|
||||
[ObservableProperty]
|
||||
bool _migratingDatabaseError;
|
||||
[ObservableProperty]
|
||||
bool _migratingDatabaseOk;
|
||||
[ObservableProperty]
|
||||
bool _migratingDatabaseUnknown;
|
||||
|
||||
public SplashWindowViewModel()
|
||||
{
|
||||
ExitCommand = ReactiveCommand.Create(ExecuteExitCommand);
|
||||
ExitCommand = new RelayCommand(ExecuteExitCommand);
|
||||
|
||||
LoadingSettingsOk = false;
|
||||
LoadingSettingsError = false;
|
||||
@@ -81,103 +99,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
ExitVisible = false;
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> ExitCommand { get; }
|
||||
|
||||
public bool LoadingSettingsOk
|
||||
{
|
||||
get => _loadingSettingsOk;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingSettingsOk, value);
|
||||
}
|
||||
|
||||
public bool LoadingSettingsError
|
||||
{
|
||||
get => _loadingSettingsError;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingSettingsError, value);
|
||||
}
|
||||
|
||||
public bool LoadingSettingsUnknown
|
||||
{
|
||||
get => _loadingSettingsUnknown;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingSettingsUnknown, value);
|
||||
}
|
||||
|
||||
public bool CheckingUnArOk
|
||||
{
|
||||
get => _checkingUnArOk;
|
||||
set => this.RaiseAndSetIfChanged(ref _checkingUnArOk, value);
|
||||
}
|
||||
|
||||
public bool CheckingUnArError
|
||||
{
|
||||
get => _checkingUnArError;
|
||||
set => this.RaiseAndSetIfChanged(ref _checkingUnArError, value);
|
||||
}
|
||||
|
||||
public bool CheckingUnArUnknown
|
||||
{
|
||||
get => _checkingUnArUnknown;
|
||||
set => this.RaiseAndSetIfChanged(ref _checkingUnArUnknown, value);
|
||||
}
|
||||
|
||||
public bool LoadingDatabaseOk
|
||||
{
|
||||
get => _loadingDatabaseOk;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingDatabaseOk, value);
|
||||
}
|
||||
|
||||
public bool LoadingDatabaseError
|
||||
{
|
||||
get => _loadingDatabaseError;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingDatabaseError, value);
|
||||
}
|
||||
|
||||
public bool LoadingDatabaseUnknown
|
||||
{
|
||||
get => _loadingDatabaseUnknown;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingDatabaseUnknown, value);
|
||||
}
|
||||
|
||||
public bool MigratingDatabaseOk
|
||||
{
|
||||
get => _migratingDatabaseOk;
|
||||
set => this.RaiseAndSetIfChanged(ref _migratingDatabaseOk, value);
|
||||
}
|
||||
|
||||
public bool MigratingDatabaseError
|
||||
{
|
||||
get => _migratingDatabaseError;
|
||||
set => this.RaiseAndSetIfChanged(ref _migratingDatabaseError, value);
|
||||
}
|
||||
|
||||
public bool MigratingDatabaseUnknown
|
||||
{
|
||||
get => _migratingDatabaseUnknown;
|
||||
set => this.RaiseAndSetIfChanged(ref _migratingDatabaseUnknown, value);
|
||||
}
|
||||
|
||||
public bool ExitVisible
|
||||
{
|
||||
get => _exitVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _exitVisible, value);
|
||||
}
|
||||
|
||||
public bool LoadingRomSetsOk
|
||||
{
|
||||
get => _loadingRomSetsOk;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingRomSetsOk, value);
|
||||
}
|
||||
|
||||
public bool LoadingRomSetsError
|
||||
{
|
||||
get => _loadingRomSetsError;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingRomSetsError, value);
|
||||
}
|
||||
|
||||
public bool LoadingRomSetsUnknown
|
||||
{
|
||||
get => _loadingRomSetsUnknown;
|
||||
set => this.RaiseAndSetIfChanged(ref _loadingRomSetsUnknown, value);
|
||||
}
|
||||
public ICommand ExitCommand { get; }
|
||||
|
||||
public string LoadingText => "ROM Repository Manager";
|
||||
|
||||
@@ -198,7 +120,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Log.Error(e, "Error loading settings");
|
||||
Dispatcher.UIThread.Post(FailedLoadingSettings);
|
||||
}
|
||||
});
|
||||
@@ -227,7 +149,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Log.Error(e, "Error checking unar");
|
||||
Dispatcher.UIThread.Post(FailedCheckUnAr);
|
||||
}
|
||||
});
|
||||
@@ -259,7 +181,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Log.Error(e, "Error loading database");
|
||||
Dispatcher.UIThread.Post(FailedLoadingDatabase);
|
||||
}
|
||||
});
|
||||
@@ -289,7 +211,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Log.Error(e, "Error migrating database");
|
||||
Dispatcher.UIThread.Post(FailedMigratingDatabase);
|
||||
}
|
||||
});
|
||||
@@ -349,7 +271,7 @@ public sealed class SplashWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: Log error
|
||||
Log.Error(e, "Error loading ROM sets");
|
||||
Dispatcher.UIThread.Post(FailedLoadingRomSets);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
// Copyright © 2020-2024 Natalia Portillo
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ReactiveUI;
|
||||
using RomRepoMgr.Core.Models;
|
||||
using RomRepoMgr.Database;
|
||||
using RomRepoMgr.Database.Models;
|
||||
@@ -39,17 +39,25 @@ using RomRepoMgr.Views;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public sealed class UpdateStatsViewModel : ViewModelBase
|
||||
public sealed partial class UpdateStatsViewModel : ViewModelBase
|
||||
{
|
||||
readonly UpdateStats _view;
|
||||
bool _canClose;
|
||||
double _currentValue;
|
||||
bool _indeterminateProgress;
|
||||
double _maximumValue;
|
||||
double _minimumValue;
|
||||
bool _progressVisible;
|
||||
RomSetModel _selectedRomSet;
|
||||
string _statusMessage;
|
||||
[ObservableProperty]
|
||||
bool _canClose;
|
||||
[ObservableProperty]
|
||||
double _currentValue;
|
||||
[ObservableProperty]
|
||||
bool _indeterminateProgress;
|
||||
[ObservableProperty]
|
||||
double _maximumValue;
|
||||
[ObservableProperty]
|
||||
double _minimumValue;
|
||||
[ObservableProperty]
|
||||
bool _progressVisible;
|
||||
[ObservableProperty]
|
||||
RomSetModel _selectedRomSet;
|
||||
[ObservableProperty]
|
||||
string _statusMessage;
|
||||
|
||||
// Mock
|
||||
public UpdateStatsViewModel() {}
|
||||
@@ -57,63 +65,15 @@ public sealed class UpdateStatsViewModel : ViewModelBase
|
||||
public UpdateStatsViewModel(UpdateStats view)
|
||||
{
|
||||
_view = view;
|
||||
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
|
||||
CloseCommand = new RelayCommand(ExecuteCloseCommand);
|
||||
IndeterminateProgress = true;
|
||||
ProgressVisible = false;
|
||||
RomSets = [];
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public bool IndeterminateProgress
|
||||
{
|
||||
get => _indeterminateProgress;
|
||||
set => this.RaiseAndSetIfChanged(ref _indeterminateProgress, value);
|
||||
}
|
||||
|
||||
public double MaximumValue
|
||||
{
|
||||
get => _maximumValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _maximumValue, value);
|
||||
}
|
||||
|
||||
public double MinimumValue
|
||||
{
|
||||
get => _minimumValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _minimumValue, value);
|
||||
}
|
||||
|
||||
public double CurrentValue
|
||||
{
|
||||
get => _currentValue;
|
||||
set => this.RaiseAndSetIfChanged(ref _currentValue, value);
|
||||
}
|
||||
|
||||
public bool ProgressVisible
|
||||
{
|
||||
get => _progressVisible;
|
||||
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
|
||||
}
|
||||
|
||||
public RomSetModel SelectedRomSet
|
||||
{
|
||||
get => _selectedRomSet;
|
||||
set => this.RaiseAndSetIfChanged(ref _selectedRomSet, value);
|
||||
}
|
||||
|
||||
public bool CanClose
|
||||
{
|
||||
get => _canClose;
|
||||
set => this.RaiseAndSetIfChanged(ref _canClose, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<RomSetModel> RomSets { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
internal void OnOpened()
|
||||
{
|
||||
@@ -226,10 +186,12 @@ public sealed class UpdateStatsViewModel : ViewModelBase
|
||||
});
|
||||
});
|
||||
}
|
||||
catch(Exception)
|
||||
catch
|
||||
#pragma warning disable PH2098
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
#pragma warning restore PH2098
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
// Copyright © 2020-2024 Natalia Portillo
|
||||
*******************************************************************************/
|
||||
|
||||
using ReactiveUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace RomRepoMgr.ViewModels;
|
||||
|
||||
public class ViewModelBase : ReactiveObject {}
|
||||
public class ViewModelBase : ObservableObject;
|
||||
Reference in New Issue
Block a user