From 8c1945e352cbf78ff189471274f950ca8a4eb051 Mon Sep 17 00:00:00 2001 From: Edmand46 Date: Thu, 26 May 2022 21:06:26 +0400 Subject: [PATCH] feat: added RagonSerializer, removed RagonHeader, reduced boilerplate code --- Ragon.Common/Protocol/RagonHeader.cs | 35 ----- Ragon.Common/Protocol/RagonSerializer.cs | 167 +++++++++++++++++++++++ 2 files changed, 167 insertions(+), 35 deletions(-) delete mode 100644 Ragon.Common/Protocol/RagonHeader.cs create mode 100644 Ragon.Common/Protocol/RagonSerializer.cs diff --git a/Ragon.Common/Protocol/RagonHeader.cs b/Ragon.Common/Protocol/RagonHeader.cs deleted file mode 100644 index 8a8fbe4..0000000 --- a/Ragon.Common/Protocol/RagonHeader.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using NetStack.Buffers; - -namespace Ragon.Common -{ - public static class RagonHeader - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteUShort(ushort id, ref Span data) { - data[0] = (byte)(id & 0x00FF); - data[1] = (byte)((id & 0xFF00) >> 8); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort ReadUShort(ref ReadOnlySpan data) - { - return (ushort)(data[0] + (data[1] << 8)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteInt(int id, ref Span data) { - data[0] = (byte)(id & 0x00FF); - data[1] = (byte)((id & 0xFF00) >> 8); - data[2] = (byte)((id & 0xFF00) >> 16); - data[3] = (byte)((id & 0xFF00) >> 24); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadInt(ref ReadOnlySpan data) - { - return (ushort)(data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)); - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/RagonSerializer.cs b/Ragon.Common/Protocol/RagonSerializer.cs new file mode 100644 index 0000000..f2d8d7a --- /dev/null +++ b/Ragon.Common/Protocol/RagonSerializer.cs @@ -0,0 +1,167 @@ +using System; +using System.Runtime.CompilerServices; +using System.Text; + + +namespace Ragon.Common +{ + + public class RagonSerializer + { + private byte[] _data; + private int _offset; + private int _size; + public int Lenght => _offset; + public int Size => _size - _offset; + + public RagonSerializer(int capacity = 2048) + { + _data = new byte[capacity]; + _offset = 0; + _size = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteByte(byte value) + { + _data[_offset] = value; + _offset += 1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadByte() + { + var value = _data[_offset]; + _offset += 1; + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteInt(int value) + { + _data[_offset] = (byte) (value & 0x00FF); + _data[_offset + 1] = (byte) ((value & 0xFF00) >> 8); + _data[_offset + 2] = (byte) ((value & 0xFF00) >> 16); + _data[_offset + 3] = (byte) ((value & 0xFF00) >> 24); + _offset += 4; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadInt() + { + var value = _data[_offset] + (_data[_offset + 1] << 8) + (_data[_offset + 2] << 16) + (_data[_offset + 3] << 24); + _offset += 4; + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteString(string value) + { + var stringRaw = Encoding.UTF8.GetBytes(value).AsSpan(); + WriteUShort((ushort) stringRaw.Length); + + var data = _data.AsSpan().Slice(_offset, stringRaw.Length); + stringRaw.CopyTo(data); + _offset += stringRaw.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string ReadString() + { + var lenght = ReadUShort(); + var stringRaw = _data.AsSpan().Slice(_offset, lenght); + var str = Encoding.UTF8.GetString(stringRaw); + _offset += lenght; + return str; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan ReadData(int lenght) + { + var data = _data.AsSpan(); + var payloadData = data.Slice(_offset, lenght); + + _offset += payloadData.Length; + return payloadData; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteData(ref ReadOnlySpan payload) + { + var data = _data.AsSpan(); + var payloadData = data.Slice(_offset, payload.Length); + + payload.CopyTo(payloadData); + _offset += payload.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetWritableData(int lenght) + { + var data = _data.AsSpan(); + var payloadData = data.Slice(_offset, lenght); + + _offset += lenght; + return payloadData; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteOperation(RagonOperation ragonOperation) + { + _data[_offset] = (byte) ragonOperation; + _offset += 1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public RagonOperation ReadOperation() + { + var op = (RagonOperation) _data[_offset]; + _offset += 1; + return op; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void WriteUShort(ushort value) + { + _data[_offset] = (byte) (value & 0x00FF); + _data[_offset + 1] = (byte) ((value & 0xFF00) >> 8); + _offset += 2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ushort ReadUShort() + { + var value = (ushort) (_data[_offset] + (_data[_offset + 1] << 8)); + _offset += 2; + return value; + } + + public void Clear() + { + _offset = 0; + _size = 0; + } + + public void ToSpan(ref Span data) + { + var span = _data.AsSpan(); + var dataSpan = span.Slice(0, _offset); + dataSpan.CopyTo(data); + } + + public byte[] ToArray() + { + var bytes = new byte[_offset]; + Buffer.BlockCopy(_data, 0, bytes, 0, _offset); + return bytes; + } + + public void FromSpan(ref ReadOnlySpan data) + { + Clear(); + var dataSpan = _data.AsSpan(); + data.CopyTo(dataSpan); + _size = data.Length; + } + } +} \ No newline at end of file