quantum-space-buddies/QuantumUNET/Transport/QNetBuffer.cs
2021-11-20 19:55:54 +00:00

163 lines
3.8 KiB
C#

using System;
using UnityEngine;
namespace QuantumUNET.Transport
{
internal class QNetBuffer
{
public QNetBuffer() => m_Buffer = new byte[64];
public QNetBuffer(byte[] buffer) => m_Buffer = buffer;
public uint Position { get; private set; }
public int Length => m_Buffer.Length;
public byte ReadByte()
{
if (Position >= (ulong)m_Buffer.Length)
{
throw new IndexOutOfRangeException($"NetworkReader:ReadByte out of range:{ToString()}");
}
return m_Buffer[(int)(UIntPtr)Position++];
}
public void ReadBytes(byte[] buffer, uint count)
{
if (Position + count > (ulong)m_Buffer.Length)
{
throw new IndexOutOfRangeException($"NetworkReader:ReadBytes out of range: ({count}) {ToString()}");
}
ushort num = 0;
while (num < count)
{
buffer[num] = m_Buffer[(int)(UIntPtr)(Position + num)];
num += 1;
}
Position += count;
}
internal ArraySegment<byte> AsArraySegment() => new(m_Buffer, 0, (int)Position);
public void WriteByte(byte value)
{
WriteCheckForSpace(1);
m_Buffer[(int)(UIntPtr)Position] = value;
Position += 1U;
}
public void WriteByte2(byte value0, byte value1)
{
WriteCheckForSpace(2);
m_Buffer[(int)(UIntPtr)Position] = value0;
m_Buffer[(int)(UIntPtr)(Position + 1U)] = value1;
Position += 2U;
}
public void WriteByte4(byte value0, byte value1, byte value2, byte value3)
{
WriteCheckForSpace(4);
m_Buffer[(int)(UIntPtr)Position] = value0;
m_Buffer[(int)(UIntPtr)(Position + 1U)] = value1;
m_Buffer[(int)(UIntPtr)(Position + 2U)] = value2;
m_Buffer[(int)(UIntPtr)(Position + 3U)] = value3;
Position += 4U;
}
public void WriteByte8(byte value0, byte value1, byte value2, byte value3, byte value4, byte value5, byte value6, byte value7)
{
WriteCheckForSpace(8);
m_Buffer[(int)(UIntPtr)Position] = value0;
m_Buffer[(int)(UIntPtr)(Position + 1U)] = value1;
m_Buffer[(int)(UIntPtr)(Position + 2U)] = value2;
m_Buffer[(int)(UIntPtr)(Position + 3U)] = value3;
m_Buffer[(int)(UIntPtr)(Position + 4U)] = value4;
m_Buffer[(int)(UIntPtr)(Position + 5U)] = value5;
m_Buffer[(int)(UIntPtr)(Position + 6U)] = value6;
m_Buffer[(int)(UIntPtr)(Position + 7U)] = value7;
Position += 8U;
}
public void WriteBytesAtOffset(byte[] buffer, ushort targetOffset, ushort count)
{
var num = (uint)(count + targetOffset);
WriteCheckForSpace((ushort)num);
if (targetOffset == 0 && count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)Position);
}
else
{
for (var i = 0; i < count; i++)
{
m_Buffer[targetOffset + i] = buffer[i];
}
}
if (num > Position)
{
Position = num;
}
}
public void WriteBytes(byte[] buffer, ushort count)
{
WriteCheckForSpace(count);
if (count == buffer.Length)
{
buffer.CopyTo(m_Buffer, (int)Position);
}
else
{
for (var i = 0; i < count; i++)
{
m_Buffer[(int)checked(unchecked(Position + (ulong)i))] = buffer[i];
}
}
Position += count;
}
private void WriteCheckForSpace(ushort count)
{
if (Position + count >= (ulong)m_Buffer.Length)
{
var num = (int)Math.Ceiling(m_Buffer.Length * 1.5f);
while (Position + count >= (ulong)num)
{
num = (int)Math.Ceiling(num * 1.5f);
if (num > 134217728)
{
Debug.LogWarning($"NetworkBuffer size is {num} bytes!");
}
}
var array = new byte[num];
m_Buffer.CopyTo(array, 0);
m_Buffer = array;
}
}
public void FinishMessage()
{
var num = (ushort)(Position - 4U);
m_Buffer[0] = (byte)(num & 255);
m_Buffer[1] = (byte)((num >> 8) & 255);
}
public void SeekZero() =>
Position = 0U;
public void Replace(byte[] buffer)
{
m_Buffer = buffer;
Position = 0U;
}
public override string ToString() => $"NetBuf sz:{m_Buffer.Length} pos:{Position}";
private byte[] m_Buffer;
}
}