60 lines
2.9 KiB
C#
60 lines
2.9 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Text;
|
|
using System.Buffers;
|
|
using System.IO;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace ShrinkNetwork
|
|
{
|
|
public sealed class ShrinkJsonNetworkSerializer : IShrinkNetworkBufferSerializer
|
|
{
|
|
private static readonly JsonSerializerSettings Settings = new()
|
|
{
|
|
NullValueHandling = NullValueHandling.Ignore,
|
|
DefaultValueHandling = DefaultValueHandling.Include,
|
|
Formatting = Formatting.None
|
|
};
|
|
|
|
public byte[] Serialize(object value)
|
|
=> Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value, Settings));
|
|
|
|
public object Deserialize(byte[] payload, Type type)
|
|
=> JsonConvert.DeserializeObject(Encoding.UTF8.GetString(payload), type, Settings)
|
|
?? throw new JsonSerializationException($"Failed to deserialize payload into {type.FullName}.");
|
|
|
|
public T Deserialize<T>(byte[] payload)
|
|
=> JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(payload), Settings)
|
|
?? throw new JsonSerializationException($"Failed to deserialize payload into {typeof(T).FullName}.");
|
|
|
|
public void Serialize(IBufferWriter<byte> writer, object value)
|
|
{
|
|
using var stream = new BufferStream(writer);
|
|
using var text = new StreamWriter(stream, new UTF8Encoding(false), 1024, leaveOpen: true);
|
|
using var json = new JsonTextWriter(text);
|
|
JsonSerializer.Create(Settings).Serialize(json, value);
|
|
}
|
|
|
|
public object Deserialize(ReadOnlyMemory<byte> payload, Type type) =>
|
|
JsonConvert.DeserializeObject(Encoding.UTF8.GetString(payload.Span), type, Settings)
|
|
?? throw new JsonSerializationException($"Failed to deserialize payload into {type.FullName}.");
|
|
|
|
private sealed class BufferStream : Stream
|
|
{
|
|
private readonly IBufferWriter<byte> _writer;
|
|
public BufferStream(IBufferWriter<byte> writer) => _writer = writer;
|
|
public override bool CanRead => false;
|
|
public override bool CanSeek => false;
|
|
public override bool CanWrite => true;
|
|
public override long Length => throw new NotSupportedException();
|
|
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
|
|
public override void Flush() { }
|
|
public override void Write(byte[] buffer, int offset, int count) { buffer.AsSpan(offset, count).CopyTo(_writer.GetSpan(count)); _writer.Advance(count); }
|
|
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
|
|
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
|
|
public override void SetLength(long value) => throw new NotSupportedException();
|
|
}
|
|
}
|
|
}
|