From 23e8539500edc71e17ac685c2790c0c2d922a300 Mon Sep 17 00:00:00 2001 From: StarBeats <977663818@qq.com> Date: Wed, 22 Oct 2025 21:39:13 +0800 Subject: [PATCH] add AssetDependencyGraph --- .../AssetDependencyGraph-Editor.asmdef | 16 + .../AssetDependencyGraph-Editor.asmdef.meta | 7 + AssetDependencyGraph/Editor.meta | 8 + AssetDependencyGraph/Editor/AssetDefine.cs | 323 +++++ .../Editor/AssetDefine.cs.meta | 11 + .../Editor/AssetDependencyGraph.cs | 207 ++- .../Editor/AssetDependencyGraph.cs.meta | 11 + AssetDependencyGraph/Plugins.meta | 8 + .../Plugins/MemoryPack.Core.meta | 8 + .../Plugins/MemoryPack.Core/Attributes.cs | 166 +++ .../MemoryPack.Core/Attributes.cs.meta | 11 + .../Plugins/MemoryPack.Core/Compression.meta | 8 + .../Compression/BitPackFormatter.cs | 181 +++ .../Compression/BitPackFormatter.cs.meta | 11 + .../Compression/BrotliCompressor.cs | 338 +++++ .../Compression/BrotliCompressor.cs.meta | 11 + .../Compression/BrotliDecompressor.cs | 162 +++ .../Compression/BrotliDecompressor.cs.meta | 11 + .../Compression/BrotliFormatter.cs | 213 +++ .../Compression/BrotliFormatter.cs.meta | 11 + .../CustomFormatterAttributes.cs | 136 ++ .../CustomFormatterAttributes.cs.meta | 11 + .../Plugins/MemoryPack.Core/Formatters.meta | 8 + .../Formatters/ArrayFormatters.cs | 228 +++ .../Formatters/ArrayFormatters.cs.meta | 11 + .../Formatters/BigIntegerFormatter.cs | 55 + .../Formatters/BigIntegerFormatter.cs.meta | 11 + .../Formatters/BitArrayFormatter.cs | 67 + .../Formatters/BitArrayFormatter.cs.meta | 11 + .../Formatters/CollectionFormatters.cs | 1201 ++++++++++++++++ .../Formatters/CollectionFormatters.cs.meta | 11 + .../Formatters/CultureInfoFormatter.cs | 40 + .../Formatters/CultureInfoFormatter.cs.meta | 11 + .../Formatters/DynamicUnionFormatter.cs | 65 + .../Formatters/DynamicUnionFormatter.cs.meta | 11 + .../Formatters/GenericCollectionFormatters.cs | 182 +++ .../GenericCollectionFormatters.cs.meta | 11 + .../InterfaceCollectionFormatters.cs | 725 ++++++++++ .../InterfaceCollectionFormatters.cs.meta | 11 + .../Formatters/KeyValuePairFormatter.cs | 92 ++ .../Formatters/KeyValuePairFormatter.cs.meta | 11 + .../Formatters/LazyFormatter.cs | 46 + .../Formatters/LazyFormatter.cs.meta | 11 + .../Formatters/MemoryPackableFormatter.cs | 36 + .../MemoryPackableFormatter.cs.meta | 11 + .../MultiDimensionalArrayFormatters.cs | 373 +++++ .../MultiDimensionalArrayFormatters.cs.meta | 11 + .../Formatters/NullableFormatter.cs | 65 + .../Formatters/NullableFormatter.cs.meta | 11 + .../Formatters/StringBuilderFormatter.cs | 83 ++ .../Formatters/StringBuilderFormatter.cs.meta | 11 + .../Formatters/StringFormatter.cs | 279 ++++ .../Formatters/StringFormatter.cs.meta | 11 + .../Formatters/TimeZoneInfoFormatter.cs | 38 + .../Formatters/TimeZoneInfoFormatter.cs.meta | 11 + .../Formatters/TupleFormatter.cs | 657 +++++++++ .../Formatters/TupleFormatter.cs.meta | 11 + .../Formatters/TypeFormatter.cs | 62 + .../Formatters/TypeFormatter.cs.meta | 11 + .../Formatters/UnmanagedFormatter.cs | 58 + .../Formatters/UnmanagedFormatter.cs.meta | 11 + .../Formatters/UriFormatter.cs | 41 + .../Formatters/UriFormatter.cs.meta | 11 + .../Formatters/VersionFormatter.cs | 63 + .../Formatters/VersionFormatter.cs.meta | 11 + .../MemoryPack.Core/IMemoryPackFormatter.cs | 76 + .../IMemoryPackFormatter.cs.meta | 11 + .../MemoryPack.Core/IMemoryPackable.cs | 42 + .../MemoryPack.Core/IMemoryPackable.cs.meta | 11 + .../Plugins/MemoryPack.Core/Internal.meta | 8 + .../Internal/EnumerableExtensions.cs | 43 + .../Internal/EnumerableExtensions.cs.meta | 11 + .../Internal/FixedArrayBufferWriter.cs | 69 + .../Internal/FixedArrayBufferWriter.cs.meta | 11 + .../MemoryPack.Core/Internal/MathEx.cs | 30 + .../MemoryPack.Core/Internal/MathEx.cs.meta | 11 + .../Internal/MemoryMarshalEx.cs | 35 + .../Internal/MemoryMarshalEx.cs.meta | 11 + .../Internal/PreserveAttribute.cs | 18 + .../Internal/PreserveAttribute.cs.meta | 11 + .../ReusableLinkedArrayBufferWriter.cs | 395 ++++++ .../ReusableLinkedArrayBufferWriter.cs.meta | 11 + .../ReusableReadOnlySequenceBuilder.cs | 158 +++ .../ReusableReadOnlySequenceBuilder.cs.meta | 11 + .../MemoryPack.Core/Internal/TypeHelpers.cs | 114 ++ .../Internal/TypeHelpers.cs.meta | 11 + .../Plugins/MemoryPack.Core/MemoryPackCode.cs | 35 + .../MemoryPack.Core/MemoryPackCode.cs.meta | 11 + ...oryPackFormatterProvider.WellknownTypes.cs | 144 ++ ...ckFormatterProvider.WellknownTypes.cs.meta | 11 + .../MemoryPackFormatterProvider.cs | 458 ++++++ .../MemoryPackFormatterProvider.cs.meta | 11 + .../MemoryPackReader.Unmanaged.cs | 620 ++++++++ .../MemoryPackReader.Unmanaged.cs.meta | 11 + .../MemoryPack.Core/MemoryPackReader.cs | 930 ++++++++++++ .../MemoryPack.Core/MemoryPackReader.cs.meta | 11 + .../MemoryPackReaderOptionalState.cs | 82 ++ .../MemoryPackReaderOptionalState.cs.meta | 11 + .../MemoryPackReaderWriter.VarInt.cs | 448 ++++++ .../MemoryPackReaderWriter.VarInt.cs.meta | 11 + .../MemoryPackSerializationException.cs | 154 ++ .../MemoryPackSerializationException.cs.meta | 11 + .../MemoryPackSerializer.Deserialize.cs | 160 +++ .../MemoryPackSerializer.Deserialize.cs.meta | 11 + .../MemoryPackSerializer.NonGenerics.cs | 244 ++++ .../MemoryPackSerializer.NonGenerics.cs.meta | 11 + .../MemoryPackSerializer.Serialize.cs | 213 +++ .../MemoryPackSerializer.Serialize.cs.meta | 11 + .../MemoryPackSerializerOptions.cs | 40 + .../MemoryPackSerializerOptions.cs.meta | 11 + .../MemoryPackWriter.Unmanaged.cs | 1250 +++++++++++++++++ .../MemoryPackWriter.Unmanaged.cs.meta | 11 + .../MemoryPack.Core/MemoryPackWriter.cs | 715 ++++++++++ .../MemoryPack.Core/MemoryPackWriter.cs.meta | 11 + .../MemoryPackWriterOptionalState.cs | 122 ++ .../MemoryPackWriterOptionalState.cs.meta | 11 + .../Plugins/MemoryPack.Generator.meta | 8 + .../MemoryPack.Generator.Roslyn3.dll | Bin 0 -> 125952 bytes .../MemoryPack.Generator.Roslyn3.dll.meta | 71 + .../Plugins/MemoryPack.Unity.meta | 8 + .../MemoryPack.Unity/ProviderInitializer.cs | 64 + .../ProviderInitializer.cs.meta | 11 + .../MemoryPack.Unity/UnityFormatters.cs | 134 ++ .../MemoryPack.Unity/UnityFormatters.cs.meta | 11 + .../Plugins/Microsoft.Bcl.AsyncInterfaces.dll | Bin 0 -> 26920 bytes .../Microsoft.Bcl.AsyncInterfaces.dll.meta | 33 + .../Plugins/System.IO.Pipelines.dll | Bin 0 -> 84792 bytes .../Plugins/System.IO.Pipelines.dll.meta | 33 + ...System.Runtime.CompilerServices.Unsafe.dll | Bin 0 -> 18024 bytes ...m.Runtime.CompilerServices.Unsafe.dll.meta | 33 + .../Plugins/System.Text.Encodings.Web.dll | Bin 0 -> 79664 bytes .../System.Text.Encodings.Web.dll.meta | 33 + .../Plugins/System.Text.Json.dll | Bin 0 -> 742672 bytes .../Plugins/System.Text.Json.dll.meta | 33 + UnityDependencyAnalyzer/AssetDefine.cs | 2 + UnityDependencyAnalyzer/DependencyAnalysis.cs | 48 +- UnityDependencyAnalyzer/Program.cs | 2 +- .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../UnityDependencyAnalyzer.csproj | 1 - .../UnityDependencyAnalyzer.csproj.user | 2 +- UnityDependencyAnalyzer/UnityLmdb.cs | 24 +- 141 files changed, 13898 insertions(+), 97 deletions(-) create mode 100644 AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef create mode 100644 AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef.meta create mode 100644 AssetDependencyGraph/Editor.meta create mode 100644 AssetDependencyGraph/Editor/AssetDefine.cs create mode 100644 AssetDependencyGraph/Editor/AssetDefine.cs.meta rename AssetDependencyGraph.cs => AssetDependencyGraph/Editor/AssetDependencyGraph.cs (85%) create mode 100644 AssetDependencyGraph/Editor/AssetDependencyGraph.cs.meta create mode 100644 AssetDependencyGraph/Plugins.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Generator.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Unity.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs.meta create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs create mode 100644 AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs.meta create mode 100644 AssetDependencyGraph/Plugins/Microsoft.Bcl.AsyncInterfaces.dll create mode 100644 AssetDependencyGraph/Plugins/Microsoft.Bcl.AsyncInterfaces.dll.meta create mode 100644 AssetDependencyGraph/Plugins/System.IO.Pipelines.dll create mode 100644 AssetDependencyGraph/Plugins/System.IO.Pipelines.dll.meta create mode 100644 AssetDependencyGraph/Plugins/System.Runtime.CompilerServices.Unsafe.dll create mode 100644 AssetDependencyGraph/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta create mode 100644 AssetDependencyGraph/Plugins/System.Text.Encodings.Web.dll create mode 100644 AssetDependencyGraph/Plugins/System.Text.Encodings.Web.dll.meta create mode 100644 AssetDependencyGraph/Plugins/System.Text.Json.dll create mode 100644 AssetDependencyGraph/Plugins/System.Text.Json.dll.meta diff --git a/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef b/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef new file mode 100644 index 0000000..e107d52 --- /dev/null +++ b/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "AssetDependencyGraph-Editor", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef.meta b/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef.meta new file mode 100644 index 0000000..ce2967d --- /dev/null +++ b/AssetDependencyGraph/AssetDependencyGraph-Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0f6edbbfd6f04b1479b191b629a0421f +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Editor.meta b/AssetDependencyGraph/Editor.meta new file mode 100644 index 0000000..f500c85 --- /dev/null +++ b/AssetDependencyGraph/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9303f9c952516f34cbc668b8d9217ee7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Editor/AssetDefine.cs b/AssetDependencyGraph/Editor/AssetDefine.cs new file mode 100644 index 0000000..db6f69d --- /dev/null +++ b/AssetDependencyGraph/Editor/AssetDefine.cs @@ -0,0 +1,323 @@ +using MemoryPack; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace AssetDependencyGraph +{ + [BsonIgnoreExtraElements] + [MemoryPackable] + public partial class AssetIdentify + { + public string Path = null!; + public string AssetType = null!; + public string Guid; + public string Md5; + } + + public sealed class AssetIdentifyJsonConverter : JsonConverter + { + static JsonSerializerOptions serializerOptions = new JsonSerializerOptions() { IncludeFields = true }; + + public override AssetIdentify? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(reader.GetString()!, serializerOptions); + } + + public override void Write(Utf8JsonWriter writer, AssetIdentify value, JsonSerializerOptions options) + { + writer.WriteStringValue(JsonSerializer.Serialize(value, serializerOptions)); + } + + public override AssetIdentify ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return Read(ref reader, typeToConvert, serializerOptions)!; + } + + public override void WriteAsPropertyName(Utf8JsonWriter writer, [DisallowNull] AssetIdentify value, JsonSerializerOptions options) + { + writer.WritePropertyName(JsonSerializer.Serialize(value, serializerOptions)); + } + } + + [BsonIgnoreExtraElements] + [MemoryPackable] + public partial class AssetNode + { + public AssetIdentify Self = null!; + public string AssetType = null!; + [JsonIgnore] + [MemoryPackIgnore] + public ConcurrentBag Dependencies = new(); + [JsonIgnore] + [MemoryPackIgnore] + public ConcurrentBag Dependent = new(); + + [AllowNull] + public HashSet DependencySet; + [AllowNull] + public HashSet DependentSet; + } + + public sealed class AssetNodeJsonConverter : JsonConverter + { + static JsonSerializerOptions serializerOptions = new JsonSerializerOptions() + { + IncludeFields = true, + Converters = { new AssetIdentifyJsonConverter() } + }; + + public override AssetNode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(reader.GetString()!, serializerOptions); + } + + public override void Write(Utf8JsonWriter writer, AssetNode value, JsonSerializerOptions options) + { + writer.WriteStringValue(JsonSerializer.Serialize(value, serializerOptions)); + } + } + + [BsonIgnoreExtraElements] + public sealed class FolderNode : AssetNode + { + } + + [BsonIgnoreExtraElements] + public sealed class PackageNode : AssetNode + { + } + + public class AssetDependencyGraphDB + { + MongoClient client; + IMongoCollection FolderNodes; + IMongoCollection PackageNodes; + IMongoCollection AssetNodes; + Dictionary findCacheDic = new(); + + public AssetDependencyGraphDB(string user, string passwd, string ip) + { + MongoClientSettings settings; + if (string.IsNullOrWhiteSpace(user) && !string.IsNullOrEmpty(ip)) + { + settings = MongoClientSettings.FromUrl(new MongoUrl($"mongodb://{ip}:27017/")); + } + else + { + settings = MongoClientSettings.FromUrl(new MongoUrl($"mongodb://{user}:{passwd}@{ip}:27017/")); + } + + settings.ConnectTimeout = TimeSpan.FromSeconds(5); + settings.MinConnectionPoolSize = 1; + settings.MaxConnectionPoolSize = 25; + client = new MongoClient(settings); + var db = client.GetDatabase("assetgraph"); + FolderNodes = db.GetCollection("folder_nodes"); + PackageNodes = db.GetCollection("package_nodes"); + AssetNodes = db.GetCollection("asset_nodes"); + } + + public void Clean() + { + client.DropDatabase("assetgraph"); + var db = client.GetDatabase("assetgraph"); + FolderNodes = db.GetCollection("folder_nodes"); + PackageNodes = db.GetCollection("package_nodes"); + AssetNodes = db.GetCollection("asset_nodes"); + } + + public void Insert(T node) where T : AssetNode + { + switch (node) + { + case FolderNode folderNode: + { + FolderNodes.InsertOne(folderNode); + break; + } + case PackageNode packageNode: + { + PackageNodes.InsertOne(packageNode); + break; + } + case AssetNode assetNode: + { + AssetNodes.InsertOne(assetNode); + break; + } + default: + break; + } + } + + public void UpdateOrInsert(T node) where T : AssetNode + { + switch (node) + { + case FolderNode folderNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = FolderNodes.Find(filter); + if (found == null || found.CountDocuments() == 0) + { + FolderNodes.InsertOne(folderNode); + } + else + { + var result = FolderNodes.UpdateOne(filter, Builders.Update.Combine( + Builders.Update.Set(fn => fn.Self, folderNode.Self), + Builders.Update.Set(fn => fn.AssetType, folderNode.AssetType), + Builders.Update.Set(fn => fn.Dependencies, folderNode.Dependencies), + Builders.Update.Set(fn => fn.Dependent, folderNode.Dependent) + )); + } + + break; + } + case PackageNode packageNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = PackageNodes.Find(filter); + if (found == null || found.CountDocuments() == 0) + { + PackageNodes.InsertOne(packageNode); + } + else + { + var result = PackageNodes.UpdateOne(filter, Builders.Update.Combine( + Builders.Update.Set(fn => fn.Self, packageNode.Self), + Builders.Update.Set(fn => fn.AssetType, packageNode.AssetType), + Builders.Update.Set(fn => fn.Dependencies, packageNode.Dependencies), + Builders.Update.Set(fn => fn.Dependent, packageNode.Dependent) + )); + } + break; + } + case AssetNode assetNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = AssetNodes.Find(filter); + if (found == null || found.CountDocuments() == 0) + { + AssetNodes.InsertOne(assetNode); + } + else + { + var result = AssetNodes.UpdateOne(filter, Builders.Update.Combine( + Builders.Update.Set(fn => fn.Self, assetNode.Self), + Builders.Update.Set(fn => fn.AssetType, assetNode.AssetType), + Builders.Update.Set(fn => fn.Dependencies, assetNode.Dependencies), + Builders.Update.Set(fn => fn.Dependent, assetNode.Dependent) + )); + } + break; + } + default: + break; + } + } + + public void Delete(T node) where T : AssetNode + { + switch (node) + { + case FolderNode folderNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = FolderNodes.Find(filter); + if (found != null && found.CountDocuments() == 0) + { + // TODO: del ref dep + FolderNodes.DeleteOne(filter); + } + break; + } + case PackageNode packageNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = PackageNodes.Find(filter); + if (found != null && found.CountDocuments() == 0) + { + // TODO: del ref dep + PackageNodes.DeleteOne(filter); + } + break; + } + case AssetNode assetNode: + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, node.Self.Path) + ); + var found = AssetNodes.Find(filter); + if (found != null && found.CountDocuments() == 0) + { + // TODO: del ref dep + AssetNodes.DeleteOne(filter); + } + break; + } + default: + break; + } + } + + public AssetNode Find(string path) + { + if (findCacheDic.TryGetValue(path, out var assetNode)) + { + return assetNode; + } + + var filter = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, path) + ); + var found = AssetNodes.Find(filter); + if (found != null && found.CountDocuments() != 0) + { + assetNode = found.First(); + findCacheDic[path] = assetNode; + return assetNode; + } + + var filter1 = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, path) + ); + var found1 = PackageNodes.Find(filter1); + if (found1 != null && found1.CountDocuments() != 0) + { + assetNode = found1.First(); + findCacheDic[path] = assetNode; + return assetNode; + } + + var filter2 = Builders.Filter.And( + Builders.Filter.Eq(fn => fn.Self.Path, path) + ); + var found2 = FolderNodes.Find(filter2); + if (found2 != null && found2.CountDocuments() != 0) + { + assetNode = found2.First(); + findCacheDic[path] = assetNode; + return assetNode; + } + + return null!; + } + } +} diff --git a/AssetDependencyGraph/Editor/AssetDefine.cs.meta b/AssetDependencyGraph/Editor/AssetDefine.cs.meta new file mode 100644 index 0000000..184b12b --- /dev/null +++ b/AssetDependencyGraph/Editor/AssetDefine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b678f0fc58371c4cb7735b9906443fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph.cs b/AssetDependencyGraph/Editor/AssetDependencyGraph.cs similarity index 85% rename from AssetDependencyGraph.cs rename to AssetDependencyGraph/Editor/AssetDependencyGraph.cs index e8a4c99..533f70d 100644 --- a/AssetDependencyGraph.cs +++ b/AssetDependencyGraph/Editor/AssetDependencyGraph.cs @@ -1,7 +1,8 @@ +using MemoryPack; +using Sirenix.Utilities; +using System; using System.Collections.Generic; using System.IO; -using System.Text.Json; -using System.Threading.Tasks; using UnityEditor; using UnityEditor.Experimental.GraphView; using UnityEditor.UIElements; @@ -33,6 +34,7 @@ namespace AssetDependencyGraph background.StretchToParentSize(); } + } public class AssetGroup @@ -72,7 +74,9 @@ namespace AssetDependencyGraph private static Dictionary assetId2NodeDic; private static Dictionary path2NodeIdDic; - + private static Dictionary guid2PathDic = new(); + private static Dictionary path2GuidDic = new(); + static AssetNode FindAssetNode(string path) { if (path2NodeIdDic.TryGetValue(path, out var id)) @@ -109,25 +113,71 @@ namespace AssetDependencyGraph return false; } + private static string GUIDToPath(string guid) + { + if(guid2PathDic != null) + { + if (guid2PathDic.ContainsKey(guid)) + { + return guid2PathDic[guid]; + } + } + return AssetDatabase.GUIDToAssetPath(guid); + } + + private static string PathToGUID(string path) + { + if(path2NodeIdDic != null) + { + if(path2NodeIdDic.ContainsKey(path)) + { + return path2GuidDic[path]; + } + } + + return AssetDatabase.AssetPathToGUID(path); + } + void ResolveDependency() { - var dependencyGraph = Path.Combine(Application.dataPath.Replace("Assets", ""), "Library", "dependencyGraph.json"); + System.Diagnostics.Stopwatch stopwatch = new(); + + var projectPath = Application.dataPath.Replace("Assets", ""); + var libraryPath = Path.Combine(projectPath, "Library"); + var dependencyGraph = Path.Combine(libraryPath, "dependencyGraph.bin"); if (!File.Exists(dependencyGraph)) { EditorUtility.DisplayDialog("提示", "需要解析引用关系", "确认"); return; } - var js = File.ReadAllText(dependencyGraph); - assetId2NodeDic = JsonSerializer.Deserialize>(js, options: new JsonSerializerOptions() + + var bytes = File.ReadAllBytes(dependencyGraph); + stopwatch.Restart(); + + assetId2NodeDic = MemoryPackSerializer.Deserialize>(bytes.AsSpan()); + + var guid2pathBinPath = Path.Combine(libraryPath, "guid2path.bin"); + if (File.Exists(guid2pathBinPath)) { - IncludeFields = true, - Converters = { new AssetIdentifyJsonConverter(), new AssetNodeJsonConverter() } - }); + guid2PathDic = MemoryPackSerializer.Deserialize>(File.ReadAllBytes(guid2pathBinPath)); + } + + var path2guidBinPath = Path.Combine(libraryPath, "path2guid.bin"); + if (File.Exists(path2guidBinPath)) + { + path2GuidDic = MemoryPackSerializer.Deserialize>(File.ReadAllBytes(path2guidBinPath)); + } + + stopwatch.Stop(); + Debug.Log($"Deserialize {stopwatch.ElapsedMilliseconds}"); + stopwatch.Restart(); path2NodeIdDic = new(); foreach (var node in assetId2NodeDic) { path2NodeIdDic[node.Key.Path] = node.Key; } + stopwatch.Stop(); + Debug.Log($"ResolveDependency {stopwatch.ElapsedMilliseconds}"); } void CreateGraph() @@ -168,7 +218,7 @@ namespace AssetDependencyGraph toolbar.Add(options); toolbar.Add(new Button(ExploreAsset) { - text = "Explore Asset", + text = "展示选择对象引用关系", }); toolbar.Add(new Button(ClearGraph) { @@ -184,21 +234,21 @@ namespace AssetDependencyGraph }); toolbar.Add(new Button(() => { - Task.Run(() => + System.Diagnostics.Stopwatch stopwatch = new(); + stopwatch.Restart(); + System.Diagnostics.Process.Start(startInfo: new() { - System.Diagnostics.Process.Start(startInfo: new() - { - FileName = $"{Application.dataPath}/../Tools/UnityDependencyAnalyzer.exe", - Arguments = $"{Application.dataPath.Replace("Assets", "")} \" \" \" \" localhost ", - UseShellExecute = true, - }) - .WaitForExit(); - - ResolveDependency(); - }); + FileName = $"{Application.dataPath}/../Tools/UnityDependencyAnalyzer.exe", + Arguments = $"-reference {Application.dataPath.Replace("Assets", "")} \" \" \" \" localhost ", + UseShellExecute = true, + }) + .WaitForExit(); + stopwatch.Stop(); + Debug.Log($"resolve {stopwatch.ElapsedMilliseconds}"); + ResolveDependency(); }) { - text = "Analyze Reference" + text = "分析或更新引用" }); var ts = new ToolbarSearchField(); @@ -271,13 +321,32 @@ namespace AssetDependencyGraph return toolbar; } + private static string GetAnalyzedAssetPath(UnityEngine.Object obj) + { + return AssetDatabase.GetAssetPath(obj).Replace('\\', '/').ToLowerInvariant(); + } + + private static void OnDeleteAsset(UnityEngine.Object asset) + { + var path = GetAnalyzedAssetPath(asset); + var delAssetNode = FindAssetNode(path); + foreach (var dependency in delAssetNode.DependencySet) + { + assetId2NodeDic[dependency].DependentSet.Remove(delAssetNode.Self); + } + + assetId2NodeDic.Remove(delAssetNode.Self); + path2NodeIdDic.Remove(path); + } + private void ExploreAsset() { Object[] objs = Selection.objects; - if(path2NodeIdDic == null || path2NodeIdDic.Count == 0) + if (path2NodeIdDic == null || path2NodeIdDic.Count == 0) { ResolveDependency(); } + foreach (var obj in objs) { //Prevent readding same object @@ -289,7 +358,7 @@ namespace AssetDependencyGraph selectedObjects.Add(obj); AssetGroup AssetGroup = new AssetGroup(); - AssetGroup.AssetNode = FindAssetNode(AssetDatabase.GetAssetPath(obj).Replace('\\', '/').ToLowerInvariant()); + AssetGroup.AssetNode = FindAssetNode(GetAnalyzedAssetPath(obj)); assetGroups.Add(AssetGroup); // assetPath will be empty if obj is null or isn't an asset (a scene object) @@ -400,11 +469,9 @@ namespace AssetDependencyGraph } var fullPath = dependAssetId.Path; - Debug.Log(fullPath); if (IsGuid(fullPath)) { - fullPath = AssetDatabase.GUIDToAssetPath(fullPath); - Debug.Log(fullPath); + fullPath = GUIDToPath(fullPath); } var obj = AssetDatabase.LoadMainAssetAtPath(fullPath); if(obj == null) @@ -493,11 +560,9 @@ namespace AssetDependencyGraph continue; } var fullPath = dependAssetId.Path; - Debug.Log(fullPath); if (IsGuid(fullPath)) { - fullPath = AssetDatabase.GUIDToAssetPath(fullPath); - Debug.Log(fullPath); + fullPath = GUIDToPath(fullPath); } var obj = AssetDatabase.LoadMainAssetAtPath(fullPath); if (obj == null) @@ -606,13 +671,13 @@ namespace AssetDependencyGraph { title = obj.name, style = - { - width = NodeWidth - } + { + width = NodeWidth + } }; objNode.extensionContainer.style.backgroundColor = new Color(0.24f, 0.24f, 0.24f, 0.8f); - + #region Select button objNode.titleContainer.Add(new Button(() => { @@ -648,6 +713,7 @@ namespace AssetDependencyGraph { if (EditorUtility.DisplayDialog("提示", "当前 asset 没有引用,是否直接删除", "确认删除", "取消")) { + OnDeleteAsset(obj); AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(obj)); } } @@ -708,15 +774,23 @@ namespace AssetDependencyGraph { style = { - paddingBottom = 4.0f, - paddingTop = 4.0f, - paddingLeft = 4.0f, - paddingRight = 4.0f, - backgroundColor = GetColorByAssetType(typeName) - } + paddingBottom = 4.0f, + paddingTop = 4.0f, + paddingLeft = 4.0f, + paddingRight = 4.0f, + backgroundColor = GetColorByAssetType(typeName) + } }; objNode.extensionContainer.Add(typeContainer); + objNode.RegisterCallback(e => + { + }); + + objNode.RegisterCallback(e => + { + + }); #region Node Icon, replaced with color //Texture assetTexture = AssetPreview.GetAssetPreview(obj); @@ -755,19 +829,19 @@ namespace AssetDependencyGraph { Port port = objNode.InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(Object)); port.Add(new Button(() => - { - CreateDependentNodes(assetGroup, assetNode, fullPathNodeLookup[fullPath], assetGroup.GroupNode, (int)fullPathNodeLookup[fullPath].userData - 1); - EditorApplication.delayCall += () => ResetAllNodes(); - }) - { - style = - { - height = 16.0f, - alignSelf = Align.Center, - alignItems = Align.Center - }, - text = "展开" - }); + { + CreateDependentNodes(assetGroup, assetNode, fullPathNodeLookup[fullPath], assetGroup.GroupNode, (int)fullPathNodeLookup[fullPath].userData - 1); + EditorApplication.delayCall += () => ResetAllNodes(); + }) + { + style = + { + height = 16.0f, + alignSelf = Align.Center, + alignItems = Align.Center + }, + text = "展开" + }); port.portName = dependentAmount + "个引用"; objNode.inputContainer.Add(port); } @@ -777,20 +851,19 @@ namespace AssetDependencyGraph { Port port = objNode.InstantiatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Single, typeof(Object)); port.Add(new Button(() => - { - CreateDependencyNodes(assetGroup, assetNode, fullPathNodeLookup[fullPath], assetGroup.GroupNode, (int)fullPathNodeLookup[fullPath].userData + 1); - EditorApplication.delayCall += () => ResetAllNodes(); - - }) - { - style = - { - height = 16.0f, - alignSelf = Align.Center, - alignItems = Align.FlexEnd - }, - text = "展开" - }); + { + CreateDependencyNodes(assetGroup, assetNode, fullPathNodeLookup[fullPath], assetGroup.GroupNode, (int)fullPathNodeLookup[fullPath].userData + 1); + EditorApplication.delayCall += () => ResetAllNodes(); + }) + { + style = + { + height = 16.0f, + alignSelf = Align.Center, + alignItems = Align.FlexEnd + }, + text = "展开" + }); port.portName = dependencyAmount + "个依赖"; objNode.outputContainer.Add(port); objNode.RefreshPorts(); diff --git a/AssetDependencyGraph/Editor/AssetDependencyGraph.cs.meta b/AssetDependencyGraph/Editor/AssetDependencyGraph.cs.meta new file mode 100644 index 0000000..d9fbff0 --- /dev/null +++ b/AssetDependencyGraph/Editor/AssetDependencyGraph.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43eecbcf2afaca84aa2af29388e193de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins.meta b/AssetDependencyGraph/Plugins.meta new file mode 100644 index 0000000..3d17c62 --- /dev/null +++ b/AssetDependencyGraph/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9acdcfd297aa7ad4a91bbfde679a3688 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core.meta new file mode 100644 index 0000000..3ea5100 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 590b08b0771f0bd47beca317303e050f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs new file mode 100644 index 0000000..8ca56e5 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack { + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackableAttribute : Attribute +{ + public GenerateType GenerateType { get; } + public SerializeLayout SerializeLayout { get; } + + // ctor parameter is parsed in MemoryPackGenerator.Parser TypeMeta for detect which ctor used in MemoryPack.Generator. + // if modify ctor, be careful. + + /// + /// [generateType, (VersionTolerant or CircularReference) ? SerializeLayout.Explicit : SerializeLayout.Sequential] + /// + /// + public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object) + { + this.GenerateType = generateType; + this.SerializeLayout = (generateType == GenerateType.VersionTolerant || generateType == GenerateType.CircularReference) + ? SerializeLayout.Explicit + : SerializeLayout.Sequential; + } + + /// + /// [GenerateType.Object, serializeLayout] + /// + public MemoryPackableAttribute(SerializeLayout serializeLayout) + { + this.GenerateType = GenerateType.Object; + this.SerializeLayout = serializeLayout; + } + + public MemoryPackableAttribute(GenerateType generateType, SerializeLayout serializeLayout) + { + this.GenerateType = generateType; + this.SerializeLayout = serializeLayout; + } +} + +public enum GenerateType +{ + Object, + VersionTolerant, + CircularReference, + Collection, + NoGenerate +} + +public enum SerializeLayout +{ + Sequential, // default + Explicit +} + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] +public sealed class MemoryPackUnionAttribute : Attribute +{ + public ushort Tag { get; } + public Type Type { get; } + + public MemoryPackUnionAttribute(ushort tag, Type type) + { + this.Tag = tag; + this.Type = type; + } +} + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackUnionFormatterAttribute : Attribute +{ + public Type Type { get; } + + public MemoryPackUnionFormatterAttribute(Type type) + { + this.Type = type; + } +} + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackAllowSerializeAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackOrderAttribute : Attribute +{ + public int Order { get; } + + public MemoryPackOrderAttribute(int order) + { + this.Order = order; + } +} + +#if !UNITY_2021_2_OR_NEWER + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public abstract class MemoryPackCustomFormatterAttribute : Attribute +{ + public abstract IMemoryPackFormatter GetFormatter(); +} + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public abstract class MemoryPackCustomFormatterAttribute : Attribute + where TFormatter : IMemoryPackFormatter +{ + public abstract TFormatter GetFormatter(); +} + +#endif + +// similar naming as System.Text.Json attribtues +// https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonattribute + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackIgnoreAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackIncludeAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackConstructorAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackOnSerializingAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackOnSerializedAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackOnDeserializingAttribute : Attribute +{ +} + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +public sealed class MemoryPackOnDeserializedAttribute : Attribute +{ +} + +// Others + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] +public sealed class GenerateTypeScriptAttribute : Attribute +{ +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs.meta new file mode 100644 index 0000000..3c7ab82 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Attributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e370fb1f0283f164ba65d0874cbef7f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression.meta new file mode 100644 index 0000000..07f6096 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6a28c9e101e0f564c9ab6b19218741bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs new file mode 100644 index 0000000..adc90d0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; + +#if NET7_0_OR_GREATER +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +#endif + +namespace MemoryPack.Compression { + +[Preserve] +public sealed class BitPackFormatter : MemoryPackFormatter +{ + public static readonly BitPackFormatter Default = new BitPackFormatter(); + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref bool[]? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + writer.WriteCollectionHeader(value.Length); + if (value.Length == 0) + { + return; + } + + var data = 0; +#if NET7_0_OR_GREATER + ref var item = ref MemoryMarshal.GetArrayDataReference(value); +#else + ref var item = ref value[0]; +#endif + ref var end = ref Unsafe.Add(ref item, value.Length); + +#if NET7_0_OR_GREATER + if (value.Length >= 32) + { + ref var loopEnd = ref Unsafe.Subtract(ref end, 32); + if (Vector256.IsHardwareAccelerated) + { + while (!Unsafe.IsAddressGreaterThan(ref item, ref loopEnd)) + { + var vector = Vector256.LoadUnsafe(ref Unsafe.As(ref item)); + // false -> 1 true -> 0 + data = (int)Vector256.Equals(vector, Vector256.Zero).ExtractMostSignificantBits(); + writer.WriteUnmanaged(~data); + item = ref Unsafe.Add(ref item, 32); + } + } + else if (Vector128.IsHardwareAccelerated) + { + while (!Unsafe.IsAddressGreaterThan(ref item, ref loopEnd)) + { + var bits0 = (ushort)Vector128.Equals(Vector128.LoadUnsafe(ref Unsafe.As(ref item)), Vector128.Zero).ExtractMostSignificantBits(); + var bits1 = (ushort)Vector128.Equals(Vector128.LoadUnsafe(ref Unsafe.As(ref item), 16), Vector128.Zero).ExtractMostSignificantBits(); + data = bits0 | (bits1 << 16); + writer.WriteUnmanaged(~data); + item = ref Unsafe.Add(ref item, 32); + } + } + else if (Vector64.IsHardwareAccelerated) + { + while (!Unsafe.IsAddressGreaterThan(ref item, ref loopEnd)) + { + var bits0 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As(ref item)), Vector64.Zero).ExtractMostSignificantBits(); + var bits1 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As(ref item), 8), Vector64.Zero).ExtractMostSignificantBits(); + var bits2 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As(ref item), 16), Vector64.Zero).ExtractMostSignificantBits(); + var bits3 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As(ref item), 24), Vector64.Zero).ExtractMostSignificantBits(); + data = bits0 | (bits1 << 8) | (bits2 << 16) | (bits3 << 24); + writer.WriteUnmanaged(~data); + item = ref Unsafe.Add(ref item, 32); + } + } + + data = 0; + } +#endif + var bit = 0; + while (Unsafe.IsAddressLessThan(ref item, ref end)) + { + Set(ref data, bit, item); + + item = ref Unsafe.Add(ref item, 1); + bit += 1; + + if (bit == 32) + { + writer.WriteUnmanaged(data); + data = 0; + bit = 0; + } + } + + if (bit != 0) + { + writer.WriteUnmanaged(data); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref bool[]? value) + { + if (!reader.DangerousTryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + var readCount = ((length - 1) / 32) + 1; + var requireSize = readCount * 4; + if (reader.Remaining < requireSize) + { + MemoryPackSerializationException.ThrowInsufficientBufferUnless(length); + } + + if (value == null || value.Length != length) + { + value = new bool[length]; + } + + var bit = 0; + var data = 0; + for (int i = 0; i < value.Length; i++) + { + if (bit == 0) + { + reader.ReadUnmanaged(out data); + } + + value[i] = Get(data, bit); + + bit += 1; + + if (bit == 32) + { + data = 0; + bit = 0; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Get(int data, int index) + { + return (data & (1 << index)) != 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Set(ref int data, int index, bool value) + { + int bitMask = 1 << index; + if (value) + { + data |= bitMask; + } + else + { + data &= ~bitMask; + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs.meta new file mode 100644 index 0000000..63d4d5f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BitPackFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61f1625193facbe4abecb4f90defa276 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs new file mode 100644 index 0000000..fbb12d5 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Diagnostics.CodeAnalysis; +using System.IO.Compression; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Compression { + +#if !NET7_0_OR_GREATER +#pragma warning disable CS8602 +#endif + +public +#if NET7_0_OR_GREATER + struct +#else + class +#endif + BrotliCompressor : IBufferWriter, IDisposable +{ + ReusableLinkedArrayBufferWriter? bufferWriter; + readonly int quality; + readonly int window; + +#if NET7_0_OR_GREATER + + public BrotliCompressor() + : this(CompressionLevel.Fastest) + { + + } + +#endif + + public BrotliCompressor(CompressionLevel compressionLevel) + : this(BrotliUtils.GetQualityFromCompressionLevel(compressionLevel), BrotliUtils.WindowBits_Default) + { + + } + + public BrotliCompressor(CompressionLevel compressionLevel, int window) + : this(BrotliUtils.GetQualityFromCompressionLevel(compressionLevel), window) + { + + } + + public BrotliCompressor(int quality = 1, int window = 22) + { + this.bufferWriter = ReusableLinkedArrayBufferWriterPool.Rent(); + this.quality = quality; + this.window = window; + } + + void IBufferWriter.Advance(int count) + { + ThrowIfDisposed(); + bufferWriter.Advance(count); + } + + Memory IBufferWriter.GetMemory(int sizeHint) + { + ThrowIfDisposed(); + return bufferWriter.GetMemory(sizeHint); + } + + Span IBufferWriter.GetSpan(int sizeHint) + { + ThrowIfDisposed(); + return bufferWriter.GetSpan(sizeHint); + } + + public byte[] ToArray() + { + ThrowIfDisposed(); + + using var encoder = new BrotliEncoder(quality, window); + + var maxLength = BrotliUtils.BrotliEncoderMaxCompressedSize(bufferWriter.TotalWritten); + + var finalBuffer = ArrayPool.Shared.Rent(maxLength); + try + { + var writtenCount = 0; + var destination = finalBuffer.AsSpan(0, maxLength); + foreach (var source in bufferWriter) + { + var status = encoder.Compress(source.Span, destination, out var bytesConsumed, out var bytesWritten, isFinalBlock: false); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + if (bytesConsumed != source.Span.Length) + { + MemoryPackSerializationException.ThrowCompressionFailed(); + } + + if (bytesWritten > 0) + { + destination = destination.Slice(bytesWritten); + writtenCount += bytesWritten; + } + } + + // call BrotliEncoderOperation.Finish + var finalStatus = encoder.Compress(ReadOnlySpan.Empty, destination, out var consumed, out var written, isFinalBlock: true); + writtenCount += written; + + return finalBuffer.AsSpan(0, writtenCount).ToArray(); + } + finally + { + ArrayPool.Shared.Return(finalBuffer); + } + } + + public void CopyTo(in IBufferWriter destBufferWriter) + + { + ThrowIfDisposed(); + + var encoder = new BrotliEncoder(quality, window); + try + { + var writtenNotAdvanced = 0; + foreach (var item in bufferWriter) + { + writtenNotAdvanced = CompressCore(ref encoder, item.Span, ref Unsafe.AsRef(destBufferWriter), initialLength: null, isFinalBlock: false); + } + + // call BrotliEncoderOperation.Finish + var finalBlockLength = (writtenNotAdvanced == 0) ? null : (int?)(writtenNotAdvanced + 10); + CompressCore(ref encoder, ReadOnlySpan.Empty, ref Unsafe.AsRef(destBufferWriter), initialLength: finalBlockLength, isFinalBlock: true); + } + finally + { + encoder.Dispose(); + } + } + + public async ValueTask CopyToAsync(Stream stream, int bufferSize = 65535, CancellationToken cancellationToken = default) + { + ThrowIfDisposed(); + + using var encoder = new BrotliEncoder(quality, window); + + var buffer = ArrayPool.Shared.Rent(bufferSize); + try + { + foreach (var item in bufferWriter) + { + var source = item; + var lastResult = OperationStatus.DestinationTooSmall; + while (lastResult == OperationStatus.DestinationTooSmall) + { + lastResult = encoder.Compress(source.Span, buffer, out int bytesConsumed, out int bytesWritten, isFinalBlock: false); + if (lastResult == OperationStatus.InvalidData) MemoryPackSerializationException.ThrowCompressionFailed(); + if (bytesWritten > 0) + { + await stream.WriteAsync(buffer.AsMemory(0, bytesWritten), cancellationToken).ConfigureAwait(false); + } + if (bytesConsumed > 0) + { + source = source.Slice(bytesConsumed); + } + } + } + + // call BrotliEncoderOperation.Finish + var finalStatus = encoder.Compress(ReadOnlySpan.Empty, buffer, out var consumed, out var written, isFinalBlock: true); + if (written > 0) + { + await stream.WriteAsync(buffer.AsMemory(0, written), cancellationToken).ConfigureAwait(false); + } + } + finally + { + ArrayPool.Shared.Return(buffer); + } + } + + public void CopyTo(ref MemoryPackWriter memoryPackWriter) +#if NET7_0_OR_GREATER + +#else + +#endif + { + ThrowIfDisposed(); + + var encoder = new BrotliEncoder(quality, window); + try + { + var writtenNotAdvanced = 0; + foreach (var item in bufferWriter) + { + writtenNotAdvanced = CompressCore(ref encoder, item.Span, ref memoryPackWriter, initialLength: null, isFinalBlock: false); + } + + // call BrotliEncoderOperation.Finish + var finalBlockLength = (writtenNotAdvanced == 0) ? null : (int?)(writtenNotAdvanced + 10); + CompressCore(ref encoder, ReadOnlySpan.Empty, ref memoryPackWriter, initialLength: finalBlockLength, isFinalBlock: true); + } + finally + { + encoder.Dispose(); + } + } + + static int CompressCore(ref BrotliEncoder encoder, ReadOnlySpan source, ref IBufferWriter destBufferWriter, int? initialLength, bool isFinalBlock) + + { + var writtenNotAdvanced = 0; + + var lastResult = OperationStatus.DestinationTooSmall; + while (lastResult == OperationStatus.DestinationTooSmall) + { + var dest = destBufferWriter.GetSpan(initialLength ?? source.Length); + + lastResult = encoder.Compress(source, dest, out int bytesConsumed, out int bytesWritten, isFinalBlock: isFinalBlock); + writtenNotAdvanced += bytesConsumed; + + if (lastResult == OperationStatus.InvalidData) MemoryPackSerializationException.ThrowCompressionFailed(); + if (bytesWritten > 0) + { + destBufferWriter.Advance(bytesWritten); + writtenNotAdvanced = 0; + } + if (bytesConsumed > 0) + { + source = source.Slice(bytesConsumed); + } + } + + return writtenNotAdvanced; + } + + static int CompressCore(ref BrotliEncoder encoder, ReadOnlySpan source, ref MemoryPackWriter destBufferWriter, int? initialLength, bool isFinalBlock) +#if NET7_0_OR_GREATER + +#else + +#endif + { + var writtenNotAdvanced = 0; + + var lastResult = OperationStatus.DestinationTooSmall; + while (lastResult == OperationStatus.DestinationTooSmall) + { + ref var spanRef = ref destBufferWriter.GetSpanReference(initialLength ?? source.Length); + var dest = MemoryMarshal.CreateSpan(ref spanRef, destBufferWriter.BufferLength); + + lastResult = encoder.Compress(source, dest, out int bytesConsumed, out int bytesWritten, isFinalBlock: isFinalBlock); + writtenNotAdvanced += bytesConsumed; + + if (lastResult == OperationStatus.InvalidData) MemoryPackSerializationException.ThrowCompressionFailed(); + if (bytesWritten > 0) + { + destBufferWriter.Advance(bytesWritten); + writtenNotAdvanced = 0; + } + if (bytesConsumed > 0) + { + source = source.Slice(bytesConsumed); + } + } + + return writtenNotAdvanced; + } + + public void Dispose() + { + if (bufferWriter == null) return; + + bufferWriter.Reset(); + ReusableLinkedArrayBufferWriterPool.Return(bufferWriter); + bufferWriter = null!; + } + +#if NET7_0_OR_GREATER + [MemberNotNull(nameof(bufferWriter))] +#endif + void ThrowIfDisposed() + { + if (bufferWriter == null) + { + throw new ObjectDisposedException(null); + } + } +} + +internal static partial class BrotliUtils +{ + public const int WindowBits_Min = 10; + public const int WindowBits_Default = 22; + public const int WindowBits_Max = 24; + public const int Quality_Min = 0; + public const int Quality_Default = 4; + public const int Quality_Max = 11; + public const int MaxInputSize = int.MaxValue - 515; // 515 is the max compressed extra bytes + + internal static int GetQualityFromCompressionLevel(CompressionLevel compressionLevel) => + compressionLevel switch + { + CompressionLevel.NoCompression => Quality_Min, + CompressionLevel.Fastest => 1, + CompressionLevel.Optimal => Quality_Default, +#if NET7_0_OR_GREATER + CompressionLevel.SmallestSize => Quality_Max, +#endif + _ => throw new ArgumentException() + }; + + + // https://github.com/dotnet/runtime/issues/35142 + // BrotliEncoder.GetMaxCompressedLength is broken in .NET 7 + // port from encode.c https://github.com/google/brotli/blob/3914999fcc1fda92e750ef9190aa6db9bf7bdb07/c/enc/encode.c#L1200 + internal static int BrotliEncoderMaxCompressedSize(int input_size) + { + var num_large_blocks = input_size >> 14; + var overhead = 2 + (4 * num_large_blocks) + 3 + 1; + var result = input_size + overhead; + if (input_size == 0) return 2; + return (result < input_size) ? 0 : result; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs.meta new file mode 100644 index 0000000..fa308e9 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliCompressor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62473f8441644d1479405f2eb8f863c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs new file mode 100644 index 0000000..c1f5b24 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Diagnostics; +using System.IO.Compression; + +namespace MemoryPack.Compression { + +public struct BrotliDecompressor : IDisposable +{ + ReusableReadOnlySequenceBuilder? sequenceBuilder; + + public ReadOnlySequence Decompress(ReadOnlySpan compressedSpan) + { + return Decompress(compressedSpan, out _); + } + + public ReadOnlySequence Decompress(ReadOnlySpan compressedSpan, out int consumed) + { + if (sequenceBuilder != null) + { + MemoryPackSerializationException.ThrowAlreadyDecompressed(); + } + + sequenceBuilder = ReusableReadOnlySequenceBuilderPool.Rent(); + var decoder = new BrotliDecoder(); + try + { + var status = OperationStatus.DestinationTooSmall; + DecompressCore(ref status, ref decoder, compressedSpan, out consumed); + if (status == OperationStatus.NeedMoreData) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + } + finally + { + decoder.Dispose(); + } + + return sequenceBuilder.Build(); + } + + public ReadOnlySequence Decompress(ReadOnlySequence compressedSequence) + { + return Decompress(compressedSequence, out _); + } + + public ReadOnlySequence Decompress(ReadOnlySequence compressedSequence, out int consumed) + { + if (sequenceBuilder != null) + { + MemoryPackSerializationException.ThrowAlreadyDecompressed(); + } + + sequenceBuilder = ReusableReadOnlySequenceBuilderPool.Rent(); + var decoder = new BrotliDecoder(); + try + { + var status = OperationStatus.DestinationTooSmall; + consumed = 0; + foreach (var item in compressedSequence) + { + DecompressCore(ref status, ref decoder, item.Span, out var bytesConsumed); + consumed += bytesConsumed; + } + + if (status == OperationStatus.NeedMoreData) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + } + finally + { + decoder.Dispose(); + } + + return sequenceBuilder.Build(); + } + + void DecompressCore(ref OperationStatus status, ref BrotliDecoder decoder, ReadOnlySpan source, out int consumed) + { + Debug.Assert(sequenceBuilder != null); + consumed = 0; + + byte[]? buffer = null; + status = OperationStatus.DestinationTooSmall; + var nextCapacity = source.Length; + while (status == OperationStatus.DestinationTooSmall) + { + if (buffer == null) + { + nextCapacity = GetDoubleCapacity(nextCapacity); + buffer = ArrayPool.Shared.Rent(nextCapacity); + } + + status = decoder.Decompress(source, buffer, out var bytesConsumed, out var bytesWritten); + consumed += bytesConsumed; + + if (status == OperationStatus.InvalidData) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + if (status == OperationStatus.NeedMoreData) + { + if (bytesWritten > 0) + { + sequenceBuilder.Add(buffer.AsMemory(0, bytesWritten), true); + } + if (bytesConsumed > 0) + { + source = source.Slice(bytesConsumed); + } + if (source.Length != 0) + { + // not consumed source fully + MemoryPackSerializationException.ThrowCompressionFailed(); + } + + // continue for next sequence. + return; + } + + if (bytesConsumed > 0) + { + source = source.Slice(bytesConsumed); + } + if (bytesWritten > 0) + { + sequenceBuilder.Add(buffer.AsMemory(0, bytesWritten), true); + buffer = null; + } + } + } + + public void Dispose() + { + if (sequenceBuilder != null) + { + ReusableReadOnlySequenceBuilderPool.Return(sequenceBuilder); + sequenceBuilder = null; + } + } + + int GetDoubleCapacity(int length) + { + var newCapacity = unchecked(length * 2); + if ((uint)newCapacity > int.MaxValue) newCapacity = int.MaxValue; + return Math.Max(newCapacity, 4096); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs.meta new file mode 100644 index 0000000..b35a9a1 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliDecompressor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe3786d11daa23f4488fa639754af3a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs new file mode 100644 index 0000000..b23285f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.IO.Compression; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Compression { + +// serialize as (uncompressedLength, compressedLength, values...) + +[Preserve] +public sealed class BrotliFormatter : MemoryPackFormatter +{ + internal const int DefaultDecompssionSizeLimit = 1024 * 1024 * 128; // 128MB + + public static readonly BrotliFormatter Default = new BrotliFormatter(); + + readonly System.IO.Compression.CompressionLevel compressionLevel; + readonly int window; + readonly int decompressionSizeLimit; + + public BrotliFormatter() + : this(System.IO.Compression.CompressionLevel.Fastest) + { + + } + + public BrotliFormatter(System.IO.Compression.CompressionLevel compressionLevel) + : this(compressionLevel, BrotliUtils.WindowBits_Default) + { + } + + public BrotliFormatter(System.IO.Compression.CompressionLevel compressionLevel, int window) + : this(compressionLevel, window, DefaultDecompssionSizeLimit) + { + } + + public BrotliFormatter(System.IO.Compression.CompressionLevel compressionLevel, int window, int decompressionSizeLimit) + { + this.compressionLevel = compressionLevel; + this.window = window; + this.decompressionSizeLimit = decompressionSizeLimit; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref byte[]? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + if (value.Length == 0) + { + writer.WriteCollectionHeader(0); + return; + } + + var quality = BrotliUtils.GetQualityFromCompressionLevel(compressionLevel); + + using var encoder = new BrotliEncoder(quality, window); + + var maxLength = BrotliUtils.BrotliEncoderMaxCompressedSize(value.Length); + + ref var head = ref writer.GetSpanReference(maxLength + 8); + + var dest = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref head, 8), maxLength); + var status = encoder.Compress(value.AsSpan(), dest, out var bytesConsumed, out var bytesWritten, isFinalBlock: true); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + if (bytesConsumed != value.Length) + { + MemoryPackSerializationException.ThrowCompressionFailed(); + } + + // write to buffer header (uncompressedLength, compressedLength, values...) + Unsafe.WriteUnaligned(ref head, value.Length); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref head, 4), bytesWritten); + + writer.Advance(bytesWritten + 8); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref byte[]? value) + { + var uncompressedLength = reader.ReadUnmanaged(); + + reader.DangerousReadUnmanagedSpanView(out var isNull, out var compressedBuffer); + + if (isNull) + { + value = null; + return; + } + + if (compressedBuffer.Length == 0) + { + value = Array.Empty(); + return; + } + + // security, require to check length + if (decompressionSizeLimit < uncompressedLength) + { + MemoryPackSerializationException.ThrowDecompressionSizeLimitExceeded(decompressionSizeLimit, uncompressedLength); + } + + if (value == null || value.Length != uncompressedLength) + { + value = new byte[uncompressedLength]; + } + + using var decoder = new BrotliDecoder(); + + var status = decoder.Decompress(compressedBuffer, value, out var bytesConsumed, out var bytesWritten); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + if (bytesConsumed != compressedBuffer.Length || bytesWritten != value.Length) + { + MemoryPackSerializationException.ThrowCompressionFailed(); + } + } +} + + +[Preserve] +public sealed class BrotliFormatter : MemoryPackFormatter +{ + internal const int DefaultDecompssionSizeLimit = 1024 * 1024 * 128; // 128MB + + public static readonly BrotliFormatter Default = new BrotliFormatter(); + + readonly System.IO.Compression.CompressionLevel compressionLevel; + readonly int window; + + public BrotliFormatter() + : this(System.IO.Compression.CompressionLevel.Fastest) + { + + } + + public BrotliFormatter(System.IO.Compression.CompressionLevel compressionLevel) + : this(compressionLevel, BrotliUtils.WindowBits_Default) + { + } + + public BrotliFormatter(System.IO.Compression.CompressionLevel compressionLevel, int window) + { + this.compressionLevel = compressionLevel; + this.window = window; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + var compressor = new BrotliCompressor(compressionLevel, window); + try + { + var coWriter = new MemoryPackWriter(ref Unsafe.As>(ref compressor), writer.OptionalState); + + coWriter.WriteValue(value); + coWriter.Flush(); + + compressor.CopyTo(ref writer); + } + finally + { + compressor.Dispose(); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + using var decompressor = new BrotliDecompressor(); + + reader.GetRemainingSource(out var singleSource, out var remainingSource); + + int consumed; + ReadOnlySequence decompressedSource; + if (singleSource.Length != 0) + { + decompressedSource = decompressor.Decompress(singleSource, out consumed); + } + else + { + decompressedSource = decompressor.Decompress(remainingSource, out consumed); + } + + using var coReader = new MemoryPackReader(decompressedSource, reader.OptionalState); + coReader.ReadValue(ref value); + + reader.Advance(consumed); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs.meta new file mode 100644 index 0000000..1de7fcc --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Compression/BrotliFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 45b39997d100c0848bcdb691400b2c1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs new file mode 100644 index 0000000..6c52ac8 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Compression; +using MemoryPack.Formatters; + +namespace MemoryPack { + +#if !UNITY_2021_2_OR_NEWER + +public sealed class Utf8StringFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public override Utf8StringFormatter GetFormatter() + { + return Utf8StringFormatter.Default; + } +} + +public sealed class Utf16StringFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public override Utf16StringFormatter GetFormatter() + { + return Utf16StringFormatter.Default; + } +} + +public sealed class OrdinalIgnoreCaseStringDictionaryFormatter : MemoryPackCustomFormatterAttribute, Dictionary> +{ + static readonly DictionaryFormatter formatter = new DictionaryFormatter(StringComparer.OrdinalIgnoreCase); + + public override DictionaryFormatter GetFormatter() + { + return formatter; + } +} + +public sealed class InternStringFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public override InternStringFormatter GetFormatter() + { + return InternStringFormatter.Default; + } +} + +public sealed class BitPackFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public override BitPackFormatter GetFormatter() + { + return BitPackFormatter.Default; + } +} + +public sealed class BrotliFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public System.IO.Compression.CompressionLevel CompressionLevel { get; } + public int Window { get; } + public int DecompressionSizeLimit { get; } + + public BrotliFormatterAttribute(System.IO.Compression.CompressionLevel compressionLevel = System.IO.Compression.CompressionLevel.Fastest, int window = BrotliUtils.WindowBits_Default, int decompressionSizeLimit = BrotliFormatter.DefaultDecompssionSizeLimit) + { + this.CompressionLevel = compressionLevel; + this.Window = window; + this.DecompressionSizeLimit = decompressionSizeLimit; + } + + public override BrotliFormatter GetFormatter() + { + return new BrotliFormatter(CompressionLevel, Window, DecompressionSizeLimit); + } +} + +public sealed class BrotliFormatterAttribute : MemoryPackCustomFormatterAttribute, T> +{ + public System.IO.Compression.CompressionLevel CompressionLevel { get; } + public int Window { get; } + + public BrotliFormatterAttribute(System.IO.Compression.CompressionLevel compressionLevel = System.IO.Compression.CompressionLevel.Fastest, int window = BrotliUtils.WindowBits_Default) + { + this.CompressionLevel = compressionLevel; + this.Window = window; + } + + public override BrotliFormatter GetFormatter() + { + return new BrotliFormatter(CompressionLevel, Window); + } +} + +public sealed class BrotliStringFormatterAttribute : MemoryPackCustomFormatterAttribute +{ + public System.IO.Compression.CompressionLevel CompressionLevel { get; } + public int Window { get; } + public int DecompressionSizeLimit { get; } + + public BrotliStringFormatterAttribute(System.IO.Compression.CompressionLevel compressionLevel = System.IO.Compression.CompressionLevel.Fastest, int window = BrotliUtils.WindowBits_Default, int decompressionSizeLimit = BrotliFormatter.DefaultDecompssionSizeLimit) + { + this.CompressionLevel = compressionLevel; + this.Window = window; + this.DecompressionSizeLimit = decompressionSizeLimit; + } + + public override BrotliStringFormatter GetFormatter() + { + return new BrotliStringFormatter(CompressionLevel, Window, DecompressionSizeLimit); + } +} + +public sealed class MemoryPoolFormatterAttribute : MemoryPackCustomFormatterAttribute, Memory> +{ + static readonly MemoryPoolFormatter formatter = new MemoryPoolFormatter(); + + public override MemoryPoolFormatter GetFormatter() + { + return formatter; + } +} + +public sealed class ReadOnlyMemoryPoolFormatterAttribute : MemoryPackCustomFormatterAttribute, ReadOnlyMemory> +{ + static readonly ReadOnlyMemoryPoolFormatter formatter = new ReadOnlyMemoryPoolFormatter(); + + public override ReadOnlyMemoryPoolFormatter GetFormatter() + { + return formatter; + } +} + +#endif + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs.meta new file mode 100644 index 0000000..c308553 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/CustomFormatterAttributes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1cc6f8595850d1c41ba61d06616f2d67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters.meta new file mode 100644 index 0000000..4861b05 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3c76a067728428843ae9ce827d31f1ec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs new file mode 100644 index 0000000..820e214 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs @@ -0,0 +1,228 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Formatters; +using MemoryPack.Internal; +using System.Buffers; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Runtime.CompilerServices; + +// Array and Array-like type formatters +// T[] +// T[] where T: unmnaged +// Memory +// ReadOnlyMemory +// ArraySegment +// ReadOnlySequence + +namespace MemoryPack +{ + public static partial class MemoryPackFormatterProvider + { + static readonly Dictionary ArrayLikeFormatters = new Dictionary(4) + { + // If T[], choose UnmanagedArrayFormatter or DangerousUnmanagedTypeArrayFormatter or ArrayFormatter + { typeof(ArraySegment<>), typeof(ArraySegmentFormatter<>) }, + { typeof(Memory<>), typeof(MemoryFormatter<>) }, + { typeof(ReadOnlyMemory<>), typeof(ReadOnlyMemoryFormatter<>) }, + { typeof(ReadOnlySequence<>), typeof(ReadOnlySequenceFormatter<>) }, + }; + } +} + +namespace MemoryPack.Formatters +{ + [Preserve] + public sealed class UnmanagedArrayFormatter : MemoryPackFormatter + where T : unmanaged + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T[]? value) + { + writer.WriteUnmanagedArray(value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T[]? value) + { + reader.ReadUnmanagedArray(ref value); + } + } + + [Preserve] + public sealed class DangerousUnmanagedArrayFormatter : MemoryPackFormatter + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T[]? value) + { + writer.DangerousWriteUnmanagedArray(value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T[]? value) + { + reader.DangerousReadUnmanagedArray(ref value); + } + } + + [Preserve] + public sealed class ArrayFormatter : MemoryPackFormatter + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T?[]? value) + { + writer.WriteArray(value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T?[]? value) + { + reader.ReadArray(ref value); + } + } + + [Preserve] + public sealed class ArraySegmentFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ArraySegment value) + { + writer.WriteSpan(value.AsMemory().Span); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ArraySegment value) + { + var array = reader.ReadArray(); + value = (array == null) ? default : (ArraySegment)array; + } + } + + [Preserve] + public sealed class MemoryFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Memory value) + { + writer.WriteSpan(value.Span); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Memory value) + { + value = reader.ReadArray(); + } + } + + [Preserve] + public sealed class ReadOnlyMemoryFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyMemory value) + { + writer.WriteSpan(value.Span); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyMemory value) + { + value = reader.ReadArray(); + } + } + + [Preserve] + public sealed class ReadOnlySequenceFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlySequence value) + { + if (value.IsSingleSegment) + { + writer.WriteSpan(value.FirstSpan); + return; + } + + writer.WriteCollectionHeader(checked((int)value.Length)); + foreach (var memory in value) + { + writer.WriteSpanWithoutLengthHeader(memory.Span); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlySequence value) + { + var array = reader.ReadArray(); + value = (array == null) ? default : new ReadOnlySequence(array); + } + } + + [Preserve] + public sealed class MemoryPoolFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Memory value) + { + writer.WriteSpan(value.Span); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Memory value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Memory.Empty; + return; + } + + var memory = ArrayPool.Shared.Rent(length).AsMemory(0, length); + var span = memory.Span; + reader.ReadSpanWithoutReadLengthHeader(length, ref span); + value = memory; + } + } + + [Preserve] + public sealed class ReadOnlyMemoryPoolFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyMemory value) + { + writer.WriteSpan(value.Span); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyMemory value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Memory.Empty; + return; + } + + var memory = ArrayPool.Shared.Rent(length).AsMemory(0, length); + var span = memory.Span; + reader.ReadSpanWithoutReadLengthHeader(length, ref span); + value = memory; + } + } +} diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs.meta new file mode 100644 index 0000000..3af1b7e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/ArrayFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ea47c22508b03445aabd57919531dc4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs new file mode 100644 index 0000000..adebc99 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class BigIntegerFormatter : MemoryPackFormatter +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref BigInteger value) + { +#if !UNITY_2021_2_OR_NEWER + Span temp = stackalloc byte[255]; + if (value.TryWriteBytes(temp, out var written)) + { + writer.WriteUnmanagedSpan(temp.Slice(written)); + return; + } + else +#endif + { + var byteArray = value.ToByteArray(); + writer.WriteUnmanagedArray(byteArray); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref BigInteger value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + ref var src = ref reader.GetSpanReference(length); + value = new BigInteger(MemoryMarshal.CreateReadOnlySpan(ref src, length)); + + reader.Advance(length); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs.meta new file mode 100644 index 0000000..0f2809c --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BigIntegerFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85c3a3fc180ed724798da6a6bd7c8635 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs new file mode 100644 index 0000000..2c1393f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Collections; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class BitArrayFormatter : MemoryPackFormatter +{ + // serialize [m_length, m_array] + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref BitArray? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + ref var view = ref Unsafe.As(ref value); + + writer.WriteUnmanagedWithObjectHeader(2, view.m_length); + writer.WriteUnmanagedArray(view.m_array); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref BitArray? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 2) MemoryPackSerializationException.ThrowInvalidPropertyCount(2, count); + + reader.ReadUnmanaged(out int length); + + var bitArray = new BitArray(length, false); // create internal int[] and set m_length to length + + ref var view = ref Unsafe.As(ref bitArray); + reader.ReadUnmanagedArray(ref view.m_array!); + + value = bitArray; + } +} + +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. +[Preserve] +internal class BitArrayView +{ + public int[] m_array; + public int m_length; + public int _version; +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs.meta new file mode 100644 index 0000000..caa1796 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/BitArrayFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7910d03f8a5023479d0bf2968f56267 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs new file mode 100644 index 0000000..111988e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs @@ -0,0 +1,1201 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Formatters; +using MemoryPack.Internal; +using System.Buffers; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Clear support collection formatters +// List, Stack, Queue, LinkedList, HashSet, PriorityQueue, +// ObservableCollection, Collection +// ConcurrentQueue, ConcurrentStack, ConcurrentBag +// Dictionary, SortedDictionary, SortedList, ConcurrentDictionary + +// Not supported clear +// ReadOnlyCollection, ReadOnlyObservableCollection, BlockingCollection + +namespace MemoryPack +{ + public static partial class MemoryPackFormatterProvider + { + static readonly Dictionary CollectionFormatters = new Dictionary(18) + { + { typeof(List<>), typeof(ListFormatter<>) }, + { typeof(Stack<>), typeof(StackFormatter<>) }, + { typeof(Queue<>), typeof(QueueFormatter<>) }, + { typeof(LinkedList<>), typeof(LinkedListFormatter<>) }, + { typeof(HashSet<>), typeof(HashSetFormatter<>) }, + { typeof(SortedSet<>), typeof(SortedSetFormatter<>) }, +#if NET7_0_OR_GREATER + { typeof(PriorityQueue<,>), typeof(PriorityQueueFormatter<,>) }, +#endif + { typeof(ObservableCollection<>), typeof(ObservableCollectionFormatter<>) }, + { typeof(Collection<>), typeof(CollectionFormatter<>) }, + { typeof(ConcurrentQueue<>), typeof(ConcurrentQueueFormatter<>) }, + { typeof(ConcurrentStack<>), typeof(ConcurrentStackFormatter<>) }, + { typeof(ConcurrentBag<>), typeof(ConcurrentBagFormatter<>) }, + { typeof(Dictionary<,>), typeof(DictionaryFormatter<,>) }, + { typeof(SortedDictionary<,>), typeof(SortedDictionaryFormatter<,>) }, + { typeof(SortedList<,>), typeof(SortedListFormatter<,>) }, + { typeof(ConcurrentDictionary<,>), typeof(ConcurrentDictionaryFormatter<,>) }, + { typeof(ReadOnlyCollection<>), typeof(ReadOnlyCollectionFormatter<>) }, + { typeof(ReadOnlyObservableCollection<>), typeof(ReadOnlyObservableCollectionFormatter<>) }, + { typeof(BlockingCollection<>), typeof(BlockingCollectionFormatter<>) }, + }; + } +} + +namespace MemoryPack.Formatters +{ + [Preserve] + public static class ListFormatter + { + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializePackable(ref MemoryPackWriter writer, ref List? value) + where T : IMemoryPackable +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + +#if NET7_0_OR_GREATER + writer.WritePackableSpan(CollectionsMarshal.AsSpan(value)); +#else + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } +#endif + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static List? DeserializePackable(ref MemoryPackReader reader) + where T : IMemoryPackable + { + List? value = default; + DeserializePackable(ref reader, ref value); + return value; + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void DeserializePackable(ref MemoryPackReader reader, ref List? value) + where T : IMemoryPackable + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new List(length); + } +#if NET7_0_OR_GREATER + else if (value.Count == length) + { + value.Clear(); + } + + var span = CollectionsMarshalEx.CreateSpan(value, length); + reader.ReadPackableSpanWithoutReadLengthHeader(length, ref span); +#else + else + { + value.Clear(); + } + var formatter = reader.GetFormatter(); + for (var i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } +#endif + } + } + + [Preserve] + public sealed class ListFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref List? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } +#if NET7_0_OR_GREATER + writer.WriteSpan(CollectionsMarshal.AsSpan(value)); +#else + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } +#endif + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref List? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new List(length); + } +#if NET7_0_OR_GREATER + else if (value.Count == length) + { + value.Clear(); + } + + var span = CollectionsMarshalEx.CreateSpan(value, length); + reader.ReadSpanWithoutReadLengthHeader(length, ref span); +#else + else + { + value.Clear(); + } + var formatter = reader.GetFormatter(); + for (var i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } +#endif + } + } + + [Preserve] + public sealed class StackFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Stack? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + +#if NET7_0_OR_GREATER + writer.WriteSpan(CollectionsMarshalEx.AsSpan(value)); +#else + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value.Reverse()) // serialize reverse order + { + var v = item; + formatter.Serialize(ref writer, ref v); + } +#endif + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Stack? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new Stack(length); + } +#if NET7_0_OR_GREATER + else if (value.Count != length) + { + value.Clear(); + } + + var span = CollectionsMarshalEx.CreateSpan(value, length); + reader.ReadSpanWithoutReadLengthHeader(length, ref span); +#else + else + { + value.Clear(); + } + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Push(v); + } +#endif + } + } + + [Preserve] + public sealed class QueueFormatter : MemoryPackFormatter> + { + // Queue is circular buffer, can't optimize like List, Stack. + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Queue? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Queue? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new Queue(length); + } + else + { + value.Clear(); +#if NET7_0_OR_GREATER + value.EnsureCapacity(length); +#endif + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Enqueue(v); + } + } + } + + [Preserve] + public sealed class LinkedListFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref LinkedList? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref LinkedList? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new LinkedList(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.AddLast(v); + } + } + } + + [Preserve] + public sealed class HashSetFormatter : MemoryPackFormatter> + { + readonly IEqualityComparer? equalityComparer; + + public HashSetFormatter() + : this(null) + { + } + + public HashSetFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref HashSet? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref HashSet? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new HashSet(length, equalityComparer); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } + + [Preserve] + public sealed class SortedSetFormatter : MemoryPackFormatter> + { + readonly IComparer? comparer; + + public SortedSetFormatter() + : this(null) + { + } + + public SortedSetFormatter(IComparer? comparer) + { + this.comparer = comparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref SortedSet? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref SortedSet? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new SortedSet(comparer); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } + +#if NET7_0_OR_GREATER + + [Preserve] + public sealed class PriorityQueueFormatter : MemoryPackFormatter> + { + static PriorityQueueFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered<(TElement?, TPriority?)>()) + { + MemoryPackFormatterProvider.Register(new ValueTupleFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref PriorityQueue? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter<(TElement?, TPriority?)>(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value.UnorderedItems) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref PriorityQueue? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new PriorityQueue(length); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter<(TElement?, TPriority?)>(); + for (int i = 0; i < length; i++) + { + (TElement?, TPriority?) v = default; + formatter.Deserialize(ref reader, ref v); + value.Enqueue(v.Item1, v.Item2); + } + } + } + +#endif + + [Preserve] + public sealed class CollectionFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Collection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Collection? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new Collection(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } + + [Preserve] + public sealed class ObservableCollectionFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ObservableCollection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ObservableCollection? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new ObservableCollection(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } + + [Preserve] + public sealed class ConcurrentQueueFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ConcurrentQueue? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + // note: serializing ConcurretnCollection(Queue/Stack/Bag/Dictionary) is not thread-safe. + // operate Add/Remove in iterating in other thread, not guranteed correct result + + var formatter = writer.GetFormatter(); + var count = value.Count; + writer.WriteCollectionHeader(count); + var i = 0; + foreach (var item in value) + { + i++; + var v = item; + formatter.Serialize(ref writer, ref v); + } + + if (i != count) MemoryPackSerializationException.ThrowInvalidConcurrrentCollectionOperation(); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ConcurrentQueue? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new ConcurrentQueue(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Enqueue(v); + } + } + } + + [Preserve] + public sealed class ConcurrentStackFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ConcurrentStack? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + // reverse order in serialize + var count = value.Count; + T?[] rentArray = ArrayPool.Shared.Rent(count); + try + { + var i = 0; + foreach (var item in value) + { + rentArray[i++] = item; + } + if (i != count) MemoryPackSerializationException.ThrowInvalidConcurrrentCollectionOperation(); + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(count); + for (i = i - 1; i >= 0; i--) + { + formatter.Serialize(ref writer, ref rentArray[i]); + } + } + finally + { + ArrayPool.Shared.Return(rentArray, clearArray: RuntimeHelpers.IsReferenceOrContainsReferences()); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ConcurrentStack? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new ConcurrentStack(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Push(v); + } + } + } + + [Preserve] + public sealed class ConcurrentBagFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ConcurrentBag? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + var count = value.Count; + writer.WriteCollectionHeader(count); + var i = 0; + foreach (var item in value) + { + i++; + var v = item; + formatter.Serialize(ref writer, ref v); + } + + if (i != count) MemoryPackSerializationException.ThrowInvalidConcurrrentCollectionOperation(); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ConcurrentBag? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new ConcurrentBag(); + } + else + { + value.Clear(); + } + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } + + [Preserve] + public sealed class DictionaryFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IEqualityComparer? equalityComparer; + + public DictionaryFormatter() + : this(null) + { + + } + + public DictionaryFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Dictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Dictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new Dictionary(length, equalityComparer); + } + else + { + value.Clear(); + } + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + value.Add(k!, v); + } + } + } + + [Preserve] + public sealed class SortedDictionaryFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IComparer? comparer; + + public SortedDictionaryFormatter() + : this(null) + { + + } + + public SortedDictionaryFormatter(IComparer? comparer) + { + this.comparer = comparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref SortedDictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref SortedDictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new SortedDictionary(comparer); + } + else + { + value.Clear(); + } + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + value.Add(k!, v); + } + } + } + + [Preserve] + public sealed class SortedListFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IComparer? comparer; + + public SortedListFormatter() + : this(null) + { + + } + + public SortedListFormatter(IComparer? comparer) + { + this.comparer = comparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref SortedList? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref SortedList? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new SortedList(length, comparer); + } + else + { + value.Clear(); + } + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + value.Add(k!, v); + } + } + } + + [Preserve] + public sealed class ConcurrentDictionaryFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IEqualityComparer? equalityComparer; + + public ConcurrentDictionaryFormatter() + : this(null) + { + + } + + public ConcurrentDictionaryFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ConcurrentDictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + var count = value.Count; + writer.WriteCollectionHeader(count); + var i = 0; + foreach (var item in value) + { + i++; + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + + if (i != count) MemoryPackSerializationException.ThrowInvalidConcurrrentCollectionOperation(); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ConcurrentDictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new ConcurrentDictionary(equalityComparer); + } + else + { + value.Clear(); + } + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + value.TryAdd(k!, v); + } + } + } + + [Preserve] + public sealed class ReadOnlyCollectionFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyCollection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyCollection? value) + { + var array = reader.ReadArray(); + + if (array == null) + { + value = null; + } + else + { + value = new ReadOnlyCollection(array); + } + } + } + + [Preserve] + public sealed class ReadOnlyObservableCollectionFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyObservableCollection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyObservableCollection? value) + { + var array = reader.ReadArray(); + + if (array == null) + { + value = null; + } + else + { + value = new ReadOnlyObservableCollection(new ObservableCollection(array)); + } + } + } + + [Preserve] + public sealed class BlockingCollectionFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref BlockingCollection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref BlockingCollection? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + value = new BlockingCollection(); + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? v = default; + formatter.Deserialize(ref reader, ref v); + value.Add(v); + } + } + } +} diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs.meta new file mode 100644 index 0000000..2917aec --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CollectionFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e648f2f021a720e45a7fda5bddd7aae9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs new file mode 100644 index 0000000..684dcbe --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Globalization; +using MemoryPack.Internal; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class CultureInfoFormatter : MemoryPackFormatter +{ + // treat as a string(Name). + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref CultureInfo? value) + { + writer.WriteString(value?.Name); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref CultureInfo? value) + { + var str = reader.ReadString(); + if (str == null) + { + value = null; + } + else + { + value = CultureInfo.GetCultureInfo(str); + } + } +} +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs.meta new file mode 100644 index 0000000..9a10651 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/CultureInfoFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20da488211e109640859d46ab47e442d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs new file mode 100644 index 0000000..f1fab23 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack.Formatters { + +public sealed class DynamicUnionFormatter : MemoryPackFormatter + where T : class +{ + readonly Dictionary typeToTag; + readonly Dictionary tagToType; + + public DynamicUnionFormatter(params (ushort Tag, Type Type)[] memoryPackUnions) + { + typeToTag = memoryPackUnions.ToDictionary(x => x.Type, x => x.Tag); + tagToType = memoryPackUnions.ToDictionary(x => x.Tag, x => x.Type); + } + + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + if (value == null) + { + writer.WriteNullUnionHeader(); + return; + } + + var type = value.GetType(); + if (typeToTag.TryGetValue(type, out var tag)) + { + writer.WriteUnionHeader(tag); + writer.WriteValue(type, value); + } + else + { + MemoryPackSerializationException.ThrowNotFoundInUnionType(type, typeof(T)); + } + } + + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + if (!reader.TryReadUnionHeader(out var tag)) + { + value = default; + return; + } + + if (tagToType.TryGetValue(tag, out var type)) + { + object? v = value; + reader.ReadValue(type, ref v); + value = (T?)v; + } + else + { + MemoryPackSerializationException.ThrowInvalidTag(tag, typeof(T)); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs.meta new file mode 100644 index 0000000..b7d1040 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/DynamicUnionFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6edda14b6f541844284c998396cafa2a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs new file mode 100644 index 0000000..fa95e09 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class GenericCollectionFormatter : MemoryPackFormatter + where TCollection : ICollection, new() +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref TCollection? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref TCollection? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + var formatter = reader.GetFormatter(); + + var collection = new TCollection(); + for (int i = 0; i < length; i++) + { + TElement? v = default; + formatter.Deserialize(ref reader, ref v); + collection.Add(v); + } + + value = collection; + } +} + +[Preserve] +public abstract class GenericSetFormatterBase : MemoryPackFormatter + where TSet : ISet +{ + [Preserve] + protected abstract TSet CreateSet(); + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref TSet? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref TSet? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + var formatter = reader.GetFormatter(); + + var collection = CreateSet(); + for (int i = 0; i < length; i++) + { + TElement? v = default; + formatter.Deserialize(ref reader, ref v); + collection.Add(v); + } + + value = collection; + } +} + +[Preserve] +public sealed class GenericSetFormatter : GenericSetFormatterBase + where TSet : ISet, new() +{ + protected override TSet CreateSet() + { + return new(); + } +} + +[Preserve] +public abstract class GenericDictionaryFormatterBase : MemoryPackFormatter + where TKey : notnull + where TDictionary : IDictionary +{ + [Preserve] + protected abstract TDictionary CreateDictionary(); + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref TDictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref TDictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + + var dict = CreateDictionary(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + dict.Add(k!, v); + } + + value = dict; + } +} + +[Preserve] +public sealed class GenericDictionaryFormatter : GenericDictionaryFormatterBase + where TKey : notnull + where TDictionary : IDictionary, new() +{ + [Preserve] + protected override TDictionary CreateDictionary() + { + return new(); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs.meta new file mode 100644 index 0000000..ad0f0fc --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/GenericCollectionFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5b0ee256b8ba5bf44904e20cbfd830e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs new file mode 100644 index 0000000..284eceb --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs @@ -0,0 +1,725 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Formatters; +using MemoryPack.Internal; +using System.Buffers; +using System.Collections; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// interface collection formatters +// IEnumerable, ICollection, IReadOnlyCollection, IList, IReadOnlyList +// IDictionary, IReadOnlyDictionary, ILookup, IGrouping, ISet, IReadOnlySet + +namespace MemoryPack +{ + public static partial class MemoryPackFormatterProvider + { + static readonly Dictionary InterfaceCollectionFormatters = new(11) + { + { typeof(IEnumerable<>), typeof(InterfaceEnumerableFormatter<>) }, + { typeof(ICollection<>), typeof(InterfaceCollectionFormatter<>) }, + { typeof(IReadOnlyCollection<>), typeof(InterfaceReadOnlyCollectionFormatter<>) }, + { typeof(IList<>), typeof(InterfaceListFormatter<>) }, + { typeof(IReadOnlyList<>), typeof(InterfaceReadOnlyListFormatter<>) }, + { typeof(IDictionary<,>), typeof(InterfaceDictionaryFormatter<,>) }, + { typeof(IReadOnlyDictionary<,>), typeof(InterfaceReadOnlyDictionaryFormatter<,>) }, + { typeof(ILookup<,>), typeof(InterfaceLookupFormatter<,>) }, + { typeof(IGrouping<,>), typeof(InterfaceGroupingFormatter<,>) }, + { typeof(ISet<>), typeof(InterfaceSetFormatter<>) }, +#if NET7_0_OR_GREATER + { typeof(IReadOnlySet<>), typeof(InterfaceReadOnlySetFormatter<>) }, +#endif + }; + } +} + +namespace MemoryPack.Formatters +{ + using static InterfaceCollectionFormatterUtils; + + internal static class InterfaceCollectionFormatterUtils + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TrySerializeOptimized(ref MemoryPackWriter writer, [NotNullWhen(false)] ref TCollection? value) + where TCollection : IEnumerable +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return true; + } + + // optimize for list or array + + if (value is TElement?[] array) + { + writer.WriteArray(array); + return true; + } + +#if NET7_0_OR_GREATER + if (value is List list) + { + writer.WriteSpan(CollectionsMarshal.AsSpan(list)); + return true; + } +#endif + + return false; + } + + public static void SerializeCollection(ref MemoryPackWriter writer, ref TCollection? value) + where TCollection : ICollection +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (TrySerializeOptimized(ref writer, ref value)) return; + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v!); + } + } + + public static void SerializeReadOnlyCollection(ref MemoryPackWriter writer, ref TCollection? value) + where TCollection : IReadOnlyCollection +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (TrySerializeOptimized(ref writer, ref value)) return; + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v!); + } + } + + public static List? ReadList(ref MemoryPackReader reader) + { + var formatter = reader.GetFormatter>(); + List? v = default; + formatter.Deserialize(ref reader, ref v); + return v; + } + } + + [Preserve] + public sealed class InterfaceEnumerableFormatter : MemoryPackFormatter> + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IEnumerable? value) + { + if (TrySerializeOptimized, T?>(ref writer, ref value)) return; + + if (value.TryGetNonEnumeratedCountEx(out var count)) + { + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + else + { + // write to tempbuffer(because we don't know length so can't write header) + var tempBuffer = ReusableLinkedArrayBufferWriterPool.Rent(); + try + { + var tempWriter = new MemoryPackWriter(ref Unsafe.As>(ref tempBuffer), writer.OptionalState); + + count = 0; + var formatter = writer.GetFormatter(); + foreach (var item in value) + { + count++; + var v = item; + formatter.Serialize(ref tempWriter, ref v); + } + + tempWriter.Flush(); + + // write to parameter writer. + writer.WriteCollectionHeader(count); + tempBuffer.WriteToAndReset(ref writer); + } + finally + { + ReusableLinkedArrayBufferWriterPool.Return(tempBuffer); + } + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IEnumerable? value) + { + value = reader.ReadArray(); + } + } + + [Preserve] + public sealed class InterfaceCollectionFormatter : MemoryPackFormatter> + { + static InterfaceCollectionFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new ListFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ICollection? value) + { + SerializeCollection, T?>(ref writer, ref value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ICollection? value) + { + value = ReadList(ref reader); + } + } + + [Preserve] + public sealed class InterfaceReadOnlyCollectionFormatter : MemoryPackFormatter> + { + static InterfaceReadOnlyCollectionFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new ListFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyCollection? value) + { + SerializeReadOnlyCollection, T?>(ref writer, ref value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlyCollection? value) + { + value = ReadList(ref reader); + } + } + + [Preserve] + public sealed class InterfaceListFormatter : MemoryPackFormatter> + { + static InterfaceListFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new ListFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IList? value) + { + SerializeCollection, T?>(ref writer, ref value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IList? value) + { + value = ReadList(ref reader); + } + } + + [Preserve] + public sealed class InterfaceReadOnlyListFormatter : MemoryPackFormatter> + { + static InterfaceReadOnlyListFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new ListFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyList? value) + { + SerializeReadOnlyCollection, T?>(ref writer, ref value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlyList? value) + { + value = ReadList(ref reader); + } + } + + [Preserve] + public sealed class InterfaceDictionaryFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IEqualityComparer? equalityComparer; + + public InterfaceDictionaryFormatter() + : this(null) + { + + } + + public InterfaceDictionaryFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IDictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IDictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + var dict = new Dictionary(equalityComparer); + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + dict.Add(k!, v); + } + + value = dict; + } + } + + [Preserve] + public sealed class InterfaceReadOnlyDictionaryFormatter : MemoryPackFormatter> + where TKey : notnull + { + readonly IEqualityComparer? equalityComparer; + + public InterfaceReadOnlyDictionaryFormatter() + : this(null) + { + + } + + public InterfaceReadOnlyDictionaryFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyDictionary? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var keyFormatter = writer.GetFormatter(); + var valueFormatter = writer.GetFormatter(); + + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + KeyValuePairFormatter.Serialize(keyFormatter, valueFormatter, ref writer, item!); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlyDictionary? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + var dict = new Dictionary(equalityComparer); + + var keyFormatter = reader.GetFormatter(); + var valueFormatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + KeyValuePairFormatter.Deserialize(keyFormatter, valueFormatter, ref reader, out var k, out var v); + dict.Add(k!, v); + } + + value = dict; + } + } + + [Preserve] + public sealed class InterfaceLookupFormatter : MemoryPackFormatter> + where TKey : notnull + { + static InterfaceLookupFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new InterfaceGroupingFormatter()); + } + } + + readonly IEqualityComparer? equalityComparer; + + public InterfaceLookupFormatter() + : this(null) + { + + } + + public InterfaceLookupFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ILookup? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter>(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ILookup? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + var dict = new Dictionary>(equalityComparer); + + var formatter = reader.GetFormatter>(); + for (int i = 0; i < length; i++) + { + IGrouping? item = default; + formatter.Deserialize(ref reader, ref item); + if (item != null) + { + dict.Add(item.Key, item); + } + } + value = new Lookup(dict); + } + } + + [Preserve] + public sealed class InterfaceGroupingFormatter : MemoryPackFormatter> + where TKey : notnull + { + // serialize as {key, [collection]} + + static InterfaceGroupingFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new InterfaceEnumerableFormatter()); + } + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IGrouping? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(2); + writer.WriteValue(value.Key); + writer.WriteValue>(value); // write as IEnumerable + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IGrouping? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 2) MemoryPackSerializationException.ThrowInvalidPropertyCount(2, count); + + var key = reader.ReadValue(); + var values = reader.ReadArray() as IEnumerable; + + if (key == null) MemoryPackSerializationException.ThrowDeserializeObjectIsNull(nameof(key)); + if (values == null) MemoryPackSerializationException.ThrowDeserializeObjectIsNull(nameof(values)); + + value = new Grouping(key, values); + + } + } + + [Preserve] + public sealed class InterfaceSetFormatter : MemoryPackFormatter> + { + static InterfaceSetFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new HashSetFormatter()); + } + } + + readonly IEqualityComparer? equalityComparer; + + public InterfaceSetFormatter() + : this(null) + { + } + + public InterfaceSetFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ISet? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ISet? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + var set = new HashSet(length, equalityComparer); + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? item = default; + formatter.Deserialize(ref reader, ref item); + set.Add(item); + } + + value = set; + } + } + +#if NET7_0_OR_GREATER + + [Preserve] + public sealed class InterfaceReadOnlySetFormatter : MemoryPackFormatter> + { + static InterfaceReadOnlySetFormatter() + { + if (!MemoryPackFormatterProvider.IsRegistered>()) + { + MemoryPackFormatterProvider.Register(new HashSetFormatter()); + } + } + + readonly IEqualityComparer? equalityComparer; + + public InterfaceReadOnlySetFormatter() + : this(null) + { + } + + public InterfaceReadOnlySetFormatter(IEqualityComparer? equalityComparer) + { + this.equalityComparer = equalityComparer; + } + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlySet? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var formatter = writer.GetFormatter(); + writer.WriteCollectionHeader(value.Count); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlySet? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + var set = new HashSet(length, equalityComparer); + + var formatter = reader.GetFormatter(); + for (int i = 0; i < length; i++) + { + T? item = default; + formatter.Deserialize(ref reader, ref item); + set.Add(item); + } + + value = set; + } + } + +#endif + + [Preserve] + internal sealed class Grouping : IGrouping + { + readonly TKey key; + readonly IEnumerable elements; + + public Grouping(TKey key, IEnumerable elements) + { + this.key = key; + this.elements = elements; + } + + public TKey Key + { + get + { + return this.key; + } + } + + public IEnumerator GetEnumerator() + { + return this.elements.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.elements.GetEnumerator(); + } + } + + [Preserve] + internal sealed class Lookup : ILookup + where TKey : notnull + { + readonly Dictionary> groupings; + + public Lookup(Dictionary> groupings) + { + this.groupings = groupings; + } + + public IEnumerable this[TKey key] + { + get + { + return this.groupings[key]; + } + } + + public int Count + { + get + { + return this.groupings.Count; + } + } + + public bool Contains(TKey key) + { + return this.groupings.ContainsKey(key); + } + + public IEnumerator> GetEnumerator() + { + return this.groupings.Values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.groupings.Values.GetEnumerator(); + } + } +} diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs.meta new file mode 100644 index 0000000..77b222a --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/InterfaceCollectionFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92a5c3e606f68e940a5504e80e372051 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs new file mode 100644 index 0000000..4bacaec --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +[Preserve] +public static class KeyValuePairFormatter +{ + // for Dictionary serialization + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(IMemoryPackFormatter keyFormatter, IMemoryPackFormatter valueFormatter, ref MemoryPackWriter writer, KeyValuePair value) +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + value.Deconstruct(out var k, out var v); + keyFormatter.Serialize(ref writer, ref k); + valueFormatter.Serialize(ref writer, ref v); + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Deserialize(IMemoryPackFormatter keyFormatter, IMemoryPackFormatter valueFormatter, ref MemoryPackReader reader, out TKey? key, out TValue? value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out KeyValuePair kvp); + key = kvp.Key; + value = kvp.Value; + return; + } + + key = default; + value = default; + keyFormatter.Deserialize(ref reader, ref key); + valueFormatter.Deserialize(ref reader, ref value); + } +} + +[Preserve] +public sealed class KeyValuePairFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref KeyValuePair value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Key); + writer.WriteValue(value.Value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref KeyValuePair value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new KeyValuePair( + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs.meta new file mode 100644 index 0000000..0b72b41 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/KeyValuePairFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f407ce074ce08af448c71d52ab5ef2c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs new file mode 100644 index 0000000..f329a67 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class LazyFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Lazy? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(1); + writer.WriteValue(value.Value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Lazy? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count); + + var v = reader.ReadValue(); + value = new Lazy(v); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs.meta new file mode 100644 index 0000000..bcdbcf9 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/LazyFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 435e06feb1c6e99469622c788eb68163 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs new file mode 100644 index 0000000..d929307 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +#if NET7_0_OR_GREATER + +[Preserve] +public sealed class MemoryPackableFormatter : MemoryPackFormatter + where T : IMemoryPackable +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + T.Serialize(ref writer, ref Unsafe.AsRef(value)); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + T.Deserialize(ref reader, ref value); + } +} + +#endif + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs.meta new file mode 100644 index 0000000..0f54bac --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MemoryPackableFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86918186878d8454db7dc10ffc57057d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs new file mode 100644 index 0000000..488173a --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs @@ -0,0 +1,373 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class TwoDimensionalArrayFormatter : MemoryPackFormatter +{ + // {i-length, j-length, [total-length, values]} + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T?[,]? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(3); + + var i = value.GetLength(0); + var j = value.GetLength(1); + writer.WriteUnmanaged(i, j); + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * i * j; + ref var src = ref MemoryMarshal.GetArrayDataReference(value); + ref var dest = ref writer.GetSpanReference(byteCount + 4); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)byteCount); + writer.Advance(byteCount + 4); + } + else +#endif + { + + writer.WriteCollectionHeader(value.Length); + var formatter = writer.GetFormatter(); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T?[,]? value) + { + if (!reader.TryReadObjectHeader(out var propertyCount)) + { + value = null; + return; + } + + if (propertyCount != 3) + { + MemoryPackSerializationException.ThrowInvalidPropertyCount(3, propertyCount); + } + + reader.ReadUnmanaged(out int iLength, out int jLength); + + if (!reader.TryReadCollectionHeader(out var length)) + { + MemoryPackSerializationException.ThrowInvalidCollection(); + } + + if (value != null && value.GetLength(0) == iLength && value.GetLength(1) == jLength && value.Length == length) + { + // allow overwrite + } + else + { + value = new T[iLength, jLength]; + } + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * iLength * jLength; + ref var dest = ref MemoryMarshal.GetArrayDataReference(value); + ref var src = ref reader.GetSpanReference(byteCount); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + reader.Advance(byteCount); + } + else +#endif + { + var formatter = reader.GetFormatter(); + + var i = 0; + var j = -1; + var count = 0; + while (count++ < length) + { + if (j < jLength - 1) + { + j++; + } + else + { + j = 0; + i++; + } + + formatter.Deserialize(ref reader, ref value[i, j]); + } + } + } +} + +[Preserve] +public sealed class ThreeDimensionalArrayFormatter : MemoryPackFormatter +{ + // {i-length, j-length, k-length, [total-length, values]} + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T?[,,]? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(4); + + var i = value.GetLength(0); + var j = value.GetLength(1); + var k = value.GetLength(2); + writer.WriteUnmanaged(i, j, k); + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * i * j * k; + ref var src = ref MemoryMarshal.GetArrayDataReference(value); + ref var dest = ref writer.GetSpanReference(byteCount + 4); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)byteCount); + writer.Advance(byteCount + 4); + } + else +#endif + { + writer.WriteCollectionHeader(value.Length); + var formatter = writer.GetFormatter(); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T?[,,]? value) + { + if (!reader.TryReadObjectHeader(out var propertyCount)) + { + value = null; + return; + } + + if (propertyCount != 4) + { + MemoryPackSerializationException.ThrowInvalidPropertyCount(4, propertyCount); + } + + reader.ReadUnmanaged(out int iLength, out int jLength, out int kLength); + + if (!reader.TryReadCollectionHeader(out var length)) + { + MemoryPackSerializationException.ThrowInvalidCollection(); + } + + if (value != null && value.GetLength(0) == iLength && value.GetLength(1) == jLength && value.GetLength(2) == kLength && value.Length == length) + { + // allow overwrite + } + else + { + value = new T[iLength, jLength, kLength]; + } + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * iLength * jLength * kLength; + ref var dest = ref MemoryMarshal.GetArrayDataReference(value); + ref var src = ref reader.GetSpanReference(byteCount); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + reader.Advance(byteCount); + } + else +#endif + { + var formatter = reader.GetFormatter(); + + var i = 0; + var j = 0; + var k = -1; + var count = 0; + while (count++ < length) + { + if (k < kLength - 1) + { + k++; + } + else if (j < jLength - 1) + { + k = 0; + j++; + } + else + { + k = 0; + j = 0; + i++; + } + + formatter.Deserialize(ref reader, ref value[i, j, k]); + } + } + } +} + +[Preserve] +public sealed class FourDimensionalArrayFormatter : MemoryPackFormatter +{ + // {i-length, j-length, k-length, l-length, [total-length, values]} + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T?[,,,]? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(5); + + var i = value.GetLength(0); + var j = value.GetLength(1); + var k = value.GetLength(2); + var l = value.GetLength(3); + writer.WriteUnmanaged(i, j, k, l); + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * i * j * k * l; + ref var src = ref MemoryMarshal.GetArrayDataReference(value); + ref var dest = ref writer.GetSpanReference(byteCount + 4); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)byteCount); + writer.Advance(byteCount + 4); + } + else +#endif + { + writer.WriteCollectionHeader(value.Length); + var formatter = writer.GetFormatter(); + foreach (var item in value) + { + var v = item; + formatter.Serialize(ref writer, ref v); + } + } + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T?[,,,]? value) + { + if (!reader.TryReadObjectHeader(out var propertyCount)) + { + value = null; + return; + } + + if (propertyCount != 5) + { + MemoryPackSerializationException.ThrowInvalidPropertyCount(5, propertyCount); + } + + reader.ReadUnmanaged(out int iLength, out int jLength, out int kLength, out int lLength); + + if (!reader.TryReadCollectionHeader(out var length)) + { + MemoryPackSerializationException.ThrowInvalidCollection(); + } + + if (value != null && value.GetLength(0) == iLength && value.GetLength(1) == jLength && value.GetLength(2) == kLength && value.GetLength(3) == lLength && value.Length == length) + { + // allow overwrite + } + else + { + value = new T[iLength, jLength, kLength, lLength]; + } + +#if NET7_0_OR_GREATER + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var byteCount = Unsafe.SizeOf() * iLength * jLength * kLength * lLength; + ref var dest = ref MemoryMarshal.GetArrayDataReference(value); + ref var src = ref reader.GetSpanReference(byteCount); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + reader.Advance(byteCount); + } + else +#endif + { + var formatter = reader.GetFormatter(); + + var i = 0; + var j = 0; + var k = 0; + var l = -1; + var count = 0; + while (count++ < length) + { + if (l < lLength - 1) + { + l++; + } + else if (k < kLength - 1) + { + l = 0; + k++; + } + else if (j < jLength - 1) + { + l = 0; + k = 0; + j++; + } + else + { + l = 0; + k = 0; + j = 0; + i++; + } + + formatter.Deserialize(ref reader, ref value[i, j, k, l]); + } + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs.meta new file mode 100644 index 0000000..ef83c6c --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/MultiDimensionalArrayFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 31ec28888c1521f45a5e0eb1ca226149 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs new file mode 100644 index 0000000..3ce657f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class NullableFormatter : MemoryPackFormatter + where T : struct +{ + // Nullable is sometimes serialized on UnmanagedFormatter. + // to keep same result, check if type is unmanaged. + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + if (!value.HasValue) + { + writer.WriteNullObjectHeader(); + return; + } + else + { + writer.WriteObjectHeader(1); + } + + writer.WriteValue(value.Value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count); + + value = reader.ReadValue(); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs.meta new file mode 100644 index 0000000..e2362a0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/NullableFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cbe20000eeecfe429b3f80fca2ba176 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs new file mode 100644 index 0000000..9368ea9 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class StringBuilderFormatter : MemoryPackFormatter +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref StringBuilder? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + +#if NET7_0_OR_GREATER + + // for performance reason, currently StringBuilder encode as Utf16, however try to write Utf8? + // if (writer.Options.StringEncoding == StringEncoding.Utf16) + { + writer.WriteCollectionHeader(value.Length); + + foreach (var chunk in value.GetChunks()) + { + ref var p = ref writer.GetSpanReference(checked(chunk.Length * 2)); + ref var src = ref Unsafe.As(ref MemoryMarshal.GetReference(chunk.Span)); + Unsafe.CopyBlockUnaligned(ref p, ref src, (uint)chunk.Length * 2); + + writer.Advance(chunk.Length * 2); + } + return; + } + +#else + // write as utf16 + writer.WriteUtf16(value.ToString()); +#endif + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref StringBuilder? value) + { + if (!reader.TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (value == null) + { + value = new StringBuilder(length); + } + else + { + value.Clear(); + value.EnsureCapacity(length); + } + + // note: require to check is Utf8 + // note: to improvement append as chunk(per 64K?) + var size = checked(length * 2); + ref var p = ref reader.GetSpanReference(size); + var src = MemoryMarshal.CreateSpan(ref Unsafe.As(ref p), length); + value.Append(src); + + reader.Advance(size); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs.meta new file mode 100644 index 0000000..f364294 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringBuilderFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 78f865f986bf7a844bcb6d3474b401a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs new file mode 100644 index 0000000..cae15c6 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs @@ -0,0 +1,279 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Compression; +using MemoryPack.Internal; +using System.Buffers; +using System.IO.Compression; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class StringFormatter : MemoryPackFormatter +{ + public static readonly StringFormatter Default = new StringFormatter(); + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref string? value) + { + writer.WriteString(value); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref string? value) + { + value = reader.ReadString(); + } +} + +[Preserve] +public sealed class Utf8StringFormatter : MemoryPackFormatter +{ + public static readonly Utf8StringFormatter Default = new Utf8StringFormatter(); + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Serialize(ref MemoryPackWriter writer, ref string? value) + { + writer.WriteUtf8(value); + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Deserialize(ref MemoryPackReader reader, ref string? value) + { + value = reader.ReadString(); + } +} + +[Preserve] +public sealed class Utf16StringFormatter : MemoryPackFormatter +{ + public static readonly Utf16StringFormatter Default = new Utf16StringFormatter(); + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Serialize(ref MemoryPackWriter writer, ref string? value) + { + writer.WriteUtf16(value); + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Deserialize(ref MemoryPackReader reader, ref string? value) + { + value = reader.ReadString(); + } +} + +[Preserve] +public sealed class InternStringFormatter : MemoryPackFormatter +{ + public static readonly InternStringFormatter Default = new InternStringFormatter(); + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Serialize(ref MemoryPackWriter writer, ref string? value) + { + writer.WriteString(value); + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Deserialize(ref MemoryPackReader reader, ref string? value) + { + var str = reader.ReadString(); + if (str == null) + { + value = null; + return; + } + + value = string.Intern(str); + } +} + +[Preserve] +public sealed class BrotliStringFormatter : MemoryPackFormatter +{ + [ThreadStatic] + static StrongBox? threadStaticConsumedBox; + + internal const int DefaultDecompssionSizeLimit = 1024 * 1024 * 128; // 128MB + + public static readonly BrotliStringFormatter Default = new BrotliStringFormatter(); + + readonly System.IO.Compression.CompressionLevel compressionLevel; + readonly int window; + readonly int decompressionSizeLimit; + + public BrotliStringFormatter() + : this(System.IO.Compression.CompressionLevel.Fastest) + { + + } + + public BrotliStringFormatter(System.IO.Compression.CompressionLevel compressionLevel) + : this(compressionLevel, BrotliUtils.WindowBits_Default) + { + this.compressionLevel = compressionLevel; + } + + public BrotliStringFormatter(System.IO.Compression.CompressionLevel compressionLevel, int window) + : this(compressionLevel, window, DefaultDecompssionSizeLimit) + { + } + + public BrotliStringFormatter(System.IO.Compression.CompressionLevel compressionLevel, int window, int decompressionSizeLimit) + { + this.compressionLevel = compressionLevel; + this.window = window; + this.decompressionSizeLimit = decompressionSizeLimit; + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Serialize(ref MemoryPackWriter writer, ref string? value) + { + if (value == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + if (value.Length == 0) + { + writer.WriteCollectionHeader(0); + return; + } + + var quality = BrotliUtils.GetQualityFromCompressionLevel(compressionLevel); + using var encoder = new BrotliEncoder(quality, window); + + var srcLength = value.Length * 2; + var maxLength = BrotliUtils.BrotliEncoderMaxCompressedSize(srcLength); + + ref var spanRef = ref writer.GetSpanReference(maxLength + 4); + var dest = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref spanRef, 4), maxLength); + + var status = encoder.Compress(MemoryMarshal.AsBytes(value.AsSpan()), dest, out var bytesConsumed, out var bytesWritten, isFinalBlock: true); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + if (bytesConsumed != srcLength) + { + MemoryPackSerializationException.ThrowCompressionFailed(); + } + + Unsafe.WriteUnaligned(ref spanRef, value.Length); + writer.Advance(bytesWritten + 4); + } + + [Preserve] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Deserialize(ref MemoryPackReader reader, ref string? value) + { + if (!reader.DangerousTryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = ""; + return; + } + + var byteLength = length * 2; + + // security, require to check length + if (decompressionSizeLimit < byteLength) + { + MemoryPackSerializationException.ThrowDecompressionSizeLimitExceeded(decompressionSizeLimit, byteLength); + } + + reader.GetRemainingSource(out var singleSource, out var remainingSource); + + var consumedBox = threadStaticConsumedBox; + if (consumedBox == null) + { + consumedBox = threadStaticConsumedBox = new StrongBox(); + } + else + { + consumedBox.Value = 0; + } + + if (singleSource.Length != 0) + { + unsafe + { + fixed (byte* p = singleSource) + { + value = string.Create(length, ((IntPtr)p, singleSource.Length, byteLength, consumedBox), static (stringSpan, state) => + { + var src = MemoryMarshal.CreateSpan(ref Unsafe.AsRef((byte*)state.Item1), state.Item2); + var destination = MemoryMarshal.AsBytes(stringSpan); + + using var decoder = new BrotliDecoder(); + var status = decoder.Decompress(src, destination, out var bytesConsumed, out var bytesWritten); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + if (bytesWritten != state.byteLength) + { + MemoryPackSerializationException.ThrowCompressionFailed(); + } + + state.consumedBox.Value = bytesConsumed; + }); + reader.Advance(consumedBox.Value); + } + } + } + else + { + value = string.Create(length, (remainingSource, remainingSource.Length, byteLength, consumedBox), static (stringSpan, state) => + { + var destination = MemoryMarshal.AsBytes(stringSpan); + + using var decoder = new BrotliDecoder(); + + var consumed = 0; + OperationStatus status = OperationStatus.DestinationTooSmall; + foreach (var item in state.remainingSource) + { + status = decoder.Decompress(item.Span, destination, out var bytesConsumed, out var bytesWritten); + consumed += bytesConsumed; + + destination = destination.Slice(bytesWritten); + if (status == OperationStatus.Done) + { + break; + } + } + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowCompressionFailed(status); + } + + state.consumedBox.Value = consumed; + }); + reader.Advance(consumedBox.Value); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs.meta new file mode 100644 index 0000000..69b1196 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/StringFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07af9b01eb2a94d439eba905a7b72deb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs new file mode 100644 index 0000000..8538d10 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class TimeZoneInfoFormatter : MemoryPackFormatter +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref TimeZoneInfo? value) + { + writer.WriteString(value?.ToSerializedString()); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref TimeZoneInfo? value) + { + var source = reader.ReadString(); + if (source == null) + { + value = null; + return; + } + + value = TimeZoneInfo.FromSerializedString(source); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs.meta new file mode 100644 index 0000000..3ab0233 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TimeZoneInfoFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ec2daec89486cc439549ac3139a872a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs new file mode 100644 index 0000000..3834c2a --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs @@ -0,0 +1,657 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; + +namespace MemoryPack.Formatters { + +internal static class TupleFormatterTypes +{ + public static readonly Dictionary TupleFormatters = new Dictionary(16) + { + { typeof(Tuple<>), typeof(TupleFormatter<>) }, + { typeof(ValueTuple<>), typeof(ValueTupleFormatter<>) }, + { typeof(Tuple<,>), typeof(TupleFormatter<,>) }, + { typeof(ValueTuple<,>), typeof(ValueTupleFormatter<,>) }, + { typeof(Tuple<,,>), typeof(TupleFormatter<,,>) }, + { typeof(ValueTuple<,,>), typeof(ValueTupleFormatter<,,>) }, + { typeof(Tuple<,,,>), typeof(TupleFormatter<,,,>) }, + { typeof(ValueTuple<,,,>), typeof(ValueTupleFormatter<,,,>) }, + { typeof(Tuple<,,,,>), typeof(TupleFormatter<,,,,>) }, + { typeof(ValueTuple<,,,,>), typeof(ValueTupleFormatter<,,,,>) }, + { typeof(Tuple<,,,,,>), typeof(TupleFormatter<,,,,,>) }, + { typeof(ValueTuple<,,,,,>), typeof(ValueTupleFormatter<,,,,,>) }, + { typeof(Tuple<,,,,,,>), typeof(TupleFormatter<,,,,,,>) }, + { typeof(ValueTuple<,,,,,,>), typeof(ValueTupleFormatter<,,,,,,>) }, + { typeof(Tuple<,,,,,,,>), typeof(TupleFormatter<,,,,,,,>) }, + { typeof(ValueTuple<,,,,,,,>), typeof(ValueTupleFormatter<,,,,,,,>) }, + }; +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(1); + writer.WriteValue(value.Item1); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count); + + value = new Tuple( + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(2); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 2) MemoryPackSerializationException.ThrowInvalidPropertyCount(2, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(3); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 3) MemoryPackSerializationException.ThrowInvalidPropertyCount(3, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(4); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 4) MemoryPackSerializationException.ThrowInvalidPropertyCount(4, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(5); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 5) MemoryPackSerializationException.ThrowInvalidPropertyCount(5, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(6); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 6) MemoryPackSerializationException.ThrowInvalidPropertyCount(6, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(7); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + writer.WriteValue(value.Item7); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 7) MemoryPackSerializationException.ThrowInvalidPropertyCount(7, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class TupleFormatter : MemoryPackFormatter> + where TRest : notnull +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Tuple? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(8); + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + writer.WriteValue(value.Item7); + writer.WriteValue(value.Rest); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Tuple? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 8) MemoryPackSerializationException.ThrowInvalidPropertyCount(8, count); + + value = new Tuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue()! + ); + } +} + + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + writer.WriteValue(value.Item7); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue() + ); + } +} + +[Preserve] +public sealed class ValueTupleFormatter : MemoryPackFormatter> + where TRest : struct +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + writer.DangerousWriteUnmanaged(value); + return; + } + + writer.WriteValue(value.Item1); + writer.WriteValue(value.Item2); + writer.WriteValue(value.Item3); + writer.WriteValue(value.Item4); + writer.WriteValue(value.Item5); + writer.WriteValue(value.Item6); + writer.WriteValue(value.Item7); + writer.WriteValue(value.Rest); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple value) + { + if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences>()) + { + reader.DangerousReadUnmanaged(out value); + return; + } + + value = new ValueTuple( + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue(), + reader.ReadValue()! + ); + } +} + + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs.meta new file mode 100644 index 0000000..bc6b642 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TupleFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 82746260603df5a45a8369e256a78e75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs new file mode 100644 index 0000000..f5df976 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Text.RegularExpressions; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed partial class TypeFormatter : MemoryPackFormatter +{ + // Remove Version, Culture, PublicKeyToken from AssemblyQualifiedName. + // Result will be "TypeName, Assembly" + // see:http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx + +#if NET7_0_OR_GREATER + + [GeneratedRegex(@", Version=\d+.\d+.\d+.\d+, Culture=[\w-]+, PublicKeyToken=(?:null|[a-f0-9]{16})")] + private static partial Regex ShortTypeNameRegex(); + +#else + + static readonly Regex _shortTypeNameRegex = new Regex(@", Version=\d+.\d+.\d+.\d+, Culture=[\w-]+, PublicKeyToken=(?:null|[a-f0-9]{16})", RegexOptions.Compiled); + static Regex ShortTypeNameRegex() => _shortTypeNameRegex; + +#endif + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Type? value) + { + var full = value?.AssemblyQualifiedName; + if (full == null) + { + writer.WriteNullCollectionHeader(); + return; + } + + var shortName = ShortTypeNameRegex().Replace(full, ""); + writer.WriteString(shortName); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Type? value) + { + var typeName = reader.ReadString(); + if (typeName == null) + { + value = null; + return; + } + + value = Type.GetType(typeName, throwOnError: true); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs.meta new file mode 100644 index 0000000..8b0ab0f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/TypeFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f1f7f7bddb1670c4ea52c7efc399000a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs new file mode 100644 index 0000000..a471c0b --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Formatters { + +// for unamanged types( https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/unmanaged-types ) +// * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool +// * Any enum type +// * Any pointer type +// * Any user-defined struct type that contains fields of unmanaged types only +[Preserve] +public sealed class UnmanagedFormatter : MemoryPackFormatter +where T : unmanaged +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T value) + { + Unsafe.WriteUnaligned(ref writer.GetSpanReference(Unsafe.SizeOf()), value); + writer.Advance(Unsafe.SizeOf()); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T value) + { + value = Unsafe.ReadUnaligned(ref reader.GetSpanReference(Unsafe.SizeOf())); + reader.Advance(Unsafe.SizeOf()); + } +} + +[Preserve] +public sealed class DangerousUnmanagedFormatter : MemoryPackFormatter +{ + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + Unsafe.WriteUnaligned(ref writer.GetSpanReference(Unsafe.SizeOf()), value); + writer.Advance(Unsafe.SizeOf()); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + value = Unsafe.ReadUnaligned(ref reader.GetSpanReference(Unsafe.SizeOf())); + reader.Advance(Unsafe.SizeOf()); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs.meta new file mode 100644 index 0000000..1ec7077 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UnmanagedFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87c49cf15480faa4aa13b0027ba10b2b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs new file mode 100644 index 0000000..a0c6bcb --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class UriFormatter : MemoryPackFormatter +{ + // treat as a string(OriginalString). + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Uri? value) + { + writer.WriteString(value?.OriginalString); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Uri? value) + { + var str = reader.ReadString(); + if (str == null) + { + value = null; + } + else + { + value = new Uri(str, UriKind.RelativeOrAbsolute); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs.meta new file mode 100644 index 0000000..634652f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/UriFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 815be7f2c6d469548b382f4531c8d4d4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs new file mode 100644 index 0000000..c65d4c0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; + +namespace MemoryPack.Formatters { + +[Preserve] +public sealed class VersionFormatter : MemoryPackFormatter +{ + // Serialize as [Major, Minor, Build, Revision] + + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Version? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteUnmanagedWithObjectHeader(4, value.Major, value.Minor, value.Build, value.Revision); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Version? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 4) MemoryPackSerializationException.ThrowInvalidPropertyCount(4, count); + + reader.ReadUnmanaged(out int major, out int minor, out int build, out int revision); + + // when use new Version(major, minor), build and revision will be -1, it can not use constructor. + if (revision == -1) + { + if (build == -1) + { + value = new Version(major, minor); + } + else + { + value = new Version(major, minor, build); + } + } + else + { + value = new Version(major, minor, build, revision); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs.meta new file mode 100644 index 0000000..692b7d7 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Formatters/VersionFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65775f54fba192b47a6014ccdccf27ed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs new file mode 100644 index 0000000..b3cebea --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; + +namespace MemoryPack { + +[Preserve] +public interface IMemoryPackFormatter +{ + [Preserve] + void Serialize(ref MemoryPackWriter writer, ref object? value) +#if NET7_0_OR_GREATER + ; +#else + ; +#endif + [Preserve] + void Deserialize(ref MemoryPackReader reader, ref object? value); +} + +[Preserve] +public interface IMemoryPackFormatter +{ + [Preserve] + void Serialize(ref MemoryPackWriter writer, ref T? value) +#if NET7_0_OR_GREATER + ; +#else + ; +#endif + [Preserve] + void Deserialize(ref MemoryPackReader reader, ref T? value); +} + +[Preserve] +public abstract class MemoryPackFormatter : IMemoryPackFormatter, IMemoryPackFormatter +{ + [Preserve] + public abstract void Serialize(ref MemoryPackWriter writer, ref T? value) +#if NET7_0_OR_GREATER + ; +#else + ; +#endif + [Preserve] + public abstract void Deserialize(ref MemoryPackReader reader, ref T? value); + + [Preserve] + void IMemoryPackFormatter.Serialize(ref MemoryPackWriter writer, ref object? value) + { + var v = (value == null) + ? default(T?) + : (T?)value; + Serialize(ref writer, ref v); + } + + [Preserve] + void IMemoryPackFormatter.Deserialize(ref MemoryPackReader reader, ref object? value) + { + var v = (value == null) + ? default(T?) + : (T?)value; + Deserialize(ref reader, ref v); + value = v; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs.meta new file mode 100644 index 0000000..a54d98f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b17111635233244459e4c2668df6e763 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs new file mode 100644 index 0000000..e249891 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; + +namespace MemoryPack { + +#if NET7_0_OR_GREATER + +public interface IFixedSizeMemoryPackable +{ + static abstract int Size { get; } +} + +#endif + +public interface IMemoryPackFormatterRegister +{ +#if NET7_0_OR_GREATER + static abstract void RegisterFormatter(); +#endif +} + +public interface IMemoryPackable : IMemoryPackFormatterRegister +{ + // note: serialize parameter should be `ref readonly` but current lang spec can not. + // see proposal https://github.com/dotnet/csharplang/issues/6010 + +#if NET7_0_OR_GREATER + static abstract void Serialize(ref MemoryPackWriter writer, ref T? value) + ; + static abstract void Deserialize(ref MemoryPackReader reader, ref T? value); +#endif +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs.meta new file mode 100644 index 0000000..deec564 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/IMemoryPackable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53c6fb0170766704aa3ec4b1aedf050d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal.meta new file mode 100644 index 0000000..e6f19d0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2f8ccfb431cbe7f4299e0245f9c74309 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs new file mode 100644 index 0000000..c2f3346 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack.Internal { + +internal static class EnumerableExtensions +{ + public static bool TryGetNonEnumeratedCountEx(this IEnumerable value, out int count) + { + // TryGetNonEnumeratedCount is not check IReadOnlyCollection so add check manually. + // https://github.com/dotnet/runtime/issues/54764 + +#if NET7_0_OR_GREATER + if (value.TryGetNonEnumeratedCount(out count)) + { + return true; + } +#else + count = 0; + if (value is ICollection collection) + { + count = collection.Count; + return true; + } +#endif + + if (value is IReadOnlyCollection readOnlyCollection) + { + count = readOnlyCollection.Count; + return true; + } + + return false; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs.meta new file mode 100644 index 0000000..e514c18 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/EnumerableExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b7de601a63709940b09c18eb34cf772 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs new file mode 100644 index 0000000..95d3e86 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace MemoryPack.Internal { + +internal struct FixedArrayBufferWriter : IBufferWriter +{ + byte[] buffer; + int written; + + public FixedArrayBufferWriter(byte[] buffer) + { + this.buffer = buffer; + this.written = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int count) + { + this.written += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Memory GetMemory(int sizeHint = 0) + { + var memory = buffer.AsMemory(written); + if (memory.Length >= sizeHint) + { + return memory; + } + + MemoryPackSerializationException.ThrowMessage("Requested invalid sizeHint."); + return memory; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetSpan(int sizeHint = 0) + { + var span = buffer.AsSpan(written); + if (span.Length >= sizeHint) + { + return span; + } + + MemoryPackSerializationException.ThrowMessage("Requested invalid sizeHint."); + return span; + } + + public byte[] GetFilledBuffer() + { + if (written != buffer.Length) + { + MemoryPackSerializationException.ThrowMessage("Not filled buffer."); + } + + return buffer; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs.meta new file mode 100644 index 0000000..5f0e2e0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/FixedArrayBufferWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 61f475a704e250d4ab0dd882130e9fdd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs new file mode 100644 index 0000000..6593417 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Runtime.CompilerServices; + +namespace MemoryPack.Internal { + +internal static class MathEx +{ + const int ArrayMexLength = 0x7FFFFFC7; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int NewArrayCapacity(int size) + { + var newSize = unchecked(size * 2); + if ((uint)newSize > ArrayMexLength) + { + newSize = ArrayMexLength; + } + return newSize; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs.meta new file mode 100644 index 0000000..c928f0d --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MathEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 927c0eadb944275499836693dc80f88b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs new file mode 100644 index 0000000..91c24ae --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +#if !NET7_0_OR_GREATER + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Internal { + +internal static class MemoryMarshalEx +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T GetArrayDataReference(T[] array) + { + return ref MemoryMarshal.GetReference(array.AsSpan()); + } + + // GC + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T[] AllocateUninitializedArray(int length, bool pinned = false) + { + return new T[length]; + } +} + +#endif + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs.meta new file mode 100644 index 0000000..da0f3e2 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/MemoryMarshalEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2909cb9ffb605ae47b659f8140c62ca9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs new file mode 100644 index 0000000..49d779e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack.Internal { + +// Preserve for Unity IL2CPP(internal but used for code generator) + +public sealed class PreserveAttribute : System.Attribute +{ +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs.meta new file mode 100644 index 0000000..3dd47e0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/PreserveAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d985418ff3c30b2429f7cdc878e0ddf9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs new file mode 100644 index 0000000..85427c1 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Collections; +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Internal { + +#if NET7_0_OR_GREATER +using static GC; +using static MemoryMarshal; +#else +using static MemoryPack.Internal.MemoryMarshalEx; +#endif + +// internal but used by generator code + +public static class ReusableLinkedArrayBufferWriterPool +{ + static readonly ConcurrentQueue queue = new ConcurrentQueue(); + + public static ReusableLinkedArrayBufferWriter Rent() + { + if (queue.TryDequeue(out var writer)) + { + return writer; + } + return new ReusableLinkedArrayBufferWriter(useFirstBuffer: false, pinned: false); // does not cache firstBuffer + } + + public static void Return(ReusableLinkedArrayBufferWriter writer) + { + writer.Reset(); + queue.Enqueue(writer); + } +} + +// This class has large buffer so should cache [ThreadStatic] or Pool. +public sealed class ReusableLinkedArrayBufferWriter : IBufferWriter +{ + const int InitialBufferSize = 262144; // 256K(32768, 65536, 131072, 262144) + static readonly byte[] noUseFirstBufferSentinel = new byte[0]; + + List buffers; // add freezed buffer. + + byte[] firstBuffer; // cache firstBuffer to avoid call ArrayPoo.Rent/Return + int firstBufferWritten; + + BufferSegment current; + int nextBufferSize; + + int totalWritten; + + public int TotalWritten => totalWritten; + bool UseFirstBuffer => firstBuffer != noUseFirstBufferSentinel; + + public ReusableLinkedArrayBufferWriter(bool useFirstBuffer, bool pinned) + { + this.buffers = new List(); + this.firstBuffer = useFirstBuffer + ? AllocateUninitializedArray(InitialBufferSize, pinned) + : noUseFirstBufferSentinel; + this.firstBufferWritten = 0; + this.current = default; + this.nextBufferSize = InitialBufferSize; + this.totalWritten = 0; + } + + public byte[] DangerousGetFirstBuffer() => firstBuffer; + + public Memory GetMemory(int sizeHint = 0) + { + // MemoryPack don't use GetMemory. + throw new NotSupportedException(); + } + + public Span GetSpan(int sizeHint = 0) + { + if (current.IsNull) + { + // use firstBuffer + var free = firstBuffer.Length - firstBufferWritten; + if (free != 0 && sizeHint <= free) + { + return firstBuffer.AsSpan(firstBufferWritten); + } + } + else + { + var buffer = current.FreeBuffer; + if (buffer.Length > sizeHint) + { + return buffer; + } + } + + BufferSegment next; + if (sizeHint <= nextBufferSize) + { + next = new BufferSegment(nextBufferSize); + nextBufferSize = MathEx.NewArrayCapacity(nextBufferSize); + } + else + { + next = new BufferSegment(sizeHint); + } + + if (current.WrittenCount != 0) + { + buffers.Add(current); + } + current = next; + return next.FreeBuffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int count) + { + if (current.IsNull) + { + firstBufferWritten += count; + } + else + { + current.Advance(count); + } + totalWritten += count; + } + + public byte[] ToArrayAndReset() + { + if (totalWritten == 0) return Array.Empty(); + + var result = AllocateUninitializedArray(totalWritten); + var dest = result.AsSpan(); + + if (UseFirstBuffer) + { + firstBuffer.AsSpan(0, firstBufferWritten).CopyTo(dest); + dest = dest.Slice(firstBufferWritten); + } + + if (buffers.Count > 0) + { +#if NET7_0_OR_GREATER + foreach (ref var item in CollectionsMarshal.AsSpan(buffers)) +#else + foreach (var item in buffers) +#endif + { + item.WrittenBuffer.CopyTo(dest); + dest = dest.Slice(item.WrittenCount); + item.Clear(); // reset buffer-segment in this loop to avoid iterate twice for Reset + } + } + + if (!current.IsNull) + { + current.WrittenBuffer.CopyTo(dest); + current.Clear(); + } + + ResetCore(); + return result; + } + + public void WriteToAndReset(ref MemoryPackWriter writer) +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (totalWritten == 0) return; + + if (UseFirstBuffer) + { + ref var spanRef = ref writer.GetSpanReference(firstBufferWritten); + firstBuffer.AsSpan(0, firstBufferWritten).CopyTo(MemoryMarshal.CreateSpan(ref spanRef, firstBufferWritten)); + writer.Advance(firstBufferWritten); + } + + if (buffers.Count > 0) + { +#if NET7_0_OR_GREATER + foreach (ref var item in CollectionsMarshal.AsSpan(buffers)) +#else + foreach (var item in buffers) +#endif + { + ref var spanRef = ref writer.GetSpanReference(item.WrittenCount); + item.WrittenBuffer.CopyTo(MemoryMarshal.CreateSpan(ref spanRef, item.WrittenCount)); + writer.Advance(item.WrittenCount); + item.Clear(); // reset + } + } + + if (!current.IsNull) + { + ref var spanRef = ref writer.GetSpanReference(current.WrittenCount); + current.WrittenBuffer.CopyTo(MemoryMarshal.CreateSpan(ref spanRef, current.WrittenCount)); + writer.Advance(current.WrittenCount); + current.Clear(); + } + + ResetCore(); + } + + public async ValueTask WriteToAndResetAsync(Stream stream, CancellationToken cancellationToken) + { + if (totalWritten == 0) return; + + if (UseFirstBuffer) + { + await stream.WriteAsync(firstBuffer.AsMemory(0, firstBufferWritten), cancellationToken).ConfigureAwait(false); + } + + if (buffers.Count > 0) + { + foreach (var item in buffers) + { + await stream.WriteAsync(item.WrittenMemory, cancellationToken).ConfigureAwait(false); + item.Clear(); // reset + } + } + + if (!current.IsNull) + { + await stream.WriteAsync(current.WrittenMemory, cancellationToken).ConfigureAwait(false); + current.Clear(); + } + + ResetCore(); + } + + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + // reset without list's BufferSegment element + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void ResetCore() + { + firstBufferWritten = 0; + buffers.Clear(); + totalWritten = 0; + current = default; + nextBufferSize = InitialBufferSize; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Reset() + { + if (totalWritten == 0) return; +#if NET7_0_OR_GREATER + foreach (ref var item in CollectionsMarshal.AsSpan(buffers)) +#else + foreach (var item in buffers) +#endif + { + item.Clear(); + } + current.Clear(); + ResetCore(); + } + + public struct Enumerator : IEnumerator> + { + ReusableLinkedArrayBufferWriter parent; + State state; + Memory current; + List.Enumerator buffersEnumerator; + + public Enumerator(ReusableLinkedArrayBufferWriter parent) + { + this.parent = parent; + this.state = default; + this.current = default; + this.buffersEnumerator = default; + } + + public Memory Current => current; + + object IEnumerator.Current => throw new NotSupportedException(); + + public void Dispose() + { + } + + public bool MoveNext() + { + if (state == State.FirstBuffer) + { + state = State.BuffersInit; + + if (parent.UseFirstBuffer) + { + current = parent.firstBuffer.AsMemory(0, parent.firstBufferWritten); + return true; + } + } + + if (state == State.BuffersInit) + { + state = State.BuffersIterate; + + buffersEnumerator = parent.buffers.GetEnumerator(); + } + + if (state == State.BuffersIterate) + { + if (buffersEnumerator.MoveNext()) + { + current = buffersEnumerator.Current.WrittenMemory; + return true; + } + + buffersEnumerator.Dispose(); + state = State.Current; + } + + if (state == State.Current) + { + state = State.End; + + current = parent.current.WrittenMemory; + return true; + } + + return false; + } + + public void Reset() + { + throw new NotSupportedException(); + } + + enum State + { + FirstBuffer, + BuffersInit, + BuffersIterate, + Current, + End + } + } +} + +internal struct BufferSegment +{ + byte[] buffer; + int written; + + public bool IsNull => buffer == null; + + public int WrittenCount => written; + public Span WrittenBuffer => buffer.AsSpan(0, written); + public Memory WrittenMemory => buffer.AsMemory(0, written); + public Span FreeBuffer => buffer.AsSpan(written); + + public BufferSegment(int size) + { + buffer = ArrayPool.Shared.Rent(size); + written = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int count) + { + written += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } + buffer = null!; + written = 0; + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs.meta new file mode 100644 index 0000000..ffd7feb --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableLinkedArrayBufferWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42122ccd6d229c5478197bd7fbce99d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs new file mode 100644 index 0000000..766e6c4 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Collections.Concurrent; +using System.Runtime.InteropServices; + +namespace MemoryPack.Internal { + +internal static class ReusableReadOnlySequenceBuilderPool +{ + static readonly ConcurrentQueue queue = new(); + + public static ReusableReadOnlySequenceBuilder Rent() + { + if (queue.TryDequeue(out var builder)) + { + return builder; + } + return new ReusableReadOnlySequenceBuilder(); + } + + public static void Return(ReusableReadOnlySequenceBuilder builder) + { + builder.Reset(); + queue.Enqueue(builder); + } +} + +internal sealed class ReusableReadOnlySequenceBuilder +{ + readonly Stack segmentPool; + readonly List list; + + public ReusableReadOnlySequenceBuilder() + { + list = new(); + segmentPool = new Stack(); + } + + public void Add(ReadOnlyMemory buffer, bool returnToPool) + { + if (!segmentPool.TryPop(out var segment)) + { + segment = new Segment(); + } + + segment.SetBuffer(buffer, returnToPool); + list.Add(segment); + } + + public bool TryGetSingleMemory(out ReadOnlyMemory memory) + { + if (list.Count == 1) + { + memory = list[0].Memory; + return true; + } + memory = default; + return false; + } + + public ReadOnlySequence Build() + { + if (list.Count == 0) + { + return ReadOnlySequence.Empty; + } + + if (list.Count == 1) + { + return new ReadOnlySequence(list[0].Memory); + } + + long running = 0; +#if NET7_0_OR_GREATER + var span = CollectionsMarshal.AsSpan(list); + for (int i = 0; i < span.Length; i++) + { + var next = i < span.Length - 1 ? span[i + 1] : null; + span[i].SetRunningIndexAndNext(running, next); + running += span[i].Memory.Length; + } + var firstSegment = span[0]; + var lastSegment = span[span.Length - 1]; +#else + var span = list; + for (int i = 0; i < span.Count; i++) + { + var next = i < span.Count - 1 ? span[i + 1] : null; + span[i].SetRunningIndexAndNext(running, next); + running += span[i].Memory.Length; + } + var firstSegment = span[0]; + var lastSegment = span[span.Count - 1]; +#endif + return new ReadOnlySequence(firstSegment, 0, lastSegment, lastSegment.Memory.Length); + } + + public void Reset() + { +#if NET7_0_OR_GREATER + var span = CollectionsMarshal.AsSpan(list); +#else + var span = list; +#endif + foreach (var item in span) + { + item.Reset(); + segmentPool.Push(item); + } + list.Clear(); + } + + class Segment : ReadOnlySequenceSegment + { + bool returnToPool; + + public Segment() + { + returnToPool = false; + } + + public void SetBuffer(ReadOnlyMemory buffer, bool returnToPool) + { + Memory = buffer; + this.returnToPool = returnToPool; + } + + public void Reset() + { + if (returnToPool) + { + if (MemoryMarshal.TryGetArray(Memory, out var segment) && segment.Array != null) + { + ArrayPool.Shared.Return(segment.Array, clearArray: false); + } + } + Memory = default; + RunningIndex = 0; + Next = null; + } + + public void SetRunningIndexAndNext(long runningIndex, Segment? nextSegment) + { + RunningIndex = runningIndex; + Next = nextSegment; + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs.meta new file mode 100644 index 0000000..0dbbbde --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/ReusableReadOnlySequenceBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b700925f1ee40614ca7c44623074da57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs new file mode 100644 index 0000000..9561588 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack.Internal { + +internal static class TypeHelpers +{ + static readonly MethodInfo isReferenceOrContainsReferences = typeof(RuntimeHelpers).GetMethod("IsReferenceOrContainsReferences")!; + static readonly MethodInfo unsafeSizeOf = typeof(Unsafe).GetMethod("SizeOf")!; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsReferenceOrNullable() + { + return Cache.IsReferenceOrNullable; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TypeKind TryGetUnmanagedSZArrayElementSizeOrMemoryPackableFixedSize(out int size) + { + if (Cache.IsUnmanagedSZArray) + { + size = Cache.UnmanagedSZArrayElementSize; + return TypeKind.UnmanagedSZArray; + } + else + { + if (Cache.IsFixedSizeMemoryPackable) + { + size = Cache.MemoryPackableFixedSize; + return TypeKind.FixedSizeMemoryPackable; + } + } + + size = 0; + return TypeKind.None; + } + + public static bool IsAnonymous(Type type) + { + return type.Namespace == null + && type.IsSealed + && (type.Name.StartsWith("<>f__AnonymousType", StringComparison.Ordinal) + || type.Name.StartsWith("<>__AnonType", StringComparison.Ordinal) + || type.Name.StartsWith("VB$AnonymousType_", StringComparison.Ordinal)) + && type.IsDefined(typeof(CompilerGeneratedAttribute), false); + } + + static class Cache + { + public static bool IsReferenceOrNullable; + public static bool IsUnmanagedSZArray; + public static int UnmanagedSZArrayElementSize; + public static bool IsFixedSizeMemoryPackable = false; + public static int MemoryPackableFixedSize = 0; + + static Cache() + { + try + { + var type = typeof(T); + IsReferenceOrNullable = !type.IsValueType || Nullable.GetUnderlyingType(type) != null; + + if (type.IsSZArray) + { + var elementType = type.GetElementType(); + bool containsReference = (bool)(isReferenceOrContainsReferences.MakeGenericMethod(elementType!).Invoke(null, null)!); + if (!containsReference) + { + IsUnmanagedSZArray = true; + UnmanagedSZArrayElementSize = (int)unsafeSizeOf.MakeGenericMethod(elementType!).Invoke(null, null)!; + } + } +#if NET7_0_OR_GREATER + else + { + if (typeof(IFixedSizeMemoryPackable).IsAssignableFrom(type)) + { + var prop = type.GetProperty("global::MemoryPack.IFixedSizeMemoryPackable.Size", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + if (prop != null) + { + IsFixedSizeMemoryPackable = true; + MemoryPackableFixedSize = (int)prop.GetValue(null)!; + } + } + } +#endif + } + catch + { + IsUnmanagedSZArray = false; + IsFixedSizeMemoryPackable = false; + } + } + } + + internal enum TypeKind : byte + { + None, + UnmanagedSZArray, + FixedSizeMemoryPackable + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs.meta new file mode 100644 index 0000000..9bac052 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/Internal/TypeHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 329bffde10972564f8819da18337cbc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs new file mode 100644 index 0000000..a82b5b7 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack { + +public static class MemoryPackCode +{ + // Collection Header + // 0~* is length, -1 is null + public const int NullCollection = -1; + + // Object/Union Header + // 0~249 is member count or tag, 250~254 is unused, 255 is null + public const byte WideTag = 250; // for Union, 250 is wide tag + public const byte ReferenceId = 250; // for CircularReference, 250 is referenceId marker, next VarInt id reference. + + public const byte Reserved1 = 250; + public const byte Reserved2 = 251; + public const byte Reserved3 = 252; + public const byte Reserved4 = 253; + public const byte Reserved5 = 254; + public const byte NullObject = 255; + + // predefined, C# compiler optimize byte[] as ReadOnlySpan property + internal static ReadOnlySpan NullCollectionData => new byte[] { 255, 255, 255, 255 }; // -1 + internal static ReadOnlySpan ZeroCollectionData => new byte[] { 0, 0, 0, 0 }; // 0 +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs.meta new file mode 100644 index 0000000..b18e486 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47fb89e30884e9940988b0d3021773f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs new file mode 100644 index 0000000..d34cf93 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Formatters; +using System.Collections; +using System.Globalization; +using System.Text; +using System.Numerics; + +namespace MemoryPack { + +public static partial class MemoryPackFormatterProvider +{ + internal static void RegisterWellKnownTypesFormatters() + { + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); +#if NET7_0_OR_GREATER + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new NullableFormatter()); +#endif + Register(new StringFormatter()); + Register(new ArrayFormatter()); + Register(new VersionFormatter()); + Register(new ArrayFormatter()); + Register(new UriFormatter()); + Register(new ArrayFormatter()); + Register(new TimeZoneInfoFormatter()); + Register(new ArrayFormatter()); + Register(new BigIntegerFormatter()); + Register(new ArrayFormatter()); + Register(new BitArrayFormatter()); + Register(new ArrayFormatter()); + Register(new StringBuilderFormatter()); + Register(new ArrayFormatter()); + Register(new TypeFormatter()); + Register(new ArrayFormatter()); + Register(new CultureInfoFormatter()); + Register(new ArrayFormatter()); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs.meta new file mode 100644 index 0000000..f3896db --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.WellknownTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c06329799b27a34abe37d38dac0a197 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs new file mode 100644 index 0000000..9dec50f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs @@ -0,0 +1,458 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Formatters; +using MemoryPack.Internal; +using System.Buffers; +using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; + +namespace MemoryPack { + +// This service provider is not extension point, for wellknown types +// and fallback if can't resolve in compile time(like generics). +// Therefore, unlike MessagePack for C#, it is static and not extensible. + +public static partial class MemoryPackFormatterProvider +{ + // for nongenerics methods + static readonly ConcurrentDictionary formatters = new ConcurrentDictionary(Environment.ProcessorCount, 150); + + // custom generic formatters + static readonly ConcurrentDictionary genericFormatterFactory = new ConcurrentDictionary(); + + // custom generic collection formatters + static readonly ConcurrentDictionary genericCollectionFormatterFactory = new ConcurrentDictionary(); + + // generics known types + static readonly Dictionary KnownGenericTypeFormatters = new Dictionary(3) + { + { typeof(KeyValuePair<,>), typeof(KeyValuePairFormatter<,>) }, + { typeof(Lazy<>), typeof(LazyFormatter<>) }, + { typeof(Nullable<>), typeof(NullableFormatter<>) }, + }; + + static partial void RegisterInitialFormatters(); + + static MemoryPackFormatterProvider() + { + // Initialize on startup + RegisterWellKnownTypesFormatters(); + // Extension for Unity or others + RegisterInitialFormatters(); + } + + public static bool IsRegistered() => Check.registered; + + public static void Register(MemoryPackFormatter formatter) + { + Check.registered = true; // avoid to call Cache() constructor called. + formatters[typeof(T)] = formatter; + Cache.formatter = formatter; + } + +#if NET7_0_OR_GREATER + + public static void Register() + where T : IMemoryPackFormatterRegister + { + T.RegisterFormatter(); + } + +#endif + + public static void RegisterGenericType(Type genericType, Type genericFormatterType) + { + if (genericType.IsGenericType && genericFormatterType.IsGenericType) + { + genericFormatterFactory[genericType] = genericFormatterType; + } + else + { + MemoryPackSerializationException.ThrowMessage($"Registered type is not generic type. genericType:{genericType.FullName}, formatterType:{genericFormatterType.FullName}"); + } + } + + public static void RegisterCollection() + where TCollection : ICollection, new() + { + Register(new GenericCollectionFormatter()); + } + + public static void RegisterCollection(Type genericCollectionType) + { + if (genericCollectionType.IsGenericType && genericCollectionType.GetGenericArguments().Length == 1) + { + genericCollectionFormatterFactory[genericCollectionType] = typeof(GenericCollectionFormatter<,>); + } + else + { + MemoryPackSerializationException.ThrowMessage($"Registered generic collection is not filled generic formatter constraint. type: {genericCollectionType.FullName}"); + } + } + + public static void RegisterSet() + where TSet : ISet, new() + { + Register(new GenericSetFormatter()); + } + + public static void RegisterSet(Type genericSetType) + { + if (genericSetType.IsGenericType && genericSetType.GetGenericArguments().Length == 1) + { + genericCollectionFormatterFactory[genericSetType] = typeof(GenericSetFormatter<,>); + } + else + { + MemoryPackSerializationException.ThrowMessage($"Registered generic set is not filled generic formatter constraint. type: {genericSetType.FullName}"); + } + } + + public static void RegisterDictionary() + where TKey : notnull + where TDictionary : IDictionary, new() + { + Register(new GenericDictionaryFormatter()); + } + + public static void RegisterDictionary(Type genericDictionaryType) + { + if (genericDictionaryType.IsGenericType && genericDictionaryType.GetGenericArguments().Length == 2) + { + genericCollectionFormatterFactory[genericDictionaryType] = typeof(GenericDictionaryFormatter<,,>); + } + else + { + MemoryPackSerializationException.ThrowMessage($"Registered generic collection is not filled generic formatter constraint. type: {genericDictionaryType.FullName}"); + } + } + + // almostly get from Writer/Reader + // in future, will change static provider to instance provider. + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static MemoryPackFormatter GetFormatter() + { + return Cache.formatter; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static IMemoryPackFormatter GetFormatter(Type type) + { + if (formatters.TryGetValue(type, out var formatter)) + { + return formatter; + } + + if (TryInvokeRegisterFormatter(type)) + { + // try again + if (formatters.TryGetValue(type, out formatter)) + { + return formatter; + } + } + + if (TypeHelpers.IsAnonymous(type)) + { + formatter = new ErrorMemoryPackFormatter(type, "Serialize anonymous type is not supported, use record or tuple instead."); + goto END; + } + + // non registered, try to create generic formatter + // can not detect IsReferenceOrContainsReference but it only uses array type select so safe). + var formatter2 = CreateGenericFormatter(type, typeIsReferenceOrContainsReferences: true) as IMemoryPackFormatter; + if (formatter2 == null) + { + formatter2 = new ErrorMemoryPackFormatter(type); + } + formatter = formatter2; + + END: + formatters[type] = formatter; + return formatter; + } + + static bool TryInvokeRegisterFormatter(Type type) + { + if (typeof(IMemoryPackFormatterRegister).IsAssignableFrom(type)) + { + // currently C# can not call like `if (T is IMemoryPackFormatterRegister) T.RegisterFormatter()`, so use reflection instead. + var m = type.GetMethod("MemoryPack.IMemoryPackFormatterRegister.RegisterFormatter", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + if (m == null) + { + // Roslyn3.11 generator generate public static method + m = type.GetMethod("RegisterFormatter", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + } + if (m == null) + { + throw new InvalidOperationException("Type implements IMemoryPackFormatterRegister but can not found RegisterFormatter. Type: " + type.FullName); + } + m!.Invoke(null, null); // Cache.formatter will set from method + return true; + } + + return false; + } + + static class Check + { + public static bool registered; + } + + static class Cache + { + public static MemoryPackFormatter formatter = default!; + + static Cache() + { + if (Check.registered) return; + + try + { + var type = typeof(T); + if (TryInvokeRegisterFormatter(type)) + { + return; + } + + if (TypeHelpers.IsAnonymous(type)) + { + formatter = new ErrorMemoryPackFormatter("Serialize anonymous type is not supported, use record or tuple instead."); + goto END; + } + + var typeIsReferenceOrContainsReferences = RuntimeHelpers.IsReferenceOrContainsReferences(); + var f = CreateGenericFormatter(type, typeIsReferenceOrContainsReferences) as MemoryPackFormatter; + + formatter = f ?? new ErrorMemoryPackFormatter(); + } + catch (Exception ex) + { + formatter = new ErrorMemoryPackFormatter(ex); + } + + END: + formatters[typeof(T)] = formatter; + Check.registered = true; + } + } + + internal static object? CreateGenericFormatter(Type type, bool typeIsReferenceOrContainsReferences) + { + Type? formatterType = null; + + if (type.IsArray) + { + if (type.IsSZArray) + { + if (!typeIsReferenceOrContainsReferences) + { + formatterType = typeof(DangerousUnmanagedArrayFormatter<>).MakeGenericType(type.GetElementType()!); + goto CREATE; + } + else + { + formatterType = typeof(ArrayFormatter<>).MakeGenericType(type.GetElementType()!); + goto CREATE; + } + } + else + { + var rank = type.GetArrayRank(); + switch (rank) + { + case 2: + formatterType = typeof(TwoDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()!); + goto CREATE; + case 3: + formatterType = typeof(ThreeDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()!); + goto CREATE; + case 4: + formatterType = typeof(FourDimensionalArrayFormatter<>).MakeGenericType(type.GetElementType()!); + goto CREATE; + default: + return null; // not supported + } + } + } + + if (type.IsEnum || !typeIsReferenceOrContainsReferences) + { + formatterType = typeof(DangerousUnmanagedFormatter<>).MakeGenericType(type); + goto CREATE; + } + + formatterType = TryCreateGenericFormatterType(type, TupleFormatterTypes.TupleFormatters); + if (formatterType != null) goto CREATE; + + formatterType = TryCreateGenericFormatterType(type, KnownGenericTypeFormatters); + if (formatterType != null) goto CREATE; + + formatterType = TryCreateGenericFormatterType(type, ArrayLikeFormatters); + if (formatterType != null) goto CREATE; + + formatterType = TryCreateGenericFormatterType(type, CollectionFormatters); + if (formatterType != null) goto CREATE; + +#if !UNITY_2021_2_OR_NEWER + formatterType = TryCreateGenericFormatterType(type, ImmutableCollectionFormatters); + if (formatterType != null) goto CREATE; +#endif + + formatterType = TryCreateGenericFormatterType(type, InterfaceCollectionFormatters); + if (formatterType != null) goto CREATE; + + // finally custom generated + formatterType = TryCreateGenericFormatterType(type, genericFormatterFactory); + if (formatterType != null) goto CREATE; + + // genericCollectionFormatterFactory + formatterType = TryCreateGenericCollectionFormatterType(type); + if (formatterType != null) goto CREATE; + + // Can't resolve formatter, return null(will create ErrorMemoryPackFormatter). + return null; + + CREATE: + return Activator.CreateInstance(formatterType); + } + + static Type? TryCreateGenericFormatterType(Type type, IDictionary knownTypes) + { + if (type.IsGenericType) + { + var genericDefinition = type.GetGenericTypeDefinition(); + + if (knownTypes.TryGetValue(genericDefinition, out var formatterType)) + { + return formatterType.MakeGenericType(type.GetGenericArguments()); + } + } + + return null; + } + + static Type? TryCreateGenericCollectionFormatterType(Type type) + { + if (type.IsGenericType && genericCollectionFormatterFactory.TryGetValue(type, out var formatterType)) + { + var genericDefinition = type.GetGenericTypeDefinition(); + var elementTypes = genericDefinition.GetGenericArguments(); + + // formatterType is so concat type at first + return formatterType.MakeGenericType(elementTypes.Prepend(type).ToArray()); + } + + return null; + } +} + +internal sealed class ErrorMemoryPackFormatter : IMemoryPackFormatter +{ + readonly Type type; + readonly string? message; + + public ErrorMemoryPackFormatter(Type type) + { + this.type = type; + this.message = null; + } + + public ErrorMemoryPackFormatter(Type type, string message) + { + this.type = type; + this.message = message; + } + + public void Serialize(ref MemoryPackWriter writer, ref object? value) +#if NET7_0_OR_GREATER + +#else + +#endif + { + Throw(); + } + + public void Deserialize(ref MemoryPackReader reader, ref object? value) + { + Throw(); + } + + [DoesNotReturn] + void Throw() + { + if (message != null) + { + MemoryPackSerializationException.ThrowMessage(message); + } + else + { + MemoryPackSerializationException.ThrowNotRegisteredInProvider(type); + } + } +} + +internal sealed class ErrorMemoryPackFormatter : MemoryPackFormatter +{ + readonly Exception? exception; + readonly string? message; + + public ErrorMemoryPackFormatter() + { + this.exception = null; + this.message = null; + } + + public ErrorMemoryPackFormatter(Exception exception) + { + this.exception = exception; + this.message = null; + } + + public ErrorMemoryPackFormatter(string message) + { + this.exception = null; + this.message = message; + } + + public override void Serialize(ref MemoryPackWriter writer, ref T? value) + { + Throw(); + } + + public override void Deserialize(ref MemoryPackReader reader, ref T? value) + { + Throw(); + } + + [DoesNotReturn] + void Throw() + { + if (exception != null) + { + MemoryPackSerializationException.ThrowRegisterInProviderFailed(typeof(T), exception); + } + else if (message != null) + { + MemoryPackSerializationException.ThrowMessage(message); + } + else + { + MemoryPackSerializationException.ThrowNotRegisteredInProvider(typeof(T)); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs.meta new file mode 100644 index 0000000..bbe7fff --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackFormatterProvider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f1200521b3b3b7344a1cfe3b1b58439a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs new file mode 100644 index 0000000..ee0cc53 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs @@ -0,0 +1,620 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack { + +public ref partial struct MemoryPackReader +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1) + where T1 : unmanaged + { + var size = Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2) + where T1 : unmanaged + where T2 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value14 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14, out T15 value15) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + where T15 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value14 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value15 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1) + { + var size = Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value14 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousReadUnmanaged(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6, out T7 value7, out T8 value8, out T9 value9, out T10 value10, out T11 value11, out T12 value12, out T13 value13, out T14 value14, out T15 value15) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + value1 = Unsafe.ReadUnaligned(ref spanRef); + value2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf())); + value3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf())); + value4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value5 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value6 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value7 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value8 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value9 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value10 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value11 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value12 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value13 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value14 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + value15 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf())); + Advance(size); + } + +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs.meta new file mode 100644 index 0000000..2930e6a --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.Unmanaged.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5edf80b8ed9aae143b689d072859a209 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs new file mode 100644 index 0000000..9926b0c --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs @@ -0,0 +1,930 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +#if NET7_0_OR_GREATER +using System.Text.Unicode; +#endif + +namespace MemoryPack { + +#if NET7_0_OR_GREATER +using static GC; +using static MemoryMarshal; +#else +using static MemoryPack.Internal.MemoryMarshalEx; +#endif + +[StructLayout(LayoutKind.Auto)] +public ref partial struct MemoryPackReader +{ + ReadOnlySequence bufferSource; + readonly long totalLength; +#if NET7_0_OR_GREATER + ref byte bufferReference; +#else + ReadOnlySpan bufferReference; +#endif + int bufferLength; + byte[]? rentBuffer; + int advancedCount; + int consumed; // total length of consumed + readonly MemoryPackReaderOptionalState optionalState; + + public int Consumed => consumed; + public long Remaining => totalLength - consumed; + public MemoryPackReaderOptionalState OptionalState => optionalState; + public MemoryPackSerializerOptions Options => optionalState.Options; + + public MemoryPackReader(in ReadOnlySequence sequence, MemoryPackReaderOptionalState optionalState) + { + this.bufferSource = sequence.IsSingleSegment ? ReadOnlySequence.Empty : sequence; + var span = sequence.FirstSpan; +#if NET7_0_OR_GREATER + this.bufferReference = ref MemoryMarshal.GetReference(span); +#else + this.bufferReference = span; +#endif + this.bufferLength = span.Length; + this.advancedCount = 0; + this.consumed = 0; + this.rentBuffer = null; + this.totalLength = sequence.Length; + this.optionalState = optionalState; + } + + public MemoryPackReader(ReadOnlySpan buffer, MemoryPackReaderOptionalState optionalState) + { + this.bufferSource = ReadOnlySequence.Empty; +#if NET7_0_OR_GREATER + this.bufferReference = ref MemoryMarshal.GetReference(buffer); +#else + this.bufferReference = buffer; +#endif + this.bufferLength = buffer.Length; + this.advancedCount = 0; + this.consumed = 0; + this.rentBuffer = null; + this.totalLength = buffer.Length; + this.optionalState = optionalState; + } + + // buffer operations + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref byte GetSpanReference(int sizeHint) + { + if (sizeHint <= bufferLength) + { +#if NET7_0_OR_GREATER + return ref bufferReference; +#else + return ref MemoryMarshal.GetReference(bufferReference); +#endif + } + + return ref GetNextSpan(sizeHint); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + ref byte GetNextSpan(int sizeHint) + { + if (rentBuffer != null) + { + ArrayPool.Shared.Return(rentBuffer); + rentBuffer = null; + } + + if (Remaining == 0) + { + MemoryPackSerializationException.ThrowSequenceReachedEnd(); + } + + try + { + bufferSource = bufferSource.Slice(advancedCount); + } + catch (ArgumentOutOfRangeException) + { + MemoryPackSerializationException.ThrowSequenceReachedEnd(); + } + + advancedCount = 0; + + if (sizeHint <= Remaining) + { + if (sizeHint <= bufferSource.FirstSpan.Length) + { +#if NET7_0_OR_GREATER + bufferReference = ref MemoryMarshal.GetReference(bufferSource.FirstSpan); + bufferLength = bufferSource.FirstSpan.Length; + return ref bufferReference; +#else + bufferReference = bufferSource.FirstSpan; + bufferLength = bufferSource.FirstSpan.Length; + return ref MemoryMarshal.GetReference(bufferReference); +#endif + } + + rentBuffer = ArrayPool.Shared.Rent(sizeHint); + bufferSource.Slice(0, sizeHint).CopyTo(rentBuffer); + var span = rentBuffer.AsSpan(0, sizeHint); +#if NET7_0_OR_GREATER + bufferReference = ref MemoryMarshal.GetReference(span); + bufferLength = span.Length; + return ref bufferReference; +#else + bufferReference = span; + bufferLength = span.Length; + return ref MemoryMarshal.GetReference(bufferReference); +#endif + } + + MemoryPackSerializationException.ThrowSequenceReachedEnd(); +#if NET7_0_OR_GREATER + return ref bufferReference; // dummy. +#else + return ref MemoryMarshal.GetReference(bufferReference); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int count) + { + if (count == 0) return; + + var rest = bufferLength - count; + if (rest < 0) + { + if (TryAdvanceSequence(count)) + { + return; + } + } + + bufferLength = rest; +#if NET7_0_OR_GREATER + bufferReference = ref Unsafe.Add(ref bufferReference, count); +#else + bufferReference = bufferReference.Slice(count); +#endif + advancedCount += count; + consumed += count; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + bool TryAdvanceSequence(int count) + { + var rest = bufferSource.Length - count; + if (rest < 0) + { + MemoryPackSerializationException.ThrowInvalidAdvance(); + } + + bufferSource = bufferSource.Slice(advancedCount + count); +#if NET7_0_OR_GREATER + bufferReference = ref MemoryMarshal.GetReference(bufferSource.FirstSpan); +#else + bufferReference = bufferSource.FirstSpan; +#endif + bufferLength = bufferSource.FirstSpan.Length; + advancedCount = 0; + consumed += count; + return true; + } + + public void GetRemainingSource(out ReadOnlySpan singleSource, out ReadOnlySequence remainingSource) + { + if (bufferSource.IsEmpty) + { + remainingSource = ReadOnlySequence.Empty; +#if NET7_0_OR_GREATER + singleSource = MemoryMarshal.CreateReadOnlySpan(ref bufferReference, bufferLength); +#else + singleSource = bufferReference; +#endif + return; + } + else + { + if (bufferSource.IsSingleSegment) + { + remainingSource = ReadOnlySequence.Empty; + singleSource = bufferSource.FirstSpan.Slice(advancedCount); + return; + } + + singleSource = default; + remainingSource = bufferSource.Slice(advancedCount); + if (remainingSource.IsSingleSegment) + { + singleSource = remainingSource.FirstSpan; + remainingSource = ReadOnlySequence.Empty; + return; + } + return; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + if (rentBuffer != null) + { + ArrayPool.Shared.Return(rentBuffer); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IMemoryPackFormatter GetFormatter(Type type) + { + return MemoryPackFormatterProvider.GetFormatter(type); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IMemoryPackFormatter GetFormatter() + { + return MemoryPackFormatterProvider.GetFormatter(); + } + + // read methods + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryReadObjectHeader(out byte memberCount) + { + memberCount = GetSpanReference(1); + Advance(1); + return memberCount != MemoryPackCode.NullObject; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryReadUnionHeader(out ushort tag) + { + var firstTag = GetSpanReference(1); + Advance(1); + if (firstTag < MemoryPackCode.WideTag) + { + tag = firstTag; + return true; + } + else if (firstTag == MemoryPackCode.WideTag) + { + ReadUnmanaged(out tag); + return true; + } + else + { + tag = 0; + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryReadCollectionHeader(out int length) + { + length = Unsafe.ReadUnaligned(ref GetSpanReference(4)); + Advance(4); + + // If collection-length is larger than buffer-length, it is invalid data. + if (Remaining < length) + { + MemoryPackSerializationException.ThrowInsufficientBufferUnless(length); + } + + return length != MemoryPackCode.NullCollection; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool PeekIsNull() + { + var code = GetSpanReference(1); + return code == MemoryPackCode.NullObject; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPeekObjectHeader(out byte memberCount) + { + memberCount = GetSpanReference(1); + return memberCount != MemoryPackCode.NullObject; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPeekUnionHeader(out ushort tag) + { + var firstTag = GetSpanReference(1); + if (firstTag < MemoryPackCode.WideTag) + { + tag = firstTag; + return true; + } + else if (firstTag == MemoryPackCode.WideTag) + { + ref var spanRef = ref GetSpanReference(sizeof(ushort) + 1); // skip firstTag + tag = Unsafe.ReadUnaligned(ref Unsafe.Add(ref spanRef, 1)); + return true; + } + else + { + tag = 0; + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryPeekCollectionHeader(out int length) + { + length = Unsafe.ReadUnaligned(ref GetSpanReference(4)); + + // If collection-length is larger than buffer-length, it is invalid data. + if (Remaining < length) + { + MemoryPackSerializationException.ThrowInsufficientBufferUnless(length); + } + + return length != MemoryPackCode.NullCollection; + } + + /// + /// no validate collection size, be careful to use. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool DangerousTryReadCollectionHeader(out int length) + { + length = Unsafe.ReadUnaligned(ref GetSpanReference(4)); + Advance(4); + + return length != MemoryPackCode.NullCollection; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string? ReadString() + { + if (!TryReadCollectionHeader(out var length)) + { + return null; + } + if (length == 0) + { + return ""; + } + + if (length > 0) + { + return ReadUtf16(length); + } + else + { + return ReadUtf8(length); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + string ReadUtf16(int length) + { + var byteCount = checked(length * 2); + ref var src = ref GetSpanReference(byteCount); + + var str = new string(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref src), length)); + + Advance(byteCount); + + return str; + } + + [MethodImpl(MethodImplOptions.NoInlining)] // non default, no inline + string ReadUtf8(int utf8Length) + { + // (int ~utf8-byte-count, int utf16-length, utf8-bytes) + // already read utf8 length, but it is complement. + + utf8Length = ~utf8Length; + + ref var spanRef = ref GetSpanReference(utf8Length + 4); // + read utf16 length + + string str; + var utf16Length = Unsafe.ReadUnaligned(ref spanRef); + + if (utf16Length <= 0) + { + var src = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref spanRef, 4), utf8Length); + str = Encoding.UTF8.GetString(src); + } + else + { + // check malformed utf16Length + var max = unchecked((Remaining + 1) * 3); + if (max < 0) max = int.MaxValue; + if (max < utf16Length) + { + MemoryPackSerializationException.ThrowInsufficientBufferUnless(utf8Length); + } + + +#if NET7_0_OR_GREATER + // regular path, know decoded UTF16 length will gets faster decode result + unsafe + { + fixed (byte* p = &Unsafe.Add(ref spanRef, 4)) + { + str = string.Create(utf16Length, ((IntPtr)p, utf8Length), static (dest, state) => + { + var src = MemoryMarshal.CreateSpan(ref Unsafe.AsRef((byte*)state.Item1), state.Item2); + var status = Utf8.ToUtf16(src, dest, out var bytesRead, out var charsWritten, replaceInvalidSequences: false); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowFailedEncoding(status); + } + }); + } + } +#else + var src = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref spanRef, 4), utf8Length); + str = Encoding.UTF8.GetString(src); +#endif + } + + Advance(utf8Length + 4); + + return str; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T1 ReadUnmanaged() + where T1 : unmanaged + { + var size = Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + var value1 = Unsafe.ReadUnaligned(ref spanRef); + Advance(size); + return value1; + } + +#if NET7_0_OR_GREATER + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadPackable(ref T? value) + where T : IMemoryPackable + { + T.Deserialize(ref this, ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T? ReadPackable() + where T : IMemoryPackable + { + T? value = default; + T.Deserialize(ref this, ref value); + return value; + } + +#else + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadPackable(ref T? value) + where T : IMemoryPackable + { + ReadValue(ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T? ReadPackable() + where T : IMemoryPackable + { + return ReadValue(); + } + +#endif + + // non packable, get formatter dynamically. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadValue(ref T? value) + { + GetFormatter().Deserialize(ref this, ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T? ReadValue() + { + T? value = default; + GetFormatter().Deserialize(ref this, ref value); + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadValue(Type type, ref object? value) + { + GetFormatter(type).Deserialize(ref this, ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public object? ReadValue(Type type) + { + object? value = default; + GetFormatter(type).Deserialize(ref this, ref value); + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadValueWithFormatter(TFormatter formatter, ref T? value) + where TFormatter : IMemoryPackFormatter + { + formatter.Deserialize(ref this, ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T? ReadValueWithFormatter(TFormatter formatter) + where TFormatter : IMemoryPackFormatter + { + T? value = default; + formatter.Deserialize(ref this, ref value); + return value; + } + + #region ReadArray/Span + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T?[]? ReadArray() + { + T?[]? value = default; + ReadArray(ref value); + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadArray(ref T?[]? value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousReadUnmanagedArray(ref value); + return; + } + + if (!TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + // T[] support overwrite + if (value == null || value.Length != length) + { + value = new T[length]; + } + + var formatter = GetFormatter(); + for (int i = 0; i < length; i++) + { + formatter.Deserialize(ref this, ref value[i]); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadSpan(ref Span value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousReadUnmanagedSpan(ref value); + return; + } + + if (!TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + if (value.Length != length) + { + value = new T[length]; + } + + var formatter = GetFormatter(); + for (int i = 0; i < length; i++) + { + formatter.Deserialize(ref this, ref value[i]); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T?[]? ReadPackableArray() + where T : IMemoryPackable + { + T?[]? value = default; + ReadPackableArray(ref value); + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadPackableArray(ref T?[]? value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + ReadArray(ref value); + return; +#else + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousReadUnmanagedArray(ref value); + return; + } + + if (!TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + // T[] support overwrite + if (value == null || value.Length != length) + { + value = new T[length]; + } + + for (int i = 0; i < length; i++) + { + T.Deserialize(ref this, ref value[i]); + } +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadPackableSpan(ref Span value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + ReadSpan(ref value); + return; +#else + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousReadUnmanagedSpan(ref value); + return; + } + + if (!TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + if (value.Length != length) + { + value = new T[length]; + } + + for (int i = 0; i < length; i++) + { + T.Deserialize(ref this, ref value[i]); + } +#endif + } + + #endregion + + #region UnmanagedArray/Span + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T[]? ReadUnmanagedArray() + where T : unmanaged + { + return DangerousReadUnmanagedArray(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanagedArray(ref T[]? value) + where T : unmanaged + { + DangerousReadUnmanagedArray(ref value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadUnmanagedSpan(ref Span value) + where T : unmanaged + { + DangerousReadUnmanagedSpan(ref value); + } + + // T: should be unamanged type + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe T[]? DangerousReadUnmanagedArray() + { + if (!TryReadCollectionHeader(out var length)) + { + return null; + } + + if (length == 0) return Array.Empty(); + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + var dest = AllocateUninitializedArray(length); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref GetArrayDataReference(dest)), ref src, (uint)byteCount); + Advance(byteCount); + + return dest; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void DangerousReadUnmanagedArray(ref T[]? value) + { + if (!TryReadCollectionHeader(out var length)) + { + value = null; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + + if (value == null || value.Length != length) + { + value = AllocateUninitializedArray(length); + } + + ref var dest = ref Unsafe.As(ref GetArrayDataReference(value)); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + Advance(byteCount); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void DangerousReadUnmanagedSpan(ref Span value) + { + if (!TryReadCollectionHeader(out var length)) + { + value = default; + return; + } + + if (length == 0) + { + value = Array.Empty(); + return; + } + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + + if (value == null || value.Length != length) + { + value = AllocateUninitializedArray(length); + } + + ref var dest = ref Unsafe.As(ref MemoryMarshal.GetReference(value)); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + Advance(byteCount); + } + + #endregion + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadSpanWithoutReadLengthHeader(int length, ref Span value) + { + if (length == 0) + { + value = Array.Empty(); + return; + } + + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + if (value.Length != length) + { + value = AllocateUninitializedArray(length); + } + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + ref var dest = ref Unsafe.As(ref MemoryMarshal.GetReference(value)!); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + Advance(byteCount); + } + else + { + if (value.Length != length) + { + value = new T[length]; + } + + var formatter = GetFormatter(); + for (int i = 0; i < length; i++) + { + formatter.Deserialize(ref this, ref value[i]); + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadPackableSpanWithoutReadLengthHeader(int length, ref Span value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + ReadSpanWithoutReadLengthHeader(length, ref value); + return; +#else + if (length == 0) + { + value = Array.Empty(); + return; + } + + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + if (value.Length != length) + { + value = AllocateUninitializedArray(length); + } + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + ref var dest = ref Unsafe.As(ref MemoryMarshal.GetReference(value)!); + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount); + + Advance(byteCount); + } + else + { + if (value.Length != length) + { + value = new T[length]; + } + + for (int i = 0; i < length; i++) + { + T.Deserialize(ref this, ref value[i]); + } + } +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void DangerousReadUnmanagedSpanView(out bool isNull, out ReadOnlySpan view) + { + if (!TryReadCollectionHeader(out var length)) + { + isNull = true; + view = default; + return; + } + + isNull = false; + + if (length == 0) + { + view = Array.Empty(); + return; + } + + var byteCount = length * Unsafe.SizeOf(); + ref var src = ref GetSpanReference(byteCount); + + var span = MemoryMarshal.CreateReadOnlySpan(ref src, byteCount); + + Advance(byteCount); + view = span; // safe until call next GetSpanReference + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs.meta new file mode 100644 index 0000000..6e5b625 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27df744bfc004694c9598738f9d32cce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs new file mode 100644 index 0000000..51826e2 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Collections.Concurrent; + +namespace MemoryPack { + +public static class MemoryPackReaderOptionalStatePool +{ + static readonly ConcurrentQueue queue = new ConcurrentQueue(); + + public static MemoryPackReaderOptionalState Rent(MemoryPackSerializerOptions? options) + { + if (!queue.TryDequeue(out var state)) + { + state = new MemoryPackReaderOptionalState(); + } + + state.Init(options); + return state; + } + + internal static void Return(MemoryPackReaderOptionalState state) + { + state.Reset(); + queue.Enqueue(state); + } +} + +public sealed class MemoryPackReaderOptionalState : IDisposable +{ + readonly Dictionary refToObject; + public MemoryPackSerializerOptions Options { get; private set; } + + internal MemoryPackReaderOptionalState() + { + refToObject = new Dictionary(); + Options = null!; + } + + internal void Init(MemoryPackSerializerOptions? options) + { + Options = options ?? MemoryPackSerializerOptions.Default; + } + + public object GetObjectReference(uint id) + { + if (refToObject.TryGetValue(id, out var value)) + { + return value; + } + MemoryPackSerializationException.ThrowMessage("Object is not found in this reference id:" + id); + return null!; + } + + public void AddObjectReference(uint id, object value) + { + if (!refToObject.TryAdd(id, value)) + { + MemoryPackSerializationException.ThrowMessage("Object is already added, id:" + id); + } + } + + public void Reset() + { + refToObject.Clear(); + Options = null!; + } + + void IDisposable.Dispose() + { + MemoryPackReaderOptionalStatePool.Return(this); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs.meta new file mode 100644 index 0000000..e215e4e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderOptionalState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a381067d43337845bd228a2207155da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs new file mode 100644 index 0000000..a6fa7c2 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs @@ -0,0 +1,448 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack { + +// VarInt, first sbyte is value or typeCode + +// 0~127 = unsigned byte value +// -1~-120 = signed byte value +// -121 = byte +// -122 = sbyte +// -123 = ushort +// -124 = short +// -125 = uint +// -126 = int +// -127 = ulong +// -128 = long + +internal static class VarIntCodes +{ + public const byte MaxSingleValue = 127; + public const sbyte MinSingleValue = -120; + + public const sbyte Byte = -121; + public const sbyte SByte = -122; + public const sbyte UInt16 = -123; + public const sbyte Int16 = -124; + public const sbyte UInt32 = -125; + public const sbyte Int32 = -126; + public const sbyte UInt64 = -127; + public const sbyte Int64 = -128; +} + +public ref partial struct MemoryPackWriter +{ + public void WriteVarInt(byte x) + { + if (x <= VarIntCodes.MaxSingleValue) + { + WriteUnmanaged((sbyte)x); + } + else + { + WriteUnmanaged(VarIntCodes.Byte, x); + } + } + + public void WriteVarInt(sbyte x) + { + if (VarIntCodes.MinSingleValue <= x) + { + WriteUnmanaged(x); + } + else + { + WriteUnmanaged(VarIntCodes.SByte, x); + } + } + + public void WriteVarInt(ushort x) + { + if (x <= VarIntCodes.MaxSingleValue) + { + WriteUnmanaged((sbyte)x); + } + else + { + WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); + } + } + + public void WriteVarInt(short x) + { + if (0 <= x) + { + if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue + { + WriteUnmanaged((sbyte)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + } + else + { + if (VarIntCodes.MinSingleValue <= x) + { + WriteUnmanaged((sbyte)x); + } + else if (sbyte.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.SByte, (SByte)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + } + } + + public void WriteVarInt(uint x) + { + if (x <= VarIntCodes.MaxSingleValue) + { + WriteUnmanaged((sbyte)x); + } + else if (x <= ushort.MaxValue) + { + WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); + } + else + { + WriteUnmanaged(VarIntCodes.UInt32, (UInt32)x); + } + } + + public void WriteVarInt(int x) + { + if (0 <= x) + { + if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue + { + WriteUnmanaged((sbyte)x); + } + else if (x <= short.MaxValue) + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int32, (Int32)x); + } + } + else + { + if (VarIntCodes.MinSingleValue <= x) + { + WriteUnmanaged((sbyte)x); + } + else if (sbyte.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.SByte, (SByte)x); + } + else if (short.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int32, (Int32)x); + } + } + } + + public void WriteVarInt(ulong x) + { + if (x <= VarIntCodes.MaxSingleValue) + { + WriteUnmanaged((sbyte)x); + } + else if (x <= ushort.MaxValue) + { + WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); + } + else if (x <= uint.MaxValue) + { + WriteUnmanaged(VarIntCodes.UInt32, (UInt32)x); + } + else + { + WriteUnmanaged(VarIntCodes.UInt64, (UInt64)x); + } + } + + public void WriteVarInt(long x) + { + if (0 <= x) + { + if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue + { + WriteUnmanaged((sbyte)x); + } + else if (x <= short.MaxValue) + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + else if (x <= int.MaxValue) + { + WriteUnmanaged(VarIntCodes.Int32, (Int32)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int64, (Int64)x); + } + } + else + { + if (VarIntCodes.MinSingleValue <= x) + { + WriteUnmanaged((sbyte)x); + } + else if (sbyte.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.SByte, (SByte)x); + } + else if (short.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.Int16, (Int16)x); + } + else if (int.MinValue <= x) + { + WriteUnmanaged(VarIntCodes.Int32, (Int32)x); + } + else + { + WriteUnmanaged(VarIntCodes.Int64, (Int64)x); + } + } + } +} + +public ref partial struct MemoryPackReader +{ + public byte ReadVarIntByte() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.UInt16: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.Int16: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.UInt32: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.Int32: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.UInt64: + return checked((byte)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((byte)ReadUnmanaged()); + default: + return checked((byte)typeCode); + } + } + + public sbyte ReadVarIntSByte() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.SByte: + return ReadUnmanaged(); + case VarIntCodes.UInt16: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.Int16: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.UInt32: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.Int32: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.UInt64: + return checked((sbyte)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((sbyte)ReadUnmanaged()); + default: + return typeCode; + } + } + + public ushort ReadVarIntUInt16() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return checked((ushort)ReadUnmanaged()); + case VarIntCodes.UInt16: + return ReadUnmanaged(); + case VarIntCodes.Int16: + return checked((ushort)ReadUnmanaged()); + case VarIntCodes.UInt32: + return checked((ushort)ReadUnmanaged()); + case VarIntCodes.Int32: + return checked((ushort)ReadUnmanaged()); + case VarIntCodes.UInt64: + return checked((ushort)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((ushort)ReadUnmanaged()); + default: + return checked((ushort)typeCode); + } + } + + public short ReadVarIntInt16() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return ReadUnmanaged(); + case VarIntCodes.UInt16: + return checked((short)ReadUnmanaged()); + case VarIntCodes.Int16: + return ReadUnmanaged(); + case VarIntCodes.UInt32: + return checked((short)ReadUnmanaged()); + case VarIntCodes.Int32: + return checked((short)ReadUnmanaged()); + case VarIntCodes.UInt64: + return checked((short)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((short)ReadUnmanaged()); + default: + return typeCode; + } + } + + public uint ReadVarIntUInt32() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return checked((uint)ReadUnmanaged()); + case VarIntCodes.UInt16: + return ReadUnmanaged(); + case VarIntCodes.Int16: + return checked((uint)ReadUnmanaged()); + case VarIntCodes.UInt32: + return ReadUnmanaged(); + case VarIntCodes.Int32: + return checked((uint)ReadUnmanaged()); + case VarIntCodes.UInt64: + return checked((uint)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((uint)ReadUnmanaged()); + default: + return checked((uint)typeCode); + } + } + + public int ReadVarIntInt32() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return ReadUnmanaged(); + case VarIntCodes.UInt16: + return ReadUnmanaged(); + case VarIntCodes.Int16: + return ReadUnmanaged(); + case VarIntCodes.UInt32: + return checked((int)ReadUnmanaged()); + case VarIntCodes.Int32: + return ReadUnmanaged(); + case VarIntCodes.UInt64: + return checked((int)ReadUnmanaged()); + case VarIntCodes.Int64: + return checked((int)ReadUnmanaged()); + default: + return typeCode; + } + } + + public ulong ReadVarIntUInt64() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return checked((ulong)ReadUnmanaged()); + case VarIntCodes.UInt16: + return ReadUnmanaged(); + case VarIntCodes.Int16: + return checked((ulong)ReadUnmanaged()); + case VarIntCodes.UInt32: + return ReadUnmanaged(); + case VarIntCodes.Int32: + return checked((ulong)ReadUnmanaged()); + case VarIntCodes.UInt64: + return ReadUnmanaged(); + case VarIntCodes.Int64: + return checked((ulong)ReadUnmanaged()); + default: + return checked((ulong)typeCode); + } + } + + public long ReadVarIntInt64() + { + ReadUnmanaged(out sbyte typeCode); + + switch (typeCode) + { + case VarIntCodes.Byte: + return ReadUnmanaged(); + case VarIntCodes.SByte: + return ReadUnmanaged(); + case VarIntCodes.UInt16: + return ReadUnmanaged(); + case VarIntCodes.Int16: + return ReadUnmanaged(); + case VarIntCodes.UInt32: + return ReadUnmanaged(); + case VarIntCodes.Int32: + return ReadUnmanaged(); + case VarIntCodes.UInt64: + return checked((long)ReadUnmanaged()); + case VarIntCodes.Int64: + return ReadUnmanaged(); + default: + return typeCode; + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs.meta new file mode 100644 index 0000000..26bce1a --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackReaderWriter.VarInt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a312341bf29b42429b858550384dd1a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs new file mode 100644 index 0000000..9acd411 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Diagnostics.CodeAnalysis; + +namespace MemoryPack { + +public class MemoryPackSerializationException : Exception +{ + public MemoryPackSerializationException(string message) + : base(message) + { + } + + public MemoryPackSerializationException(string message, Exception innerException) + : base(message, innerException) + { + } + + [DoesNotReturn] + public static void ThrowMessage(string message) + { + throw new MemoryPackSerializationException(message); + } + + [DoesNotReturn] + public static void ThrowInvalidPropertyCount(byte expected, byte actual) + { + throw new MemoryPackSerializationException($"Current object's property count is {expected} but binary's header maked as {actual}, can't deserialize about versioning."); + } + + [DoesNotReturn] + public static void ThrowInvalidPropertyCount(Type type, byte expected, byte actual) + { + throw new MemoryPackSerializationException($"{type.FullName} property count is {expected} but binary's header maked as {actual}, can't deserialize about versioning."); + } + + [DoesNotReturn] + public static void ThrowInvalidCollection() + { + throw new MemoryPackSerializationException($"Current read to collection, the buffer header is not collection."); + } + + [DoesNotReturn] + public static void ThrowInvalidRange(int expected, int actual) + { + throw new MemoryPackSerializationException($"Requires size is {expected} but buffer length is {actual}."); + } + + [DoesNotReturn] + public static void ThrowInvalidAdvance() + { + throw new MemoryPackSerializationException($"Cannot advance past the end of the buffer."); + } + + [DoesNotReturn] + public static void ThrowSequenceReachedEnd() + { + throw new MemoryPackSerializationException($"Sequence reached end, reader can not provide more buffer."); + } + + [DoesNotReturn] + public static void ThrowWriteInvalidMemberCount(byte memberCount) + { + throw new MemoryPackSerializationException($"MemberCount/Tag allows < 250 but try to write {memberCount}."); + } + + [DoesNotReturn] + public static void ThrowInsufficientBufferUnless(int length) + { + throw new MemoryPackSerializationException($"Length header size is larger than buffer size, length: {length}."); + } + + [DoesNotReturn] + public static void ThrowNotRegisteredInProvider(Type type) + { + throw new MemoryPackSerializationException($"{type.FullName} is not registered in this provider."); + } + + [DoesNotReturn] + public static void ThrowRegisterInProviderFailed(Type type, Exception innerException) + { + throw new MemoryPackSerializationException($"{type.FullName} is failed in provider at creating formatter.", innerException); + } + + [DoesNotReturn] + public static void ThrowNotFoundInUnionType(Type actualType, Type baseType) + { + throw new MemoryPackSerializationException($"Type {actualType.FullName} is not annotated in {baseType.FullName} MemoryPackUnion."); + } + + [DoesNotReturn] + public static void ThrowInvalidTag(ushort tag, Type baseType) + { + throw new MemoryPackSerializationException($"Data read tag: {tag} but not found in {baseType.FullName} MemoryPackUnion annotations."); + } + + [DoesNotReturn] + public static void ThrowReachedDepthLimit(Type type) + { + throw new MemoryPackSerializationException($"Serializing Type '{type}' reached depth limit, maybe detect circular reference."); + } + + [DoesNotReturn] + public static void ThrowInvalidConcurrrentCollectionOperation() + { + throw new MemoryPackSerializationException($"ConcurrentCollection is Added/Removed in serializing, however serialize concurrent collection is not thread-safe."); + } + + [DoesNotReturn] + public static void ThrowDeserializeObjectIsNull(string target) + { + throw new MemoryPackSerializationException($"Deserialized {target} is null."); + } + + [DoesNotReturn] + public static void ThrowFailedEncoding(OperationStatus status) + { + throw new MemoryPackSerializationException($"Failed in Utf8 encoding/decoding process, status: {status}."); + } + + [DoesNotReturn] + public static void ThrowCompressionFailed(OperationStatus status) + { + throw new MemoryPackSerializationException($"Failed in Brotli compression/decompression process, status: {status}."); + } + + [DoesNotReturn] + public static void ThrowCompressionFailed() + { + throw new MemoryPackSerializationException($"Failed in Brotli compression/decompression process."); + } + + [DoesNotReturn] + public static void ThrowAlreadyDecompressed() + { + throw new MemoryPackSerializationException($"BrotliDecompressor can not invoke Decompress twice, already invoked."); + } + + [DoesNotReturn] + public static void ThrowDecompressionSizeLimitExceeded(int limit, int size) + { + throw new MemoryPackSerializationException($"In decompress process, limit is {limit} but target size is {size}."); + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs.meta new file mode 100644 index 0000000..738f555 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8591f1e7c0c859a42910d40b48ed19c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs new file mode 100644 index 0000000..24b4b47 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack { + +public static partial class MemoryPackSerializer +{ + [ThreadStatic] + static MemoryPackReaderOptionalState? threadStaticReaderOptionalState; + + public static T? Deserialize(ReadOnlySpan buffer, MemoryPackSerializerOptions? options = default) + { + T? value = default; + Deserialize(buffer, ref value, options); + return value; + } + + public static int Deserialize(ReadOnlySpan buffer, ref T? value, MemoryPackSerializerOptions? options = default) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + if (buffer.Length < Unsafe.SizeOf()) + { + MemoryPackSerializationException.ThrowInvalidRange(Unsafe.SizeOf(), buffer.Length); + } + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(buffer)); + return Unsafe.SizeOf(); + } + + var state = threadStaticReaderOptionalState; + if (state == null) + { + state = threadStaticReaderOptionalState = new MemoryPackReaderOptionalState(); + } + state.Init(options); + + var reader = new MemoryPackReader(buffer, state); + try + { + reader.ReadValue(ref value); + return reader.Consumed; + } + finally + { + reader.Dispose(); + state.Reset(); + } + } + + public static T? Deserialize(in ReadOnlySequence buffer, MemoryPackSerializerOptions? options = default) + { + T? value = default; + Deserialize(buffer, ref value, options); + return value; + } + + public static int Deserialize(in ReadOnlySequence buffer, ref T? value, MemoryPackSerializerOptions? options = default) + { + var state = threadStaticReaderOptionalState; + if (state == null) + { + state = threadStaticReaderOptionalState = new MemoryPackReaderOptionalState(); + } + state.Init(options); + + var reader = new MemoryPackReader(buffer, state); + try + { + reader.ReadValue(ref value); + return reader.Consumed; + } + finally + { + reader.Dispose(); + state.Reset(); + } + } + + public static async ValueTask DeserializeAsync(Stream stream, MemoryPackSerializerOptions? options = default, CancellationToken cancellationToken = default) + { + if (stream is MemoryStream ms && ms.TryGetBuffer(out ArraySegment streamBuffer)) + { + cancellationToken.ThrowIfCancellationRequested(); + T? value = default; + var bytesRead = Deserialize(streamBuffer.AsSpan(checked((int)ms.Position)), ref value, options); + + // Emulate that we had actually "read" from the stream. + ms.Seek(bytesRead, SeekOrigin.Current); + + return value; + } + + var builder = ReusableReadOnlySequenceBuilderPool.Rent(); + try + { + var buffer = ArrayPool.Shared.Rent(65536); // initial 64K + var offset = 0; + do + { + if (offset == buffer.Length) + { + builder.Add(buffer, returnToPool: true); + buffer = ArrayPool.Shared.Rent(MathEx.NewArrayCapacity(buffer.Length)); + offset = 0; + } + + int read = 0; + try + { + read = await stream.ReadAsync(buffer.AsMemory(offset, buffer.Length - offset), cancellationToken).ConfigureAwait(false); + } + catch + { + // buffer is not added in builder, so return here. + ArrayPool.Shared.Return(buffer); + throw; + } + + offset += read; + + if (read == 0) + { + builder.Add(buffer.AsMemory(0, offset), returnToPool: true); + break; + + } + } while (true); + + // If single buffer, we can avoid ReadOnlySequence build cost. + if (builder.TryGetSingleMemory(out var memory)) + { + return Deserialize(memory.Span, options); + } + else + { + var seq = builder.Build(); + var result = Deserialize(seq, options); + return result; + } + } + finally + { + builder.Reset(); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs.meta new file mode 100644 index 0000000..bbeeb3d --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Deserialize.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e69bbb05f943a6b4281b6f289017c864 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs new file mode 100644 index 0000000..94a396e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack { + +public static partial class MemoryPackSerializer +{ + // Serialize + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte[] Serialize(Type type, object? value, MemoryPackSerializerOptions? options = default) + { + var state = threadStaticState; + if (state == null) + { + state = threadStaticState = new SerializerWriterThreadStaticState(); + } + state.Init(options); + + try + { + var writer = new MemoryPackWriter(ref Unsafe.As>(ref state.BufferWriter), state.BufferWriter.DangerousGetFirstBuffer(), state.OptionalState); + Serialize(type, ref writer, value); + return state.BufferWriter.ToArrayAndReset(); + } + finally + { + state.Reset(); + } + } + + public static unsafe void Serialize(Type type, in IBufferWriter bufferWriter, object? value, MemoryPackSerializerOptions? options = default) +#if NET7_0_OR_GREATER + +#else + +#endif + { + var state = threadStaticWriterOptionalState; + if (state == null) + { + state = threadStaticWriterOptionalState = new MemoryPackWriterOptionalState(); + } + state.Init(options); + + try + { + var writer = new MemoryPackWriter(ref Unsafe.AsRef(bufferWriter), state); + Serialize(type, ref writer, value); + } + finally + { + state.Reset(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(Type type, ref MemoryPackWriter writer, object? value) +#if NET7_0_OR_GREATER + +#else + +#endif + { + writer.GetFormatter(type).Serialize(ref writer, ref value); + writer.Flush(); + } + + public static async ValueTask SerializeAsync(Type type, Stream stream, object? value, MemoryPackSerializerOptions? options = default, CancellationToken cancellationToken = default) + { + var tempWriter = ReusableLinkedArrayBufferWriterPool.Rent(); + try + { + SerializeToTempWriter(tempWriter, type, value, options); + await tempWriter.WriteToAndResetAsync(stream, cancellationToken).ConfigureAwait(false); + } + finally + { + ReusableLinkedArrayBufferWriterPool.Return(tempWriter); + } + } + + static void SerializeToTempWriter(ReusableLinkedArrayBufferWriter bufferWriter, Type type, object? value, MemoryPackSerializerOptions? options) + { + var state = threadStaticWriterOptionalState; + if (state == null) + { + state = threadStaticWriterOptionalState = new MemoryPackWriterOptionalState(); + } + state.Init(options); + + var writer = new MemoryPackWriter(ref Unsafe.As>(ref bufferWriter), state); + + try + { + Serialize(type, ref writer, value); + } + finally + { + state.Reset(); + } + } + + // Deserialize + + public static object? Deserialize(Type type, ReadOnlySpan buffer, MemoryPackSerializerOptions? options = default) + { + object? value = default; + Deserialize(type, buffer, ref value, options); + return value; + } + + public static int Deserialize(Type type, ReadOnlySpan buffer, ref object? value, MemoryPackSerializerOptions? options = default) + { + var state = threadStaticReaderOptionalState; + if (state == null) + { + state = threadStaticReaderOptionalState = new MemoryPackReaderOptionalState(); + } + state.Init(options); + + var reader = new MemoryPackReader(buffer, state); + try + { + reader.GetFormatter(type).Deserialize(ref reader, ref value); + return reader.Consumed; + } + finally + { + reader.Dispose(); + state.Reset(); + } + } + + public static object? Deserialize(Type type, in ReadOnlySequence buffer, MemoryPackSerializerOptions? options = default) + { + object? value = default; + Deserialize(type, buffer, ref value, options); + return value; + } + + public static int Deserialize(Type type, in ReadOnlySequence buffer, ref object? value, MemoryPackSerializerOptions? options = default) + { + var state = threadStaticReaderOptionalState; + if (state == null) + { + state = threadStaticReaderOptionalState = new MemoryPackReaderOptionalState(); + } + state.Init(options); + + var reader = new MemoryPackReader(buffer, state); + try + { + reader.GetFormatter(type).Deserialize(ref reader, ref value); + return reader.Consumed; + } + finally + { + reader.Dispose(); + state.Reset(); + } + } + + public static async ValueTask DeserializeAsync(Type type, Stream stream, MemoryPackSerializerOptions? options = default, CancellationToken cancellationToken = default) + { + if (stream is MemoryStream ms && ms.TryGetBuffer(out ArraySegment streamBuffer)) + { + cancellationToken.ThrowIfCancellationRequested(); + object? value = default; + var bytesRead = Deserialize(type, streamBuffer.AsSpan(checked((int)ms.Position)), ref value, options); + + // Emulate that we had actually "read" from the stream. + ms.Seek(bytesRead, SeekOrigin.Current); + + return value; + } + + var builder = ReusableReadOnlySequenceBuilderPool.Rent(); + try + { + var buffer = ArrayPool.Shared.Rent(65536); // initial 64K + var offset = 0; + do + { + if (offset == buffer.Length) + { + builder.Add(buffer, returnToPool: true); + buffer = ArrayPool.Shared.Rent(MathEx.NewArrayCapacity(buffer.Length)); + offset = 0; + } + + int read = 0; + try + { + read = await stream.ReadAsync(buffer.AsMemory(offset, buffer.Length - offset), cancellationToken).ConfigureAwait(false); + } + catch + { + // buffer is not added in builder, so return here. + ArrayPool.Shared.Return(buffer); + throw; + } + + offset += read; + + if (read == 0) + { + builder.Add(buffer.AsMemory(0, offset), returnToPool: true); + break; + + } + } while (true); + + // If single buffer, we can avoid ReadOnlySequence build cost. + if (builder.TryGetSingleMemory(out var memory)) + { + return Deserialize(type, memory.Span, options); + } + else + { + var seq = builder.Build(); + var result = Deserialize(type, seq, options); + return result; + } + } + finally + { + builder.Reset(); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs.meta new file mode 100644 index 0000000..89581e2 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.NonGenerics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6b6c145f5b998ff40b7cf2ee834dba62 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs new file mode 100644 index 0000000..0f5b483 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using MemoryPack.Internal; +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack { + +#if NET7_0_OR_GREATER +using static MemoryMarshal; +using static GC; +#else +using static MemoryPack.Internal.MemoryMarshalEx; +#endif + +public static partial class MemoryPackSerializer +{ + [ThreadStatic] + static SerializerWriterThreadStaticState? threadStaticState; + [ThreadStatic] + static MemoryPackWriterOptionalState? threadStaticWriterOptionalState; + + public static byte[] Serialize(in T? value, MemoryPackSerializerOptions? options = default) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var array = AllocateUninitializedArray(Unsafe.SizeOf()); + Unsafe.WriteUnaligned(ref GetArrayDataReference(array), value); + return array; + } +#if NET7_0_OR_GREATER + var typeKind = TypeHelpers.TryGetUnmanagedSZArrayElementSizeOrMemoryPackableFixedSize(out var elementSize); + if (typeKind == TypeHelpers.TypeKind.None) + { + // do nothing + } + else if (typeKind == TypeHelpers.TypeKind.UnmanagedSZArray) + { + if (value == null) + { + return MemoryPackCode.NullCollectionData.ToArray(); + } + + var srcArray = ((Array)(object)value!); + var length = srcArray.Length; + if (length == 0) + { + return new byte[4] { 0, 0, 0, 0 }; + } + + var dataSize = elementSize * length; + var destArray = AllocateUninitializedArray(dataSize + 4); + ref var head = ref MemoryMarshal.GetArrayDataReference(destArray); + + Unsafe.WriteUnaligned(ref head, length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref head, 4), ref MemoryMarshal.GetArrayDataReference(srcArray), (uint)dataSize); + + return destArray; + } + else if (typeKind == TypeHelpers.TypeKind.FixedSizeMemoryPackable) + { + var buffer = new byte[(value == null) ? 1 : elementSize]; + var bufferWriter = new FixedArrayBufferWriter(buffer); + var writer = new MemoryPackWriter(ref bufferWriter, buffer, MemoryPackWriterOptionalState.NullState); + Serialize(ref writer, value); + return bufferWriter.GetFilledBuffer(); + } +#endif + + var state = threadStaticState; + if (state == null) + { + state = threadStaticState = new SerializerWriterThreadStaticState(); + } + state.Init(options); + + try + { + var writer = new MemoryPackWriter(ref Unsafe.As>(ref state.BufferWriter), state.BufferWriter.DangerousGetFirstBuffer(), state.OptionalState); + Serialize(ref writer, value); + return state.BufferWriter.ToArrayAndReset(); + } + finally + { + state.Reset(); + } + } + + public static unsafe void Serialize(in IBufferWriter bufferWriter, in T? value, MemoryPackSerializerOptions? options = default) +#if NET7_0_OR_GREATER + +#else + +#endif + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var buffer = bufferWriter.GetSpan(Unsafe.SizeOf()); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(buffer), value); + bufferWriter.Advance(Unsafe.SizeOf()); + return; + } +#if NET7_0_OR_GREATER + var typeKind = TypeHelpers.TryGetUnmanagedSZArrayElementSizeOrMemoryPackableFixedSize(out var elementSize); + if (typeKind == TypeHelpers.TypeKind.UnmanagedSZArray) + { + if (value == null) + { + var span = bufferWriter.GetSpan(4); + MemoryPackCode.NullCollectionData.CopyTo(span); + bufferWriter.Advance(4); + return; + } + + var srcArray = ((Array)(object)value!); + var length = srcArray.Length; + if (length == 0) + { + var span = bufferWriter.GetSpan(4); + MemoryPackCode.ZeroCollectionData.CopyTo(span); + bufferWriter.Advance(4); + return; + } + var dataSize = elementSize * length; + var destSpan = bufferWriter.GetSpan(dataSize + 4); + ref var head = ref MemoryMarshal.GetReference(destSpan); + + Unsafe.WriteUnaligned(ref head, length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref head, 4), ref MemoryMarshal.GetArrayDataReference(srcArray), (uint)dataSize); + + bufferWriter.Advance(dataSize + 4); + return; + } +#endif + + var state = threadStaticWriterOptionalState; + if (state == null) + { + state = threadStaticWriterOptionalState = new MemoryPackWriterOptionalState(); + } + state.Init(options); + + try + { + var writer = new MemoryPackWriter(ref Unsafe.AsRef(bufferWriter), state); + Serialize(ref writer, value); + } + finally + { + state.Reset(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(ref MemoryPackWriter writer, in T? value) +#if NET7_0_OR_GREATER + +#else + +#endif + { + writer.WriteValue(value); + writer.Flush(); + } + + public static async ValueTask SerializeAsync(Stream stream, T? value, MemoryPackSerializerOptions? options = default, CancellationToken cancellationToken = default) + { + var tempWriter = ReusableLinkedArrayBufferWriterPool.Rent(); + try + { + Serialize(tempWriter, value, options); + await tempWriter.WriteToAndResetAsync(stream, cancellationToken).ConfigureAwait(false); + await stream.FlushAsync(cancellationToken).ConfigureAwait(false); + } + finally + { + ReusableLinkedArrayBufferWriterPool.Return(tempWriter); + } + } + + sealed class SerializerWriterThreadStaticState + { + public ReusableLinkedArrayBufferWriter BufferWriter; + public MemoryPackWriterOptionalState OptionalState; + + public SerializerWriterThreadStaticState() + { + BufferWriter = new ReusableLinkedArrayBufferWriter(useFirstBuffer: true, pinned: true); + OptionalState = new MemoryPackWriterOptionalState(); + } + + public void Init(MemoryPackSerializerOptions? options) + { + OptionalState.Init(options); + } + + public void Reset() + { + BufferWriter.Reset(); + OptionalState.Reset(); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs.meta new file mode 100644 index 0000000..e79a9f7 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializer.Serialize.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a26d6b30a51949459998c7c3ce820c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs new file mode 100644 index 0000000..54514f1 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +namespace MemoryPack +{ + public record MemoryPackSerializerOptions + { + // Default is Utf8 + public static readonly MemoryPackSerializerOptions Default = new MemoryPackSerializerOptions { StringEncoding = StringEncoding.Utf8 }; + + public static readonly MemoryPackSerializerOptions Utf8 = Default with { StringEncoding = StringEncoding.Utf8 }; + public static readonly MemoryPackSerializerOptions Utf16 = Default with { StringEncoding = StringEncoding.Utf16 }; + + public StringEncoding StringEncoding { get; init; } + public IServiceProvider? ServiceProvider { get; init; } + } + + public enum StringEncoding : byte + { + Utf16, + Utf8, + } +} + +#if !NET5_0_OR_GREATER + +namespace System.Runtime.CompilerServices +{ + internal sealed class IsExternalInit + { + } +} + +#endif diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs.meta new file mode 100644 index 0000000..0b7b43c --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackSerializerOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d62e6c3f830e86d4d81a5c67669f2e0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs new file mode 100644 index 0000000..af74520 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs @@ -0,0 +1,1250 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace MemoryPack { + +public ref partial struct MemoryPackWriter +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1) + where T1 : unmanaged + { + var size = Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1) + where T1 : unmanaged + { + var size = Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2) + where T1 : unmanaged + where T2 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2) + where T1 : unmanaged + where T2 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value14); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value14); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14, in T15 value15) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + where T15 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value14); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value15); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14, in T15 value15) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where T8 : unmanaged + where T9 : unmanaged + where T10 : unmanaged + where T11 : unmanaged + where T12 : unmanaged + where T13 : unmanaged + where T14 : unmanaged + where T15 : unmanaged + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value14); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value15); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1) + { + var size = Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1) + { + var size = Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value14); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value14); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanaged(in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14, in T15 value15) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf(); + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf()), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf()), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value14); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf()), value15); + Advance(size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedWithObjectHeader(byte propertyCount, in T1 value1, in T2 value2, in T3 value3, in T4 value4, in T5 value5, in T6 value6, in T7 value7, in T8 value8, in T9 value9, in T10 value10, in T11 value11, in T12 value12, in T13 value13, in T14 value14, in T15 value15) + { + var size = Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1; + ref var spanRef = ref GetSpanReference(size); + Unsafe.WriteUnaligned(ref spanRef, propertyCount); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), value1); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + 1), value2); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value3); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value4); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value5); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value6); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value7); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value8); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value9); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value10); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value11); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value12); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value13); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value14); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + Unsafe.SizeOf() + 1), value15); + Advance(size); + } + +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs.meta new file mode 100644 index 0000000..bceb91e --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.Unmanaged.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6798d0fa4e0103a49a13a1ea087594d6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs new file mode 100644 index 0000000..ae7f1c0 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs @@ -0,0 +1,715 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +#if NET7_0_OR_GREATER +using System.Text.Unicode; +#endif + +namespace MemoryPack { + +#if NET7_0_OR_GREATER +using static MemoryMarshal; +#else +using static MemoryPack.Internal.MemoryMarshalEx; +#endif + +[StructLayout(LayoutKind.Auto)] +public ref partial struct MemoryPackWriter +#if NET7_0_OR_GREATER + +#else + +#endif +{ + const int DepthLimit = 1000; + +#if NET7_0_OR_GREATER + ref IBufferWriter bufferWriter; + ref byte bufferReference; +#else + IBufferWriter bufferWriter; + Span bufferReference; +#endif + int bufferLength; + int advancedCount; + int depth; // check recursive serialize + int writtenCount; + readonly bool serializeStringAsUtf8; + readonly MemoryPackWriterOptionalState optionalState; + + public int WrittenCount => writtenCount; + public int BufferLength => bufferLength; + public MemoryPackWriterOptionalState OptionalState => optionalState; + public MemoryPackSerializerOptions Options => optionalState.Options; + + public MemoryPackWriter(ref IBufferWriter writer, MemoryPackWriterOptionalState optionalState) + { +#if NET7_0_OR_GREATER + this.bufferWriter = ref writer; + this.bufferReference = ref Unsafe.NullRef(); +#else + this.bufferWriter = writer; + this.bufferReference = default; +#endif + this.bufferLength = 0; + this.advancedCount = 0; + this.writtenCount = 0; + this.depth = 0; + this.serializeStringAsUtf8 = optionalState.Options.StringEncoding == StringEncoding.Utf8; + this.optionalState = optionalState; + } + + // optimized ctor, avoid first GetSpan call if we can. + public MemoryPackWriter(ref IBufferWriter writer, byte[] firstBufferOfWriter, MemoryPackWriterOptionalState optionalState) + { +#if NET7_0_OR_GREATER + this.bufferWriter = ref writer; + this.bufferReference = ref GetArrayDataReference(firstBufferOfWriter); +#else + this.bufferWriter = writer; + this.bufferReference = firstBufferOfWriter.AsSpan(); +#endif + this.bufferLength = firstBufferOfWriter.Length; + this.advancedCount = 0; + this.writtenCount = 0; + this.depth = 0; + this.serializeStringAsUtf8 = optionalState.Options.StringEncoding == StringEncoding.Utf8; + this.optionalState = optionalState; + } + + public MemoryPackWriter(ref IBufferWriter writer, Span firstBufferOfWriter, MemoryPackWriterOptionalState optionalState) + { +#if NET7_0_OR_GREATER + this.bufferWriter = ref writer; + this.bufferReference = ref MemoryMarshal.GetReference(firstBufferOfWriter); +#else + this.bufferWriter = writer; + this.bufferReference = firstBufferOfWriter; +#endif + this.bufferLength = firstBufferOfWriter.Length; + this.advancedCount = 0; + this.writtenCount = 0; + this.depth = 0; + this.serializeStringAsUtf8 = optionalState.Options.StringEncoding == StringEncoding.Utf8; + this.optionalState = optionalState; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref byte GetSpanReference(int sizeHint) + { + if (bufferLength < sizeHint) + { + RequestNewBuffer(sizeHint); + } + +#if NET7_0_OR_GREATER + return ref bufferReference; +#else + return ref MemoryMarshal.GetReference(bufferReference); +#endif + } + + [MethodImpl(MethodImplOptions.NoInlining)] + void RequestNewBuffer(int sizeHint) + { + if (advancedCount != 0) + { + bufferWriter.Advance(advancedCount); + advancedCount = 0; + } + var span = bufferWriter.GetSpan(sizeHint); +#if NET7_0_OR_GREATER + bufferReference = ref MemoryMarshal.GetReference(span); +#else + bufferReference = span; +#endif + bufferLength = span.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int count) + { + if (count == 0) return; + + var rest = bufferLength - count; + if (rest < 0) + { + MemoryPackSerializationException.ThrowInvalidAdvance(); + } + + bufferLength = rest; +#if NET7_0_OR_GREATER + bufferReference = ref Unsafe.Add(ref bufferReference, count); +#else + bufferReference = bufferReference.Slice(count); +#endif + advancedCount += count; + writtenCount += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Flush() + { + if (advancedCount != 0) + { + bufferWriter.Advance(advancedCount); + advancedCount = 0; + } +#if NET7_0_OR_GREATER + bufferReference = ref Unsafe.NullRef(); +#else + bufferReference = default; +#endif + bufferLength = 0; + writtenCount = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IMemoryPackFormatter GetFormatter(Type type) + { + return MemoryPackFormatterProvider.GetFormatter(type); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IMemoryPackFormatter GetFormatter() + { + return MemoryPackFormatterProvider.GetFormatter(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetStringWriteLength(string? value) + { + if (value == null || value.Length == 0) + { + return 4; + } + + if (serializeStringAsUtf8) + { + return Encoding.UTF8.GetByteCount(value) + 8; + } + else + { + return checked(value.Length * 2) + 4; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetUnmanageArrayWriteLength(T[]? value) + where T : unmanaged + { + if (value == null || value.Length == 0) + { + return 4; + } + + return (Unsafe.SizeOf() * value.Length) + 4; + } + + // Write methods + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteObjectHeader(byte memberCount) + { + if (memberCount >= MemoryPackCode.Reserved1) + { + MemoryPackSerializationException.ThrowWriteInvalidMemberCount(memberCount); + } + GetSpanReference(1) = memberCount; + Advance(1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteNullObjectHeader() + { + GetSpanReference(1) = MemoryPackCode.NullObject; + Advance(1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteObjectReferenceId(uint referenceId) + { + GetSpanReference(1) = MemoryPackCode.ReferenceId; + Advance(1); + WriteVarInt(referenceId); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnionHeader(ushort tag) + { + if (tag < MemoryPackCode.WideTag) + { + GetSpanReference(1) = (byte)tag; + Advance(1); + } + else + { + ref var spanRef = ref GetSpanReference(3); + Unsafe.WriteUnaligned(ref spanRef, MemoryPackCode.WideTag); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref spanRef, 1), tag); + Advance(3); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteNullUnionHeader() + { + WriteNullObjectHeader(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteCollectionHeader(int length) + { + Unsafe.WriteUnaligned(ref GetSpanReference(4), length); + Advance(4); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteNullCollectionHeader() + { + Unsafe.WriteUnaligned(ref GetSpanReference(4), MemoryPackCode.NullCollection); + Advance(4); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteString(string? value) + { + if (serializeStringAsUtf8) + { + WriteUtf8(value); + } + else + { + WriteUtf16(value); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUtf16(string? value) + { + if (value == null) + { + WriteNullCollectionHeader(); + return; + } + + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + var copyByteCount = checked(value.Length * 2); + + ref var dest = ref GetSpanReference(copyByteCount + 4); + Unsafe.WriteUnaligned(ref dest, value.Length); + +#if NET7_0_OR_GREATER + ref var src = ref Unsafe.As(ref Unsafe.AsRef(value.GetPinnableReference())); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)copyByteCount); +#else + MemoryMarshal.AsBytes(value.AsSpan()).CopyTo(MemoryMarshal.CreateSpan(ref Unsafe.Add(ref dest, 4), copyByteCount)); +#endif + + Advance(copyByteCount + 4); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUtf16(ReadOnlySpan value) + { + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + var copyByteCount = checked(value.Length * 2); + + ref var dest = ref GetSpanReference(copyByteCount + 4); + Unsafe.WriteUnaligned(ref dest, value.Length); + MemoryMarshal.AsBytes(value).CopyTo(MemoryMarshal.CreateSpan(ref Unsafe.Add(ref dest, 4), copyByteCount)); + Advance(copyByteCount + 4); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUtf8(string? value) + { + if (value == null) + { + WriteNullCollectionHeader(); + return; + } + + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + // (int ~utf8-byte-count, int utf16-length, utf8-bytes) + + var source = value.AsSpan(); + + // UTF8.GetMaxByteCount -> (length + 1) * 3 + var maxByteCount = (source.Length + 1) * 3; + + ref var destPointer = ref GetSpanReference(maxByteCount + 8); // header + + // write utf16-length + Unsafe.WriteUnaligned(ref Unsafe.Add(ref destPointer, 4), source.Length); + + var dest = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref destPointer, 8), maxByteCount); +#if NET7_0_OR_GREATER + var status = Utf8.FromUtf16(source, dest, out var _, out var bytesWritten, replaceInvalidSequences: false); + if (status != OperationStatus.Done) + { + MemoryPackSerializationException.ThrowFailedEncoding(status); + } +#else + var bytesWritten = Encoding.UTF8.GetBytes(value, dest); +#endif + + // write written utf8-length in header, that is ~length + Unsafe.WriteUnaligned(ref destPointer, ~bytesWritten); + Advance(bytesWritten + 8); // + header + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUtf8(ReadOnlySpan utf8Value, int utf16Length = -1) + { + if (utf8Value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + // (int ~utf8-byte-count, int utf16-length, utf8-bytes) + + ref var destPointer = ref GetSpanReference(utf8Value.Length + 8); // header + + Unsafe.WriteUnaligned(ref destPointer, ~utf8Value.Length); + Unsafe.WriteUnaligned(ref Unsafe.Add(ref destPointer, 4), utf16Length); + + var dest = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref destPointer, 8), utf8Value.Length); + utf8Value.CopyTo(dest); + + Advance(utf8Value.Length + 8); + } + +#if NET7_0_OR_GREATER + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WritePackable(in T? value) + where T : IMemoryPackable + { + depth++; + if (depth == DepthLimit) MemoryPackSerializationException.ThrowReachedDepthLimit(typeof(T)); + T.Serialize(ref this, ref Unsafe.AsRef(value)); + depth--; + } + +#else + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WritePackable(in T? value) + where T : IMemoryPackable + { + WriteValue(value); + } + +#endif + + // non packable, get formatter dynamically. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteValue(in T? value) + { + depth++; + if (depth == DepthLimit) MemoryPackSerializationException.ThrowReachedDepthLimit(typeof(T)); + GetFormatter().Serialize(ref this, ref Unsafe.AsRef(value)); + depth--; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteValue(Type type, object? value) + { + depth++; + if (depth == DepthLimit) MemoryPackSerializationException.ThrowReachedDepthLimit(type); + GetFormatter(type).Serialize(ref this, ref value); + depth--; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteValueWithFormatter(TFormatter formatter, in T? value) + where TFormatter : IMemoryPackFormatter + { + depth++; + formatter.Serialize(ref this, ref Unsafe.AsRef(value)); + depth--; + } + + #region WriteArray/Span + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteArray(T?[]? value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedArray(value); + return; + } + + if (value == null) + { + WriteNullCollectionHeader(); + return; + } + + var formatter = GetFormatter(); + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + formatter.Serialize(ref this, ref value[i]); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteSpan(Span value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedSpan(value); + return; + } + + var formatter = GetFormatter(); + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + formatter.Serialize(ref this, ref value[i]); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteSpan(ReadOnlySpan value) + { + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedSpan(value); + return; + } + + var formatter = GetFormatter(); + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + formatter.Serialize(ref this, ref Unsafe.AsRef(value[i])); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WritePackableArray(T?[]? value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + WriteArray(value); + return; +#else + + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedArray(value); + return; + } + + if (value == null) + { + WriteNullCollectionHeader(); + return; + } + + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + T.Serialize(ref this, ref value[i]); + } +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WritePackableSpan(Span value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + WriteSpan(value); + return; +#else + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedSpan(value); + return; + } + + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + T.Serialize(ref this, ref value[i]); + } +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WritePackableSpan(ReadOnlySpan value) + where T : IMemoryPackable + { +#if !NET7_0_OR_GREATER + WriteSpan(value); + return; +#else + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + DangerousWriteUnmanagedSpan(value); + return; + } + + WriteCollectionHeader(value.Length); + for (int i = 0; i < value.Length; i++) + { + T.Serialize(ref this, ref Unsafe.AsRef(value[i])); + } +#endif + } + + #endregion + + #region WriteUnmanagedArray/Span + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedArray(T[]? value) + where T : unmanaged + { + DangerousWriteUnmanagedArray(value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedSpan(Span value) + where T : unmanaged + { + DangerousWriteUnmanagedSpan(value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUnmanagedSpan(ReadOnlySpan value) + where T : unmanaged + { + DangerousWriteUnmanagedSpan(value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedArray(T[]? value) + { + if (value == null) + { + WriteNullCollectionHeader(); + return; + } + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + var srcLength = Unsafe.SizeOf() * value.Length; + var allocSize = srcLength + 4; + + ref var dest = ref GetSpanReference(allocSize); + ref var src = ref Unsafe.As(ref GetArrayDataReference(value)); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)srcLength); + + Advance(allocSize); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedSpan(Span value) + { + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + var srcLength = Unsafe.SizeOf() * value.Length; + var allocSize = srcLength + 4; + + ref var dest = ref GetSpanReference(allocSize); + ref var src = ref Unsafe.As(ref MemoryMarshal.GetReference(value)); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)srcLength); + + Advance(allocSize); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DangerousWriteUnmanagedSpan(ReadOnlySpan value) + { + if (value.Length == 0) + { + WriteCollectionHeader(0); + return; + } + + var srcLength = Unsafe.SizeOf() * value.Length; + var allocSize = srcLength + 4; + + ref var dest = ref GetSpanReference(allocSize); + ref var src = ref Unsafe.As(ref MemoryMarshal.GetReference(value)); + + Unsafe.WriteUnaligned(ref dest, value.Length); + Unsafe.CopyBlockUnaligned(ref Unsafe.Add(ref dest, 4), ref src, (uint)srcLength); + + Advance(allocSize); + } + + #endregion + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteSpanWithoutLengthHeader(ReadOnlySpan value) + { + if (value.Length == 0) return; + + if (!RuntimeHelpers.IsReferenceOrContainsReferences()) + { + var srcLength = Unsafe.SizeOf() * value.Length; + ref var dest = ref GetSpanReference(srcLength); + ref var src = ref Unsafe.As(ref MemoryMarshal.GetReference(value)!); + + Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)srcLength); + + Advance(srcLength); + return; + } + else + { + var formatter = GetFormatter(); + for (int i = 0; i < value.Length; i++) + { + formatter.Serialize(ref this, ref Unsafe.AsRef(value[i])); + } + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs.meta new file mode 100644 index 0000000..4617f29 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 694e1cfc99967af499c579224bd74f41 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs new file mode 100644 index 0000000..b7cb713 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +#nullable enable +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +namespace MemoryPack { + +public static class MemoryPackWriterOptionalStatePool +{ + static readonly ConcurrentQueue queue = new ConcurrentQueue(); + + public static MemoryPackWriterOptionalState Rent(MemoryPackSerializerOptions? options) + { + if (!queue.TryDequeue(out var state)) + { + state = new MemoryPackWriterOptionalState(); + } + + state.Init(options); + return state; + } + + internal static void Return(MemoryPackWriterOptionalState state) + { + state.Reset(); + queue.Enqueue(state); + } +} + +public sealed class MemoryPackWriterOptionalState : IDisposable +{ + internal static readonly MemoryPackWriterOptionalState NullState = new MemoryPackWriterOptionalState(true); + + uint nextId; + readonly Dictionary objectToRef; + + public MemoryPackSerializerOptions Options { get; private set; } + + internal MemoryPackWriterOptionalState() + { + objectToRef = new Dictionary(ReferenceEqualityComparer.Instance); + Options = null!; + nextId = 0; + } + + MemoryPackWriterOptionalState(bool _) + { + objectToRef = null!; + Options = MemoryPackSerializerOptions.Default; + nextId = 0; + } + + internal void Init(MemoryPackSerializerOptions? options) + { + Options = options ?? MemoryPackSerializerOptions.Default; + } + + public void Reset() + { + objectToRef.Clear(); + Options = null!; + nextId = 0; + } + + public (bool existsReference, uint id) GetOrAddReference(object value) + { +#if NET7_0_OR_GREATER + ref var id = ref CollectionsMarshal.GetValueRefOrAddDefault(objectToRef, value, out var exists); + if (exists) + { + return (true, id); + } + else + { + id = nextId++; + return (false, id); + } +#else + if (objectToRef.TryGetValue(value, out var id)) + { + return (true, id); + } + else + { + id = nextId++; + objectToRef.Add(value, id); + return (false, id); + } +#endif + } + + void IDisposable.Dispose() + { + MemoryPackWriterOptionalStatePool.Return(this); + } + + // ReferenceEqualityComparer is exsits in .NET 6 but NetStandard 2.1 does not. + sealed class ReferenceEqualityComparer : IEqualityComparer + { + ReferenceEqualityComparer() { } + + public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer(); + + public new bool Equals(object? x, object? y) => ReferenceEquals(x, y); + + public int GetHashCode(object obj) + { + return RuntimeHelpers.GetHashCode(obj); + } + } +} + +} \ No newline at end of file diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs.meta new file mode 100644 index 0000000..e7e2e00 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Core/MemoryPackWriterOptionalState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9d13eff4e4acac42a411940227fc067 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Generator.meta b/AssetDependencyGraph/Plugins/MemoryPack.Generator.meta new file mode 100644 index 0000000..87da08c --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Generator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e0f1520c391ebd54281e535320cf5308 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll b/AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll new file mode 100644 index 0000000000000000000000000000000000000000..1eb665e5620bb6742beafbb6468bbfba82cdeee5 GIT binary patch literal 125952 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 Prj4>DWsL0bUwv0%sgUXEEW? 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

*nq9i&s8Jj3RxF83U*FT}3@ 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 ar1Aeu-ed~I6{A)E4A<;`{`>zQ1^z#G)-6Q< literal 0 HcmV?d00001 diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll.meta b/AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll.meta new file mode 100644 index 0000000..ce971fc --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Generator/MemoryPack.Generator.Roslyn3.dll.meta @@ -0,0 +1,71 @@ +fileFormatVersion: 2 +guid: f94f433c2cc4d574a85c9ff168cf15d7 +labels: +- RoslynAnalyzer +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 1 + validateReferences: 0 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Unity.meta b/AssetDependencyGraph/Plugins/MemoryPack.Unity.meta new file mode 100644 index 0000000..d22a26f --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5b96d72a14b21b44ba91c25a42ef2032 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs b/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs new file mode 100644 index 0000000..edef847 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs @@ -0,0 +1,64 @@ +#nullable enable + +using MemoryPack.Formatters; +using UnityEngine; + +namespace MemoryPack +{ + public static partial class MemoryPackFormatterProvider + { + static void UnityRegister() + where T : unmanaged + { + Register(new UnmanagedFormatter()); + Register(new UnmanagedArrayFormatter()); + Register(new ListFormatter()); + Register(new NullableFormatter()); + } + + static partial void RegisterInitialFormatters() + { + // struct + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + Register(new UnmanagedFormatter()); + UnityRegister(); + UnityRegister(); + UnityRegister(); + Register(new UnmanagedFormatter()); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + UnityRegister(); + + // class + if (!IsRegistered()) + { + Register(new AnimationCurveFormatter()); + Register(new ArrayFormatter()); + Register(new ListFormatter()); + } + if (!IsRegistered()) + { + Register(new GradientFormatter()); + Register(new ArrayFormatter()); + Register(new ListFormatter()); + } + if (!IsRegistered()) + { + Register(new RectOffsetFormatter()); + Register(new ArrayFormatter()); + Register(new ListFormatter()); + } + } + } +} diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs.meta new file mode 100644 index 0000000..4cf5ad5 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Unity/ProviderInitializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 031150f227b81a94a8fd30bb205ab850 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs b/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs new file mode 100644 index 0000000..d7045a3 --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs @@ -0,0 +1,134 @@ +#nullable enable + +using MemoryPack.Internal; +using UnityEngine; + +namespace MemoryPack +{ + [Preserve] + internal sealed class AnimationCurveFormatter : MemoryPackFormatter + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref AnimationCurve? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteUnmanagedWithObjectHeader(3, value.@preWrapMode, value.@postWrapMode); + writer.WriteUnmanagedArray(value.@keys); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref AnimationCurve? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 3) MemoryPackSerializationException.ThrowInvalidPropertyCount(3, count); + + reader.ReadUnmanaged(out WrapMode preWrapMode, out WrapMode postWrapMode); + var keys = reader.ReadUnmanagedArray(); + + if (value == null) + { + value = new AnimationCurve(); + } + + value.preWrapMode = preWrapMode; + value.postWrapMode = postWrapMode; + value.keys = keys; + } + } + + [Preserve] + internal sealed class GradientFormatter : MemoryPackFormatter + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref Gradient? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteObjectHeader(3); + writer.WriteUnmanagedArray(value.@colorKeys); + writer.WriteUnmanagedArray(value.@alphaKeys); + writer.WriteUnmanaged(value.@mode); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref Gradient? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 3) MemoryPackSerializationException.ThrowInvalidPropertyCount(3, count); + + var colorKeys = reader.ReadUnmanagedArray(); + var alphaKeys = reader.ReadUnmanagedArray(); + reader.ReadUnmanaged(out GradientMode mode); + + if (value == null) + { + value = new Gradient(); + } + + value.colorKeys = colorKeys; + value.alphaKeys = alphaKeys; + value.mode = mode; + } + } + + [Preserve] + internal sealed class RectOffsetFormatter : MemoryPackFormatter + { + [Preserve] + public override void Serialize(ref MemoryPackWriter writer, ref RectOffset? value) + { + if (value == null) + { + writer.WriteNullObjectHeader(); + return; + } + + writer.WriteUnmanagedWithObjectHeader(4, value.@left, value.@right, value.@top, value.@bottom); + } + + [Preserve] + public override void Deserialize(ref MemoryPackReader reader, ref RectOffset? value) + { + if (!reader.TryReadObjectHeader(out var count)) + { + value = null; + return; + } + + if (count != 4) MemoryPackSerializationException.ThrowInvalidPropertyCount(4, count); + + reader.ReadUnmanaged(out int left, out int right, out int top, out int bottom); + + if (value == null) + { + value = new RectOffset(left, right, top, bottom); + } + else + { + value.left = left; + value.right = right; + value.top = top; + value.bottom = bottom; + } + } + } +} diff --git a/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs.meta b/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs.meta new file mode 100644 index 0000000..f884cff --- /dev/null +++ b/AssetDependencyGraph/Plugins/MemoryPack.Unity/UnityFormatters.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e8b601bad4e9394baceb6c8449f22c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/Microsoft.Bcl.AsyncInterfaces.dll b/AssetDependencyGraph/Plugins/Microsoft.Bcl.AsyncInterfaces.dll new file mode 100644 index 0000000000000000000000000000000000000000..c06e69c3902220559e197dc5069c5136c80d8789 GIT binary patch literal 26920 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 literal 0 HcmV?d00001 diff --git a/AssetDependencyGraph/Plugins/System.IO.Pipelines.dll.meta b/AssetDependencyGraph/Plugins/System.IO.Pipelines.dll.meta new file mode 100644 index 0000000..6051275 --- /dev/null +++ b/AssetDependencyGraph/Plugins/System.IO.Pipelines.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: a11a7d009eeecd0438f253ac36007662 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/System.Runtime.CompilerServices.Unsafe.dll b/AssetDependencyGraph/Plugins/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000000000000000000000000000000000000..491a80a97880de93aa893f6974c5f76891d2de73 GIT binary patch literal 18024 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 S^fsyfgHi*nKCJ8GOaC8xl->OR literal 0 HcmV?d00001 diff --git a/AssetDependencyGraph/Plugins/System.Text.Encodings.Web.dll.meta b/AssetDependencyGraph/Plugins/System.Text.Encodings.Web.dll.meta new file mode 100644 index 0000000..1168a89 --- /dev/null +++ b/AssetDependencyGraph/Plugins/System.Text.Encodings.Web.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 25b095a5378ae5940badfecc21c31006 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/AssetDependencyGraph/Plugins/System.Text.Json.dll b/AssetDependencyGraph/Plugins/System.Text.Json.dll new file mode 100644 index 0000000000000000000000000000000000000000..cc96fe50af30f2d49b401cebb5b81a229bb1a49e GIT binary patch literal 742672 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

uqHz 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

KL))6NUiyNc=xH?dwq#u&f#*wLPH)M=JM-&7 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 Dependencies = new(); [JsonIgnore] + [MemoryPackIgnore] public ConcurrentBag Dependent = new(); [AllowNull] diff --git a/UnityDependencyAnalyzer/DependencyAnalysis.cs b/UnityDependencyAnalyzer/DependencyAnalysis.cs index 4dd7479..d0dd4f5 100644 --- a/UnityDependencyAnalyzer/DependencyAnalysis.cs +++ b/UnityDependencyAnalyzer/DependencyAnalysis.cs @@ -1,7 +1,6 @@ using MemoryPack; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Options; -using System; using System.Collections.Concurrent; using System.Diagnostics; using System.Text.Json; @@ -238,9 +237,11 @@ namespace AssetDependencyGraph private JsonSerializerOptions options = new JsonSerializerOptions { IncludeFields = true }; [BsonDictionaryOptions(Representation = DictionaryRepresentation.ArrayOfArrays)] + private ConcurrentDictionary assetIdentify2AssetNodeDic = new(); private ConcurrentDictionary path2Id = new(); private ConcurrentBag<(string path, bool isDir)> allPath = new(); + private UnityLmdb unityLmdb; private static Regex isGuid = new Regex("^[\\da-f]{32}$"); @@ -261,7 +262,7 @@ namespace AssetDependencyGraph allPath.Add((path, Directory.Exists(path))); } - public static bool IsGuid(string str) + private static bool IsGuid(string str) { if (str.Length == 32) { @@ -270,7 +271,7 @@ namespace AssetDependencyGraph return false; } - public (AssetIdentify id, AssetNode node) GetOrCreateFolderNode(string path) + private (AssetIdentify id, AssetNode node) GetOrCreateFolderNode(string path) { if (!path2Id.TryGetValue(path, out var k)) { @@ -294,7 +295,7 @@ namespace AssetDependencyGraph return (k, assetIdentify2AssetNodeDic[k]); } - public (AssetIdentify id, AssetNode node) GetOrCreateAssetNode(string path) + private (AssetIdentify id, AssetNode node) GetOrCreateAssetNode(string path) { if (!path2Id.TryGetValue(path, out var k)) { @@ -331,11 +332,17 @@ namespace AssetDependencyGraph return (k, assetIdentify2AssetNodeDic[k]); } - public void ResolveGuidDatabase() + private void ResolveGuidDatabase() { unityLmdb.ResolveGuidPath(); } + private void SaveGuidPathDic() + { + File.WriteAllBytes(Path.Combine(UnityLmdb.ProjPath, "Library", "guid2path.bin"), MemoryPackSerializer.Serialize(unityLmdb.Guid2Path)); + File.WriteAllBytes(Path.Combine(UnityLmdb.ProjPath, "Library", "path2guid.bin"), MemoryPackSerializer.Serialize(unityLmdb.Path2Guid)); + } + public async ValueTask AnalyzeMainProcess(string projectPath, string rootFolder, int processCnt = 8) { Stopwatch sw = Stopwatch.StartNew(); @@ -345,6 +352,9 @@ namespace AssetDependencyGraph Console.WriteLine($"遍历目录耗时:{sw.ElapsedMilliseconds / 1000f}s"); sw.Restart(); + path2Id = new(concurrencyLevel: Environment.ProcessorCount, capacity: allPath.Count); + assetIdentify2AssetNodeDic = new(concurrencyLevel: Environment.ProcessorCount, capacity: allPath.Count); + var itemCnt = allPath.Count / processCnt; List subProcessArgs = new(); List resultPaths = new(); @@ -365,7 +375,7 @@ namespace AssetDependencyGraph File.WriteAllText(jsonPath, s); } - Task[] subProcessTask = new Task[subProcessArgs.Count]; + Task[] subProcessTask = new Task[subProcessArgs.Count + 1]; var exe = Environment.GetCommandLineArgs()[0]; if (exe.EndsWith(".dll")) { @@ -393,13 +403,20 @@ namespace AssetDependencyGraph }); } - Stopwatch sw1 = Stopwatch.StartNew(); - sw1.Start(); - ResolveGuidDatabase(); - sw1.Stop(); - Console.WriteLine($"加载数据库耗时:{sw1.ElapsedMilliseconds / 1000f}s"); + subProcessTask[^1] = Task.Run(() => + { + Stopwatch sw1 = Stopwatch.StartNew(); + sw1.Start(); + ResolveGuidDatabase(); + SaveGuidPathDic(); + sw1.Stop(); + Console.WriteLine($"加载数据库耗时:{sw1.ElapsedMilliseconds / 1000f}s"); + }); Task.WaitAll(subProcessTask); + sw.Stop(); + Console.WriteLine($"分析引用耗时:{sw.ElapsedMilliseconds / 1000f}s"); + sw.Restart(); List>> subProcessResults = new(); foreach (var item in resultPaths) { @@ -407,7 +424,7 @@ namespace AssetDependencyGraph subProcessResults.Add(MemoryPackSerializer.Deserialize>>(s.AsSpan())!); } sw.Stop(); - Console.WriteLine($"分析引用耗时:{sw.ElapsedMilliseconds / 1000f}s"); + Console.WriteLine($"加载子线程结果耗时:{sw.ElapsedMilliseconds / 1000f}s"); sw.Restart(); Parallel.ForEach(subProcessResults, arg => ResolveSubProcessResult(arg)); sw.Stop(); @@ -419,8 +436,10 @@ namespace AssetDependencyGraph item.Value.DependentSet = item.Value.Dependent.ToHashSet(); } - using var wr = File.OpenWrite(Path.Combine(UnityLmdb.ProjPath, "Library", "dependencyGraph.bin")); - await MemoryPackSerializer.SerializeAsync(wr, assetIdentify2AssetNodeDic); + { + using var wr = File.OpenWrite(Path.Combine(UnityLmdb.ProjPath, "Library", "dependencyGraph.bin")); + await MemoryPackSerializer.SerializeAsync(wr, assetIdentify2AssetNodeDic); + } sw.Stop(); Console.WriteLine($"写入文件耗时:{sw.ElapsedMilliseconds / 1000f}s"); @@ -511,7 +530,6 @@ namespace AssetDependencyGraph } } - public void Analyze(string rootFolder) { Stopwatch sw = Stopwatch.StartNew(); diff --git a/UnityDependencyAnalyzer/Program.cs b/UnityDependencyAnalyzer/Program.cs index 3e77a8e..b907095 100644 --- a/UnityDependencyAnalyzer/Program.cs +++ b/UnityDependencyAnalyzer/Program.cs @@ -42,7 +42,7 @@ switch (Environment.GetCommandLineArgs()[1]) } else { - await new DependencyAnalyzer().AnalyzeMainProcess(UnityLmdb.ProjPath, Utils.DataPath, 10); + await new DependencyAnalyzer().AnalyzeMainProcess(UnityLmdb.ProjPath, Utils.DataPath, Environment.ProcessorCount); } break; } diff --git a/UnityDependencyAnalyzer/Properties/PublishProfiles/FolderProfile.pubxml.user b/UnityDependencyAnalyzer/Properties/PublishProfiles/FolderProfile.pubxml.user index c5dc233..018fb50 100644 --- a/UnityDependencyAnalyzer/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/UnityDependencyAnalyzer/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2025-07-08T03:14:03.4969097Z||;True|2025-07-07T16:09:23.5193447+08:00||;True|2025-07-07T16:07:31.9772710+08:00||;True|2025-07-07T16:07:24.6544267+08:00||;True|2025-07-07T16:06:58.2999030+08:00||;True|2025-07-07T16:06:47.5176281+08:00||;True|2025-07-07T16:06:30.9937062+08:00||;True|2025-07-07T16:06:16.1827410+08:00||;True|2025-07-04T20:51:36.2342905+08:00||;True|2025-07-04T20:49:41.4585526+08:00||;True|2025-07-04T20:46:06.1627373+08:00||;True|2025-07-04T20:39:45.9777563+08:00||;True|2025-07-04T20:38:51.7922210+08:00||;True|2025-07-04T20:38:30.7653415+08:00||;True|2025-07-04T20:37:48.1335374+08:00||;True|2025-07-04T20:37:32.2007568+08:00||;True|2025-07-04T20:37:03.6443318+08:00||;True|2025-07-04T20:35:04.7675245+08:00||;True|2025-04-16T20:37:48.8637838+08:00||;True|2025-04-16T20:23:11.1448355+08:00||;True|2025-04-16T16:49:35.4476343+08:00||;True|2025-04-16T16:36:22.8513231+08:00||;True|2025-04-16T12:23:59.6108463+08:00||;True|2025-04-16T12:08:50.9715020+08:00||;True|2025-04-16T11:57:10.7843966+08:00||;False|2025-04-16T11:02:10.7479206+08:00||;False|2025-04-16T10:59:42.9239923+08:00||;False|2025-04-16T10:54:01.4031170+08:00||;True|2025-04-16T10:29:13.7528358+08:00||;False|2025-04-16T10:27:03.3522077+08:00||;False|2025-04-16T10:26:07.1734998+08:00||; + True|2025-10-22T12:29:32.7349288Z||;True|2025-07-08T11:14:03.4969097+08:00||;True|2025-07-07T16:09:23.5193447+08:00||;True|2025-07-07T16:07:31.9772710+08:00||;True|2025-07-07T16:07:24.6544267+08:00||;True|2025-07-07T16:06:58.2999030+08:00||;True|2025-07-07T16:06:47.5176281+08:00||;True|2025-07-07T16:06:30.9937062+08:00||;True|2025-07-07T16:06:16.1827410+08:00||;True|2025-07-04T20:51:36.2342905+08:00||;True|2025-07-04T20:49:41.4585526+08:00||;True|2025-07-04T20:46:06.1627373+08:00||;True|2025-07-04T20:39:45.9777563+08:00||;True|2025-07-04T20:38:51.7922210+08:00||;True|2025-07-04T20:38:30.7653415+08:00||;True|2025-07-04T20:37:48.1335374+08:00||;True|2025-07-04T20:37:32.2007568+08:00||;True|2025-07-04T20:37:03.6443318+08:00||;True|2025-07-04T20:35:04.7675245+08:00||;True|2025-04-16T20:37:48.8637838+08:00||;True|2025-04-16T20:23:11.1448355+08:00||;True|2025-04-16T16:49:35.4476343+08:00||;True|2025-04-16T16:36:22.8513231+08:00||;True|2025-04-16T12:23:59.6108463+08:00||;True|2025-04-16T12:08:50.9715020+08:00||;True|2025-04-16T11:57:10.7843966+08:00||;False|2025-04-16T11:02:10.7479206+08:00||;False|2025-04-16T10:59:42.9239923+08:00||;False|2025-04-16T10:54:01.4031170+08:00||;True|2025-04-16T10:29:13.7528358+08:00||;False|2025-04-16T10:27:03.3522077+08:00||;False|2025-04-16T10:26:07.1734998+08:00||; \ No newline at end of file diff --git a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj index a67c13d..9da22ef 100644 --- a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj +++ b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj @@ -5,7 +5,6 @@ net8.0 enable enable - False diff --git a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj.user b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj.user index 6365cfd..71e5c62 100644 --- a/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj.user +++ b/UnityDependencyAnalyzer/UnityDependencyAnalyzer.csproj.user @@ -1,6 +1,6 @@  - <_LastSelectedProfileId>C:\Users\xinyt\source\repos\UnityFileDumper\UnityDependencyAnalyzer\Properties\PublishProfiles\FolderProfile.pubxml + <_LastSelectedProfileId>G:\UnityDependencyAnalyzer\UnityDependencyAnalyzer\Properties\PublishProfiles\FolderProfile.pubxml \ No newline at end of file diff --git a/UnityDependencyAnalyzer/UnityLmdb.cs b/UnityDependencyAnalyzer/UnityLmdb.cs index 2a452bc..e36471f 100644 --- a/UnityDependencyAnalyzer/UnityLmdb.cs +++ b/UnityDependencyAnalyzer/UnityLmdb.cs @@ -13,6 +13,9 @@ namespace AssetDependencyGraph private string dbFilePath = null!; + public Dictionary Path2Guid { get => path2Guid; set => path2Guid = value; } + public Dictionary Guid2Path { get => guid2Path; set => guid2Path = value; } + public static byte[] Guid2LmdbKey(string guid) { var inputByteArray = new byte[guid.Length / 2]; @@ -69,7 +72,7 @@ namespace AssetDependencyGraph { foreach (var item in cursor.AsEnumerable()) { - guid2Path[LmdbKey2Guid(item.Item1.AsSpan().ToArray())] = Encoding.UTF8.GetString(item.Item2.AsSpan()).ToLowerInvariant().Trim('\0'); + Guid2Path[LmdbKey2Guid(item.Item1.AsSpan().ToArray())] = Encoding.UTF8.GetString(item.Item2.AsSpan()).ToLowerInvariant().Trim('\0'); } } @@ -78,12 +81,11 @@ namespace AssetDependencyGraph { foreach (var item in cursor.AsEnumerable()) { - path2Guid[Encoding.UTF8.GetString(item.Item1.AsSpan()).ToLowerInvariant().Trim('\0')] = LmdbKey2Guid(item.Item2.AsSpan().ToArray()); + Path2Guid[Encoding.UTF8.GetString(item.Item1.AsSpan()).ToLowerInvariant().Trim('\0')] = LmdbKey2Guid(item.Item2.AsSpan().ToArray()); } } } - public void ResolveGuidPathByDBPath(string dbPath) { dbFilePath = dbPath; @@ -99,7 +101,7 @@ namespace AssetDependencyGraph { foreach (var item in cursor.AsEnumerable()) { - guid2Path[LmdbKey2Guid(item.Item1.AsSpan().ToArray())] = Encoding.UTF8.GetString(item.Item2.AsSpan()).ToLowerInvariant().Trim('\0'); + Guid2Path[LmdbKey2Guid(item.Item1.AsSpan().ToArray())] = Encoding.UTF8.GetString(item.Item2.AsSpan()).ToLowerInvariant().Trim('\0'); } } @@ -108,7 +110,7 @@ namespace AssetDependencyGraph { foreach (var item in cursor.AsEnumerable()) { - path2Guid[Encoding.UTF8.GetString(item.Item1.AsSpan()).ToLowerInvariant().Trim('\0')] = LmdbKey2Guid(item.Item2.AsSpan().ToArray()); + Path2Guid[Encoding.UTF8.GetString(item.Item1.AsSpan()).ToLowerInvariant().Trim('\0')] = LmdbKey2Guid(item.Item2.AsSpan().ToArray()); } } } @@ -116,7 +118,7 @@ namespace AssetDependencyGraph public ConcurrentBag VerifyGUID() { ConcurrentBag result = new (); - Parallel.ForEach(path2Guid, (item) => + Parallel.ForEach(Path2Guid, (item) => { var f = item.Key + ".meta"; if (File.Exists(f)) @@ -134,14 +136,14 @@ namespace AssetDependencyGraph public string ResultToJson() { - return JsonSerializer.Serialize(path2Guid, new JsonSerializerOptions { IncludeFields = true }); + return JsonSerializer.Serialize(Path2Guid, new JsonSerializerOptions { IncludeFields = true }); } public string GetGuidByPath(string path) { - if (path2Guid.ContainsKey(path)) + if (Path2Guid.ContainsKey(path)) { - return path2Guid[path]; + return Path2Guid[path]; } else { @@ -151,9 +153,9 @@ namespace AssetDependencyGraph public string GetPathByGuid(string guid) { - if (guid2Path.ContainsKey(guid)) + if (Guid2Path.ContainsKey(guid)) { - return guid2Path[guid]; + return Guid2Path[guid]; } else {