Merge pull request #1365 from neuecc/master

Merge master to develop
This commit is contained in:
Andrew Arnott 2021-12-24 18:02:46 -07:00 коммит произвёл GitHub
Родитель 5e3b1073fb 76f3f651e7
Коммит 0dc9c785e7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 428 добавлений и 151 удалений

Просмотреть файл

@ -132,6 +132,9 @@
<Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\Resolvers\DynamicUnionResolver.cs">
<Link>Code\DynamicUnionResolver.cs</Link>
</Compile>
<Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\Resolvers\ResolverUtilities.cs">
<Link>Code\ResolverUtilities.cs</Link>
</Compile>
<Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\StringEncoding.cs">
<Link>Code\StringEncoding.cs</Link>
</Compile>

Просмотреть файл

@ -44,6 +44,7 @@ namespace DynamicCodeDumper
////DynamicObjectResolver.Instance.GetFormatter<StringKeySerializerTarget>();
////DynamicObjectResolver.Instance.GetFormatter<LongestString>();
IMessagePackFormatter<MyClass> f = DynamicObjectResolverAllowPrivate.Instance.GetFormatter<MyClass>();
////IMessagePackFormatter<MessagePackFormatterFieldUser> f = DynamicObjectResolver.Instance.GetFormatter<MessagePackFormatterFieldUser>();
////DynamicObjectResolver.Instance.GetFormatter<StringKeySerializerTargetBinary>();
////DynamicObjectResolver.Instance.GetFormatter<Callback1>();
////DynamicObjectResolver.Instance.GetFormatter<Callback1_2>();

Просмотреть файл

