Skip to content

Commit 1869199

Browse files
authored
Merge pull request MessagePack-CSharp#1100 from AArnott/fix1097
Fix `[MessagePackFormatter(TypelessFormatter)]`
2 parents 090c73f + dedb9c3 commit 1869199

File tree

3 files changed

+37
-19
lines changed

3 files changed

+37
-19
lines changed

src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/TypelessFormatter.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ public sealed class TypelessFormatter : IMessagePackFormatter<object>
5050
/// </summary>
5151
public static readonly IMessagePackFormatter<object> Instance = new TypelessFormatter();
5252

53-
private readonly ThreadsafeTypeKeyHashTable<SerializeMethod> serializers = new ThreadsafeTypeKeyHashTable<SerializeMethod>();
54-
private readonly ThreadsafeTypeKeyHashTable<DeserializeMethod> deserializers = new ThreadsafeTypeKeyHashTable<DeserializeMethod>();
55-
private readonly ThreadsafeTypeKeyHashTable<byte[]> fullTypeNameCache = new ThreadsafeTypeKeyHashTable<byte[]>();
56-
private readonly ThreadsafeTypeKeyHashTable<byte[]> shortenedTypeNameCache = new ThreadsafeTypeKeyHashTable<byte[]>();
57-
private readonly AsymmetricKeyHashTable<byte[], ArraySegment<byte>, Type> typeCache = new AsymmetricKeyHashTable<byte[], ArraySegment<byte>, Type>(new StringArraySegmentByteAscymmetricEqualityComparer());
53+
private static readonly ThreadsafeTypeKeyHashTable<SerializeMethod> Serializers = new ThreadsafeTypeKeyHashTable<SerializeMethod>();
54+
private static readonly ThreadsafeTypeKeyHashTable<DeserializeMethod> Deserializers = new ThreadsafeTypeKeyHashTable<DeserializeMethod>();
55+
private static readonly ThreadsafeTypeKeyHashTable<byte[]> FullTypeNameCache = new ThreadsafeTypeKeyHashTable<byte[]>();
56+
private static readonly ThreadsafeTypeKeyHashTable<byte[]> ShortenedTypeNameCache = new ThreadsafeTypeKeyHashTable<byte[]>();
57+
private static readonly AsymmetricKeyHashTable<byte[], ArraySegment<byte>, Type> TypeCache = new AsymmetricKeyHashTable<byte[], ArraySegment<byte>, Type>(new StringArraySegmentByteAscymmetricEqualityComparer());
5858

