// 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.Runtime.CompilerServices; namespace MessagePack.Formatters { public sealed class GenericEnumFormatter : IMessagePackFormatter where T : Enum { private delegate void EnumSerialize(ref MessagePackWriter writer, ref T value); private delegate T EnumDeserialize(ref MessagePackReader reader); private readonly EnumSerialize serializer; private readonly EnumDeserialize deserializer; public GenericEnumFormatter() { var underlyingType = typeof(T).GetEnumUnderlyingType(); switch (Type.GetTypeCode(underlyingType)) { #pragma warning disable SA1107 // Avoid multiple statements on same line. case TypeCode.Byte: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadByte(); return Unsafe.As(ref v); }; break; case TypeCode.Int16: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadInt16(); return Unsafe.As(ref v); }; break; case TypeCode.Int32: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadInt32(); return Unsafe.As(ref v); }; break; case TypeCode.Int64: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadInt64(); return Unsafe.As(ref v); }; break; case TypeCode.SByte: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadSByte(); return Unsafe.As(ref v); }; break; case TypeCode.UInt16: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadUInt16(); return Unsafe.As(ref v); }; break; case TypeCode.UInt32: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadUInt32(); return Unsafe.As(ref v); }; break; case TypeCode.UInt64: serializer = (ref MessagePackWriter writer, ref T value) => writer.Write(Unsafe.As(ref value)); deserializer = (ref MessagePackReader reader) => { var v = reader.ReadUInt64(); return Unsafe.As(ref v); }; break; default: break; #pragma warning restore SA1107 // Avoid multiple statements on same line. } } public void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializerOptions options) { serializer(ref writer, ref value); } public T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { return deserializer(ref reader); } } }