@ -49,7 +49,7 @@ namespace MessagePack.Resolvers
static GeneratedResolverGetFormatterHelper()
{
lookup = new global::System.Collections.Generic.Dictionary<Type, int>(71)
lookup = new global::System.Collections.Generic.Dictionary<Type, int>(72)
{
{ typeof(global::GlobalMyEnum[,]), 0 },
{ typeof(global::GlobalMyEnum[]), 1 },
@ -72,56 +72,57 @@ namespace MessagePack.Resolvers
{ typeof(global::ComplexModel), 18 },
{ typeof(global::GlobalMan), 19 },
{ typeof(global::Message), 20 },
{ typeof(global::PerfBenchmarkDotNet.StringKeySerializerTarget), 21 },
{ typeof(global::QuestMessageBody), 22 },
{ typeof(global::SharedData.ArrayOptimizeClass), 23 },
{ typeof(global::SharedData.BarClass), 24 },
{ typeof(global::SharedData.Callback1), 25 },
{ typeof(global::SharedData.Callback1_2), 26 },
{ typeof(global::SharedData.Callback2), 27 },
{ typeof(global::SharedData.Callback2_2), 28 },
{ typeof(global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor), 29 },
{ typeof(global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor), 30 },
{ typeof(global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor), 31 },
{ typeof(global::SharedData.DefaultValueStringKeyClassWithExplicitConstructor), 32 },
{ typeof(global::SharedData.DefaultValueStringKeyClassWithoutExplicitConstructor), 33 },
{ typeof(global::SharedData.DefaultValueStringKeyStructWithExplicitConstructor), 34 },
{ typeof(global::SharedData.Empty1), 35 },
{ typeof(global::SharedData.Empty2), 36 },
{ typeof(global::SharedData.EmptyClass), 37 },
{ typeof(global::SharedData.EmptyStruct), 38 },
{ typeof(global::SharedData.FirstSimpleData), 39 },
{ typeof(global::SharedData.FooClass), 40 },
{ typeof(global::SharedData.HolderV0), 41 },
{ typeof(global::SharedData.HolderV1), 42 },
{ typeof(global::SharedData.HolderV2), 43 },
{ typeof(global::SharedData.MyClass), 44 },
{ typeof(global::SharedData.MySubUnion1), 45 },
{ typeof(global::SharedData.MySubUnion2), 46 },
{ typeof(global::SharedData.MySubUnion3), 47 },
{ typeof(global::SharedData.MySubUnion4), 48 },
{ typeof(global::SharedData.NestParent.NestContract), 49 },
{ typeof(global::SharedData.NonEmpty1), 50 },
{ typeof(global::SharedData.NonEmpty2), 51 },
{ typeof(global::SharedData.SimpleIntKeyData), 52 },
{ typeof(global::SharedData.SimpleStringKeyData), 53 },
{ typeof(global::SharedData.SimpleStructIntKeyData), 54 },
{ typeof(global::SharedData.SimpleStructStringKeyData), 55 },
{ typeof(global::SharedData.SubUnionType1), 56 },
{ typeof(global::SharedData.SubUnionType2), 57 },
{ typeof(global::SharedData.UnVersionBlockTest), 58 },
{ typeof(global::SharedData.Vector2), 59 },
{ typeof(global::SharedData.Vector3Like), 60 },
{ typeof(global::SharedData.VectorLike2), 61 },
{ typeof(global::SharedData.Version0), 62 },
{ typeof(global::SharedData.Version1), 63 },
{ typeof(global::SharedData.Version2), 64 },
{ typeof(global::SharedData.VersionBlockTest), 65 },
{ typeof(global::SharedData.VersioningUnion), 66 },
{ typeof(global::SharedData.WithIndexer), 67 },
{ typeof(global::SimpleModel), 68 },
{ typeof(global::StampMessageBody), 69 },
{ typeof(global::TextMessageBody), 70 },
{ typeof(global::MessagePackFormatterFieldUser), 21 },
{ typeof(global::PerfBenchmarkDotNet.StringKeySerializerTarget), 22 },
{ typeof(global::QuestMessageBody), 23 },
{ typeof(global::SharedData.ArrayOptimizeClass), 24 },
{ typeof(global::SharedData.BarClass), 25 },
{ typeof(global::SharedData.Callback1), 26 },
{ typeof(global::SharedData.Callback1_2), 27 },
{ typeof(global::SharedData.Callback2), 28 },
{ typeof(global::SharedData.Callback2_2), 29 },
{ typeof(global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor), 30 },
{ typeof(global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor), 31 },
{ typeof(global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor), 32 },
{ typeof(global::SharedData.DefaultValueStringKeyClassWithExplicitConstructor), 33 },
{ typeof(global::SharedData.DefaultValueStringKeyClassWithoutExplicitConstructor), 34 },
{ typeof(global::SharedData.DefaultValueStringKeyStructWithExplicitConstructor), 35 },
{ typeof(global::SharedData.Empty1), 36 },
{ typeof(global::SharedData.Empty2), 37 },
{ typeof(global::SharedData.EmptyClass), 38 },
{ typeof(global::SharedData.EmptyStruct), 39 },
{ typeof(global::SharedData.FirstSimpleData), 40 },
{ typeof(global::SharedData.FooClass), 41 },
{ typeof(global::SharedData.HolderV0), 42 },
{ typeof(global::SharedData.HolderV1), 43 },
{ typeof(global::SharedData.HolderV2), 44 },
{ typeof(global::SharedData.MyClass), 45 },
{ typeof(global::SharedData.MySubUnion1), 46 },
{ typeof(global::SharedData.MySubUnion2), 47 },
{ typeof(global::SharedData.MySubUnion3), 48 },
{ typeof(global::SharedData.MySubUnion4), 49 },
{ typeof(global::SharedData.NestParent.NestContract), 50 },
{ typeof(global::SharedData.NonEmpty1), 51 },
{ typeof(global::SharedData.NonEmpty2), 52 },
{ typeof(global::SharedData.SimpleIntKeyData), 53 },
{ typeof(global::SharedData.SimpleStringKeyData), 54 },
{ typeof(global::SharedData.SimpleStructIntKeyData), 55 },
{ typeof(global::SharedData.SimpleStructStringKeyData), 56 },
{ typeof(global::SharedData.SubUnionType1), 57 },
{ typeof(global::SharedData.SubUnionType2), 58 },
{ typeof(global::SharedData.UnVersionBlockTest), 59 },
{ typeof(global::SharedData.Vector2), 60 },
{ typeof(global::SharedData.Vector3Like), 61 },
{ typeof(global::SharedData.VectorLike2), 62 },
{ typeof(global::SharedData.Version0), 63 },
{ typeof(global::SharedData.Version1), 64 },
{ typeof(global::SharedData.Version2), 65 },
{ typeof(global::SharedData.VersionBlockTest), 66 },
{ typeof(global::SharedData.VersioningUnion), 67 },
{ typeof(global::SharedData.WithIndexer), 68 },
{ typeof(global::SimpleModel), 69 },
{ typeof(global::StampMessageBody), 70 },
{ typeof(global::TextMessageBody), 71 },
};
}
@ -156,56 +157,57 @@ namespace MessagePack.Resolvers
case 18: return new MessagePack.Formatters.ComplexModelFormatter();
case 19: return new MessagePack.Formatters.GlobalManFormatter();
case 20: return new MessagePack.Formatters.MessageFormatter();
case 21: return new MessagePack.Formatters.PerfBenchmarkDotNet.StringKeySerializerTargetFormatter();
case 22: return new MessagePack.Formatters.QuestMessageBodyFormatter();
case 23: return new MessagePack.Formatters.SharedData.ArrayOptimizeClassFormatter();
case 24: return new MessagePack.Formatters.SharedData.BarClassFormatter();
case 25: return new MessagePack.Formatters.SharedData.Callback1Formatter();
case 26: return new MessagePack.Formatters.SharedData.Callback1_2Formatter();
case 27: return new MessagePack.Formatters.SharedData.Callback2Formatter();
case 28: return new MessagePack.Formatters.SharedData.Callback2_2Formatter();
case 29: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithExplicitConstructorFormatter();
case 30: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithoutExplicitConstructorFormatter();
case 31: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyStructWithExplicitConstructorFormatter();
case 32: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithExplicitConstructorFormatter();
case 33: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithoutExplicitConstructorFormatter();
case 34: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyStructWithExplicitConstructorFormatter();
case 35: return new MessagePack.Formatters.SharedData.Empty1Formatter();
case 36: return new MessagePack.Formatters.SharedData.Empty2Formatter();
case 37: return new MessagePack.Formatters.SharedData.EmptyClassFormatter();
case 38: return new MessagePack.Formatters.SharedData.EmptyStructFormatter();
case 39: return new MessagePack.Formatters.SharedData.FirstSimpleDataFormatter();
case 40: return new MessagePack.Formatters.SharedData.FooClassFormatter();
case 41: return new MessagePack.Formatters.SharedData.HolderV0Formatter();
case 42: return new MessagePack.Formatters.SharedData.HolderV1Formatter();
case 43: return new MessagePack.Formatters.SharedData.HolderV2Formatter();
case 44: return new MessagePack.Formatters.SharedData.MyClassFormatter();
case 45: return new MessagePack.Formatters.SharedData.MySubUnion1Formatter();
case 46: return new MessagePack.Formatters.SharedData.MySubUnion2Formatter();
case 47: return new MessagePack.Formatters.SharedData.MySubUnion3Formatter();
case 48: return new MessagePack.Formatters.SharedData.MySubUnion4Formatter();
case 49: return new MessagePack.Formatters.SharedData.NestParent_NestContractFormatter();
case 50: return new MessagePack.Formatters.SharedData.NonEmpty1Formatter();
case 51: return new MessagePack.Formatters.SharedData.NonEmpty2Formatter();
case 52: return new MessagePack.Formatters.SharedData.SimpleIntKeyDataFormatter();
case 53: return new MessagePack.Formatters.SharedData.SimpleStringKeyDataFormatter();
case 54: return new MessagePack.Formatters.SharedData.SimpleStructIntKeyDataFormatter();
case 55: return new MessagePack.Formatters.SharedData.SimpleStructStringKeyDataFormatter();
case 56: return new MessagePack.Formatters.SharedData.SubUnionType1Formatter();
case 57: return new MessagePack.Formatters.SharedData.SubUnionType2Formatter();
case 58: return new MessagePack.Formatters.SharedData.UnVersionBlockTestFormatter();
case 59: return new MessagePack.Formatters.SharedData.Vector2Formatter();
case 60: return new MessagePack.Formatters.SharedData.Vector3LikeFormatter();
case 61: return new MessagePack.Formatters.SharedData.VectorLike2Formatter();
case 62: return new MessagePack.Formatters.SharedData.Version0Formatter();
case 63: return new MessagePack.Formatters.SharedData.Version1Formatter();
case 64: return new MessagePack.Formatters.SharedData.Version2Formatter();
case 65: return new MessagePack.Formatters.SharedData.VersionBlockTestFormatter();
case 66: return new MessagePack.Formatters.SharedData.VersioningUnionFormatter();
case 67: return new MessagePack.Formatters.SharedData.WithIndexerFormatter();
case 68: return new MessagePack.Formatters.SimpleModelFormatter();
case 69: return new MessagePack.Formatters.StampMessageBodyFormatter();
case 70: return new MessagePack.Formatters.TextMessageBodyFormatter();
case 21: return new MessagePack.Formatters.MessagePackFormatterFieldUserFormatter();
case 22: return new MessagePack.Formatters.PerfBenchmarkDotNet.StringKeySerializerTargetFormatter();
case 23: return new MessagePack.Formatters.QuestMessageBodyFormatter();
case 24: return new MessagePack.Formatters.SharedData.ArrayOptimizeClassFormatter();
case 25: return new MessagePack.Formatters.SharedData.BarClassFormatter();
case 26: return new MessagePack.Formatters.SharedData.Callback1Formatter();
case 27: return new MessagePack.Formatters.SharedData.Callback1_2Formatter();
case 28: return new MessagePack.Formatters.SharedData.Callback2Formatter();
case 29: return new MessagePack.Formatters.SharedData.Callback2_2Formatter();
case 30: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithExplicitConstructorFormatter();
case 31: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithoutExplicitConstructorFormatter();
case 32: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyStructWithExplicitConstructorFormatter();
case 33: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithExplicitConstructorFormatter();
case 34: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithoutExplicitConstructorFormatter();
case 35: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyStructWithExplicitConstructorFormatter();
case 36: return new MessagePack.Formatters.SharedData.Empty1Formatter();
case 37: return new MessagePack.Formatters.SharedData.Empty2Formatter();
case 38: return new MessagePack.Formatters.SharedData.EmptyClassFormatter();
case 39: return new MessagePack.Formatters.SharedData.EmptyStructFormatter();
case 40: return new MessagePack.Formatters.SharedData.FirstSimpleDataFormatter();
case 41: return new MessagePack.Formatters.SharedData.FooClassFormatter();
case 42: return new MessagePack.Formatters.SharedData.HolderV0Formatter();
case 43: return new MessagePack.Formatters.SharedData.HolderV1Formatter();
case 44: return new MessagePack.Formatters.SharedData.HolderV2Formatter();
case 45: return new MessagePack.Formatters.SharedData.MyClassFormatter();
case 46: return new MessagePack.Formatters.SharedData.MySubUnion1Formatter();
case 47: return new MessagePack.Formatters.SharedData.MySubUnion2Formatter();
case 48: return new MessagePack.Formatters.SharedData.MySubUnion3Formatter();
case 49: return new MessagePack.Formatters.SharedData.MySubUnion4Formatter();
case 50: return new MessagePack.Formatters.SharedData.NestParent_NestContractFormatter();
case 51: return new MessagePack.Formatters.SharedData.NonEmpty1Formatter();
case 52: return new MessagePack.Formatters.SharedData.NonEmpty2Formatter();
case 53: return new MessagePack.Formatters.SharedData.SimpleIntKeyDataFormatter();
case 54: return new MessagePack.Formatters.SharedData.SimpleStringKeyDataFormatter();
case 55: return new MessagePack.Formatters.SharedData.SimpleStructIntKeyDataFormatter();
case 56: return new MessagePack.Formatters.SharedData.SimpleStructStringKeyDataFormatter();
case 57: return new MessagePack.Formatters.SharedData.SubUnionType1Formatter();
case 58: return new MessagePack.Formatters.SharedData.SubUnionType2Formatter();
case 59: return new MessagePack.Formatters.SharedData.UnVersionBlockTestFormatter();
case 60: return new MessagePack.Formatters.SharedData.Vector2Formatter();
case 61: return new MessagePack.Formatters.SharedData.Vector3LikeFormatter();
case 62: return new MessagePack.Formatters.SharedData.VectorLike2Formatter();
case 63: return new MessagePack.Formatters.SharedData.Version0Formatter();
case 64: return new MessagePack.Formatters.SharedData.Version1Formatter();
case 65: return new MessagePack.Formatters.SharedData.Version2Formatter();
case 66: return new MessagePack.Formatters.SharedData.VersionBlockTestFormatter();
case 67: return new MessagePack.Formatters.SharedData.VersioningUnionFormatter();
case 68: return new MessagePack.Formatters.SharedData.WithIndexerFormatter();
case 69: return new MessagePack.Formatters.SimpleModelFormatter();
case 70: return new MessagePack.Formatters.StampMessageBodyFormatter();
case 71: return new MessagePack.Formatters.TextMessageBodyFormatter();
default: return null;
}
}
@ -1173,6 +1175,51 @@ namespace MessagePack.Formatters
}
}
public sealed class MessagePackFormatterFieldUserFormatter : global::MessagePack.Formatters.IMessagePackFormatter<global::MessagePackFormatterFieldUser>
{
private readonly global::MessagePack.Formatters.NativeDateTimeFormatter __TimestampCustomFormatter__ = new global::MessagePack.Formatters.NativeDateTimeFormatter();
public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::MessagePackFormatterFieldUser value, global::MessagePack.MessagePackSerializerOptions options)
{
if (value == null)
{
writer.WriteNil();
return;
}
writer.WriteArrayHeader(1);
this.__TimestampCustomFormatter__.Serialize(ref writer, value.Timestamp, options);
}
public global::MessagePackFormatterFieldUser Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
{
if (reader.TryReadNil())
{
return null;
}
options.Security.DepthStep(ref reader);
var length = reader.ReadArrayHeader();
var ____result = new global::MessagePackFormatterFieldUser();
for (int i = 0; i < length; i++)
{
switch (i)
{
case 0:
____result.Timestamp = this.__TimestampCustomFormatter__.Deserialize(ref reader, options);
break;
default:
reader.Skip();
break;
}
}
reader.Depth--;
return ____result;
}
}
public sealed class QuestMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter<global::QuestMessageBody>
{

Просмотреть файл

@ -42,7 +42,7 @@ https://raw.githubusercontent.com/Cyan4973/xxHash/5c174cfa4e45a42f94082dc0d4539b
*/
#if !NETCOREAPP
#if !(NETCOREAPP || UNITY_2021_2_OR_NEWER)
using System.Collections.Generic;
using System.ComponentModel;

Просмотреть файл

@ -334,8 +334,8 @@ namespace MessagePack
value = float.NaN;
}
long l = *(long*)&value;
return HashCode.Combine((int)(l >> 32), unchecked((int)l));
int l = *(int*)&value;
return l;
}
}

