add AssetDependencyGraph

This commit is contained in:
StarBeats 2025-10-22 21:39:13 +08:00
parent 835ede37f6
commit 23e8539500
141 changed files with 13898 additions and 97 deletions

View File

@ -0,0 +1,16 @@
{
"name": "AssetDependencyGraph-Editor",
"rootNamespace": "",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0f6edbbfd6f04b1479b191b629a0421f
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9303f9c952516f34cbc668b8d9217ee7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<AssetIdentify>
{
static JsonSerializerOptions serializerOptions = new JsonSerializerOptions() { IncludeFields = true };
public override AssetIdentify? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<AssetIdentify>(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<AssetIdentify> Dependencies = new();
[JsonIgnore]
[MemoryPackIgnore]
public ConcurrentBag<AssetIdentify> Dependent = new();
[AllowNull]
public HashSet<AssetIdentify> DependencySet;
[AllowNull]
public HashSet<AssetIdentify> DependentSet;
}
public sealed class AssetNodeJsonConverter : JsonConverter<AssetNode>
{
static JsonSerializerOptions serializerOptions = new JsonSerializerOptions()
{
IncludeFields = true,
Converters = { new AssetIdentifyJsonConverter() }
};
public override AssetNode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<AssetNode>(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<FolderNode> FolderNodes;
IMongoCollection<PackageNode> PackageNodes;
IMongoCollection<AssetNode> AssetNodes;
Dictionary<string, AssetNode> 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<FolderNode>("folder_nodes");
PackageNodes = db.GetCollection<PackageNode>("package_nodes");
AssetNodes = db.GetCollection<AssetNode>("asset_nodes");
}
public void Clean()
{
client.DropDatabase("assetgraph");
var db = client.GetDatabase("assetgraph");
FolderNodes = db.GetCollection<FolderNode>("folder_nodes");
PackageNodes = db.GetCollection<PackageNode>("package_nodes");
AssetNodes = db.GetCollection<AssetNode>("asset_nodes");
}
public void Insert<T>(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>(T node) where T : AssetNode
{
switch (node)
{
case FolderNode folderNode:
{
var filter = Builders<FolderNode>.Filter.And(
Builders<FolderNode>.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<FolderNode>.Update.Combine(
Builders<FolderNode>.Update.Set(fn => fn.Self, folderNode.Self),
Builders<FolderNode>.Update.Set(fn => fn.AssetType, folderNode.AssetType),
Builders<FolderNode>.Update.Set(fn => fn.Dependencies, folderNode.Dependencies),
Builders<FolderNode>.Update.Set(fn => fn.Dependent, folderNode.Dependent)
));
}
break;
}
case PackageNode packageNode:
{
var filter = Builders<PackageNode>.Filter.And(
Builders<PackageNode>.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<PackageNode>.Update.Combine(
Builders<PackageNode>.Update.Set(fn => fn.Self, packageNode.Self),
Builders<PackageNode>.Update.Set(fn => fn.AssetType, packageNode.AssetType),
Builders<PackageNode>.Update.Set(fn => fn.Dependencies, packageNode.Dependencies),
Builders<PackageNode>.Update.Set(fn => fn.Dependent, packageNode.Dependent)
));
}
break;
}
case AssetNode assetNode:
{
var filter = Builders<AssetNode>.Filter.And(
Builders<AssetNode>.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<AssetNode>.Update.Combine(
Builders<AssetNode>.Update.Set(fn => fn.Self, assetNode.Self),
Builders<AssetNode>.Update.Set(fn => fn.AssetType, assetNode.AssetType),
Builders<AssetNode>.Update.Set(fn => fn.Dependencies, assetNode.Dependencies),
Builders<AssetNode>.Update.Set(fn => fn.Dependent, assetNode.Dependent)
));
}
break;
}
default:
break;
}
}
public void Delete<T>(T node) where T : AssetNode
{
switch (node)
{
case FolderNode folderNode:
{
var filter = Builders<FolderNode>.Filter.And(
Builders<FolderNode>.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<PackageNode>.Filter.And(
Builders<PackageNode>.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<AssetNode>.Filter.And(
Builders<AssetNode>.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<AssetNode>.Filter.And(
Builders<AssetNode>.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<PackageNode>.Filter.And(
Builders<PackageNode>.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<FolderNode>.Filter.And(
Builders<FolderNode>.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!;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b678f0fc58371c4cb7735b9906443fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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,6 +74,8 @@ namespace AssetDependencyGraph
private static Dictionary<AssetIdentify, AssetNode> assetId2NodeDic;
private static Dictionary<string, AssetIdentify> path2NodeIdDic;
private static Dictionary<string, string> guid2PathDic = new();
private static Dictionary<string, string> path2GuidDic = new();
static AssetNode FindAssetNode(string path)
{
@ -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<Dictionary<AssetIdentify, AssetNode>>(js, options: new JsonSerializerOptions()
var bytes = File.ReadAllBytes(dependencyGraph);
stopwatch.Restart();
assetId2NodeDic = MemoryPackSerializer.Deserialize<Dictionary<AssetIdentify, AssetNode>>(bytes.AsSpan());
var guid2pathBinPath = Path.Combine(libraryPath, "guid2path.bin");
if (File.Exists(guid2pathBinPath))
{
IncludeFields = true,
Converters = { new AssetIdentifyJsonConverter(), new AssetNodeJsonConverter() }
});
guid2PathDic = MemoryPackSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllBytes(guid2pathBinPath));
}
var path2guidBinPath = Path.Combine(libraryPath, "path2guid.bin");
if (File.Exists(path2guidBinPath))
{
path2GuidDic = MemoryPackSerializer.Deserialize<Dictionary<string, string>>(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()
{
FileName = $"{Application.dataPath}/../Tools/UnityDependencyAnalyzer.exe",
Arguments = $"{Application.dataPath.Replace("Assets", "")} \" \" \" \" localhost ",
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,6 +321,24 @@ 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;
@ -278,6 +346,7 @@ namespace AssetDependencyGraph
{
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)
@ -648,6 +713,7 @@ namespace AssetDependencyGraph
{
if (EditorUtility.DisplayDialog("提示", "当前 asset 没有引用,是否直接删除", "确认删除", "取消"))
{
OnDeleteAsset(obj);
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(obj));
}
}
@ -717,6 +783,14 @@ namespace AssetDependencyGraph
};
objNode.extensionContainer.Add(typeContainer);
objNode.RegisterCallback<FocusInEvent>(e =>
{
});
objNode.RegisterCallback<FocusOutEvent>(e =>
{
});
#region Node Icon, replaced with color
//Texture assetTexture = AssetPreview.GetAssetPreview(obj);
@ -780,7 +854,6 @@ namespace AssetDependencyGraph
{
CreateDependencyNodes(assetGroup, assetNode, fullPathNodeLookup[fullPath], assetGroup.GroupNode, (int)fullPathNodeLookup[fullPath].userData + 1);
EditorApplication.delayCall += () => ResetAllNodes();
})
{
style =

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43eecbcf2afaca84aa2af29388e193de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9acdcfd297aa7ad4a91bbfde679a3688
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 590b08b0771f0bd47beca317303e050f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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.
/// <summary>
/// [generateType, (VersionTolerant or CircularReference) ? SerializeLayout.Explicit : SerializeLayout.Sequential]
/// </summary>
/// <param name="generateType"></param>
public MemoryPackableAttribute(GenerateType generateType = GenerateType.Object)
{
this.GenerateType = generateType;
this.SerializeLayout = (generateType == GenerateType.VersionTolerant || generateType == GenerateType.CircularReference)
? SerializeLayout.Explicit
: SerializeLayout.Sequential;
}
/// <summary>
/// [GenerateType.Object, serializeLayout]
/// </summary>
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<T> : Attribute
{
public abstract IMemoryPackFormatter<T> GetFormatter();
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public abstract class MemoryPackCustomFormatterAttribute<TFormatter, T> : Attribute
where TFormatter : IMemoryPackFormatter<T>
{
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
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e370fb1f0283f164ba65d0874cbef7f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6a28c9e101e0f564c9ab6b19218741bc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<bool[]>
{
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<bool, byte>(ref item));
// false -> 1 true -> 0
data = (int)Vector256.Equals(vector, Vector256<byte>.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<bool, byte>(ref item)), Vector128<byte>.Zero).ExtractMostSignificantBits();
var bits1 = (ushort)Vector128.Equals(Vector128.LoadUnsafe(ref Unsafe.As<bool, byte>(ref item), 16), Vector128<byte>.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<bool, byte>(ref item)), Vector64<byte>.Zero).ExtractMostSignificantBits();
var bits1 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As<bool, byte>(ref item), 8), Vector64<byte>.Zero).ExtractMostSignificantBits();
var bits2 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As<bool, byte>(ref item), 16), Vector64<byte>.Zero).ExtractMostSignificantBits();
var bits3 = (byte)Vector64.Equals(Vector64.LoadUnsafe(ref Unsafe.As<bool, byte>(ref item), 24), Vector64<byte>.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<bool>();
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;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61f1625193facbe4abecb4f90defa276
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte>, 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<byte>.Advance(int count)
{
ThrowIfDisposed();
bufferWriter.Advance(count);
}
Memory<byte> IBufferWriter<byte>.GetMemory(int sizeHint)
{
ThrowIfDisposed();
return bufferWriter.GetMemory(sizeHint);
}
Span<byte> IBufferWriter<byte>.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<byte>.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<byte>.Empty, destination, out var consumed, out var written, isFinalBlock: true);
writtenCount += written;
return finalBuffer.AsSpan(0, writtenCount).ToArray();
}
finally
{
ArrayPool<byte>.Shared.Return(finalBuffer);
}
}
public void CopyTo(in IBufferWriter<byte> 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<byte>.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<byte>.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<byte>.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<byte>.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<byte>.Empty, ref memoryPackWriter, initialLength: finalBlockLength, isFinalBlock: true);
}
finally
{
encoder.Dispose();
}
}
static int CompressCore(ref BrotliEncoder encoder, ReadOnlySpan<byte> source, ref IBufferWriter<byte> 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<byte> 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 62473f8441644d1479405f2eb8f863c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte> Decompress(ReadOnlySpan<byte> compressedSpan)
{
return Decompress(compressedSpan, out _);
}
public ReadOnlySequence<byte> Decompress(ReadOnlySpan<byte> 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<byte> Decompress(ReadOnlySequence<byte> compressedSequence)
{
return Decompress(compressedSequence, out _);
}
public ReadOnlySequence<byte> Decompress(ReadOnlySequence<byte> 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<byte> 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<byte>.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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe3786d11daa23f4488fa639754af3a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte[]>
{
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<int>();
reader.DangerousReadUnmanagedSpanView<byte>(out var isNull, out var compressedBuffer);
if (isNull)
{
value = null;
return;
}
if (compressedBuffer.Length == 0)
{
value = Array.Empty<byte>();
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<T> : MemoryPackFormatter<T>
{
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<BrotliCompressor, IBufferWriter<byte>>(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<byte> 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 45b39997d100c0848bcdb691400b2c1f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Utf8StringFormatter, string>
{
public override Utf8StringFormatter GetFormatter()
{
return Utf8StringFormatter.Default;
}
}
public sealed class Utf16StringFormatterAttribute : MemoryPackCustomFormatterAttribute<Utf16StringFormatter, string>
{
public override Utf16StringFormatter GetFormatter()
{
return Utf16StringFormatter.Default;
}
}
public sealed class OrdinalIgnoreCaseStringDictionaryFormatter<TValue> : MemoryPackCustomFormatterAttribute<DictionaryFormatter<string, TValue?>, Dictionary<string, TValue?>>
{
static readonly DictionaryFormatter<string, TValue?> formatter = new DictionaryFormatter<string, TValue?>(StringComparer.OrdinalIgnoreCase);
public override DictionaryFormatter<string, TValue?> GetFormatter()
{
return formatter;
}
}
public sealed class InternStringFormatterAttribute : MemoryPackCustomFormatterAttribute<InternStringFormatter, string>
{
public override InternStringFormatter GetFormatter()
{
return InternStringFormatter.Default;
}
}
public sealed class BitPackFormatterAttribute : MemoryPackCustomFormatterAttribute<BitPackFormatter, bool[]>
{
public override BitPackFormatter GetFormatter()
{
return BitPackFormatter.Default;
}
}
public sealed class BrotliFormatterAttribute : MemoryPackCustomFormatterAttribute<BrotliFormatter, byte[]>
{
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<T> : MemoryPackCustomFormatterAttribute<BrotliFormatter<T>, 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<T> GetFormatter()
{
return new BrotliFormatter<T>(CompressionLevel, Window);
}
}
public sealed class BrotliStringFormatterAttribute : MemoryPackCustomFormatterAttribute<BrotliStringFormatter, string>
{
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<T> : MemoryPackCustomFormatterAttribute<MemoryPoolFormatter<T>, Memory<T?>>
{
static readonly MemoryPoolFormatter<T> formatter = new MemoryPoolFormatter<T>();
public override MemoryPoolFormatter<T> GetFormatter()
{
return formatter;
}
}
public sealed class ReadOnlyMemoryPoolFormatterAttribute<T> : MemoryPackCustomFormatterAttribute<ReadOnlyMemoryPoolFormatter<T>, ReadOnlyMemory<T?>>
{
static readonly ReadOnlyMemoryPoolFormatter<T> formatter = new ReadOnlyMemoryPoolFormatter<T>();
public override ReadOnlyMemoryPoolFormatter<T> GetFormatter()
{
return formatter;
}
}
#endif
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1cc6f8595850d1c41ba61d06616f2d67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3c76a067728428843ae9ce827d31f1ec
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Type, Type> ArrayLikeFormatters = new Dictionary<Type, Type>(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<T> : MemoryPackFormatter<T[]>
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<T>(ref value);
}
}
[Preserve]
public sealed class DangerousUnmanagedArrayFormatter<T> : MemoryPackFormatter<T[]>
{
[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<T>(ref value);
}
}
[Preserve]
public sealed class ArrayFormatter<T> : MemoryPackFormatter<T?[]>
{
[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<T> : MemoryPackFormatter<ArraySegment<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ArraySegment<T?> value)
{
writer.WriteSpan(value.AsMemory().Span);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ArraySegment<T?> value)
{
var array = reader.ReadArray<T>();
value = (array == null) ? default : (ArraySegment<T?>)array;
}
}
[Preserve]
public sealed class MemoryFormatter<T> : MemoryPackFormatter<Memory<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Memory<T?> value)
{
writer.WriteSpan(value.Span);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref Memory<T?> value)
{
value = reader.ReadArray<T>();
}
}
[Preserve]
public sealed class ReadOnlyMemoryFormatter<T> : MemoryPackFormatter<ReadOnlyMemory<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyMemory<T?> value)
{
writer.WriteSpan(value.Span);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyMemory<T?> value)
{
value = reader.ReadArray<T>();
}
}
[Preserve]
public sealed class ReadOnlySequenceFormatter<T> : MemoryPackFormatter<ReadOnlySequence<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlySequence<T?> 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<T?> value)
{
var array = reader.ReadArray<T>();
value = (array == null) ? default : new ReadOnlySequence<T?>(array);
}
}
[Preserve]
public sealed class MemoryPoolFormatter<T> : MemoryPackFormatter<Memory<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Memory<T?> value)
{
writer.WriteSpan(value.Span);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref Memory<T?> value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
if (length == 0)
{
value = Memory<T?>.Empty;
return;
}
var memory = ArrayPool<T?>.Shared.Rent(length).AsMemory(0, length);
var span = memory.Span;
reader.ReadSpanWithoutReadLengthHeader(length, ref span);
value = memory;
}
}
[Preserve]
public sealed class ReadOnlyMemoryPoolFormatter<T> : MemoryPackFormatter<ReadOnlyMemory<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ReadOnlyMemory<T?> value)
{
writer.WriteSpan(value.Span);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ReadOnlyMemory<T?> value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
if (length == 0)
{
value = Memory<T?>.Empty;
return;
}
var memory = ArrayPool<T?>.Shared.Rent(length).AsMemory(0, length);
var span = memory.Span;
reader.ReadSpanWithoutReadLengthHeader(length, ref span);
value = memory;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ea47c22508b03445aabd57919531dc4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<BigInteger>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref BigInteger value)
{
#if !UNITY_2021_2_OR_NEWER
Span<byte> 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85c3a3fc180ed724798da6a6bd7c8635
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<BitArray>
{
// 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<BitArray, BitArrayView>(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<BitArray, BitArrayView>(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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7910d03f8a5023479d0bf2968f56267
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e648f2f021a720e45a7fda5bddd7aae9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<CultureInfo>
{
// 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20da488211e109640859d46ab47e442d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<T>
where T : class
{
readonly Dictionary<Type, ushort> typeToTag;
readonly Dictionary<ushort, Type> 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));
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6edda14b6f541844284c998396cafa2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<TCollection, TElement> : MemoryPackFormatter<TCollection?>
where TCollection : ICollection<TElement?>, new()
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref TCollection? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var formatter = writer.GetFormatter<TElement?>();
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<TElement?>();
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<TSet, TElement> : MemoryPackFormatter<TSet?>
where TSet : ISet<TElement?>
{
[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<TElement?>();
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<TElement?>();
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<TSet, TElement> : GenericSetFormatterBase<TSet, TElement>
where TSet : ISet<TElement?>, new()
{
protected override TSet CreateSet()
{
return new();
}
}
[Preserve]
public abstract class GenericDictionaryFormatterBase<TDictionary, TKey, TValue> : MemoryPackFormatter<TDictionary?>
where TKey : notnull
where TDictionary : IDictionary<TKey, TValue?>
{
[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<TKey>();
var valueFormatter = writer.GetFormatter<TValue>();
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<TKey>();
var valueFormatter = reader.GetFormatter<TValue>();
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<TDictionary, TKey, TValue> : GenericDictionaryFormatterBase<TDictionary, TKey, TValue>
where TKey : notnull
where TDictionary : IDictionary<TKey, TValue?>, new()
{
[Preserve]
protected override TDictionary CreateDictionary()
{
return new();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b0ee256b8ba5bf44904e20cbfd830e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Type, Type> 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<TCollection, TElement>(ref MemoryPackWriter writer, [NotNullWhen(false)] ref TCollection? value)
where TCollection : IEnumerable<TElement>
#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<TElement?> list)
{
writer.WriteSpan(CollectionsMarshal.AsSpan(list));
return true;
}
#endif
return false;
}
public static void SerializeCollection<TCollection, TElement>(ref MemoryPackWriter writer, ref TCollection? value)
where TCollection : ICollection<TElement>
#if NET7_0_OR_GREATER
#else
#endif
{
if (TrySerializeOptimized<TCollection, TElement>(ref writer, ref value)) return;
var formatter = writer.GetFormatter<TElement>();
writer.WriteCollectionHeader(value.Count);
foreach (var item in value)
{
var v = item;
formatter.Serialize(ref writer, ref v!);
}
}
public static void SerializeReadOnlyCollection<TCollection, TElement>(ref MemoryPackWriter writer, ref TCollection? value)
where TCollection : IReadOnlyCollection<TElement>
#if NET7_0_OR_GREATER
#else
#endif
{
if (TrySerializeOptimized<TCollection, TElement>(ref writer, ref value)) return;
var formatter = writer.GetFormatter<TElement>();
writer.WriteCollectionHeader(value.Count);
foreach (var item in value)
{
var v = item;
formatter.Serialize(ref writer, ref v!);
}
}
public static List<T?>? ReadList<T>(ref MemoryPackReader reader)
{
var formatter = reader.GetFormatter<List<T?>>();
List<T?>? v = default;
formatter.Deserialize(ref reader, ref v);
return v;
}
}
[Preserve]
public sealed class InterfaceEnumerableFormatter<T> : MemoryPackFormatter<IEnumerable<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IEnumerable<T?>? value)
{
if (TrySerializeOptimized<IEnumerable<T?>, T?>(ref writer, ref value)) return;
if (value.TryGetNonEnumeratedCountEx(out var count))
{
var formatter = writer.GetFormatter<T?>();
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<ReusableLinkedArrayBufferWriter, IBufferWriter<byte>>(ref tempBuffer), writer.OptionalState);
count = 0;
var formatter = writer.GetFormatter<T?>();
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<T?>? value)
{
value = reader.ReadArray<T?>();
}
}
[Preserve]
public sealed class InterfaceCollectionFormatter<T> : MemoryPackFormatter<ICollection<T?>>
{
static InterfaceCollectionFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<List<T?>>())
{
MemoryPackFormatterProvider.Register(new ListFormatter<T>());
}
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ICollection<T?>? value)
{
SerializeCollection<ICollection<T?>, T?>(ref writer, ref value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ICollection<T?>? value)
{
value = ReadList<T?>(ref reader);
}
}
[Preserve]
public sealed class InterfaceReadOnlyCollectionFormatter<T> : MemoryPackFormatter<IReadOnlyCollection<T?>>
{
static InterfaceReadOnlyCollectionFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<List<T?>>())
{
MemoryPackFormatterProvider.Register(new ListFormatter<T>());
}
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyCollection<T?>? value)
{
SerializeReadOnlyCollection<IReadOnlyCollection<T?>, T?>(ref writer, ref value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlyCollection<T?>? value)
{
value = ReadList<T?>(ref reader);
}
}
[Preserve]
public sealed class InterfaceListFormatter<T> : MemoryPackFormatter<IList<T?>>
{
static InterfaceListFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<List<T?>>())
{
MemoryPackFormatterProvider.Register(new ListFormatter<T>());
}
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IList<T?>? value)
{
SerializeCollection<IList<T?>, T?>(ref writer, ref value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref IList<T?>? value)
{
value = ReadList<T?>(ref reader);
}
}
[Preserve]
public sealed class InterfaceReadOnlyListFormatter<T> : MemoryPackFormatter<IReadOnlyList<T?>>
{
static InterfaceReadOnlyListFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<List<T?>>())
{
MemoryPackFormatterProvider.Register(new ListFormatter<T>());
}
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyList<T?>? value)
{
SerializeReadOnlyCollection<IReadOnlyList<T?>, T?>(ref writer, ref value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref IReadOnlyList<T?>? value)
{
value = ReadList<T?>(ref reader);
}
}
[Preserve]
public sealed class InterfaceDictionaryFormatter<TKey, TValue> : MemoryPackFormatter<IDictionary<TKey, TValue?>>
where TKey : notnull
{
readonly IEqualityComparer<TKey>? equalityComparer;
public InterfaceDictionaryFormatter()
: this(null)
{
}
public InterfaceDictionaryFormatter(IEqualityComparer<TKey>? equalityComparer)
{
this.equalityComparer = equalityComparer;
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IDictionary<TKey, TValue?>? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var keyFormatter = writer.GetFormatter<TKey>();
var valueFormatter = writer.GetFormatter<TValue>();
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<TKey, TValue?>? value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
var dict = new Dictionary<TKey, TValue?>(equalityComparer);
var keyFormatter = reader.GetFormatter<TKey>();
var valueFormatter = reader.GetFormatter<TValue>();
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<TKey, TValue> : MemoryPackFormatter<IReadOnlyDictionary<TKey, TValue?>>
where TKey : notnull
{
readonly IEqualityComparer<TKey>? equalityComparer;
public InterfaceReadOnlyDictionaryFormatter()
: this(null)
{
}
public InterfaceReadOnlyDictionaryFormatter(IEqualityComparer<TKey>? equalityComparer)
{
this.equalityComparer = equalityComparer;
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlyDictionary<TKey, TValue?>? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var keyFormatter = writer.GetFormatter<TKey>();
var valueFormatter = writer.GetFormatter<TValue>();
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<TKey, TValue?>? value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
var dict = new Dictionary<TKey, TValue?>(equalityComparer);
var keyFormatter = reader.GetFormatter<TKey>();
var valueFormatter = reader.GetFormatter<TValue>();
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<TKey, TElement> : MemoryPackFormatter<ILookup<TKey, TElement>>
where TKey : notnull
{
static InterfaceLookupFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<IGrouping<TKey, TElement>>())
{
MemoryPackFormatterProvider.Register(new InterfaceGroupingFormatter<TKey, TElement>());
}
}
readonly IEqualityComparer<TKey>? equalityComparer;
public InterfaceLookupFormatter()
: this(null)
{
}
public InterfaceLookupFormatter(IEqualityComparer<TKey>? equalityComparer)
{
this.equalityComparer = equalityComparer;
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ILookup<TKey, TElement>? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var formatter = writer.GetFormatter<IGrouping<TKey, TElement>>();
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<TKey, TElement>? value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
var dict = new Dictionary<TKey, IGrouping<TKey, TElement>>(equalityComparer);
var formatter = reader.GetFormatter<IGrouping<TKey, TElement>>();
for (int i = 0; i < length; i++)
{
IGrouping<TKey, TElement>? item = default;
formatter.Deserialize(ref reader, ref item);
if (item != null)
{
dict.Add(item.Key, item);
}
}
value = new Lookup<TKey, TElement>(dict);
}
}
[Preserve]
public sealed class InterfaceGroupingFormatter<TKey, TElement> : MemoryPackFormatter<IGrouping<TKey, TElement>>
where TKey : notnull
{
// serialize as {key, [collection]}
static InterfaceGroupingFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<IEnumerable<TElement>>())
{
MemoryPackFormatterProvider.Register(new InterfaceEnumerableFormatter<TElement>());
}
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IGrouping<TKey, TElement>? value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WriteObjectHeader(2);
writer.WriteValue(value.Key);
writer.WriteValue<IEnumerable<TElement>>(value); // write as IEnumerable<TElement>
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref IGrouping<TKey, TElement>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 2) MemoryPackSerializationException.ThrowInvalidPropertyCount(2, count);
var key = reader.ReadValue<TKey>();
var values = reader.ReadArray<TElement>() as IEnumerable<TElement>;
if (key == null) MemoryPackSerializationException.ThrowDeserializeObjectIsNull(nameof(key));
if (values == null) MemoryPackSerializationException.ThrowDeserializeObjectIsNull(nameof(values));
value = new Grouping<TKey, TElement>(key, values);
}
}
[Preserve]
public sealed class InterfaceSetFormatter<T> : MemoryPackFormatter<ISet<T?>>
{
static InterfaceSetFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<HashSet<T>>())
{
MemoryPackFormatterProvider.Register(new HashSetFormatter<T>());
}
}
readonly IEqualityComparer<T?>? equalityComparer;
public InterfaceSetFormatter()
: this(null)
{
}
public InterfaceSetFormatter(IEqualityComparer<T?>? equalityComparer)
{
this.equalityComparer = equalityComparer;
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ISet<T?>? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var formatter = writer.GetFormatter<T>();
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<T?>? value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
var set = new HashSet<T?>(length, equalityComparer);
var formatter = reader.GetFormatter<T>();
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<T> : MemoryPackFormatter<IReadOnlySet<T?>>
{
static InterfaceReadOnlySetFormatter()
{
if (!MemoryPackFormatterProvider.IsRegistered<HashSet<T>>())
{
MemoryPackFormatterProvider.Register(new HashSetFormatter<T>());
}
}
readonly IEqualityComparer<T?>? equalityComparer;
public InterfaceReadOnlySetFormatter()
: this(null)
{
}
public InterfaceReadOnlySetFormatter(IEqualityComparer<T?>? equalityComparer)
{
this.equalityComparer = equalityComparer;
}
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref IReadOnlySet<T?>? value)
{
if (value == null)
{
writer.WriteNullCollectionHeader();
return;
}
var formatter = writer.GetFormatter<T>();
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<T?>? value)
{
if (!reader.TryReadCollectionHeader(out var length))
{
value = null;
return;
}
var set = new HashSet<T?>(length, equalityComparer);
var formatter = reader.GetFormatter<T>();
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<TKey, TElement> : IGrouping<TKey, TElement>
{
readonly TKey key;
readonly IEnumerable<TElement> elements;
public Grouping(TKey key, IEnumerable<TElement> elements)
{
this.key = key;
this.elements = elements;
}
public TKey Key
{
get
{
return this.key;
}
}
public IEnumerator<TElement> GetEnumerator()
{
return this.elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.elements.GetEnumerator();
}
}
[Preserve]
internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
where TKey : notnull
{
readonly Dictionary<TKey, IGrouping<TKey, TElement>> groupings;
public Lookup(Dictionary<TKey, IGrouping<TKey, TElement>> groupings)
{
this.groupings = groupings;
}
public IEnumerable<TElement> 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<IGrouping<TKey, TElement>> GetEnumerator()
{
return this.groupings.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.groupings.Values.GetEnumerator();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 92a5c3e606f68e940a5504e80e372051
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<TKey, TValue>(IMemoryPackFormatter<TKey> keyFormatter, IMemoryPackFormatter<TValue> valueFormatter, ref MemoryPackWriter writer, KeyValuePair<TKey?, TValue?> value)
#if NET7_0_OR_GREATER
#else
#endif
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<KeyValuePair<TKey?, TValue?>>())
{
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<TKey, TValue>(IMemoryPackFormatter<TKey> keyFormatter, IMemoryPackFormatter<TValue> valueFormatter, ref MemoryPackReader reader, out TKey? key, out TValue? value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<KeyValuePair<TKey?, TValue?>>())
{
reader.DangerousReadUnmanaged(out KeyValuePair<TKey?, TValue?> 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<TKey, TValue> : MemoryPackFormatter<KeyValuePair<TKey?, TValue?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref KeyValuePair<TKey?, TValue?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<KeyValuePair<TKey?, TValue?>>())
{
writer.DangerousWriteUnmanaged(value);
return;
}
writer.WriteValue(value.Key);
writer.WriteValue(value.Value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref KeyValuePair<TKey?, TValue?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<KeyValuePair<TKey?, TValue?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new KeyValuePair<TKey?, TValue?>(
reader.ReadValue<TKey>(),
reader.ReadValue<TValue>()
);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f407ce074ce08af448c71d52ab5ef2c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<Lazy<T?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Lazy<T?>? value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WriteObjectHeader(1);
writer.WriteValue(value.Value);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref Lazy<T?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count);
var v = reader.ReadValue<T>();
value = new Lazy<T?>(v);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 435e06feb1c6e99469622c788eb68163
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<T>
where T : IMemoryPackable<T>
{
[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
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86918186878d8454db7dc10ffc57057d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<T?[,]>
{
// {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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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<T> : MemoryPackFormatter<T?[,,]>
{
// {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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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<T> : MemoryPackFormatter<T?[,,,]>
{
// {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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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<T?>())
{
var byteCount = Unsafe.SizeOf<T>() * 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<T?>();
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]);
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31ec28888c1521f45a5e0eb1ca226149
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<T?>
where T : struct
{
// Nullable<T> 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<T>())
{
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<T>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count);
value = reader.ReadValue<T>();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5cbe20000eeecfe429b3f80fca2ba176
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<StringBuilder>
{
[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<char, byte>(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<byte, char>(ref p), length);
value.Append(src);
reader.Advance(size);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 78f865f986bf7a844bcb6d3474b401a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<string>
{
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<string>
{
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<string>
{
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<string>
{
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<string>
{
[ThreadStatic]
static StrongBox<int>? 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<int>();
}
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>((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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07af9b01eb2a94d439eba905a7b72deb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<TimeZoneInfo>
{
[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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ec2daec89486cc439549ac3139a872a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Type, Type> TupleFormatters = new Dictionary<Type, Type>(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<T1> : MemoryPackFormatter<Tuple<T1?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?>? value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WriteObjectHeader(1);
writer.WriteValue(value.Item1);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref Tuple<T1?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 1) MemoryPackSerializationException.ThrowInvalidPropertyCount(1, count);
value = new Tuple<T1?>(
reader.ReadValue<T1>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2> : MemoryPackFormatter<Tuple<T1?, T2?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?>? 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<T1?, T2?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 2) MemoryPackSerializationException.ThrowInvalidPropertyCount(2, count);
value = new Tuple<T1?, T2?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3> : MemoryPackFormatter<Tuple<T1?, T2?, T3?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?>? 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<T1?, T2?, T3?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 3) MemoryPackSerializationException.ThrowInvalidPropertyCount(3, count);
value = new Tuple<T1?, T2?, T3?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3, T4> : MemoryPackFormatter<Tuple<T1?, T2?, T3?, T4?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?, T4?>? 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<T1?, T2?, T3?, T4?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 4) MemoryPackSerializationException.ThrowInvalidPropertyCount(4, count);
value = new Tuple<T1?, T2?, T3?, T4?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3, T4, T5> : MemoryPackFormatter<Tuple<T1?, T2?, T3?, T4?, T5?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?, T4?, T5?>? 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<T1?, T2?, T3?, T4?, T5?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 5) MemoryPackSerializationException.ThrowInvalidPropertyCount(5, count);
value = new Tuple<T1?, T2?, T3?, T4?, T5?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3, T4, T5, T6> : MemoryPackFormatter<Tuple<T1?, T2?, T3?, T4?, T5?, T6?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?, T4?, T5?, T6?>? 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<T1?, T2?, T3?, T4?, T5?, T6?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 6) MemoryPackSerializationException.ThrowInvalidPropertyCount(6, count);
value = new Tuple<T1?, T2?, T3?, T4?, T5?, T6?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3, T4, T5, T6, T7> : MemoryPackFormatter<Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>? 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<T1?, T2?, T3?, T4?, T5?, T6?, T7?>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 7) MemoryPackSerializationException.ThrowInvalidPropertyCount(7, count);
value = new Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>(),
reader.ReadValue<T7>()
);
}
}
[Preserve]
public sealed class TupleFormatter<T1, T2, T3, T4, T5, T6, T7, TRest> : MemoryPackFormatter<Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>>
where TRest : notnull
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>? 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<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>? value)
{
if (!reader.TryReadObjectHeader(out var count))
{
value = null;
return;
}
if (count != 8) MemoryPackSerializationException.ThrowInvalidPropertyCount(8, count);
value = new Tuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>(),
reader.ReadValue<T7>(),
reader.ReadValue<TRest>()!
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1> : MemoryPackFormatter<ValueTuple<T1?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?>>())
{
writer.DangerousWriteUnmanaged(value);
return;
}
writer.WriteValue(value.Item1);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple<T1?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?>(
reader.ReadValue<T1>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2> : MemoryPackFormatter<ValueTuple<T1?, T2?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?>>())
{
writer.DangerousWriteUnmanaged(value);
return;
}
writer.WriteValue(value.Item1);
writer.WriteValue(value.Item2);
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref ValueTuple<T1?, T2?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?>>())
{
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<T1?, T2?, T3?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3, T4> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?, T4?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?, T4?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?>>())
{
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<T1?, T2?, T3?, T4?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?, T4?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3, T4, T5> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?, T4?, T5?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?, T4?, T5?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?>>())
{
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<T1?, T2?, T3?, T4?, T5?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?, T4?, T5?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3, T4, T5, T6> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?>>())
{
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<T1?, T2?, T3?, T4?, T5?, T6?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3, T4, T5, T6, T7> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>>())
{
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<T1?, T2?, T3?, T4?, T5?, T6?, T7?> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>(),
reader.ReadValue<T7>()
);
}
}
[Preserve]
public sealed class ValueTupleFormatter<T1, T2, T3, T4, T5, T6, T7, TRest> : MemoryPackFormatter<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>>
where TRest : struct
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>>())
{
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<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest> value)
{
if (!System.Runtime.CompilerServices.RuntimeHelpers.IsReferenceOrContainsReferences<ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>>())
{
reader.DangerousReadUnmanaged(out value);
return;
}
value = new ValueTuple<T1?, T2?, T3?, T4?, T5?, T6?, T7?, TRest>(
reader.ReadValue<T1>(),
reader.ReadValue<T2>(),
reader.ReadValue<T3>(),
reader.ReadValue<T4>(),
reader.ReadValue<T5>(),
reader.ReadValue<T6>(),
reader.ReadValue<T7>(),
reader.ReadValue<TRest>()!
);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82746260603df5a45a8369e256a78e75
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Type>
{
// 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1f7f7bddb1670c4ea52c7efc399000a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : MemoryPackFormatter<T>
where T : unmanaged
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref T value)
{
Unsafe.WriteUnaligned(ref writer.GetSpanReference(Unsafe.SizeOf<T>()), value);
writer.Advance(Unsafe.SizeOf<T>());
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref T value)
{
value = Unsafe.ReadUnaligned<T>(ref reader.GetSpanReference(Unsafe.SizeOf<T>()));
reader.Advance(Unsafe.SizeOf<T>());
}
}
[Preserve]
public sealed class DangerousUnmanagedFormatter<T> : MemoryPackFormatter<T>
{
[Preserve]
public override void Serialize(ref MemoryPackWriter writer, ref T? value)
{
Unsafe.WriteUnaligned(ref writer.GetSpanReference(Unsafe.SizeOf<T>()), value);
writer.Advance(Unsafe.SizeOf<T>());
}
[Preserve]
public override void Deserialize(ref MemoryPackReader reader, ref T? value)
{
value = Unsafe.ReadUnaligned<T>(ref reader.GetSpanReference(Unsafe.SizeOf<T>()));
reader.Advance(Unsafe.SizeOf<T>());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87c49cf15480faa4aa13b0027ba10b2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Uri>
{
// 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 815be7f2c6d469548b382f4531c8d4d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Version>
{
// 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 65775f54fba192b47a6014ccdccf27ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T>
{
[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<T> : IMemoryPackFormatter<T>, 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b17111635233244459e4c2668df6e763
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T> : 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
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 53c6fb0170766704aa3ec4b1aedf050d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2f8ccfb431cbe7f4299e0245f9c74309
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T>(this IEnumerable<T> value, out int count)
{
// TryGetNonEnumeratedCount is not check IReadOnlyCollection<T> 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<T> collection)
{
count = collection.Count;
return true;
}
#endif
if (value is IReadOnlyCollection<T> readOnlyCollection)
{
count = readOnlyCollection.Count;
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b7de601a63709940b09c18eb34cf772
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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>
{
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<byte> 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<byte> 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61f475a704e250d4ab0dd882130e9fdd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 927c0eadb944275499836693dc80f88b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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>(T[] array)
{
return ref MemoryMarshal.GetReference(array.AsSpan());
}
// GC
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T[] AllocateUninitializedArray<T>(int length, bool pinned = false)
{
return new T[length];
}
}
#endif
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2909cb9ffb605ae47b659f8140c62ca9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d985418ff3c30b2429f7cdc878e0ddf9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<ReusableLinkedArrayBufferWriter> queue = new ConcurrentQueue<ReusableLinkedArrayBufferWriter>();
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<byte>
{
const int InitialBufferSize = 262144; // 256K(32768, 65536, 131072, 262144)
static readonly byte[] noUseFirstBufferSentinel = new byte[0];
List<BufferSegment> 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<BufferSegment>();
this.firstBuffer = useFirstBuffer
? AllocateUninitializedArray<byte>(InitialBufferSize, pinned)
: noUseFirstBufferSentinel;
this.firstBufferWritten = 0;
this.current = default;
this.nextBufferSize = InitialBufferSize;
this.totalWritten = 0;
}
public byte[] DangerousGetFirstBuffer() => firstBuffer;
public Memory<byte> GetMemory(int sizeHint = 0)
{
// MemoryPack don't use GetMemory.
throw new NotSupportedException();
}
public Span<byte> 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<byte>();
var result = AllocateUninitializedArray<byte>(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<Memory<byte>>
{
ReusableLinkedArrayBufferWriter parent;
State state;
Memory<byte> current;
List<BufferSegment>.Enumerator buffersEnumerator;
public Enumerator(ReusableLinkedArrayBufferWriter parent)
{
this.parent = parent;
this.state = default;
this.current = default;
this.buffersEnumerator = default;
}
public Memory<byte> 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<byte> WrittenBuffer => buffer.AsSpan(0, written);
public Memory<byte> WrittenMemory => buffer.AsMemory(0, written);
public Span<byte> FreeBuffer => buffer.AsSpan(written);
public BufferSegment(int size)
{
buffer = ArrayPool<byte>.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<byte>.Shared.Return(buffer);
}
buffer = null!;
written = 0;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42122ccd6d229c5478197bd7fbce99d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<ReusableReadOnlySequenceBuilder> 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<Segment> segmentPool;
readonly List<Segment> list;
public ReusableReadOnlySequenceBuilder()
{
list = new();
segmentPool = new Stack<Segment>();
}
public void Add(ReadOnlyMemory<byte> buffer, bool returnToPool)
{
if (!segmentPool.TryPop(out var segment))
{
segment = new Segment();
}
segment.SetBuffer(buffer, returnToPool);
list.Add(segment);
}
public bool TryGetSingleMemory(out ReadOnlyMemory<byte> memory)
{
if (list.Count == 1)
{
memory = list[0].Memory;
return true;
}
memory = default;
return false;
}
public ReadOnlySequence<byte> Build()
{
if (list.Count == 0)
{
return ReadOnlySequence<byte>.Empty;
}
if (list.Count == 1)
{
return new ReadOnlySequence<byte>(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<byte>(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<byte>
{
bool returnToPool;
public Segment()
{
returnToPool = false;
}
public void SetBuffer(ReadOnlyMemory<byte> buffer, bool returnToPool)
{
Memory = buffer;
this.returnToPool = returnToPool;
}
public void Reset()
{
if (returnToPool)
{
if (MemoryMarshal.TryGetArray(Memory, out var segment) && segment.Array != null)
{
ArrayPool<byte>.Shared.Return(segment.Array, clearArray: false);
}
}
Memory = default;
RunningIndex = 0;
Next = null;
}
public void SetRunningIndexAndNext(long runningIndex, Segment? nextSegment)
{
RunningIndex = runningIndex;
Next = nextSegment;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b700925f1ee40614ca7c44623074da57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T>()
{
return Cache<T>.IsReferenceOrNullable;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TypeKind TryGetUnmanagedSZArrayElementSizeOrMemoryPackableFixedSize<T>(out int size)
{
if (Cache<T>.IsUnmanagedSZArray)
{
size = Cache<T>.UnmanagedSZArrayElementSize;
return TypeKind.UnmanagedSZArray;
}
else
{
if (Cache<T>.IsFixedSizeMemoryPackable)
{
size = Cache<T>.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<T>
{
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
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 329bffde10972564f8819da18337cbc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte> property
internal static ReadOnlySpan<byte> NullCollectionData => new byte[] { 255, 255, 255, 255 }; // -1
internal static ReadOnlySpan<byte> ZeroCollectionData => new byte[] { 0, 0, 0, 0 }; // 0
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 47fb89e30884e9940988b0d3021773f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<SByte>());
Register(new UnmanagedArrayFormatter<SByte>());
Register(new NullableFormatter<SByte>());
Register(new UnmanagedFormatter<Byte>());
Register(new UnmanagedArrayFormatter<Byte>());
Register(new NullableFormatter<Byte>());
Register(new UnmanagedFormatter<Int16>());
Register(new UnmanagedArrayFormatter<Int16>());
Register(new NullableFormatter<Int16>());
Register(new UnmanagedFormatter<UInt16>());
Register(new UnmanagedArrayFormatter<UInt16>());
Register(new NullableFormatter<UInt16>());
Register(new UnmanagedFormatter<Int32>());
Register(new UnmanagedArrayFormatter<Int32>());
Register(new NullableFormatter<Int32>());
Register(new UnmanagedFormatter<UInt32>());
Register(new UnmanagedArrayFormatter<UInt32>());
Register(new NullableFormatter<UInt32>());
Register(new UnmanagedFormatter<Int64>());
Register(new UnmanagedArrayFormatter<Int64>());
Register(new NullableFormatter<Int64>());
Register(new UnmanagedFormatter<UInt64>());
Register(new UnmanagedArrayFormatter<UInt64>());
Register(new NullableFormatter<UInt64>());
Register(new UnmanagedFormatter<Char>());
Register(new UnmanagedArrayFormatter<Char>());
Register(new NullableFormatter<Char>());
Register(new UnmanagedFormatter<Single>());
Register(new UnmanagedArrayFormatter<Single>());
Register(new NullableFormatter<Single>());
Register(new UnmanagedFormatter<Double>());
Register(new UnmanagedArrayFormatter<Double>());
Register(new NullableFormatter<Double>());
Register(new UnmanagedFormatter<Decimal>());
Register(new UnmanagedArrayFormatter<Decimal>());
Register(new NullableFormatter<Decimal>());
Register(new UnmanagedFormatter<Boolean>());
Register(new UnmanagedArrayFormatter<Boolean>());
Register(new NullableFormatter<Boolean>());
Register(new UnmanagedFormatter<IntPtr>());
Register(new UnmanagedArrayFormatter<IntPtr>());
Register(new NullableFormatter<IntPtr>());
Register(new UnmanagedFormatter<UIntPtr>());
Register(new UnmanagedArrayFormatter<UIntPtr>());
Register(new NullableFormatter<UIntPtr>());
Register(new UnmanagedFormatter<DateTime>());
Register(new UnmanagedArrayFormatter<DateTime>());
Register(new NullableFormatter<DateTime>());
Register(new UnmanagedFormatter<DateTimeOffset>());
Register(new UnmanagedArrayFormatter<DateTimeOffset>());
Register(new NullableFormatter<DateTimeOffset>());
Register(new UnmanagedFormatter<TimeSpan>());
Register(new UnmanagedArrayFormatter<TimeSpan>());
Register(new NullableFormatter<TimeSpan>());
Register(new UnmanagedFormatter<Guid>());
Register(new UnmanagedArrayFormatter<Guid>());
Register(new NullableFormatter<Guid>());
Register(new UnmanagedFormatter<Complex>());
Register(new UnmanagedArrayFormatter<Complex>());
Register(new NullableFormatter<Complex>());
Register(new UnmanagedFormatter<Plane>());
Register(new UnmanagedArrayFormatter<Plane>());
Register(new NullableFormatter<Plane>());
Register(new UnmanagedFormatter<Quaternion>());
Register(new UnmanagedArrayFormatter<Quaternion>());
Register(new NullableFormatter<Quaternion>());
Register(new UnmanagedFormatter<Matrix3x2>());
Register(new UnmanagedArrayFormatter<Matrix3x2>());
Register(new NullableFormatter<Matrix3x2>());
Register(new UnmanagedFormatter<Matrix4x4>());
Register(new UnmanagedArrayFormatter<Matrix4x4>());
Register(new NullableFormatter<Matrix4x4>());
Register(new UnmanagedFormatter<Vector2>());
Register(new UnmanagedArrayFormatter<Vector2>());
Register(new NullableFormatter<Vector2>());
Register(new UnmanagedFormatter<Vector3>());
Register(new UnmanagedArrayFormatter<Vector3>());
Register(new NullableFormatter<Vector3>());
Register(new UnmanagedFormatter<Vector4>());
Register(new UnmanagedArrayFormatter<Vector4>());
Register(new NullableFormatter<Vector4>());
#if NET7_0_OR_GREATER
Register(new UnmanagedFormatter<Rune>());
Register(new UnmanagedArrayFormatter<Rune>());
Register(new NullableFormatter<Rune>());
Register(new UnmanagedFormatter<DateOnly>());
Register(new UnmanagedArrayFormatter<DateOnly>());
Register(new NullableFormatter<DateOnly>());
Register(new UnmanagedFormatter<TimeOnly>());
Register(new UnmanagedArrayFormatter<TimeOnly>());
Register(new NullableFormatter<TimeOnly>());
Register(new UnmanagedFormatter<Half>());
Register(new UnmanagedArrayFormatter<Half>());
Register(new NullableFormatter<Half>());
Register(new UnmanagedFormatter<Int128>());
Register(new UnmanagedArrayFormatter<Int128>());
Register(new NullableFormatter<Int128>());
Register(new UnmanagedFormatter<UInt128>());
Register(new UnmanagedArrayFormatter<UInt128>());
Register(new NullableFormatter<UInt128>());
#endif
Register(new StringFormatter());
Register(new ArrayFormatter<String>());
Register(new VersionFormatter());
Register(new ArrayFormatter<Version>());
Register(new UriFormatter());
Register(new ArrayFormatter<Uri>());
Register(new TimeZoneInfoFormatter());
Register(new ArrayFormatter<TimeZoneInfo>());
Register(new BigIntegerFormatter());
Register(new ArrayFormatter<BigInteger>());
Register(new BitArrayFormatter());
Register(new ArrayFormatter<BitArray>());
Register(new StringBuilderFormatter());
Register(new ArrayFormatter<StringBuilder>());
Register(new TypeFormatter());
Register(new ArrayFormatter<Type>());
Register(new CultureInfoFormatter());
Register(new ArrayFormatter<CultureInfo>());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c06329799b27a34abe37d38dac0a197
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<Type, IMemoryPackFormatter> formatters = new ConcurrentDictionary<Type, IMemoryPackFormatter>(Environment.ProcessorCount, 150);
// custom generic formatters
static readonly ConcurrentDictionary<Type, Type> genericFormatterFactory = new ConcurrentDictionary<Type, Type>();
// custom generic collection formatters
static readonly ConcurrentDictionary<Type, Type> genericCollectionFormatterFactory = new ConcurrentDictionary<Type, Type>();
// generics known types
static readonly Dictionary<Type, Type> KnownGenericTypeFormatters = new Dictionary<Type, Type>(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<T>() => Check<T>.registered;
public static void Register<T>(MemoryPackFormatter<T> formatter)
{
Check<T>.registered = true; // avoid to call Cache() constructor called.
formatters[typeof(T)] = formatter;
Cache<T>.formatter = formatter;
}
#if NET7_0_OR_GREATER
public static void Register<T>()
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<TCollection, TElement>()
where TCollection : ICollection<TElement?>, new()
{
Register(new GenericCollectionFormatter<TCollection, TElement>());
}
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<TSet, TElement>()
where TSet : ISet<TElement?>, new()
{
Register(new GenericSetFormatter<TSet, TElement>());
}
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<TDictionary, TKey, TValue>()
where TKey : notnull
where TDictionary : IDictionary<TKey, TValue?>, new()
{
Register(new GenericDictionaryFormatter<TDictionary, TKey, TValue>());
}
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<T> GetFormatter<T>()
{
return Cache<T>.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<T>.formatter will set from method
return true;
}
return false;
}
static class Check<T>
{
public static bool registered;
}
static class Cache<T>
{
public static MemoryPackFormatter<T> formatter = default!;
static Cache()
{
if (Check<T>.registered) return;
try
{
var type = typeof(T);
if (TryInvokeRegisterFormatter(type))
{
return;
}
if (TypeHelpers.IsAnonymous(type))
{
formatter = new ErrorMemoryPackFormatter<T>("Serialize anonymous type is not supported, use record or tuple instead.");
goto END;
}
var typeIsReferenceOrContainsReferences = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
var f = CreateGenericFormatter(type, typeIsReferenceOrContainsReferences) as MemoryPackFormatter<T>;
formatter = f ?? new ErrorMemoryPackFormatter<T>();
}
catch (Exception ex)
{
formatter = new ErrorMemoryPackFormatter<T>(ex);
}
END:
formatters[typeof(T)] = formatter;
Check<T>.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<T>).
return null;
CREATE:
return Activator.CreateInstance(formatterType);
}
static Type? TryCreateGenericFormatterType(Type type, IDictionary<Type, Type> 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 <TCollection, TArgs> 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<T> : MemoryPackFormatter<T>
{
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));
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1200521b3b3b7344a1cfe3b1b58439a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<T1>(out T1 value1)
where T1 : unmanaged
{
var size = Unsafe.SizeOf<T1>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2>(out T1 value1, out T2 value2)
where T1 : unmanaged
where T2 : unmanaged
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3>(out T1 value1, out T2 value2, out T3 value3)
where T1 : unmanaged
where T2 : unmanaged
where T3 : unmanaged
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>() + Unsafe.SizeOf<T15>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>()));
value15 = Unsafe.ReadUnaligned<T15>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1>(out T1 value1)
{
var size = Unsafe.SizeOf<T1>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2>(out T1 value1, out T2 value2)
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3>(out T1 value1, out T2 value2, out T3 value3)
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4>(out T1 value1, out T2 value2, out T3 value3, out T4 value4)
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5)
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6>(out T1 value1, out T2 value2, out T3 value3, out T4 value4, out T5 value5, out T6 value6)
{
var size = Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>()));
Advance(size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DangerousReadUnmanaged<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(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<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>() + Unsafe.SizeOf<T15>();
ref var spanRef = ref GetSpanReference(size);
value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
value2 = Unsafe.ReadUnaligned<T2>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>()));
value3 = Unsafe.ReadUnaligned<T3>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>()));
value4 = Unsafe.ReadUnaligned<T4>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>()));
value5 = Unsafe.ReadUnaligned<T5>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>()));
value6 = Unsafe.ReadUnaligned<T6>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>()));
value7 = Unsafe.ReadUnaligned<T7>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>()));
value8 = Unsafe.ReadUnaligned<T8>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>()));
value9 = Unsafe.ReadUnaligned<T9>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>()));
value10 = Unsafe.ReadUnaligned<T10>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>()));
value11 = Unsafe.ReadUnaligned<T11>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>()));
value12 = Unsafe.ReadUnaligned<T12>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>()));
value13 = Unsafe.ReadUnaligned<T13>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>()));
value14 = Unsafe.ReadUnaligned<T14>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>()));
value15 = Unsafe.ReadUnaligned<T15>(ref Unsafe.Add(ref spanRef, Unsafe.SizeOf<T1>() + Unsafe.SizeOf<T2>() + Unsafe.SizeOf<T3>() + Unsafe.SizeOf<T4>() + Unsafe.SizeOf<T5>() + Unsafe.SizeOf<T6>() + Unsafe.SizeOf<T7>() + Unsafe.SizeOf<T8>() + Unsafe.SizeOf<T9>() + Unsafe.SizeOf<T10>() + Unsafe.SizeOf<T11>() + Unsafe.SizeOf<T12>() + Unsafe.SizeOf<T13>() + Unsafe.SizeOf<T14>()));
Advance(size);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5edf80b8ed9aae143b689d072859a209
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte> bufferSource;
readonly long totalLength;
#if NET7_0_OR_GREATER
ref byte bufferReference;
#else
ReadOnlySpan<byte> 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<byte> sequence, MemoryPackReaderOptionalState optionalState)
{
this.bufferSource = sequence.IsSingleSegment ? ReadOnlySequence<byte>.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<byte> buffer, MemoryPackReaderOptionalState optionalState)
{
this.bufferSource = ReadOnlySequence<byte>.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<byte>.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<byte>.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<byte> singleSource, out ReadOnlySequence<byte> remainingSource)
{
if (bufferSource.IsEmpty)
{
remainingSource = ReadOnlySequence<byte>.Empty;
#if NET7_0_OR_GREATER
singleSource = MemoryMarshal.CreateReadOnlySpan(ref bufferReference, bufferLength);
#else
singleSource = bufferReference;
#endif
return;
}
else
{
if (bufferSource.IsSingleSegment)
{
remainingSource = ReadOnlySequence<byte>.Empty;
singleSource = bufferSource.FirstSpan.Slice(advancedCount);
return;
}
singleSource = default;
remainingSource = bufferSource.Slice(advancedCount);
if (remainingSource.IsSingleSegment)
{
singleSource = remainingSource.FirstSpan;
remainingSource = ReadOnlySequence<byte>.Empty;
return;
}
return;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
if (rentBuffer != null)
{
ArrayPool<byte>.Shared.Return(rentBuffer);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IMemoryPackFormatter GetFormatter(Type type)
{
return MemoryPackFormatterProvider.GetFormatter(type);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IMemoryPackFormatter<T> GetFormatter<T>()
{
return MemoryPackFormatterProvider.GetFormatter<T>();
}
// 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<int>(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<ushort>(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<int>(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;
}
/// <summary>
/// no validate collection size, be careful to use.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool DangerousTryReadCollectionHeader(out int length)
{
length = Unsafe.ReadUnaligned<int>(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<byte, char>(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<int>(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>((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<T1>()
where T1 : unmanaged
{
var size = Unsafe.SizeOf<T1>();
ref var spanRef = ref GetSpanReference(size);
var value1 = Unsafe.ReadUnaligned<T1>(ref spanRef);
Advance(size);
return value1;
}
#if NET7_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadPackable<T>(ref T? value)
where T : IMemoryPackable<T>
{
T.Deserialize(ref this, ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T? ReadPackable<T>()
where T : IMemoryPackable<T>
{
T? value = default;
T.Deserialize(ref this, ref value);
return value;
}
#else
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadPackable<T>(ref T? value)
where T : IMemoryPackable<T>
{
ReadValue(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T? ReadPackable<T>()
where T : IMemoryPackable<T>
{
return ReadValue<T>();
}
#endif
// non packable, get formatter dynamically.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadValue<T>(ref T? value)
{
GetFormatter<T>().Deserialize(ref this, ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T? ReadValue<T>()
{
T? value = default;
GetFormatter<T>().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, T>(TFormatter formatter, ref T? value)
where TFormatter : IMemoryPackFormatter<T>
{
formatter.Deserialize(ref this, ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T? ReadValueWithFormatter<TFormatter, T>(TFormatter formatter)
where TFormatter : IMemoryPackFormatter<T>
{
T? value = default;
formatter.Deserialize(ref this, ref value);
return value;
}
#region ReadArray/Span
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T?[]? ReadArray<T>()
{
T?[]? value = default;
ReadArray(ref value);
return value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadArray<T>(ref T?[]? value)
{
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
DangerousReadUnmanagedArray(ref value);
return;
}
if (!TryReadCollectionHeader(out var length))
{
value = null;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
return;
}
// T[] support overwrite
if (value == null || value.Length != length)
{
value = new T[length];
}
var formatter = GetFormatter<T>();
for (int i = 0; i < length; i++)
{
formatter.Deserialize(ref this, ref value[i]);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadSpan<T>(ref Span<T?> value)
{
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
DangerousReadUnmanagedSpan(ref value);
return;
}
if (!TryReadCollectionHeader(out var length))
{
value = default;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
return;
}
if (value.Length != length)
{
value = new T[length];
}
var formatter = GetFormatter<T>();
for (int i = 0; i < length; i++)
{
formatter.Deserialize(ref this, ref value[i]);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T?[]? ReadPackableArray<T>()
where T : IMemoryPackable<T>
{
T?[]? value = default;
ReadPackableArray(ref value);
return value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadPackableArray<T>(ref T?[]? value)
where T : IMemoryPackable<T>
{
#if !NET7_0_OR_GREATER
ReadArray(ref value);
return;
#else
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
DangerousReadUnmanagedArray(ref value);
return;
}
if (!TryReadCollectionHeader(out var length))
{
value = null;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
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<T>(ref Span<T?> value)
where T : IMemoryPackable<T>
{
#if !NET7_0_OR_GREATER
ReadSpan(ref value);
return;
#else
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
DangerousReadUnmanagedSpan(ref value);
return;
}
if (!TryReadCollectionHeader(out var length))
{
value = default;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
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<T>()
where T : unmanaged
{
return DangerousReadUnmanagedArray<T>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanagedArray<T>(ref T[]? value)
where T : unmanaged
{
DangerousReadUnmanagedArray<T>(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadUnmanagedSpan<T>(ref Span<T> value)
where T : unmanaged
{
DangerousReadUnmanagedSpan<T>(ref value);
}
// T: should be unamanged type
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe T[]? DangerousReadUnmanagedArray<T>()
{
if (!TryReadCollectionHeader(out var length))
{
return null;
}
if (length == 0) return Array.Empty<T>();
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
var dest = AllocateUninitializedArray<T>(length);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<T, byte>(ref GetArrayDataReference(dest)), ref src, (uint)byteCount);
Advance(byteCount);
return dest;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void DangerousReadUnmanagedArray<T>(ref T[]? value)
{
if (!TryReadCollectionHeader(out var length))
{
value = null;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
return;
}
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
if (value == null || value.Length != length)
{
value = AllocateUninitializedArray<T>(length);
}
ref var dest = ref Unsafe.As<T, byte>(ref GetArrayDataReference(value));
Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount);
Advance(byteCount);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void DangerousReadUnmanagedSpan<T>(ref Span<T> value)
{
if (!TryReadCollectionHeader(out var length))
{
value = default;
return;
}
if (length == 0)
{
value = Array.Empty<T>();
return;
}
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
if (value == null || value.Length != length)
{
value = AllocateUninitializedArray<T>(length);
}
ref var dest = ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value));
Unsafe.CopyBlockUnaligned(ref dest, ref src, (uint)byteCount);
Advance(byteCount);
}
#endregion
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadSpanWithoutReadLengthHeader<T>(int length, ref Span<T?> value)
{
if (length == 0)
{
value = Array.Empty<T>();
return;
}
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
if (value.Length != length)
{
value = AllocateUninitializedArray<T>(length);
}
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
ref var dest = ref Unsafe.As<T, byte>(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<T>();
for (int i = 0; i < length; i++)
{
formatter.Deserialize(ref this, ref value[i]);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadPackableSpanWithoutReadLengthHeader<T>(int length, ref Span<T?> value)
where T : IMemoryPackable<T>
{
#if !NET7_0_OR_GREATER
ReadSpanWithoutReadLengthHeader(length, ref value);
return;
#else
if (length == 0)
{
value = Array.Empty<T>();
return;
}
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
if (value.Length != length)
{
value = AllocateUninitializedArray<T>(length);
}
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
ref var dest = ref Unsafe.As<T, byte>(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<T>(out bool isNull, out ReadOnlySpan<byte> view)
{
if (!TryReadCollectionHeader(out var length))
{
isNull = true;
view = default;
return;
}
isNull = false;
if (length == 0)
{
view = Array.Empty<byte>();
return;
}
var byteCount = length * Unsafe.SizeOf<T>();
ref var src = ref GetSpanReference(byteCount);
var span = MemoryMarshal.CreateReadOnlySpan(ref src, byteCount);
Advance(byteCount);
view = span; // safe until call next GetSpanReference
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27df744bfc004694c9598738f9d32cce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<MemoryPackReaderOptionalState> queue = new ConcurrentQueue<MemoryPackReaderOptionalState>();
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<uint, object> refToObject;
public MemoryPackSerializerOptions Options { get; private set; }
internal MemoryPackReaderOptionalState()
{
refToObject = new Dictionary<uint, object>();
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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8a381067d43337845bd228a2207155da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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<byte>();
case VarIntCodes.SByte:
return checked((byte)ReadUnmanaged<sbyte>());
case VarIntCodes.UInt16:
return checked((byte)ReadUnmanaged<byte>());
case VarIntCodes.Int16:
return checked((byte)ReadUnmanaged<short>());
case VarIntCodes.UInt32:
return checked((byte)ReadUnmanaged<uint>());
case VarIntCodes.Int32:
return checked((byte)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return checked((byte)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((byte)ReadUnmanaged<long>());
default:
return checked((byte)typeCode);
}
}
public sbyte ReadVarIntSByte()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return checked((sbyte)ReadUnmanaged<byte>());
case VarIntCodes.SByte:
return ReadUnmanaged<sbyte>();
case VarIntCodes.UInt16:
return checked((sbyte)ReadUnmanaged<ushort>());
case VarIntCodes.Int16:
return checked((sbyte)ReadUnmanaged<short>());
case VarIntCodes.UInt32:
return checked((sbyte)ReadUnmanaged<uint>());
case VarIntCodes.Int32:
return checked((sbyte)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return checked((sbyte)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((sbyte)ReadUnmanaged<long>());
default:
return typeCode;
}
}
public ushort ReadVarIntUInt16()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return checked((ushort)ReadUnmanaged<sbyte>());
case VarIntCodes.UInt16:
return ReadUnmanaged<ushort>();
case VarIntCodes.Int16:
return checked((ushort)ReadUnmanaged<short>());
case VarIntCodes.UInt32:
return checked((ushort)ReadUnmanaged<uint>());
case VarIntCodes.Int32:
return checked((ushort)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return checked((ushort)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((ushort)ReadUnmanaged<long>());
default:
return checked((ushort)typeCode);
}
}
public short ReadVarIntInt16()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return ReadUnmanaged<sbyte>();
case VarIntCodes.UInt16:
return checked((short)ReadUnmanaged<ushort>());
case VarIntCodes.Int16:
return ReadUnmanaged<short>();
case VarIntCodes.UInt32:
return checked((short)ReadUnmanaged<uint>());
case VarIntCodes.Int32:
return checked((short)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return checked((short)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((short)ReadUnmanaged<long>());
default:
return typeCode;
}
}
public uint ReadVarIntUInt32()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return checked((uint)ReadUnmanaged<sbyte>());
case VarIntCodes.UInt16:
return ReadUnmanaged<ushort>();
case VarIntCodes.Int16:
return checked((uint)ReadUnmanaged<short>());
case VarIntCodes.UInt32:
return ReadUnmanaged<uint>();
case VarIntCodes.Int32:
return checked((uint)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return checked((uint)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((uint)ReadUnmanaged<long>());
default:
return checked((uint)typeCode);
}
}
public int ReadVarIntInt32()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return ReadUnmanaged<sbyte>();
case VarIntCodes.UInt16:
return ReadUnmanaged<ushort>();
case VarIntCodes.Int16:
return ReadUnmanaged<short>();
case VarIntCodes.UInt32:
return checked((int)ReadUnmanaged<uint>());
case VarIntCodes.Int32:
return ReadUnmanaged<int>();
case VarIntCodes.UInt64:
return checked((int)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return checked((int)ReadUnmanaged<long>());
default:
return typeCode;
}
}
public ulong ReadVarIntUInt64()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return checked((ulong)ReadUnmanaged<sbyte>());
case VarIntCodes.UInt16:
return ReadUnmanaged<ushort>();
case VarIntCodes.Int16:
return checked((ulong)ReadUnmanaged<short>());
case VarIntCodes.UInt32:
return ReadUnmanaged<uint>();
case VarIntCodes.Int32:
return checked((ulong)ReadUnmanaged<int>());
case VarIntCodes.UInt64:
return ReadUnmanaged<ulong>();
case VarIntCodes.Int64:
return checked((ulong)ReadUnmanaged<long>());
default:
return checked((ulong)typeCode);
}
}
public long ReadVarIntInt64()
{
ReadUnmanaged(out sbyte typeCode);
switch (typeCode)
{
case VarIntCodes.Byte:
return ReadUnmanaged<byte>();
case VarIntCodes.SByte:
return ReadUnmanaged<sbyte>();
case VarIntCodes.UInt16:
return ReadUnmanaged<ushort>();
case VarIntCodes.Int16:
return ReadUnmanaged<short>();
case VarIntCodes.UInt32:
return ReadUnmanaged<uint>();
case VarIntCodes.Int32:
return ReadUnmanaged<int>();
case VarIntCodes.UInt64:
return checked((long)ReadUnmanaged<ulong>());
case VarIntCodes.Int64:
return ReadUnmanaged<long>();
default:
return typeCode;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a312341bf29b42429b858550384dd1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More