From bd575f00637492f91334101548a8aa4edc406fdc Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:19:28 -0500 Subject: [PATCH] Bump Version * Expand support for UnityGuid and Utf8String to .NET Standard --- .../UnityGuidTests.cs | 4 +- .../Utf8StringTests.cs | 2 +- .../AssetRipper.Primitives.csproj | 32 ++++++++- AssetRipper.Primitives/UnityGuid.cs | 69 ++++++++++++++++--- .../UnityGuidJsonConverter.cs | 2 +- AssetRipper.Primitives/Utf8String.cs | 14 +++- 6 files changed, 106 insertions(+), 17 deletions(-) diff --git a/AssetRipper.Primitives.Tests/UnityGuidTests.cs b/AssetRipper.Primitives.Tests/UnityGuidTests.cs index 4732ed1..0912829 100644 --- a/AssetRipper.Primitives.Tests/UnityGuidTests.cs +++ b/AssetRipper.Primitives.Tests/UnityGuidTests.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET5_0_OR_GREATER using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -83,7 +83,7 @@ public void ToBytesMethod() { Guid originalGuid = Guid.NewGuid(); UnityGuid tobyteArrayGuid = new UnityGuid(originalGuid.ToByteArray()); - UnityGuid memoryMarshallGuid = new UnityGuid(MemoryMarshal.Cast(new ReadOnlySpan(in originalGuid))); + UnityGuid memoryMarshallGuid = Unsafe.As(ref originalGuid); Assert.That(memoryMarshallGuid, Is.EqualTo(tobyteArrayGuid)); } } diff --git a/AssetRipper.Primitives.Tests/Utf8StringTests.cs b/AssetRipper.Primitives.Tests/Utf8StringTests.cs index 60ef87b..a825e25 100644 --- a/AssetRipper.Primitives.Tests/Utf8StringTests.cs +++ b/AssetRipper.Primitives.Tests/Utf8StringTests.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET5_0_OR_GREATER namespace AssetRipper.Primitives.Tests; public class Utf8StringTests diff --git a/AssetRipper.Primitives/AssetRipper.Primitives.csproj b/AssetRipper.Primitives/AssetRipper.Primitives.csproj index d5ae9fa..98d51d5 100644 --- a/AssetRipper.Primitives/AssetRipper.Primitives.csproj +++ b/AssetRipper.Primitives/AssetRipper.Primitives.csproj @@ -6,7 +6,7 @@ enable ds5678 AssetRipper - 2.1.0 + 2.1.1 $(Version) AssetRipper.Primitives C# assetripper unity unity3d @@ -36,4 +36,34 @@ + + + 1.1.1 + + + 4.5.5 + + + 8.0.1 + + + + + + 8.0.1 + + + + + + 8.0.1 + + + + + + 8.0.1 + + + diff --git a/AssetRipper.Primitives/UnityGuid.cs b/AssetRipper.Primitives/UnityGuid.cs index 80fd799..48a3fbe 100644 --- a/AssetRipper.Primitives/UnityGuid.cs +++ b/AssetRipper.Primitives/UnityGuid.cs @@ -1,6 +1,8 @@ -#if NET7_0_OR_GREATER +#if NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER using System.Buffers.Binary; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; @@ -13,9 +15,13 @@ public readonly record struct UnityGuid { public UnityGuid(Guid guid) { +#if NET5_0_OR_GREATER Span guidData = stackalloc byte[16]; bool success = guid.TryWriteBytes(guidData); Debug.Assert(success); +#else + Span guidData = guid.ToByteArray(); +#endif ConvertSystemOrUnityBytes(guidData, guidData); Data0 = ReadUInt32LittleEndian(guidData, 0); Data1 = ReadUInt32LittleEndian(guidData, 1); @@ -44,10 +50,24 @@ public static UnityGuid NewGuid() //This is not an acceptable way to convert between Unity and System Guids. //We only do it this way to efficiently get 16 random bytes. //We don't care about official Guid validity because Unity does not care either. - Guid guid = Guid.NewGuid(); - ReadOnlySpan guidSpan = new ReadOnlySpan(in guid); - ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(guidSpan); - return new UnityGuid(byteSpan); + if (Unsafe.SizeOf() == Unsafe.SizeOf()) + { + Guid guid = Guid.NewGuid(); + return Unsafe.As(ref guid); + } + else + { + return ThrowOrReturnDefault(); + } + + static UnityGuid ThrowOrReturnDefault() + { +#if DEBUG + throw new InvalidCastException($"{nameof(UnityGuid)} struct size does not match {nameof(Guid)}."); +#else + return default; +#endif + } } public static explicit operator UnityGuid(Guid systemGuid) => new UnityGuid(systemGuid); @@ -57,7 +77,11 @@ public static explicit operator Guid(UnityGuid unityGuid) Span span = stackalloc byte[16]; unityGuid.Write(span); ConvertSystemOrUnityBytes(span, span); +#if NET5_0_OR_GREATER return new Guid(span); +#else + return new Guid(span.ToArray()); +#endif } private void Write(Span span) @@ -79,7 +103,16 @@ public override string ToString() { Span span = stackalloc char[32]; ToString(span); - return new string(span); + return CreateString(span); + + static string CreateString(Span span) + { +#if NET5_0_OR_GREATER + return new string(span); +#else + return new string(span.ToArray()); +#endif + } } public void ToString(Span buffer) @@ -193,15 +226,31 @@ private static void ConvertSystemOrUnityBytes(scoped ReadOnlySpan input, s /// A stable guid corresponding to the . public static UnityGuid Md5Hash(scoped ReadOnlySpan input) { - byte[] hashBytes = MD5.HashData(input); - ConvertSystemOrUnityBytes(hashBytes, hashBytes); - return new UnityGuid(hashBytes); + Span buffer = stackalloc byte[16]; + HashData(input, buffer); + ConvertSystemOrUnityBytes(buffer, buffer); + return new UnityGuid(buffer); + } + + private static void HashData(ReadOnlySpan data, Span buffer) + { +#if NET5_0_OR_GREATER + MD5.HashData(data, buffer); +#else + MD5.Create().ComputeHash(data.ToArray()).AsSpan().CopyTo(buffer); +#endif } public static UnityGuid Md5Hash(scoped ReadOnlySpan assemblyName, scoped ReadOnlySpan @namespace, scoped ReadOnlySpan className) { int length = assemblyName.Length + @namespace.Length + className.Length; - Span input = length < 1024 ? stackalloc byte[length] : GC.AllocateUninitializedArray(length); + Span input = length < 1024 + ? stackalloc byte[length] +#if NET5_0_OR_GREATER + : GC.AllocateUninitializedArray(length); +#else + : new byte[length]; +#endif assemblyName.CopyTo(input); @namespace.CopyTo(input.Slice(assemblyName.Length)); className.CopyTo(input.Slice(assemblyName.Length + @namespace.Length)); diff --git a/AssetRipper.Primitives/UnityGuidJsonConverter.cs b/AssetRipper.Primitives/UnityGuidJsonConverter.cs index 1394950..492f39a 100644 --- a/AssetRipper.Primitives/UnityGuidJsonConverter.cs +++ b/AssetRipper.Primitives/UnityGuidJsonConverter.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER using System.Text.Json; using System.Text.Json.Serialization; diff --git a/AssetRipper.Primitives/Utf8String.cs b/AssetRipper.Primitives/Utf8String.cs index 2216ce4..27d87c6 100644 --- a/AssetRipper.Primitives/Utf8String.cs +++ b/AssetRipper.Primitives/Utf8String.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -60,7 +60,14 @@ public string String public override int GetHashCode() { HashCode hash = new(); +#if NET6_0_OR_GREATER hash.AddBytes(data); +#else + foreach (byte b in data) + { + hash.Add(b); + } +#endif return hash.ToHashCode(); } @@ -198,7 +205,10 @@ public static Utf8String Concat(Utf8String? string1, Utf8String? string2, Utf8St public static Utf8String Concat(params Utf8String?[] values) { - ArgumentNullException.ThrowIfNull(values); + if (values is null) + { + throw new ArgumentNullException(nameof(values)); + } int totalLength = 0; foreach (Utf8String? value in values)