Просмотреть файл

@ -1,10 +1,10 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Linq; // require UNITY_2018_3_OR_NEWER
using System.Linq;
using System.Reflection;
using MessagePack.Formatters;
using MessagePack.Internal;
namespace MessagePack.Resolvers
{
@ -49,14 +49,7 @@ namespace MessagePack.Resolvers
formatterType = formatterType.MakeGenericType(typeof(T).GetGenericArguments());
}
if (attr.Arguments == null)
{
Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterType);
}
else
{
Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterType, attr.Arguments);
}
Formatter = (IMessagePackFormatter<T>)ResolverUtilities.ActivateFormatter(formatterType, attr.Arguments);
}
}
}

Просмотреть файл

@ -14,6 +14,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using MessagePack.Formatters;
using MessagePack.Internal;
using MessagePack.Resolvers;
#pragma warning disable SA1403 // File may only contain a single namespace
@ -110,7 +111,7 @@ namespace MessagePack.Resolvers
return;
}
Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterTypeInfo.AsType());
Formatter = (IMessagePackFormatter<T>)ResolverUtilities.ActivateFormatter(formatterTypeInfo.AsType());
}
}
}
@ -495,7 +496,7 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
var formatter = Activator.CreateInstance(attr.FormatterType, attr.Arguments);
IMessagePackFormatter formatter = ResolverUtilities.ActivateFormatter(attr.FormatterType, attr.Arguments);
serializeCustomFormatters.Add(formatter);
}
else
@ -510,7 +511,7 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
var formatter = Activator.CreateInstance(attr.FormatterType, attr.Arguments);
IMessagePackFormatter formatter = ResolverUtilities.ActivateFormatter(attr.FormatterType, attr.Arguments);
deserializeCustomFormatters.Add(formatter);
}
else
@ -626,38 +627,55 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
// Verify that the specified formatter implements the required interface.
// Doing this now provides a more helpful error message than if we let the CLR throw an EntryPointNotFoundException later.
if (!attr.FormatterType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMessagePackFormatter<>) && i.GenericTypeArguments[0].IsEquivalentTo(item.Type)))
{
throw new MessagePackSerializationException($"{info.Type.FullName}.{item.Name} is declared as type {item.Type.FullName}, but the prescribed {attr.FormatterType.FullName} does not implement IMessagePackFormatter<{item.Type.Name}>.");
}
FieldBuilder f = builder.DefineField(item.Name + "_formatter", attr.FormatterType, FieldAttributes.Private | FieldAttributes.InitOnly);
var bindingFlags = (int)(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
LocalBuilder attrVar = il.DeclareLocal(typeof(MessagePackFormatterAttribute));
il.Emit(OpCodes.Ldtoken, info.Type);
il.EmitCall(EmitInfo.GetTypeFromHandle);
il.Emit(OpCodes.Ldstr, item.Name);
il.EmitLdc_I4(bindingFlags);
if (item.IsProperty)
// If no args were provided and the formatter implements the singleton pattern, fetch the formatter from the field.
if ((attr.Arguments == null || attr.Arguments.Length == 0) && ResolverUtilities.FetchSingletonField(attr.FormatterType) is FieldInfo singletonField)
{
il.EmitCall(EmitInfo.TypeGetProperty);
il.EmitLoadThis();
il.EmitLdsfld(singletonField);
}
else
{
il.EmitCall(EmitInfo.TypeGetField);
var bindingFlags = (int)(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
LocalBuilder attrVar = il.DeclareLocal(typeof(MessagePackFormatterAttribute));
il.Emit(OpCodes.Ldtoken, info.Type);
il.EmitCall(EmitInfo.GetTypeFromHandle);
il.Emit(OpCodes.Ldstr, item.Name);
il.EmitLdc_I4(bindingFlags);
if (item.IsProperty)
{
il.EmitCall(EmitInfo.TypeGetProperty);
}
else
{
il.EmitCall(EmitInfo.TypeGetField);
}
il.EmitTrue();
il.EmitCall(EmitInfo.GetCustomAttributeMessagePackFormatterAttribute);
il.EmitStloc(attrVar);
il.EmitLoadThis();
il.EmitLdloc(attrVar);
il.EmitCall(EmitInfo.MessagePackFormatterAttr.FormatterType);
il.EmitLdloc(attrVar);
il.EmitCall(EmitInfo.MessagePackFormatterAttr.Arguments);
il.EmitCall(EmitInfo.ActivatorCreateInstance);
il.Emit(OpCodes.Castclass, attr.FormatterType);
}
il.EmitTrue();
il.EmitCall(EmitInfo.GetCustomAttributeMessagePackFormatterAttribute);
il.EmitStloc(attrVar);
il.EmitLoadThis();
il.EmitLdloc(attrVar);
il.EmitCall(EmitInfo.MessagePackFormatterAttr.FormatterType);
il.EmitLdloc(attrVar);
il.EmitCall(EmitInfo.MessagePackFormatterAttr.Arguments);
il.EmitCall(EmitInfo.ActivatorCreateInstance);
il.Emit(OpCodes.Castclass, attr.FormatterType);
il.Emit(OpCodes.Stfld, f);
dict.Add(item, f);

Просмотреть файл

@ -0,0 +1,45 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Reflection;
using MessagePack.Formatters;
namespace MessagePack.Internal
{
internal static class ResolverUtilities
{
internal static IMessagePackFormatter ActivateFormatter(Type formatterType, object[] args = null)
{
if (args == null || args.Length == 0)
{
if (formatterType.GetConstructor(Type.EmptyTypes) is ConstructorInfo ctor)
{
return (IMessagePackFormatter)ctor.Invoke(Array.Empty<object>());
}
else if (FetchSingletonField(formatterType) is FieldInfo instance)
{
return (IMessagePackFormatter)instance.GetValue(null);
}
else
{
throw new MessagePackSerializationException($"The {formatterType.FullName} formatter has no default constructor nor implements the singleton pattern.");
}
}
else
{
return (IMessagePackFormatter)Activator.CreateInstance(formatterType, args);
}
}
internal static FieldInfo FetchSingletonField(Type formatterType)
{
if (formatterType.GetField("Instance", BindingFlags.Static | BindingFlags.Public) is FieldInfo fieldInfo && fieldInfo.IsInitOnly)
{
return fieldInfo;
}
return null;
}
}
}

Просмотреть файл

@ -1149,6 +1149,13 @@ public class SimpleModel
}
}
[MessagePackObject]
public class MessagePackFormatterFieldUser
{
[Key(0), MessagePackFormatter(typeof(NativeDateTimeFormatter))]
public DateTime Timestamp { get; set; }
}
namespace PerfBenchmarkDotNet
{
[MessagePackObject(true)]

Просмотреть файл

@ -191,6 +191,8 @@ namespace MessagePack.Tests
public bool Equals(Detail other) => other != null && this.B1 == other.B1 && this.B2 == other.B2;
}
#if !UNITY_2018_3_OR_NEWER
[Fact]
public void DataContractSerializerCompatibility()
{
@ -219,6 +221,8 @@ namespace MessagePack.Tests
Assert.Equal(dcsValue, mpValue);
}
#endif
private static T DataContractSerializerRoundTrip<T>(T value)
{
var ms = new MemoryStream();

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if !ENABLE_IL2CPP
#if !UNITY_2018_3_OR_NEWER
using System;
using System.Collections.Generic;

Просмотреть файл

@ -1,6 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if !UNITY_2018_3_OR_NEWER
using System.Dynamic;
using System.Runtime.Serialization;
using MessagePack.Resolvers;
@ -115,3 +117,5 @@ namespace MessagePack.Tests
}
}
}
#endif

