using System; using System.Linq; using System.Net; #if NET8_0_OR_GREATER using IPNetwork = System.Net.IPNetwork; #else using Microsoft.AspNetCore.HttpOverrides; using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork; #endif namespace MessagePack.Formatters { /// /// Serialization of an to and from . /// [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public class IPNetworkFormatter : IMessagePackFormatter { /// public IPNetwork Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (reader.IsNil) return default; byte[] bytes = options.Resolver.GetFormatterWithVerify().Deserialize(ref reader, options); return DeserializeInternal(bytes); } /// public void Serialize(ref MessagePackWriter writer, IPNetwork value, MessagePackSerializerOptions options) { if (value == default) { writer.WriteNil(); return; } byte[] bytes = SerializeInternal(value); options.Resolver.GetFormatterWithVerify().Serialize(ref writer, bytes, options); } internal static byte[] SerializeInternal(IPNetwork network) { // IP network prefix has a maximum of 128 bit - therefore the length can be covered with a byte. byte prefixLength = (byte)network.PrefixLength; #if NET8_0_OR_GREATER byte[] prefixBytes = network.BaseAddress.GetAddressBytes(); #else byte[] prefixBytes = network.Prefix.GetAddressBytes(); #endif byte[] bytes = new byte[prefixBytes.Length + 1]; bytes[0] = prefixLength; Array.Copy(prefixBytes, 0, bytes, 1, prefixBytes.Length); return bytes; } internal static IPNetwork DeserializeInternal(byte[] bytes) { byte prefixLength = bytes[0]; byte[] prefixBytes = bytes.Skip(1).ToArray(); var prefix = new IPAddress(prefixBytes); return new IPNetwork(prefix, prefixLength); } } }