ZK_Framework/Assets/Plugins/MessagePack/Formatters/DictionaryFormatter.cs

300 lines
12 KiB
C#

// 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.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
#pragma warning disable SA1649 // File name should match first type name
namespace MessagePack.Formatters
{
// unfortunately, can't use IDictionary<KVP> because supports IReadOnlyDictionary.
public abstract class DictionaryFormatterBase<TKey, TValue, TIntermediate, TEnumerator, TDictionary> : IMessagePackFormatter<TDictionary>
where TDictionary : IEnumerable<KeyValuePair<TKey, TValue>>
where TEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>
{
public void Serialize(ref MessagePackWriter writer, TDictionary value, MessagePackSerializerOptions options)
{
if (value == null)
{
writer.WriteNil();
}
else
{
IFormatterResolver resolver = options.Resolver;
IMessagePackFormatter<TKey> keyFormatter = resolver.GetFormatterWithVerify<TKey>();
IMessagePackFormatter<TValue> valueFormatter = resolver.GetFormatterWithVerify<TValue>();
int count;
{
var col = value as ICollection<KeyValuePair<TKey, TValue>>;
if (col != null)
{
count = col.Count;
}
else
{
var col2 = value as IReadOnlyCollection<KeyValuePair<TKey, TValue>>;
if (col2 != null)
{
count = col2.Count;
}
else
{
throw new MessagePackSerializationException("DictionaryFormatterBase's TDictionary supports only ICollection<KVP> or IReadOnlyCollection<KVP>");
}
}
}
writer.WriteMapHeader(count);
TEnumerator e = this.GetSourceEnumerator(value);
try
{
while (e.MoveNext())
{
writer.CancellationToken.ThrowIfCancellationRequested();
KeyValuePair<TKey, TValue> item = e.Current;
keyFormatter.Serialize(ref writer, item.Key, options);
valueFormatter.Serialize(ref writer, item.Value, options);
}
}
finally
{
e.Dispose();
}
}
}
public TDictionary Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
if (reader.TryReadNil())
{
return default(TDictionary);
}
else
{
IFormatterResolver resolver = options.Resolver;
IMessagePackFormatter<TKey> keyFormatter = resolver.GetFormatterWithVerify<TKey>();
IMessagePackFormatter<TValue> valueFormatter = resolver.GetFormatterWithVerify<TValue>();
var len = reader.ReadMapHeader();
TIntermediate dict = this.Create(len, options);
options.Security.DepthStep(ref reader);
try
{
for (int i = 0; i < len; i++)
{
reader.CancellationToken.ThrowIfCancellationRequested();
TKey key = keyFormatter.Deserialize(ref reader, options);
TValue value = valueFormatter.Deserialize(ref reader, options);
this.Add(dict, i, key, value, options);
}
}
finally
{
reader.Depth--;
}
return this.Complete(dict);
}
}
// abstraction for serialize
// Some collections can use struct iterator, this is optimization path
protected abstract TEnumerator GetSourceEnumerator(TDictionary source);
// abstraction for deserialize
protected abstract TIntermediate Create(int count, MessagePackSerializerOptions options);
protected abstract void Add(TIntermediate collection, int index, TKey key, TValue value, MessagePackSerializerOptions options);
protected abstract TDictionary Complete(TIntermediate intermediateCollection);
}
public abstract class DictionaryFormatterBase<TKey, TValue, TIntermediate, TDictionary> : DictionaryFormatterBase<TKey, TValue, TIntermediate, IEnumerator<KeyValuePair<TKey, TValue>>, TDictionary>
where TDictionary : IEnumerable<KeyValuePair<TKey, TValue>>
{
protected override IEnumerator<KeyValuePair<TKey, TValue>> GetSourceEnumerator(TDictionary source)
{
return source.GetEnumerator();
}
}
public abstract class DictionaryFormatterBase<TKey, TValue, TDictionary> : DictionaryFormatterBase<TKey, TValue, TDictionary, TDictionary>
where TDictionary : IDictionary<TKey, TValue>
{
protected override TDictionary Complete(TDictionary intermediateCollection)
{
return intermediateCollection;
}
}
public sealed class DictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, Dictionary<TKey, TValue>, Dictionary<TKey, TValue>.Enumerator, Dictionary<TKey, TValue>>
{
protected override void Add(Dictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override Dictionary<TKey, TValue> Complete(Dictionary<TKey, TValue> intermediateCollection)
{
return intermediateCollection;
}
protected override Dictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new Dictionary<TKey, TValue>(count, options.Security.GetEqualityComparer<TKey>());
}
protected override Dictionary<TKey, TValue>.Enumerator GetSourceEnumerator(Dictionary<TKey, TValue> source)
{
return source.GetEnumerator();
}
}
public sealed class GenericDictionaryFormatter<TKey, TValue, TDictionary> : DictionaryFormatterBase<TKey, TValue, TDictionary>
where TDictionary : IDictionary<TKey, TValue>, new()
{
protected override void Add(TDictionary collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override TDictionary Create(int count, MessagePackSerializerOptions options)
{
return CollectionHelpers<TDictionary, IEqualityComparer<TKey>>.CreateHashCollection(count, options.Security.GetEqualityComparer<TKey>());
}
}
public sealed class GenericReadOnlyDictionaryFormatter<TKey, TValue, TDictionary> : DictionaryFormatterBase<TKey, TValue, Dictionary<TKey, TValue>, TDictionary>
where TDictionary : IReadOnlyDictionary<TKey, TValue>
{
protected override void Add(Dictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override Dictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new Dictionary<TKey, TValue>(count, options.Security.GetEqualityComparer<TKey>());
}
protected override TDictionary Complete(Dictionary<TKey, TValue> intermediateCollection)
{
return (TDictionary)Activator.CreateInstance(typeof(TDictionary), intermediateCollection);
}
}
public sealed class InterfaceDictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, Dictionary<TKey, TValue>, IDictionary<TKey, TValue>>
{
protected override void Add(Dictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override Dictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new Dictionary<TKey, TValue>(count, options.Security.GetEqualityComparer<TKey>());
}
protected override IDictionary<TKey, TValue> Complete(Dictionary<TKey, TValue> intermediateCollection)
{
return intermediateCollection;
}
}
public sealed class SortedListFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, SortedList<TKey, TValue>>
{
protected override void Add(SortedList<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override SortedList<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new SortedList<TKey, TValue>(count);
}
}
public sealed class SortedDictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, SortedDictionary<TKey, TValue>, SortedDictionary<TKey, TValue>.Enumerator, SortedDictionary<TKey, TValue>>
{
protected override void Add(SortedDictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override SortedDictionary<TKey, TValue> Complete(SortedDictionary<TKey, TValue> intermediateCollection)
{
return intermediateCollection;
}
protected override SortedDictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new SortedDictionary<TKey, TValue>();
}
protected override SortedDictionary<TKey, TValue>.Enumerator GetSourceEnumerator(SortedDictionary<TKey, TValue> source)
{
return source.GetEnumerator();
}
}
public sealed class ReadOnlyDictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, Dictionary<TKey, TValue>, ReadOnlyDictionary<TKey, TValue>>
{
protected override void Add(Dictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override ReadOnlyDictionary<TKey, TValue> Complete(Dictionary<TKey, TValue> intermediateCollection)
{
return new ReadOnlyDictionary<TKey, TValue>(intermediateCollection);
}
protected override Dictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new Dictionary<TKey, TValue>(count, options.Security.GetEqualityComparer<TKey>());
}
}
public sealed class InterfaceReadOnlyDictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, Dictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>>
{
protected override void Add(Dictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.Add(key, value);
}
protected override IReadOnlyDictionary<TKey, TValue> Complete(Dictionary<TKey, TValue> intermediateCollection)
{
return intermediateCollection;
}
protected override Dictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
return new Dictionary<TKey, TValue>(count, options.Security.GetEqualityComparer<TKey>());
}
}
public sealed class ConcurrentDictionaryFormatter<TKey, TValue> : DictionaryFormatterBase<TKey, TValue, System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>>
{
protected override void Add(ConcurrentDictionary<TKey, TValue> collection, int index, TKey key, TValue value, MessagePackSerializerOptions options)
{
collection.TryAdd(key, value);
}
protected override ConcurrentDictionary<TKey, TValue> Create(int count, MessagePackSerializerOptions options)
{
// concurrent dictionary can't access defaultConcurrecyLevel so does not use count overload.
return new ConcurrentDictionary<TKey, TValue>(options.Security.GetEqualityComparer<TKey>());
}
}
}