Просмотреть файл

@ -5,16 +5,27 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using MessagePack.Formatters;
using MessagePack.Resolvers;
using Xunit;
using Xunit.Abstractions;
namespace MessagePack.Tests
{
public class MessagePackFormatterPerFieldTest
{
private readonly ITestOutputHelper logger;
public MessagePackFormatterPerFieldTest(ITestOutputHelper logger)
{
this.logger = logger;
}
[MessagePackObject]
public class MyClass
{
@ -105,5 +116,129 @@ namespace MessagePack.Tests
r2.MyProperty4.Is("bar");
}
}
[MessagePackObject]
public class BlockFormattedIntegers
{
[Key(0)] [MessagePackFormatter(typeof(ForceByteBlockFormatter))] public byte UInt8Property { get; set; }
[Key(1)] [MessagePackFormatter(typeof(ForceUInt16BlockFormatter))] public ushort UInt16Property { get; set; }
[Key(2)] [MessagePackFormatter(typeof(ForceUInt32BlockFormatter))] public uint UInt32Property { get; set; }
[Key(3)] [MessagePackFormatter(typeof(ForceUInt64BlockFormatter))] public ulong UInt64Property { get; set; }
[Key(4)] [MessagePackFormatter(typeof(ForceSByteBlockFormatter))] public sbyte Int8Property { get; set; }
[Key(5)] [MessagePackFormatter(typeof(ForceInt16BlockFormatter))] public short Int16Property { get; set; }
[Key(6)] [MessagePackFormatter(typeof(ForceInt32BlockFormatter))] public int Int32Property { get; set; }
[Key(7)] [MessagePackFormatter(typeof(ForceInt64BlockFormatter))] public long Int64Property { get; set; }
[Key(8)] [MessagePackFormatter(typeof(NullableForceByteBlockFormatter))] public byte? NullableUInt8Property { get; set; }
[Key(9)] [MessagePackFormatter(typeof(NullableForceUInt16BlockFormatter))] public ushort? NullableUInt16Property { get; set; }
[Key(10)] [MessagePackFormatter(typeof(NullableForceUInt32BlockFormatter))] public uint? NullableUInt32Property { get; set; }
[Key(11)] [MessagePackFormatter(typeof(NullableForceUInt64BlockFormatter))] public ulong? NullableUInt64Property { get; set; }
[Key(12)] [MessagePackFormatter(typeof(NullableForceSByteBlockFormatter))] public sbyte? NullableInt8Property { get; set; }
[Key(13)] [MessagePackFormatter(typeof(NullableForceInt16BlockFormatter))] public short? NullableInt16Property { get; set; }
[Key(14)] [MessagePackFormatter(typeof(NullableForceInt32BlockFormatter))] public int? NullableInt32Property { get; set; }
[Key(15)] [MessagePackFormatter(typeof(NullableForceInt64BlockFormatter))] public long? NullableInt64Property { get; set; }
}
/// <summary>
/// Asserts that every formatter offers the public API required for use by
/// <see cref="MessagePackFormatterAttribute"/>.
/// </summary>
[Fact]
public void AllFormattersOfferAreAvailableViaAttribute()
{
var formatters = (from type in typeof(ForceByteBlockFormatter).Assembly.GetTypes()
where typeof(IMessagePackFormatter).IsAssignableFrom(type) && !type.IsAbstract
let ctor = GetDefaultConstructor(type)
where ctor is object // skip formatters that require special initialization.
select new { Type = type, DefaultConstructor = ctor }).ToList();
this.logger.WriteLine("Found {0} applicable formatters to check.", formatters.Count);
Assert.All(formatters, formatter => Assert.True(formatter.DefaultConstructor.IsPublic || UsesSingletonPattern(formatter.Type)));
}
[Fact]
public void ForceBlockFormatters()
{
var block = new BlockFormattedIntegers
{
UInt8Property = 1,
UInt16Property = 2,
UInt32Property = 3,
UInt64Property = 4,
Int8Property = 1,
Int16Property = 2,
Int32Property = 3,
Int64Property = 4,
NullableUInt8Property = 1,
NullableUInt16Property = 2,
NullableUInt32Property = 3,
NullableUInt64Property = 4,
NullableInt8Property = 1,
NullableInt16Property = 2,
NullableInt32Property = 3,
NullableInt64Property = 4,
};
byte[] packed = MessagePackSerializer.Serialize(block, MessagePackSerializerOptions.Standard);
var reader = new MessagePackReader(packed);
reader.ReadArrayHeader();
Assert.Equal(MessagePackCode.UInt8, reader.NextCode);
Assert.Equal(1, reader.ReadByte());
Assert.Equal(MessagePackCode.UInt16, reader.NextCode);
Assert.Equal(2, reader.ReadUInt16());
Assert.Equal(MessagePackCode.UInt32, reader.NextCode);
Assert.Equal(3u, reader.ReadUInt32());
Assert.Equal(MessagePackCode.UInt64, reader.NextCode);
Assert.Equal(4u, reader.ReadUInt64());
Assert.Equal(MessagePackCode.Int8, reader.NextCode);
Assert.Equal(1, reader.ReadSByte());
Assert.Equal(MessagePackCode.Int16, reader.NextCode);
Assert.Equal(2, reader.ReadInt16());
Assert.Equal(MessagePackCode.Int32, reader.NextCode);
Assert.Equal(3, reader.ReadInt32());
Assert.Equal(MessagePackCode.Int64, reader.NextCode);
Assert.Equal(4, reader.ReadInt64());
Assert.Equal(MessagePackCode.UInt8, reader.NextCode);
Assert.Equal(1, reader.ReadByte());
Assert.Equal(MessagePackCode.UInt16, reader.NextCode);
Assert.Equal(2, reader.ReadUInt16());
Assert.Equal(MessagePackCode.UInt32, reader.NextCode);
Assert.Equal(3u, reader.ReadUInt32());
Assert.Equal(MessagePackCode.UInt64, reader.NextCode);
Assert.Equal(4u, reader.ReadUInt64());
Assert.Equal(MessagePackCode.Int8, reader.NextCode);
Assert.Equal(1, reader.ReadSByte());
Assert.Equal(MessagePackCode.Int16, reader.NextCode);
Assert.Equal(2, reader.ReadInt16());
Assert.Equal(MessagePackCode.Int32, reader.NextCode);
Assert.Equal(3, reader.ReadInt32());
Assert.Equal(MessagePackCode.Int64, reader.NextCode);
Assert.Equal(4, reader.ReadInt64());
}
private static ConstructorInfo GetDefaultConstructor(Type formatterType) => formatterType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(c => c.GetParameters().Length == 0);
private static bool UsesSingletonPattern(Type formatterType) => formatterType.GetField("Instance", BindingFlags.Static | BindingFlags.Public)?.IsInitOnly is true;
}
}