5959
private static readonly HashSet<Type> UseBuiltinTypes = new HashSet<Type>
6060
{
@@ -107,10 +107,10 @@ public sealed class TypelessFormatter : IMessagePackFormatter<object>
107107
// mscorlib or System.Private.CoreLib
108108
private static readonly bool IsMscorlib = typeof(int).AssemblyQualifiedName.Contains("mscorlib");
109109

110-
private TypelessFormatter()
110+
static TypelessFormatter()
111111
{
112-
this.serializers.TryAdd(typeof(object), _ => (object p1, ref MessagePackWriter p2, object p3, MessagePackSerializerOptions p4) => { });
113-
this.deserializers.TryAdd(typeof(object), _ => (object p1, ref MessagePackReader p2, MessagePackSerializerOptions p3) => new object());
112+
Serializers.TryAdd(typeof(object), _ => (object p1, ref MessagePackWriter p2, object p3, MessagePackSerializerOptions p4) => { });
113+
Deserializers.TryAdd(typeof(object), _ => (object p1, ref MessagePackReader p2, MessagePackSerializerOptions p3) => new object());
114114
}
115115

116116
private string BuildTypeName(Type type, MessagePackSerializerOptions options)
@@ -145,7 +145,7 @@ public void Serialize(ref MessagePackWriter writer, object value, MessagePackSer
145145
Type type = value.GetType();
146146

147147
byte[] typeName;
148-
var typeNameCache = options.OmitAssemblyVersion ? this.shortenedTypeNameCache : this.fullTypeNameCache;
148+
var typeNameCache = options.OmitAssemblyVersion ? ShortenedTypeNameCache : FullTypeNameCache;
149149
if (!typeNameCache.TryGetValue(type, out typeName))
150150
{
151151
TypeInfo ti = type.GetTypeInfo();
@@ -170,12 +170,12 @@ public void Serialize(ref MessagePackWriter writer, object value, MessagePackSer
170170
var formatter = options.Resolver.GetFormatterDynamicWithVerify(type);
171171

172172
// don't use GetOrAdd for avoid closure capture.
173-
if (!this.serializers.TryGetValue(type, out SerializeMethod serializeMethod))
173+
if (!Serializers.TryGetValue(type, out SerializeMethod serializeMethod))
174174
{
175175
// double check locking...
176-
lock (this.serializers)
176+
lock (Serializers)
177177
{
178-
if (!this.serializers.TryGetValue(type, out serializeMethod))
178+
if (!Serializers.TryGetValue(type, out serializeMethod))
179179
{
180180
TypeInfo ti = type.GetTypeInfo();
181181

@@ -196,7 +196,7 @@ public void Serialize(ref MessagePackWriter writer, object value, MessagePackSer
196196

197197
serializeMethod = Expression.Lambda<SerializeMethod>(body, param0, param1, param2, param3).Compile();
198198

199-
this.serializers.TryAdd(type, serializeMethod);
199+
Serializers.TryAdd(type, serializeMethod);
200200
}
201201
}
202202
}
@@ -263,7 +263,7 @@ private object DeserializeByTypeName(ArraySegment<byte> typeName, ref MessagePac
263263
{
264264
// try get type with assembly name, throw if not found
265265
Type type;
266-
if (!this.typeCache.TryGetValue(typeName, out type))
266+
if (!TypeCache.TryGetValue(typeName, out type))
267267
{
268268
var buffer = new byte[typeName.Count];
269269
Buffer.BlockCopy(typeName.Array, typeName.Offset, buffer, 0, buffer.Length);
@@ -287,18 +287,18 @@ private object DeserializeByTypeName(ArraySegment<byte> typeName, ref MessagePac
287287
}
288288
}
289289

290-
this.typeCache.TryAdd(buffer, type);
290+
TypeCache.TryAdd(buffer, type);
291291
}
292292

293293
options.ThrowIfDeserializingTypeIsDisallowed(type);
294294

295295
var formatter = options.Resolver.GetFormatterDynamicWithVerify(type);
296296

297-
if (!this.deserializers.TryGetValue(type, out DeserializeMethod deserializeMethod))
297+
if (!Deserializers.TryGetValue(type, out DeserializeMethod deserializeMethod))
298298
{
299-
lock (this.deserializers)
299+
lock (Deserializers)
300300
{
301-
if (!this.deserializers.TryGetValue(type, out deserializeMethod))
301+
if (!Deserializers.TryGetValue(type, out deserializeMethod))
302302
{
303303
TypeInfo ti = type.GetTypeInfo();
304304

@@ -323,7 +323,7 @@ private object DeserializeByTypeName(ArraySegment<byte> typeName, ref MessagePac
323323

324324
deserializeMethod = Expression.Lambda<DeserializeMethod>(body, param0, param1, param2).Compile();
325325

326-
this.deserializers.TryAdd(type, deserializeMethod);
326+
Deserializers.TryAdd(type, deserializeMethod);
327327
}
328328
}
329329
}

src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackSerializerTypelessTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Runtime.Serialization;
88
using MessagePack;
9+
using MessagePack.Formatters;
910
using MessagePack.Resolvers;
1011
using Xunit;
1112
using Xunit.Abstractions;
@@ -104,6 +105,14 @@ public void PrimitiveIntTypePreservation(object boxedValue)
104105
Assert.IsType(boxedValue.GetType(), roundTripValue);
105106
}
106107

108+
[Fact]
109+
public void TypelessFormatterAsAttribute()
110+
{
111+
byte[] msgpack = MessagePackSerializer.Serialize(new ClassWithTypelessField { Value = "hi" }, MessagePackSerializerOptions.Standard);
112+
var deserialized = MessagePackSerializer.Deserialize<ClassWithTypelessField>(msgpack, MessagePackSerializerOptions.Standard);
113+
Assert.Equal("hi", deserialized.Value);
114+
}
115+
107116
public class MyObject
108117
{
109118
public object SomeValue { get; set; }
@@ -165,6 +174,14 @@ public class TypelessNonAbstract : TypelessAbstract
165174
{
166175
public int Y { get; set; }
167176
}
177+
178+
[MessagePackObject]
179+
public class ClassWithTypelessField
180+
{
181+
[Key("Value")]
182+
[MessagePackFormatter(typeof(TypelessFormatter))]
183+
public object Value;
184+
}
168185
}
169186

170187
#endif

src/MessagePack/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ MessagePack.Formatters.ReadOnlySequenceFormatter<T>.Serialize(ref MessagePack.Me
3636
MessagePack.Formatters.TypeFormatter<T>
3737
MessagePack.Formatters.TypeFormatter<T>.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> T
3838
MessagePack.Formatters.TypeFormatter<T>.Serialize(ref MessagePack.MessagePackWriter writer, T value, MessagePack.MessagePackSerializerOptions options) -> void
39+
MessagePack.Formatters.TypelessFormatter.TypelessFormatter() -> void
3940
MessagePack.ImmutableCollection.ImmutableArrayFormatter<T>
4041
MessagePack.ImmutableCollection.ImmutableArrayFormatter<T>.Deserialize(ref MessagePack.MessagePackReader reader, MessagePack.MessagePackSerializerOptions options) -> System.Collections.Immutable.ImmutableArray<T>
4142
MessagePack.ImmutableCollection.ImmutableArrayFormatter<T>.ImmutableArrayFormatter() -> void

0 commit comments

Comments
 (0)