// 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.Buffers; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Text; using MessagePack.Formatters; using MessagePack.Internal; using MessagePack.Resolvers; #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1509 // Opening braces should not be preceded by blank line namespace MessagePack.Resolvers { public sealed class BuiltinResolver : IFormatterResolver { /// /// The singleton instance that can be used. /// public static readonly BuiltinResolver Instance = new BuiltinResolver(); private BuiltinResolver() { } public IMessagePackFormatter GetFormatter() { return FormatterCache.Formatter; } private static class FormatterCache { public static readonly IMessagePackFormatter Formatter; static FormatterCache() { // Reduce IL2CPP code generate size(don't write long code in ) Formatter = (IMessagePackFormatter)BuiltinResolverGetFormatterHelper.GetFormatter(typeof(T)); } } } } namespace MessagePack.Internal { internal static class BuiltinResolverGetFormatterHelper { private static readonly Dictionary FormatterMap = new Dictionary() { // Primitive { typeof(Int16), Int16Formatter.Instance }, { typeof(Int32), Int32Formatter.Instance }, { typeof(Int64), Int64Formatter.Instance }, { typeof(UInt16), UInt16Formatter.Instance }, { typeof(UInt32), UInt32Formatter.Instance }, { typeof(UInt64), UInt64Formatter.Instance }, { typeof(Single), SingleFormatter.Instance }, { typeof(Double), DoubleFormatter.Instance }, { typeof(bool), BooleanFormatter.Instance }, { typeof(byte), ByteFormatter.Instance }, { typeof(sbyte), SByteFormatter.Instance }, { typeof(DateTime), DateTimeFormatter.Instance }, { typeof(char), CharFormatter.Instance }, // Nulllable Primitive { typeof(Int16?), NullableInt16Formatter.Instance }, { typeof(Int32?), NullableInt32Formatter.Instance }, { typeof(Int64?), NullableInt64Formatter.Instance }, { typeof(UInt16?), NullableUInt16Formatter.Instance }, { typeof(UInt32?), NullableUInt32Formatter.Instance }, { typeof(UInt64?), NullableUInt64Formatter.Instance }, { typeof(Single?), NullableSingleFormatter.Instance }, { typeof(Double?), NullableDoubleFormatter.Instance }, { typeof(bool?), NullableBooleanFormatter.Instance }, { typeof(byte?), NullableByteFormatter.Instance }, { typeof(sbyte?), NullableSByteFormatter.Instance }, { typeof(DateTime?), NullableDateTimeFormatter.Instance }, { typeof(char?), NullableCharFormatter.Instance }, // StandardClassLibraryFormatter { typeof(string), NullableStringFormatter.Instance }, { typeof(decimal), DecimalFormatter.Instance }, { typeof(decimal?), new StaticNullableFormatter(DecimalFormatter.Instance) }, { typeof(TimeSpan), TimeSpanFormatter.Instance }, { typeof(TimeSpan?), new StaticNullableFormatter(TimeSpanFormatter.Instance) }, { typeof(DateTimeOffset), DateTimeOffsetFormatter.Instance }, { typeof(DateTimeOffset?), new StaticNullableFormatter(DateTimeOffsetFormatter.Instance) }, { typeof(Guid), GuidFormatter.Instance }, { typeof(Guid?), new StaticNullableFormatter(GuidFormatter.Instance) }, { typeof(Uri), UriFormatter.Instance }, { typeof(Version), VersionFormatter.Instance }, { typeof(StringBuilder), StringBuilderFormatter.Instance }, { typeof(BitArray), BitArrayFormatter.Instance }, { typeof(Type), TypeFormatter.Instance }, // special primitive { typeof(byte[]), ByteArrayFormatter.Instance }, // Nil { typeof(Nil), NilFormatter.Instance }, { typeof(Nil?), NullableNilFormatter.Instance }, // optimized primitive array formatter { typeof(Int16[]), Int16ArrayFormatter.Instance }, { typeof(Int32[]), Int32ArrayFormatter.Instance }, { typeof(Int64[]), Int64ArrayFormatter.Instance }, { typeof(UInt16[]), UInt16ArrayFormatter.Instance }, { typeof(UInt32[]), UInt32ArrayFormatter.Instance }, { typeof(UInt64[]), UInt64ArrayFormatter.Instance }, { typeof(Single[]), SingleArrayFormatter.Instance }, { typeof(Double[]), DoubleArrayFormatter.Instance }, { typeof(Boolean[]), BooleanArrayFormatter.Instance }, { typeof(SByte[]), SByteArrayFormatter.Instance }, { typeof(DateTime[]), DateTimeArrayFormatter.Instance }, { typeof(Char[]), CharArrayFormatter.Instance }, { typeof(string[]), NullableStringArrayFormatter.Instance }, // well known collections { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(List), new ListFormatter() }, { typeof(object[]), new ArrayFormatter() }, { typeof(List), new ListFormatter() }, { typeof(Memory), ByteMemoryFormatter.Instance }, { typeof(Memory?), new StaticNullableFormatter>(ByteMemoryFormatter.Instance) }, { typeof(ReadOnlyMemory), ByteReadOnlyMemoryFormatter.Instance }, { typeof(ReadOnlyMemory?), new StaticNullableFormatter>(ByteReadOnlyMemoryFormatter.Instance) }, { typeof(ReadOnlySequence), ByteReadOnlySequenceFormatter.Instance }, { typeof(ReadOnlySequence?), new StaticNullableFormatter>(ByteReadOnlySequenceFormatter.Instance) }, { typeof(ArraySegment), ByteArraySegmentFormatter.Instance }, { typeof(ArraySegment?), new StaticNullableFormatter>(ByteArraySegmentFormatter.Instance) }, { typeof(System.Numerics.BigInteger), BigIntegerFormatter.Instance }, { typeof(System.Numerics.BigInteger?), new StaticNullableFormatter(BigIntegerFormatter.Instance) }, { typeof(System.Numerics.Complex), ComplexFormatter.Instance }, { typeof(System.Numerics.Complex?), new StaticNullableFormatter(ComplexFormatter.Instance) }, #if NET5_0_OR_GREATER { typeof(System.Half), HalfFormatter.Instance }, #endif }; internal static object GetFormatter(Type t) { object formatter; if (FormatterMap.TryGetValue(t, out formatter)) { return formatter; } if (typeof(Type).IsAssignableFrom(t)) { return typeof(TypeFormatter<>).MakeGenericType(t).GetField(nameof(TypeFormatter.Instance)).GetValue(null); } return null; } } }