From 18553744322f6a062a25a1633a536c55601641eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JasonXuDeveloper=20-=20=E5=82=91?= Date: Sat, 16 Nov 2024 14:16:15 +1100 Subject: [PATCH] release v3.0.4 ## Nino.Serialization v3.0.4 - [Fix] Skip collecting static public members - [Feat] Support \`ReadOnlySpan\` for deserialization --- src/Nino.Core/Reader.cs | 19 ++++++++----------- src/Nino.Generator/DeserializerGenerator.cs | 4 ++-- src/Nino.Generator/NinoTypeHelper.cs | 21 ++++++++++++++------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Nino.Core/Reader.cs b/src/Nino.Core/Reader.cs index 41fbca1..803ccb7 100644 --- a/src/Nino.Core/Reader.cs +++ b/src/Nino.Core/Reader.cs @@ -7,9 +7,9 @@ namespace Nino.Core { public ref struct Reader { - private Span _data; + private ReadOnlySpan _data; - public Reader(Span buffer) + public Reader(ReadOnlySpan buffer) { _data = buffer; } @@ -50,7 +50,7 @@ public bool ReadCollectionHeader(out int length) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out T value) where T : unmanaged { - value = Unsafe.ReadUnaligned(ref _data[0]); + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(_data)); _data = _data.Slice(Unsafe.SizeOf()); } @@ -84,7 +84,7 @@ public void Read(out T[] ret) where T : unmanaged ret = new T[length]; #endif ref byte first = ref Unsafe.As(ref ret[0]); - Unsafe.CopyBlockUnaligned(ref first, ref bytes[0], (uint)bytes.Length); + Unsafe.CopyBlockUnaligned(ref first, ref MemoryMarshal.GetReference(bytes), (uint)bytes.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -123,7 +123,7 @@ public void Read(out List ret) where T : unmanaged var arr = new T[length]; #endif ref byte first = ref Unsafe.As(ref arr[0]); - Unsafe.CopyBlockUnaligned(ref first, ref bytes[0], (uint)bytes.Length); + Unsafe.CopyBlockUnaligned(ref first, ref MemoryMarshal.GetReference(bytes), (uint)bytes.Length); lst._items = arr; } @@ -213,7 +213,7 @@ public void ReadUtf8(out string ret) #if NET5_0_OR_GREATER unsafe { - ret = string.Create(length, (IntPtr)Unsafe.AsPointer(ref utf8Bytes[0]), + ret = string.Create(length, (IntPtr)Unsafe.AsPointer(ref MemoryMarshal.GetReference(utf8Bytes)), (dst, ptr) => { var src = new Span((byte*)ptr, length); @@ -245,17 +245,14 @@ public void Read(out string ret) GetBytes(length * sizeof(char), out var utf16Bytes); #if NET5_0_OR_GREATER - ret = new string( - MemoryMarshal.CreateReadOnlySpan( - ref Unsafe.As(ref utf16Bytes[0]), - length)); + ret = new string(MemoryMarshal.Cast(utf16Bytes)); #else ret = MemoryMarshal.Cast(utf16Bytes).ToString(); #endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void GetBytes(int length, out Span bytes) + private void GetBytes(int length, out ReadOnlySpan bytes) { bytes = _data.Slice(0, length); _data = _data.Slice(length); diff --git a/src/Nino.Generator/DeserializerGenerator.cs b/src/Nino.Generator/DeserializerGenerator.cs index 45627b2..c0d8bc1 100644 --- a/src/Nino.Generator/DeserializerGenerator.cs +++ b/src/Nino.Generator/DeserializerGenerator.cs @@ -84,9 +84,9 @@ public static partial class Deserializer {{GeneratePrivateDeserializeImplMethodBody("T", " ", "", "where T : unmanaged")}} [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Deserialize(Span data, out T value) where T : unmanaged + public static void Deserialize(ReadOnlySpan data, out T value) where T : unmanaged { - value = Unsafe.ReadUnaligned(ref data[0]); + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(data)); } {{GeneratePrivateDeserializeImplMethodBody("T[]", " ", "", "where T : unmanaged")}} diff --git a/src/Nino.Generator/NinoTypeHelper.cs b/src/Nino.Generator/NinoTypeHelper.cs index 766f0bd..28f4f0b 100644 --- a/src/Nino.Generator/NinoTypeHelper.cs +++ b/src/Nino.Generator/NinoTypeHelper.cs @@ -581,7 +581,7 @@ public static string GeneratePublicDeserializeMethodBody(this string typeName, s { var ret = $$""" [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Deserialize{{typeParam}}(Span data, out {{typeName}} value) {{genericConstraint}} + public static void Deserialize{{typeParam}}(ReadOnlySpan data, out {{typeName}} value) {{genericConstraint}} { var reader = new Reader(data); Deserialize(out value, ref reader); @@ -698,16 +698,18 @@ public static List GetNinoTypeMembers( if (m is IFieldSymbol fieldSymbol) { - //has to be public - return fieldSymbol.DeclaredAccessibility == Accessibility.Public; + //has to be public and not static + return fieldSymbol.DeclaredAccessibility == Accessibility.Public && + !fieldSymbol.IsStatic; } if (m is IPropertySymbol propertySymbol) { - //has to be public and has getter and setter + //has to be public and has getter and setter and not static return propertySymbol.DeclaredAccessibility == Accessibility.Public && propertySymbol.GetMethod != null && - propertySymbol.SetMethod != null; + propertySymbol.SetMethod != null && + !propertySymbol.IsStatic; } return false; @@ -718,7 +720,10 @@ public static List GetNinoTypeMembers( { // Retrieve all public instance constructors var publicConstructors = namedTypeSymbol.InstanceConstructors - .Where(c => c.DeclaredAccessibility == Accessibility.Public && !c.IsImplicitlyDeclared) + .Where(c => c.DeclaredAccessibility == Accessibility.Public + && !c.IsImplicitlyDeclared + && !c.IsStatic + ) .ToList(); foreach (var constructor in publicConstructors) @@ -728,7 +733,9 @@ public static List GetNinoTypeMembers( { var matchingProperty = namedTypeSymbol.GetMembers() .OfType() - .FirstOrDefault(p => p.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase)); + .FirstOrDefault(p => + p.Name.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) + && !p.IsStatic); // If any parameter does not have a matching readonly property, it’s likely not a primary constructor if (matchingProperty == null || !matchingProperty.IsReadOnly)