public interface IMessageReader
{
/// <summary>
- /// Gets the current position of the reader.
+ /// Gets the tag of the message.
/// </summary>
- int Position { get; }
+ byte Tag { get; }
/// <summary>
/// Gets the buffer of the message.
ReadOnlyMemory<byte> Buffer { get; }
/// <summary>
- /// Gets the tag of the message.
+ /// Gets the current position of the reader.
/// </summary>
- byte Tag { get; }
+ int Position { get; }
/// <summary>
/// Gets the length of the buffer.
/// </summary>
int Length { get; }
+ IMessageReader ReadMessage();
+
bool ReadBoolean();
sbyte ReadSByte();
uint ReadPackedUInt32();
void CopyTo(IMessageWriter writer);
+
+ IMessageReader Slice(int start);
+
+ IMessageReader Slice(int start, int length);
}
}
\ No newline at end of file
using System;
using System.Runtime.CompilerServices;
using System.Text;
-using Impostor.Server.Net;
using Impostor.Server.Net.Messages;
-namespace Impostor.Server.Hazel
+namespace Impostor.Server.Hazel.Messages
{
public class BufferMessageReader : IMessageReader
{
- // TODO: Remove _offset, we can slice the buffer.
- private readonly int _offset;
- private int _position;
- private int readHead;
-
- public ReadOnlyMemory<byte> Buffer { get; }
-
public byte Tag { get; }
+ public ReadOnlyMemory<byte> Buffer { get; }
+ public int Position { get; set; }
+ public int Length => Buffer.Length;
- public int Length { get; }
-
- public int Position
+ public BufferMessageReader(byte tag, ReadOnlyMemory<byte> buffer)
{
- get { return _position; }
- set
- {
- _position = value;
- readHead = value + _offset;
- }
+ Tag = tag;
+ Buffer = buffer;
}
- public BufferMessageReader(byte tag, ReadOnlyMemory<byte> buffer, int offset, int length)
+ public IMessageReader ReadMessage()
{
- Tag = tag;
- Buffer = buffer;
- Length = length;
- _offset = offset;
- readHead = offset;
+ var length = ReadUInt16();
+ var tag = ReadByte();
+ var pos = Position;
+
+ Position += length;
+
+ return new BufferMessageReader(tag, Buffer.Slice(pos, length));
}
public bool ReadBoolean()
// TODO: Refactor to System.Buffers.Binary.BinaryPrimitives
float output = 0;
- fixed (byte* bufPtr = &Buffer.Span[readHead])
+ fixed (byte* bufPtr = &Buffer.Span[Position])
{
byte* outPtr = (byte*)&output;
public string ReadString()
{
var len = ReadPackedInt32();
- var output = Encoding.UTF8.GetString(Buffer.Span.Slice(readHead, len));
+ var output = Encoding.UTF8.GetString(Buffer.Span.Slice(Position, len));
Position += len;
return output;
}
public ReadOnlyMemory<byte> ReadBytes(int length)
{
- var output = Buffer.Slice(readHead, length);
+ var output = Buffer.Slice(Position, length);
Position += length;
return output;
}
public void CopyTo(IMessageWriter writer)
{
- int offset, length;
- if (Tag == byte.MaxValue)
- {
- offset = _offset;
- length = Length;
- }
- else
- {
- offset = _offset - 3;
- length = Length + 3;
- }
+ writer.Write((ushort) Length);
+ writer.Write((byte) Tag);
+ writer.Write(Buffer);
+ }
- writer.Write(Buffer.Slice(offset, length));
+ public IMessageReader Slice(int start)
+ {
+ return new BufferMessageReader(Tag, Buffer.Slice(start));
+ }
+
+ public IMessageReader Slice(int start, int length)
+ {
+ return new BufferMessageReader(Tag, Buffer.Slice(start, length));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte FastByte()
{
- _position++;
- return Buffer.Span[readHead++];
+ return Buffer.Span[Position++];
}
}
}
\ No newline at end of file
using System;
using Hazel;
-using Impostor.Server.Net;
using Impostor.Server.Net.Messages;
-namespace Impostor.Server.Hazel
+namespace Impostor.Server.Hazel.Messages
{
internal class HazelMessage : IMessage, IDisposable
{
throw new ObjectDisposedException(nameof(_reader));
}
- return new BufferMessageReader(_reader.Tag, _reader.Buffer, _reader.Offset, _reader.Length);
+ return new BufferMessageReader(_reader.Tag, _reader.Buffer.AsMemory(_reader.Offset, _reader.Length));
}
private void Dispose(bool disposing)