Added Converters/Formatters for Serialization of Json/MessagePack
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dns" Version="7.0.0" />
|
||||
<PackageReference Include="MessagePack" Version="2.4.35" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitLab" Version="1.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
70
AMWD.Common/Converters/ByteArrayHexConverter.cs
Normal file
70
AMWD.Common/Converters/ByteArrayHexConverter.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a byte array from and to a hex string.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
public class ByteArrayHexConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// List of known types to use this converver.
|
||||
/// </summary>
|
||||
public static readonly Type[] KnownTypes = new[]
|
||||
{
|
||||
typeof(byte[]),
|
||||
typeof(List<byte>),
|
||||
typeof(IEnumerable<byte>)
|
||||
};
|
||||
|
||||
/// <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 hex = (string)reader.Value;
|
||||
var byteEnum = hex.HexToBytes();
|
||||
|
||||
if (typeof(byte[]) == objectType)
|
||||
return byteEnum.ToArray();
|
||||
|
||||
if (typeof(List<byte>) == objectType)
|
||||
return byteEnum.ToList();
|
||||
|
||||
return byteEnum;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
string hex = null;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteValue(hex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value is byte[] byteArray)
|
||||
hex = byteArray.BytesToHex();
|
||||
|
||||
if (value is List<byte> byteList)
|
||||
hex = byteList.BytesToHex();
|
||||
|
||||
if (value is IEnumerable<byte> byteEnum)
|
||||
hex = byteEnum.BytesToHex();
|
||||
|
||||
writer.WriteValue(hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
AMWD.Common/Converters/IPAddressConverter.cs
Normal file
78
AMWD.Common/Converters/IPAddressConverter.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an <see cref="IPAddress"/> from and to JSON.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
public class IPAddressConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// List of known types to use this converver.
|
||||
/// </summary>
|
||||
public static readonly Type[] KnownTypes = new[]
|
||||
{
|
||||
typeof(IPAddress),
|
||||
typeof(IPAddress[]),
|
||||
typeof(List<IPAddress>),
|
||||
typeof(IEnumerable<IPAddress>)
|
||||
};
|
||||
|
||||
/// <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(IPAddress) == objectType)
|
||||
return IPAddress.Parse(str);
|
||||
|
||||
var ips = str.Split(';').Select(s => IPAddress.Parse(s));
|
||||
|
||||
if (typeof(IPAddress[]) == objectType)
|
||||
return ips.ToArray();
|
||||
|
||||
if (typeof(List<IPAddress>) == objectType)
|
||||
return ips.ToList();
|
||||
|
||||
return ips;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
string str = null;
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteValue(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value is IPAddress addr)
|
||||
str = addr.ToString();
|
||||
|
||||
if (value is IPAddress[] addrArray)
|
||||
str = string.Join(";", addrArray.Select(ip => ip.ToString()));
|
||||
|
||||
if (value is List<IPAddress> addrList)
|
||||
str = string.Join(";", addrList.Select(ip => ip.ToString()));
|
||||
|
||||
if (value is List<IPAddress> addrEnum)
|
||||
str = string.Join(";", addrEnum.Select(ip => ip.ToString()));
|
||||
|
||||
writer.WriteValue(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
AMWD.Common/Formatters/IPAddressArrayFormatter.cs
Normal file
77
AMWD.Common/Formatters/IPAddressArrayFormatter.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialization of an <see cref="IPAddress"/> array to and from <see cref="MessagePack"/>.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
public class IPAddressArrayFormatter : IMessagePackFormatter<IPAddress[]>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IPAddress[] 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);
|
||||
|
||||
Swap(buffer);
|
||||
int length = BitConverter.ToInt32(buffer, 0);
|
||||
|
||||
int arrayPos = 0;
|
||||
var array = new IPAddress[length];
|
||||
while (bytePos < bytes.Length)
|
||||
{
|
||||
byte len = bytes.Skip(bytePos).First();
|
||||
bytePos++;
|
||||
|
||||
buffer = bytes.Skip(bytePos).Take(len).ToArray();
|
||||
bytePos += len;
|
||||
|
||||
array[arrayPos] = new IPAddress(buffer);
|
||||
arrayPos++;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Serialize(ref MessagePackWriter writer, IPAddress[] value, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNil();
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = new List<byte>();
|
||||
|
||||
int length = value.Length;
|
||||
byte[] buffer = BitConverter.GetBytes(length);
|
||||
Swap(buffer);
|
||||
bytes.AddRange(buffer);
|
||||
|
||||
foreach (var ip in value)
|
||||
{
|
||||
buffer = ip.GetAddressBytes();
|
||||
bytes.Add((byte)buffer.Length);
|
||||
bytes.AddRange(buffer);
|
||||
}
|
||||
|
||||
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||
}
|
||||
|
||||
private void Swap(byte[] bytes)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
AMWD.Common/Formatters/IPAddressFormatter.cs
Normal file
34
AMWD.Common/Formatters/IPAddressFormatter.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Net;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialization of an <see cref="IPAddress"/> to and from <see cref="MessagePack"/>.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
public class IPAddressFormatter : IMessagePackFormatter<IPAddress>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public IPAddress Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (reader.IsNil)
|
||||
return null;
|
||||
|
||||
byte[] bytes = options.Resolver.GetFormatterWithVerify<byte[]>().Deserialize(ref reader, options);
|
||||
return new IPAddress(bytes);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Serialize(ref MessagePackWriter writer, IPAddress value, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNil();
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] bytes = value.GetAddressBytes();
|
||||
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
AMWD.Common/Formatters/IPAddressListFormatter.cs
Normal file
72
AMWD.Common/Formatters/IPAddressListFormatter.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace MessagePack.Formatters
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialization of an <see cref="IPAddress"/> list to and from <see cref="MessagePack"/>.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
public class IPAddressListFormatter : IMessagePackFormatter<List<IPAddress>>
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public List<IPAddress> 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<IPAddress>();
|
||||
while (bytePos < bytes.Length)
|
||||
{
|
||||
byte len = bytes.Skip(bytePos).First();
|
||||
bytePos++;
|
||||
|
||||
byte[] buffer = bytes.Skip(bytePos).Take(len).ToArray();
|
||||
bytePos += len;
|
||||
|
||||
list.Add(new IPAddress(buffer));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Serialize(ref MessagePackWriter writer, List<IPAddress> value, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNil();
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = new List<byte>();
|
||||
|
||||
int length = value.Count;
|
||||
byte[] buffer = BitConverter.GetBytes(length);
|
||||
Swap(buffer);
|
||||
bytes.AddRange(buffer);
|
||||
|
||||
foreach (var ip in value)
|
||||
{
|
||||
buffer = ip.GetAddressBytes();
|
||||
bytes.Add((byte)buffer.Length);
|
||||
bytes.AddRange(buffer);
|
||||
}
|
||||
|
||||
options.Resolver.GetFormatterWithVerify<byte[]>().Serialize(ref writer, bytes.ToArray(), options);
|
||||
}
|
||||
|
||||
private void Swap(byte[] bytes)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user