Просмотреть файл

@ -92,6 +92,14 @@ namespace Xunit
Assert.False(enumerable.GetEnumerator().MoveNext());
}
public static void All<T>(IEnumerable<T> collection, Action<T> predicate)
{
foreach (T item in collection)
{
predicate(item);
}
}
public static T IsType<T>(object o)
{
NUnit.Framework.Assert.AreEqual(typeof(T), o.GetType());

Просмотреть файл

@ -1,19 +1,30 @@
{
"name": "MessagePack.Tests",
"rootNamespace": "",
"references": [
"MessagePack",
"MessagePack.Annotations",
"RuntimeUnitTestToolkit"
],
"optionalUnityReferences": [
"TestAssemblies"
"RuntimeUnitTestToolkit",
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
"overrideReferences": true,
"precompiledReferences": [
"System.Memory.dll",
"System.Buffers.dll",
"System.Threading.Tasks.Extensions.dll",
"System.Runtime.CompilerServices.Unsafe.dll",
"System.Runtime.Extensions.dll",
"nunit.framework.dll",
"MsgPack.dll"
],
"autoReferenced": false,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}

Просмотреть файл

@ -11,6 +11,7 @@
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<IncludeSymbols>false</IncludeSymbols>
<DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup>
<ItemGroup>
<Content Include="tools\*.ps1" Pack="true" PackagePath="tools\" />