From 7d0ff88595fb2703eba67f9369c3685d41f94d9f Mon Sep 17 00:00:00 2001 From: krauthaufen Date: Tue, 21 May 2024 12:02:37 +0200 Subject: [PATCH] removed usages of UnsafeCoerce --- RELEASE_NOTES.md | 3 + .../Extensions/ArrayExtensions.cs | 116 +++++++++++++++--- src/Aardvark.Base/Extensions/UnsafeCoerce.cs | 9 +- .../Random/ForcedRandomSeries.cs | 6 +- 4 files changed, 114 insertions(+), 20 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 06a1104f1..c5cb793a3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +### 5.2.30 +* removed UnsafeCoerce usages and several other net6.0+ fixes + ### 5.2.29 * Fixed color parsing to be independent of the current culture (regression in 5.2.27) * Added more value variants for Dictionary, Dict, and SymbolDict functions diff --git a/src/Aardvark.Base/Extensions/ArrayExtensions.cs b/src/Aardvark.Base/Extensions/ArrayExtensions.cs index 20edf0f9b..ff119ad3e 100644 --- a/src/Aardvark.Base/Extensions/ArrayExtensions.cs +++ b/src/Aardvark.Base/Extensions/ArrayExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -2360,11 +2361,29 @@ public static byte[] ComputeMD5Hash(this byte[] data) /// Computes the MD5 hash of the data array. /// /// 128bit/16byte data hash - public static byte[] ComputeMD5Hash(this Array data) + public static unsafe byte[] ComputeMD5Hash(this Array data) { - byte[] hash = null; - data.UnsafeCoercedApply(array => hash = array.ComputeMD5Hash()); - return hash; + var gc = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + var ptr = gc.AddrOfPinnedObject(); + byte[] hash = null; + using (var md5 = SHA1.Create()) + { + using (var s = new UnmanagedMemoryStream((byte*)ptr, data.Length, data.Length, + FileAccess.Read)) + { + hash = md5.ComputeHash(s); + } + } + + Array.Resize(ref hash, 16); + return hash; + } + finally + { + gc.Free(); + } } /// @@ -2390,11 +2409,27 @@ public static byte[] ComputeSHA1Hash(this byte[] data) /// Computes the SHA1 hash of the data array. /// /// 160bit/20byte data hash - public static byte[] ComputeSHA1Hash(this Array data) + public static unsafe byte[] ComputeSHA1Hash(this Array data) { - byte[] hash = null; - data.UnsafeCoercedApply(array => hash = array.ComputeSHA1Hash()); - return hash; + var gc = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + var ptr = gc.AddrOfPinnedObject(); + byte[] hash = null; + using (var sha1 = SHA1.Create()) + { + using (var s = new UnmanagedMemoryStream((byte*)ptr, data.Length, data.Length, + FileAccess.Read)) + { + hash = sha1.ComputeHash(s); + } + } + return hash; + } + finally + { + gc.Free(); + } } /// @@ -2420,11 +2455,27 @@ public static byte[] ComputeSHA256Hash(this byte[] data) /// Computes the SHA256 hash of the data array. /// /// 256bit/32byte data hash - public static byte[] ComputeSHA256Hash(this Array data) + public static unsafe byte[] ComputeSHA256Hash(this Array data) { - byte[] hash = null; - data.UnsafeCoercedApply(array => hash = array.ComputeSHA256Hash()); - return hash; + var gc = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + var ptr = gc.AddrOfPinnedObject(); + byte[] hash = null; + using (var sha256 = SHA256.Create()) + { + using (var s = new UnmanagedMemoryStream((byte*)ptr, data.Length, data.Length, + FileAccess.Read)) + { + hash = sha256.ComputeHash(s); + } + } + return hash; + } + finally + { + gc.Free(); + } } /// @@ -2450,11 +2501,27 @@ public static byte[] ComputeSHA512Hash(this byte[] data) /// Computes the SHA512 hash of the data array. /// /// 512bit/64byte data hash - public static byte[] ComputeSHA512Hash(this Array data) + public static unsafe byte[] ComputeSHA512Hash(this Array data) { - byte[] hash = null; - data.UnsafeCoercedApply(array => hash = array.ComputeSHA512Hash()); - return hash; + var gc = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + var ptr = gc.AddrOfPinnedObject(); + byte[] hash = null; + using (var sha512 = SHA512.Create()) + { + using (var s = new UnmanagedMemoryStream((byte*)ptr, data.Length, data.Length, + FileAccess.Read)) + { + hash = sha512.ComputeHash(s); + } + } + return hash; + } + finally + { + gc.Free(); + } } /// @@ -2479,10 +2546,23 @@ public static uint ComputeAdler32Checksum(this byte[] data) /// /// Computes a checksum of the data array using the Adler-32 algorithm (). /// - public static uint ComputeAdler32Checksum(this Array data) + public static unsafe uint ComputeAdler32Checksum(this Array data) { var a = new Adler32(); - data.UnsafeCoercedApply(array => a.Update(array)); + var gc = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + var ptr = gc.AddrOfPinnedObject(); + using (var s = new UnmanagedMemoryStream((byte*)ptr.ToPointer(), data.Length, data.Length, + FileAccess.Read)) + { + a.Update(s); + } + } + finally + { + gc.Free(); + } return a.Checksum; } diff --git a/src/Aardvark.Base/Extensions/UnsafeCoerce.cs b/src/Aardvark.Base/Extensions/UnsafeCoerce.cs index 21726cd2d..59a07b7ba 100644 --- a/src/Aardvark.Base/Extensions/UnsafeCoerce.cs +++ b/src/Aardvark.Base/Extensions/UnsafeCoerce.cs @@ -6,7 +6,8 @@ namespace Aardvark.Base public static class ArrayUnsafeCoerceExtensions { #region UnsafeCoerce - + + [Obsolete("breaks net8.0+")] public static IntPtr GetTypeIdUncached() where T : struct { @@ -19,6 +20,7 @@ public static IntPtr GetTypeIdUncached() private static FastConcurrentDict s_typeIds = new FastConcurrentDict(); + [Obsolete("breaks net8.0+")] private static IntPtr GetTypeId() where T : struct { @@ -30,6 +32,7 @@ private static IntPtr GetTypeId() return typeId; } + [Obsolete("breaks net8.0+")] internal static int GetCLRSize(Type t) { // TODO: somehow make use of sizeof operator -> requires compile time type -> cannot use ILGenerator in .net standard @@ -38,6 +41,7 @@ internal static int GetCLRSize(Type t) return Marshal.SizeOf(t); } + [Obsolete("breaks net8.0+")] internal static TR[] UnsafeCoerce(this Array input, IntPtr targetId) where TR : struct { @@ -63,12 +67,14 @@ internal static TR[] UnsafeCoerce(this Array input, IntPtr targetId) /// Both types must be structs and you may cause memory leaks when the array-byte-sizes are not multiple of each other /// WARNING: destroys the original array /// + [Obsolete("breaks net8.0+")] public static TR[] UnsafeCoerce(this Array input) where TR : struct { return UnsafeCoerce(input, GetTypeId()); } + [Obsolete("breaks net8.0+")] internal static void UnsafeCoercedApply(this Array input, Action action, IntPtr targetId) where TR : struct { @@ -95,6 +101,7 @@ internal static void UnsafeCoercedApply(this Array input, Action actio gcHandle.Free(); } + [Obsolete("breaks net8.0+")] public static void UnsafeCoercedApply(this Array input, Action action) where TR : struct { diff --git a/src/Aardvark.Base/Random/ForcedRandomSeries.cs b/src/Aardvark.Base/Random/ForcedRandomSeries.cs index 4b1e2be29..7253c54c4 100644 --- a/src/Aardvark.Base/Random/ForcedRandomSeries.cs +++ b/src/Aardvark.Base/Random/ForcedRandomSeries.cs @@ -1,4 +1,6 @@ using System.IO; +using System.Runtime.InteropServices; +using System; namespace Aardvark.Base { @@ -28,7 +30,9 @@ public static V2i[] ReadSeries(string frsSqFile) if (matrixSize * matrixSize * 8 != bytes.Length) throw new InvalidDataException("Forced Random series data has invalid length."); - return bytes.UnsafeCoerce(); + var dst = new V2i[bytes.Length / 8]; + bytes.AsSpan().CopyTo(MemoryMarshal.AsBytes(dst.AsSpan())); + return dst; } ///