Adding IPNetwork to Converter/Formatters
This commit is contained in:
@@ -69,7 +69,7 @@ namespace Newtonsoft.Json
|
|||||||
if (value is List<IPAddress> addrList)
|
if (value is List<IPAddress> addrList)
|
||||||
str = string.Join(";", addrList.Select(ip => ip.ToString()));
|
str = string.Join(";", addrList.Select(ip => ip.ToString()));
|
||||||
|
|
||||||
if (value is List<IPAddress> addrEnum)
|
if (value is IEnumerable<IPAddress> addrEnum)
|
||||||
str = string.Join(";", addrEnum.Select(ip => ip.ToString()));
|
str = string.Join(";", addrEnum.Select(ip => ip.ToString()));
|
||||||
|
|
||||||
writer.WriteValue(str);
|
writer.WriteValue(str);
|
||||||
|
|||||||
93
AMWD.Common/Converters/IPNetworkConverter.cs
Normal file
93
AMWD.Common/Converters/IPNetworkConverter.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
|
namespace Newtonsoft.Json
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an <see cref="IPNetwork"/> from and to JSON.
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
public class IPNetworkConverter : JsonConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of known types to use this converver.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Type[] KnownTypes = new[]
|
||||||
|
{
|
||||||
|
typeof(IPNetwork),
|
||||||
|
typeof(IPNetwork[]),
|
||||||
|
typeof(List<IPNetwork>),
|
||||||
|
typeof(IEnumerable<IPNetwork>)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool CanConvert(Type objectType)
|
||||||
|
{
|
||||||
|
return KnownTypes.Contains(objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.Value == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
string str = (string)reader.Value;
|
||||||
|
|
||||||
|
if (typeof(IPNetwork) == objectType)
|
||||||
|
return Parse(str);
|
||||||
|
|
||||||
|
var networks = str.Split(';').Select(s => Parse(s));
|
||||||
|
|
||||||
|
if (typeof(IPNetwork[]) == objectType)
|
||||||
|
return networks.ToArray();
|
||||||
|
|
||||||
|
if (typeof(List<IPNetwork>) == objectType)
|
||||||
|
return networks.ToList();
|
||||||
|
|
||||||
|
return networks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
string str = null;
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteValue(str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is IPNetwork net)
|
||||||
|
str = ToString(net);
|
||||||
|
|
||||||
|
if (value is IPNetwork[] netArray)
|
||||||
|
str = string.Join(";", netArray.Select(n => ToString(n)));
|
||||||
|
|
||||||
|
if (value is List<IPNetwork> netList)
|
||||||
|
str = string.Join(";", netList.Select(n => ToString(n)));
|
||||||
|
|
||||||
|
if (value is IEnumerable<IPNetwork> netEnum)
|
||||||
|
str = string.Join(";", netEnum.Select(n => ToString(n)));
|
||||||
|
|
||||||
|
writer.WriteValue(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ToString(IPNetwork net)
|
||||||
|
{
|
||||||
|
return $"{net.Prefix}/{net.PrefixLength}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPNetwork Parse(string str)
|
||||||
|
{
|
||||||
|
string[] parts = str.Split('/');
|
||||||
|
var prefix = IPAddress.Parse(parts.First());
|
||||||
|
int prefixLength = int.Parse(parts.Last());
|
||||||
|
|
||||||
|
return new IPNetwork(prefix, prefixLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using AMWD.Common.Utilities;
|
||||||
|
|
||||||
namespace MessagePack.Formatters
|
namespace MessagePack.Formatters
|
||||||
{
|
{
|
||||||
@@ -22,7 +23,7 @@ namespace MessagePack.Formatters
|
|||||||
byte[] buffer = bytes.Skip(bytePos).Take(sizeof(int)).ToArray();
|
byte[] buffer = bytes.Skip(bytePos).Take(sizeof(int)).ToArray();
|
||||||
bytePos += sizeof(int);
|
bytePos += sizeof(int);
|
||||||
|
|
||||||
Swap(buffer);
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
int length = BitConverter.ToInt32(buffer, 0);
|
int length = BitConverter.ToInt32(buffer, 0);
|
||||||
|
|
||||||
int arrayPos = 0;
|
int arrayPos = 0;
|
||||||
@@ -55,7 +56,7 @@ namespace MessagePack.Formatters
|
|||||||
|
|
||||||
int length = value.Length;
|
int length = value.Length;
|
||||||
byte[] buffer = BitConverter.GetBytes(length);
|
byte[] buffer = BitConverter.GetBytes(length);
|
||||||
Swap(buffer);
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
bytes.AddRange(buffer);
|
bytes.AddRange(buffer);
|
||||||
|
|
||||||
foreach (var ip in value)
|
foreach (var ip in value)
|
||||||
@@ -67,11 +68,5 @@ namespace MessagePack.Formatters
|
|||||||
|
|
||||||
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Swap(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (BitConverter.IsLittleEndian)
|
|
||||||
Array.Reverse(bytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using AMWD.Common.Utilities;
|
||||||
|
|
||||||
namespace MessagePack.Formatters
|
namespace MessagePack.Formatters
|
||||||
{
|
{
|
||||||
@@ -50,7 +51,7 @@ namespace MessagePack.Formatters
|
|||||||
|
|
||||||
int length = value.Count;
|
int length = value.Count;
|
||||||
byte[] buffer = BitConverter.GetBytes(length);
|
byte[] buffer = BitConverter.GetBytes(length);
|
||||||
Swap(buffer);
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
bytes.AddRange(buffer);
|
bytes.AddRange(buffer);
|
||||||
|
|
||||||
foreach (var ip in value)
|
foreach (var ip in value)
|
||||||
@@ -62,11 +63,5 @@ namespace MessagePack.Formatters
|
|||||||
|
|
||||||
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Swap(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (BitConverter.IsLittleEndian)
|
|
||||||
Array.Reverse(bytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
74
AMWD.Common/Formatters/IPNetworkArrayFormatter.cs
Normal file
74
AMWD.Common/Formatters/IPNetworkArrayFormatter.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AMWD.Common.Utilities;
|
||||||
|
using MessagePack;
|
||||||
|
using MessagePack.Formatters;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
|
namespace AMWD.Common.Formatters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serialization of an <see cref="IPNetwork"/> array to and from <see cref="MessagePack"/>.
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
public class IPNetworkArrayFormatter : IMessagePackFormatter<IPNetwork[]>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IPNetwork[] Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.IsNil)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int bytePos = 0;
|
||||||
|
byte[] bytes = options.Resolver.GetFormatterWithVerify<byte[]>().Deserialize(ref reader, options);
|
||||||
|
byte[] buffer = bytes.Skip(bytePos).Take(sizeof(int)).ToArray();
|
||||||
|
bytePos += sizeof(int);
|
||||||
|
|
||||||
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
|
int length = BitConverter.ToInt32(buffer, 0);
|
||||||
|
|
||||||
|
int arrayPos = 0;
|
||||||
|
var array = new IPNetwork[length];
|
||||||
|
while (bytePos < bytes.Length)
|
||||||
|
{
|
||||||
|
byte len = bytes.Skip(bytePos).First();
|
||||||
|
bytePos++;
|
||||||
|
|
||||||
|
buffer = bytes.Skip(bytePos).Take(len).ToArray();
|
||||||
|
bytePos += len;
|
||||||
|
|
||||||
|
array[arrayPos] = IPNetworkFormatter.DeserializeInternal(buffer);
|
||||||
|
arrayPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Serialize(ref MessagePackWriter writer, IPNetwork[] value, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = new List<byte>();
|
||||||
|
|
||||||
|
int length = value.Length;
|
||||||
|
byte[] buffer = BitConverter.GetBytes(length);
|
||||||
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
|
bytes.AddRange(buffer);
|
||||||
|
|
||||||
|
foreach (var network in value)
|
||||||
|
{
|
||||||
|
buffer = IPNetworkFormatter.SerializeInternal(network);
|
||||||
|
bytes.Add((byte)buffer.Length);
|
||||||
|
bytes.AddRange(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
AMWD.Common/Formatters/IPNetworkFormatter.cs
Normal file
59
AMWD.Common/Formatters/IPNetworkFormatter.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
|
namespace MessagePack.Formatters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serialization of an <see cref="IPNetwork"/> to and from <see cref="MessagePack"/>.
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
public class IPNetworkFormatter : IMessagePackFormatter<IPNetwork>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IPNetwork Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.IsNil)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
byte[] bytes = options.Resolver.GetFormatterWithVerify<byte[]>().Deserialize(ref reader, options);
|
||||||
|
return DeserializeInternal(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Serialize(ref MessagePackWriter writer, IPNetwork value, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bytes = SerializeInternal(value);
|
||||||
|
options.Resolver.GetFormatterWithVerify<byte[]>().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;
|
||||||
|
byte[] prefixBytes = network.Prefix.GetAddressBytes();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
AMWD.Common/Formatters/IPNetworkListFormatter.cs
Normal file
67
AMWD.Common/Formatters/IPNetworkListFormatter.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AMWD.Common.Utilities;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
|
namespace MessagePack.Formatters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serialization of an <see cref="IPNetwork"/> list to and from <see cref="MessagePack"/>.
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
public class IPNetworkListFormatter : IMessagePackFormatter<List<IPNetwork>>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public List<IPNetwork> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.IsNil)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
byte[] bytes = options.Resolver.GetFormatterWithVerify<byte[]>().Deserialize(ref reader, options);
|
||||||
|
|
||||||
|
// skipping the length information
|
||||||
|
int bytePos = sizeof(int);
|
||||||
|
|
||||||
|
var list = new List<IPNetwork>();
|
||||||
|
while (bytePos < bytes.Length)
|
||||||
|
{
|
||||||
|
byte len = bytes.Skip(bytePos).First();
|
||||||
|
bytePos++;
|
||||||
|
|
||||||
|
byte[] buffer = bytes.Skip(bytePos).Take(len).ToArray();
|
||||||
|
bytePos += len;
|
||||||
|
|
||||||
|
list.Add(IPNetworkFormatter.DeserializeInternal(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Serialize(ref MessagePackWriter writer, List<IPNetwork> value, MessagePackSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = new List<byte>();
|
||||||
|
|
||||||
|
int length = value.Count;
|
||||||
|
byte[] buffer = BitConverter.GetBytes(length);
|
||||||
|
NetworkHelper.SwapBigEndian(buffer);
|
||||||
|
bytes.AddRange(buffer);
|
||||||
|
|
||||||
|
foreach (var network in value)
|
||||||
|
{
|
||||||
|
buffer = IPNetworkFormatter.SerializeInternal(network);
|
||||||
|
bytes.Add((byte)buffer.Length);
|
||||||
|
bytes.AddRange(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -163,5 +163,11 @@ namespace AMWD.Common.Utilities
|
|||||||
.Where(a => addressFamily == AddressFamily.Unspecified || a.AddressFamily == addressFamily)
|
.Where(a => addressFamily == AddressFamily.Unspecified || a.AddressFamily == addressFamily)
|
||||||
.OrderBy(a => a.AddressFamily);
|
.OrderBy(a => a.AddressFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void SwapBigEndian(byte[] array)
|
||||||
|
{
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
Array.Reverse(array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
- Converters for `Newtonsoft.Json`
|
- Converters for `Newtonsoft.Json`
|
||||||
- `ByteArrayHexConverter` to get an byte array as hex string instead of Base64
|
- `ByteArrayHexConverter` to get an byte array as hex string instead of Base64
|
||||||
- `IPAddressConverter` to make `System.Net.IPAdress`es (and list forms) serializable.
|
- `IPAddressConverter` to make `System.Net.IPAdress`es (and list forms) serializable
|
||||||
|
- `IPNetworkConverter` to make `Microsoft.AspNetCore.HttpOverrides.IPNetwork` (and list forms) serializable
|
||||||
- Formatters for `MessagePack`
|
- Formatters for `MessagePack`
|
||||||
- `IPAddressFormatter` to serialize an `System.Net.IPAddress`
|
- `IPAddressFormatter` to serialize an `System.Net.IPAddress`
|
||||||
- `IPAddressArrayFormatter` to serialize arrays of `System.Net.IPAddress`es
|
- `IPAddressArrayFormatter` to serialize arrays of `System.Net.IPAddress`es
|
||||||
- `IPAddressListFormatter` to serialize lists of `System.Net.IPAddress`es
|
- `IPAddressListFormatter` to serialize lists of `System.Net.IPAddress`es
|
||||||
|
- `IPNetworkFormatter` to serialize an `Microsoft.AspNetCore.HttpOverrides.IPNetwork`
|
||||||
|
- `IPNetworkArrayFormatter` to serialize arrays of `Microsoft.AspNetCore.HttpOverrides.IPNetwork`
|
||||||
|
- `IPNetworkListFormatter` to serialize lists of `Microsoft.AspNetCore.HttpOverrides.IPNetwork`
|
||||||
|
|
||||||
|
|
||||||
## [v1.7.0](https://git.am-wd.de/AM.WD/common/compare/v1.6.1...v1.7.0) - 2022-07-24
|
## [v1.7.0](https://git.am-wd.de/AM.WD/common/compare/v1.6.1...v1.7.0) - 2022-07-24
|
||||||
|
|||||||
Reference in New Issue
Block a user