Files
ShrinkNetwork/Runtime/Serialization/ShrinkJsonNetworkSerializer.cs
T
cneicy 93c2b8520b
Publish UPM package / publish (push) Successful in 2s
Publish NuGet packages / publish (push) Successful in 3m5s
feat(network)!: add v2 framing, pooled buffers and bounded dispatch
2026-09-29 10:14:47 +08:00

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();
}
}
}