Update .gitignore to exclude TypeScript build info and add dist directory. Expand README with project overview, technology stack, prerequisites, and instructions for running and testing the application.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Text;
|
||||
|
||||
namespace HSchool.Protocol;
|
||||
|
||||
/// <summary>Little-endian cursor over a received frame. Mirror of <see cref="PacketWriter"/>.</summary>
|
||||
public ref struct PacketReader(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
private readonly ReadOnlySpan<byte> _buffer = buffer;
|
||||
private int _position = 0;
|
||||
|
||||
public readonly int Position => _position;
|
||||
|
||||
public readonly int Remaining => _buffer.Length - _position;
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
EnsureAvailable(sizeof(byte));
|
||||
var value = _buffer[_position];
|
||||
_position += sizeof(byte);
|
||||
return value;
|
||||
}
|
||||
|
||||
public MessageType ReadMessageType() => (MessageType)ReadByte();
|
||||
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
EnsureAvailable(sizeof(ushort));
|
||||
var value = BinaryPrimitives.ReadUInt16LittleEndian(_buffer[_position..]);
|
||||
_position += sizeof(ushort);
|
||||
return value;
|
||||
}
|
||||
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
EnsureAvailable(sizeof(uint));
|
||||
var value = BinaryPrimitives.ReadUInt32LittleEndian(_buffer[_position..]);
|
||||
_position += sizeof(uint);
|
||||
return value;
|
||||
}
|
||||
|
||||
public long ReadInt64()
|
||||
{
|
||||
EnsureAvailable(sizeof(long));
|
||||
var value = BinaryPrimitives.ReadInt64LittleEndian(_buffer[_position..]);
|
||||
_position += sizeof(long);
|
||||
return value;
|
||||
}
|
||||
|
||||
public float ReadSingle()
|
||||
{
|
||||
EnsureAvailable(sizeof(float));
|
||||
var value = BinaryPrimitives.ReadSingleLittleEndian(_buffer[_position..]);
|
||||
_position += sizeof(float);
|
||||
return value;
|
||||
}
|
||||
|
||||
public string ReadShortString()
|
||||
{
|
||||
var byteCount = ReadByte();
|
||||
EnsureAvailable(byteCount);
|
||||
var value = Encoding.UTF8.GetString(_buffer.Slice(_position, byteCount));
|
||||
_position += byteCount;
|
||||
return value;
|
||||
}
|
||||
|
||||
private readonly void EnsureAvailable(int bytes)
|
||||
{
|
||||
if (_position + bytes > _buffer.Length)
|
||||
{
|
||||
throw new ProtocolException(
|
||||
$"Truncated frame: need {bytes} bytes at offset {_position}, only {Remaining} available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user