diff --git a/Aaru6.Checksums/FletcherContext.cs b/Aaru6.Checksums/FletcherContext.cs
index 1376214..f0a26f8 100644
--- a/Aaru6.Checksums/FletcherContext.cs
+++ b/Aaru6.Checksums/FletcherContext.cs
@@ -32,7 +32,9 @@
// Disabled because the speed is abnormally slow
+using System;
using System.IO;
+using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes.Interfaces;
using Aaru.Helpers;
@@ -315,20 +317,29 @@ namespace Aaru6.Checksums
{
const byte FLETCHER_MODULE = 0xFF;
const byte NMAX = 22;
- byte _sum1, _sum2;
+
+ readonly IntPtr _nativeContext;
+ byte _sum1, _sum2;
+ readonly bool _useNative;
/// Initializes the Fletcher-16 sums
public Fletcher16Context()
{
_sum1 = 0xFF;
_sum2 = 0xFF;
+
+ if(!Native.IsSupported)
+ return;
+
+ _nativeContext = fletcher16_init();
+ _useNative = _nativeContext != IntPtr.Zero;
}
///
/// Updates the hash with data.
/// Data buffer.
/// Length of buffer to hash.
- public void Update(byte[] data, uint len) => Step(ref _sum1, ref _sum2, data, len);
+ public void Update(byte[] data, uint len) => Step(ref _sum1, ref _sum2, data, len, _useNative, _nativeContext);
///
/// Updates the hash with data.
@@ -341,6 +352,12 @@ namespace Aaru6.Checksums
{
ushort finalSum = (ushort)((_sum2 << 8) | _sum1);
+ if(!_useNative)
+ return BigEndianBitConverter.GetBytes(finalSum);
+
+ fletcher16_final(_nativeContext, ref finalSum);
+ fletcher16_free(_nativeContext);
+
return BigEndianBitConverter.GetBytes(finalSum);
}
@@ -348,8 +365,15 @@ namespace Aaru6.Checksums
/// Returns a hexadecimal representation of the hash value.
public string End()
{
- ushort finalSum = (ushort)((_sum2 << 8) | _sum1);
- var fletcherOutput = new StringBuilder();
+ ushort finalSum = (ushort)((_sum2 << 8) | _sum1);
+
+ if(_useNative)
+ {
+ fletcher16_final(_nativeContext, ref finalSum);
+ fletcher16_free(_nativeContext);
+ }
+
+ var fletcherOutput = new StringBuilder();
for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
@@ -357,8 +381,28 @@ namespace Aaru6.Checksums
return fletcherOutput.ToString();
}
- static void Step(ref byte previousSum1, ref byte previousSum2, byte[] data, uint len)
+ [DllImport("libAaru.Checksums.Native", SetLastError = true)]
+ static extern IntPtr fletcher16_init();
+
+ [DllImport("libAaru.Checksums.Native", SetLastError = true)]
+ static extern int fletcher16_update(IntPtr ctx, byte[] data, uint len);
+
+ [DllImport("libAaru.Checksums.Native", SetLastError = true)]
+ static extern int fletcher16_final(IntPtr ctx, ref ushort checksum);
+
+ [DllImport("libAaru.Checksums.Native", SetLastError = true)]
+ static extern void fletcher16_free(IntPtr ctx);
+
+ static void Step(ref byte previousSum1, ref byte previousSum2, byte[] data, uint len, bool useNative,
+ IntPtr nativeContext)
{
+ if(useNative)
+ {
+ fletcher16_update(nativeContext, data, len);
+
+ return;
+ }
+
uint sum1 = previousSum1;
uint sum2 = previousSum2;
uint n;
@@ -502,6 +546,17 @@ namespace Aaru6.Checksums
/// Byte array of the hash value.
public static string File(string filename, out byte[] hash)
{
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher16_init();
+
+ if(nativeContext == IntPtr.Zero)
+ useNative = false;
+ }
+
var fileStream = new FileStream(filename, FileMode.Open);
byte localSum1 = 0xFF;
@@ -512,13 +567,19 @@ namespace Aaru6.Checksums
while(read > 0)
{
- Step(ref localSum1, ref localSum2, buffer, (uint)read);
+ Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
read = fileStream.Read(buffer, 0, 65536);
}
ushort finalSum = (ushort)((localSum2 << 8) | localSum1);
+ if(useNative)
+ {
+ fletcher16_final(nativeContext, ref finalSum);
+ fletcher16_free(nativeContext);
+ }
+
hash = BigEndianBitConverter.GetBytes(finalSum);
var fletcherOutput = new StringBuilder();
@@ -537,13 +598,30 @@ namespace Aaru6.Checksums
/// Byte array of the hash value.
public static string Data(byte[] data, uint len, out byte[] hash)
{
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher16_init();
+
+ if(nativeContext == IntPtr.Zero)
+ useNative = false;
+ }
+
byte localSum1 = 0xFF;
byte localSum2 = 0xFF;
- Step(ref localSum1, ref localSum2, data, len);
+ Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
ushort finalSum = (ushort)((localSum2 << 8) | localSum1);
+ if(useNative)
+ {
+ fletcher16_final(nativeContext, ref finalSum);
+ fletcher16_free(nativeContext);
+ }
+
hash = BigEndianBitConverter.GetBytes(finalSum);
var adlerOutput = new StringBuilder();
diff --git a/AaruBenchmark/Checksums/Aaru.cs b/AaruBenchmark/Checksums/Aaru.cs
index c6fded4..7a37adb 100644
--- a/AaruBenchmark/Checksums/Aaru.cs
+++ b/AaruBenchmark/Checksums/Aaru.cs
@@ -148,12 +148,12 @@ namespace AaruBenchmark.Checksums
IChecksum ctx = new CRC16CCITTContext();
ctx.Update(data);
byte[] result = ctx.Final();
- /*
- if(result?.Length != _expectedRandomCrc16Ccitt.Length)
- throw new Exception("Invalid hash length");
- if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
- throw new Exception("Invalid hash value");*/
+ if(result?.Length != _expectedRandomCrc16Ccitt.Length)
+ throw new Exception("Invalid hash length");
+
+ if(result.Where((t, i) => t != _expectedRandomCrc16Ccitt[i]).Any())
+ throw new Exception("Invalid hash value");
}
public static void Crc16()
diff --git a/AaruBenchmark/Checksums/Aaru6.cs b/AaruBenchmark/Checksums/Aaru6.cs
index d0d2563..7a40034 100644
--- a/AaruBenchmark/Checksums/Aaru6.cs
+++ b/AaruBenchmark/Checksums/Aaru6.cs
@@ -77,6 +77,8 @@ namespace AaruBenchmark.Checksums
public static void Fletcher16()
{
+ Native.ForceManaged = true;
+
byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
diff --git a/AaruBenchmark/Checksums/AaruNative.cs b/AaruBenchmark/Checksums/AaruNative.cs
index 663fa8a..c4a8f42 100644
--- a/AaruBenchmark/Checksums/AaruNative.cs
+++ b/AaruBenchmark/Checksums/AaruNative.cs
@@ -76,18 +76,6 @@ namespace AaruBenchmark.Checksums
0xb5, 0xf2, 0x8c, 0xbb, 0x4a, 0xa5, 0x1b, 0x40, 0x7c, 0xb6
};
- [DllImport("libAaru.Checksums.Native", SetLastError = true)]
- static extern IntPtr fletcher16_init();
-
- [DllImport("libAaru.Checksums.Native", SetLastError = true)]
- static extern int fletcher16_update(IntPtr ctx, byte[] data, uint len);
-
- [DllImport("libAaru.Checksums.Native", SetLastError = true)]
- static extern int fletcher16_final(IntPtr ctx, ref ushort crc);
-
- [DllImport("libAaru.Checksums.Native", SetLastError = true)]
- static extern void fletcher16_free(IntPtr ctx);
-
[DllImport("libAaru.Checksums.Native", SetLastError = true)]
static extern IntPtr fletcher32_init();
@@ -114,38 +102,23 @@ namespace AaruBenchmark.Checksums
public static void Fletcher16()
{
- byte[] data = new byte[1048576];
- ushort fletcher16 = 0;
- byte[] hash;
+ Native.ForceManaged = false;
+
+ byte[] data = new byte[1048576];
var fs = new FileStream(Path.Combine(Program.Folder, "random"), FileMode.Open, FileAccess.Read);
fs.Read(data, 0, 1048576);
fs.Close();
fs.Dispose();
+ IChecksum ctx = new Fletcher16Context();
+ ctx.Update(data);
+ byte[] result = ctx.Final();
- IntPtr ctx = fletcher16_init();
+ if(result?.Length != _expectedRandomFletcher16.Length)
+ throw new Exception("Invalid hash length");
- if(ctx == IntPtr.Zero)
- throw new Exception("Could not initialize digest");
-
- int ret = fletcher16_update(ctx, data, (uint)data.Length);
-
- if(ret != 0)
- throw new Exception("Could not digest block");
-
- ret = fletcher16_final(ctx, ref fletcher16);
-
- if(ret != 0)
- throw new Exception("Could not finalize hash");
-
- fletcher16_free(ctx);
-
- fletcher16 = (ushort)((fletcher16 << 8) | (fletcher16 >> 8));
-
- hash = BitConverter.GetBytes(fletcher16);
-
- if(hash.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
+ if(result.Where((t, i) => t != _expectedRandomFletcher16[i]).Any())
throw new Exception("Invalid hash value");
}