Update Readers/Writers for Buffers & Fixes bugs (#283)

- [X] Renames PacketReader to CircularBufferReader
- [X] Fixes bugs with CircularBufferReader
- [X] Adds CircularBufferWriter
- [X] Adds SpanWriter
- [X] Adds SpanReader

Bumps release version
This commit is contained in:
Kamron Batman 2020-10-24 14:46:59 -07:00 committed by GitHub
parent 3b7f648c27
commit 6bd4f0d265
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1302 additions and 351 deletions

View file

@ -6,6 +6,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using Server.Random;
@ -106,6 +107,55 @@ namespace Server
public static Encoding Unicode => m_Unicode ??= new UnicodeEncoding(true, false, false);
public static Encoding UnicodeLE => m_UnicodeLE ??= new UnicodeEncoding(false, false, false);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetByteLengthForEncoding(Encoding encoding) =>
encoding.BodyName switch
{
"utf-16BE" => 2,
"utf-16" => 2,
"utf-32BE" => 4,
"utf-32" => 4,
_ => 1
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int IndexOfTerminator(ReadOnlySpan<byte> buffer, int sizeT) =>
sizeT switch
{
2 => MemoryMarshal.Cast<byte, char>(buffer).IndexOf((char)0) * 2,
4 => MemoryMarshal.Cast<byte, uint>(buffer).IndexOf((uint)0) * 4,
_ => buffer.IndexOf((byte)0)
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsSafeChar(ushort c) => c >= 0x20 && c < 0xFFFE;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetString(ReadOnlySpan<byte> span, Encoding encoding, bool safeString = false)
{
string s = encoding.GetString(span);
if (!safeString)
{
return s;
}
ReadOnlySpan<char> chars = s.AsSpan();
StringBuilder stringBuilder = null;
for (int i = 0, last = 0; i < chars.Length; i++)
{
if (!IsSafeChar(chars[i]) || stringBuilder != null && i == chars.Length - 1)
{
(stringBuilder ??= new StringBuilder()).Append(chars.Slice(last, i - last));
last = i + 1; // Skip the unsafe char
}
}
return stringBuilder?.ToString() ?? s;
}
public static void Separate(StringBuilder sb, string value, string separator)
{
if (sb.Length > 0)