Adds BufferReader and BufferWriter. Updates UOP handling. (#101)
This commit is contained in:
parent
2c0d97cd36
commit
038c3be258
98 changed files with 2458 additions and 2185 deletions
181
Projects/Server/Buffers/BufferReaderExtensions.cs
Normal file
181
Projects/Server/Buffers/BufferReaderExtensions.cs
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
// Copyright (c) Harry Pierson. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers
|
||||
{
|
||||
public static class BufferReaderExtensions
|
||||
{
|
||||
private static unsafe bool TryRead<T>(ref this BufferReader<byte> reader, out T value)
|
||||
where T : unmanaged
|
||||
{
|
||||
ReadOnlySpan<byte> span = reader.UnreadSpan;
|
||||
if (span.Length < sizeof(T)) return TryReadMultisegment(ref reader, out value);
|
||||
|
||||
value = Unsafe.ReadUnaligned<T>(ref MemoryMarshal.GetReference(span));
|
||||
reader.Advance(sizeof(T));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static unsafe bool TryReadMultisegment<T>(ref BufferReader<byte> reader, out T value)
|
||||
where T : unmanaged
|
||||
{
|
||||
Debug.Assert(reader.UnreadSpan.Length < sizeof(T), "reader.UnreadSpan.Length < sizeof(T)");
|
||||
|
||||
// Not enough data in the current segment, try to peek for the data we need.
|
||||
T buffer = default;
|
||||
Span<byte> tempSpan = new Span<byte>(&buffer, sizeof(T));
|
||||
|
||||
if (!reader.TryCopyTo(tempSpan))
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = Unsafe.ReadUnaligned<T>(ref MemoryMarshal.GetReference(tempSpan));
|
||||
reader.Advance(sizeof(T));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryRead(ref this BufferReader<byte> reader, out sbyte value)
|
||||
{
|
||||
if (TryRead(ref reader, out byte byteValue))
|
||||
{
|
||||
value = unchecked((sbyte)byteValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out short value) =>
|
||||
BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out short value) =>
|
||||
!BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
private static bool TryReadReverseEndianness(ref BufferReader<byte> reader, out short value)
|
||||
{
|
||||
if (reader.TryRead(out value))
|
||||
{
|
||||
value = BinaryPrimitives.ReverseEndianness(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out ushort value)
|
||||
{
|
||||
if (TryReadLittleEndian(ref reader, out short signedvalue))
|
||||
{
|
||||
value = unchecked((ushort)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out ushort value)
|
||||
{
|
||||
if (TryReadBigEndian(ref reader, out short signedvalue))
|
||||
{
|
||||
value = unchecked((ushort)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out int value) =>
|
||||
BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out int value) =>
|
||||
!BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
private static bool TryReadReverseEndianness(ref BufferReader<byte> reader, out int value)
|
||||
{
|
||||
if (reader.TryRead(out value))
|
||||
{
|
||||
value = BinaryPrimitives.ReverseEndianness(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out uint value)
|
||||
{
|
||||
if (TryReadLittleEndian(ref reader, out int signedvalue))
|
||||
{
|
||||
value = unchecked((uint)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out uint value)
|
||||
{
|
||||
if (TryReadBigEndian(ref reader, out int signedvalue))
|
||||
{
|
||||
value = unchecked((uint)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out long value) =>
|
||||
BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out long value) =>
|
||||
!BitConverter.IsLittleEndian ? reader.TryRead(out value) : TryReadReverseEndianness(ref reader, out value);
|
||||
|
||||
private static bool TryReadReverseEndianness(ref BufferReader<byte> reader, out long value)
|
||||
{
|
||||
if (reader.TryRead(out value))
|
||||
{
|
||||
value = BinaryPrimitives.ReverseEndianness(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static bool TryReadLittleEndian(ref this BufferReader<byte> reader, out ulong value)
|
||||
{
|
||||
if (TryReadLittleEndian(ref reader, out long signedvalue))
|
||||
{
|
||||
value = unchecked((ulong)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryReadBigEndian(ref this BufferReader<byte> reader, out ulong value)
|
||||
{
|
||||
if (TryReadBigEndian(ref reader, out long signedvalue))
|
||||
{
|
||||
value = unchecked((ulong)signedvalue);
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue