Skip to content

Commit

Permalink
Bump Version
Browse files Browse the repository at this point in the history
* Expand support for UnityGuid and Utf8String to .NET Standard
  • Loading branch information
ds5678 committed Jan 15, 2024
1 parent 0a6b003 commit bd575f0
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 17 deletions.
4 changes: 2 additions & 2 deletions AssetRipper.Primitives.Tests/UnityGuidTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if NET7_0_OR_GREATER
#if NET5_0_OR_GREATER
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

Expand Down Expand Up @@ -83,7 +83,7 @@ public void ToBytesMethod()
{
Guid originalGuid = Guid.NewGuid();
UnityGuid tobyteArrayGuid = new UnityGuid(originalGuid.ToByteArray());
UnityGuid memoryMarshallGuid = new UnityGuid(MemoryMarshal.Cast<Guid, byte>(new ReadOnlySpan<Guid>(in originalGuid)));
UnityGuid memoryMarshallGuid = Unsafe.As<Guid, UnityGuid>(ref originalGuid);
Assert.That(memoryMarshallGuid, Is.EqualTo(tobyteArrayGuid));
}
}
Expand Down
2 changes: 1 addition & 1 deletion AssetRipper.Primitives.Tests/Utf8StringTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if NET7_0_OR_GREATER
#if NET5_0_OR_GREATER
namespace AssetRipper.Primitives.Tests;

public class Utf8StringTests
Expand Down
32 changes: 31 additions & 1 deletion AssetRipper.Primitives/AssetRipper.Primitives.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<Version>2.1.0</Version>
<Version>2.1.1</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<PackageId>AssetRipper.Primitives</PackageId>
<PackageTags>C# assetripper unity unity3d</PackageTags>
Expand Down Expand Up @@ -36,4 +36,34 @@
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.HashCode">
<Version>1.1.1</Version>
</PackageReference>
<PackageReference Include="System.Memory">
<Version>4.5.5</Version>
</PackageReference>
<PackageReference Include="System.Text.Json">
<Version>8.0.1</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<PackageReference Include="System.Text.Json">
<Version>8.0.1</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="System.Text.Json">
<Version>8.0.1</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="System.Text.Json">
<Version>8.0.1</Version>
</PackageReference>
</ItemGroup>

</Project>
69 changes: 59 additions & 10 deletions AssetRipper.Primitives/UnityGuid.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -13,9 +15,13 @@ public readonly record struct UnityGuid
{
public UnityGuid(Guid guid)
{
#if NET5_0_OR_GREATER
Span<byte> guidData = stackalloc byte[16];
bool success = guid.TryWriteBytes(guidData);
Debug.Assert(success);
#else
Span<byte> guidData = guid.ToByteArray();
#endif
ConvertSystemOrUnityBytes(guidData, guidData);
Data0 = ReadUInt32LittleEndian(guidData, 0);
Data1 = ReadUInt32LittleEndian(guidData, 1);
Expand Down Expand Up @@ -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<Guid> guidSpan = new ReadOnlySpan<Guid>(in guid);
ReadOnlySpan<byte> byteSpan = MemoryMarshal.AsBytes(guidSpan);
return new UnityGuid(byteSpan);
if (Unsafe.SizeOf<Guid>() == Unsafe.SizeOf<UnityGuid>())
{
Guid guid = Guid.NewGuid();
return Unsafe.As<Guid, UnityGuid>(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);
Expand All @@ -57,7 +77,11 @@ public static explicit operator Guid(UnityGuid unityGuid)
Span<byte> 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<byte> span)
Expand All @@ -79,7 +103,16 @@ public override string ToString()
{
Span<char> span = stackalloc char[32];
ToString(span);
return new string(span);
return CreateString(span);

static string CreateString(Span<char> span)
{
#if NET5_0_OR_GREATER
return new string(span);
#else
return new string(span.ToArray());
#endif
}
}

public void ToString(Span<char> buffer)
Expand Down Expand Up @@ -193,15 +226,31 @@ private static void ConvertSystemOrUnityBytes(scoped ReadOnlySpan<byte> input, s
/// <returns>A stable guid corresponding to the <paramref name="input"/>.</returns>
public static UnityGuid Md5Hash(scoped ReadOnlySpan<byte> input)
{
byte[] hashBytes = MD5.HashData(input);
ConvertSystemOrUnityBytes(hashBytes, hashBytes);
return new UnityGuid(hashBytes);
Span<byte> buffer = stackalloc byte[16];
HashData(input, buffer);
ConvertSystemOrUnityBytes(buffer, buffer);
return new UnityGuid(buffer);
}

private static void HashData(ReadOnlySpan<byte> data, Span<byte> 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<byte> assemblyName, scoped ReadOnlySpan<byte> @namespace, scoped ReadOnlySpan<byte> className)
{
int length = assemblyName.Length + @namespace.Length + className.Length;
Span<byte> input = length < 1024 ? stackalloc byte[length] : GC.AllocateUninitializedArray<byte>(length);
Span<byte> input = length < 1024
? stackalloc byte[length]
#if NET5_0_OR_GREATER
: GC.AllocateUninitializedArray<byte>(length);
#else
: new byte[length];
#endif
assemblyName.CopyTo(input);
@namespace.CopyTo(input.Slice(assemblyName.Length));
className.CopyTo(input.Slice(assemblyName.Length + @namespace.Length));
Expand Down
2 changes: 1 addition & 1 deletion AssetRipper.Primitives/UnityGuidJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
14 changes: 12 additions & 2 deletions AssetRipper.Primitives/Utf8String.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit bd575f0

Please sign in to comment.