// 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; #pragma warning disable SA1649 // File name should match first type name namespace MessagePack.Formatters { public sealed class NativeGuidFormatter : IMessagePackFormatter { /// /// Unsafe binary Guid formatter. this is only allowed on LittleEndian environment. /// public static readonly IMessagePackFormatter Instance = new NativeGuidFormatter(); private NativeGuidFormatter() { } /* Guid's underlying _a,...,_k field is sequential and same layout as .NET Framework and Mono(Unity). * But target machines must be same endian so restrict only for little endian. */ public unsafe void Serialize(ref MessagePackWriter writer, Guid value, MessagePackSerializerOptions options) { if (!BitConverter.IsLittleEndian) { throw new InvalidOperationException("NativeGuidFormatter only allows on little endian env."); } var valueSpan = new ReadOnlySpan(&value, sizeof(Guid)); writer.Write(valueSpan); } public unsafe Guid Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (!BitConverter.IsLittleEndian) { throw new InvalidOperationException("NativeGuidFormatter only allows on little endian env."); } ReadOnlySequence valueSequence = reader.ReadBytes().Value; if (valueSequence.Length != sizeof(Guid)) { throw new MessagePackSerializationException("Invalid Guid Size."); } Guid result; var resultSpan = new Span(&result, sizeof(Guid)); valueSequence.CopyTo(resultSpan); return result; } } public sealed class NativeDecimalFormatter : IMessagePackFormatter { /// /// Unsafe binary Decimal formatter. this is only allows on LittleEndian environment. /// public static readonly IMessagePackFormatter Instance = new NativeDecimalFormatter(); private NativeDecimalFormatter() { } /* decimal underlying "flags, hi, lo, mid" fields are sequential and same layuout with .NET Framework and Mono(Unity) * But target machines must be same endian so restrict only for little endian. */ public unsafe void Serialize(ref MessagePackWriter writer, Decimal value, MessagePackSerializerOptions options) { if (!BitConverter.IsLittleEndian) { throw new InvalidOperationException("NativeDecimalFormatter only allows on little endian env."); } var valueSpan = new ReadOnlySpan(&value, sizeof(Decimal)); writer.Write(valueSpan); } public unsafe Decimal Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (!BitConverter.IsLittleEndian) { throw new InvalidOperationException("NativeDecimalFormatter only allows on little endian env."); } ReadOnlySequence valueSequence = reader.ReadBytes().Value; if (valueSequence.Length != sizeof(decimal)) { throw new MessagePackSerializationException("Invalid decimal Size."); } decimal result; var resultSpan = new Span(&result, sizeof(decimal)); valueSequence.CopyTo(resultSpan); return result; } } }