WX-Game1/Assets/MotionFramework/Scripts/Runtime/Engine/Engine.IO/ByteBuffer.cs

568 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//--------------------------------------------------
// Motion Framework
// Copyright©2018-2020 何冠峰
// Licensed under the MIT license
//--------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
#if MOTION_SERVER
using System.Numerics;
#else
using UnityEngine;
#endif
namespace MotionFramework.IO
{
/// <summary>
/// 字节缓冲区
/// </summary>
public class ByteBuffer
{
private readonly byte[] _buffer;
private int _readerIndex = 0;
private int _writerIndex = 0;
private int _markedReaderIndex = 0;
private int _markedWriterIndex = 0;
/// <summary>
/// 字节缓冲区
/// </summary>
public ByteBuffer(int capacity)
{
_buffer = new byte[capacity];
}
/// <summary>
/// 字节缓冲区
/// </summary>
public ByteBuffer(byte[] data)
{
_buffer = data;
_writerIndex = data.Length;
}
/// <summary>
/// 获取数据
/// </summary>
public byte[] GetBuffer()
{
return _buffer;
}
/// <summary>
/// 缓冲区容量
/// </summary>
public int Capacity
{
get { return _buffer.Length; }
}
/// <summary>
/// 清空缓冲区
/// </summary>
public void Clear()
{
_readerIndex = 0;
_writerIndex = 0;
_markedReaderIndex = 0;
_markedWriterIndex = 0;
}
/// <summary>
/// 删除已读部分,重新初始化数组
/// </summary>
public void DiscardReadBytes()
{
if (_readerIndex == 0)
return;
if (_readerIndex == _writerIndex)
{
_readerIndex = 0;
_writerIndex = 0;
}
else
{
for (int i = 0, j = _readerIndex, length = _writerIndex - _readerIndex; i < length; i++, j++)
{
_buffer[i] = _buffer[j];
}
_writerIndex -= _readerIndex;
_readerIndex = 0;
}
}
#region
/// <summary>
/// 读取的下标位置
/// </summary>
public int ReaderIndex
{
get { return _readerIndex; }
}
/// <summary>
/// 当前可读数据量
/// </summary>
public int ReadableBytes
{
get { return _writerIndex - _readerIndex; }
}
/// <summary>
/// 查询是否可以读取
/// </summary>
/// <param name="size">读取数据量</param>
public bool IsReadable(int size = 1)
{
return _writerIndex - _readerIndex >= size;
}
/// <summary>
/// 标记读取的下标位置,便于某些时候回退到该位置
/// </summary>
public void MarkReaderIndex()
{
_markedReaderIndex = _readerIndex;
}
/// <summary>
/// 回退到标记的读取下标位置
/// </summary>
public void ResetReaderIndex()
{
_readerIndex = _markedReaderIndex;
}
#endregion
#region
/// <summary>
/// 写入的下标位置
/// </summary>
public int WriterIndex
{
get { return _writerIndex; }
}
/// <summary>
/// 当前可写入数据量
/// </summary>
public int WriteableBytes
{
get { return Capacity - _writerIndex; }
}
/// <summary>
/// 查询是否可以写入
/// </summary>
/// <param name="size">写入数据量</param>
public bool IsWriteable(int size = 1)
{
return Capacity - _writerIndex >= size;
}
/// <summary>
/// 标记写入的下标位置,便于某些时候回退到该位置。
/// </summary>
public void MarkWriterIndex()
{
_markedWriterIndex = _writerIndex;
}
/// <summary>
/// 回退到标记的写入下标位置
/// </summary>
public void ResetWriterIndex()
{
_writerIndex = _markedWriterIndex;
}
#endregion
#region
[Conditional("DEBUG")]
private void CheckReaderIndex(int length)
{
if (_readerIndex + length > _writerIndex)
{
throw new IndexOutOfRangeException();
}
}
public byte[] ReadBytes(int count)
{
CheckReaderIndex(count);
var data = new byte[count];
Buffer.BlockCopy(_buffer, _readerIndex, data, 0, count);
_readerIndex += count;
return data;
}
public bool ReadBool()
{
CheckReaderIndex(1);
return _buffer[_readerIndex++] == 1;
}
public byte ReadByte()
{
CheckReaderIndex(1);
return _buffer[_readerIndex++];
}
public sbyte ReadSbyte()
{
return (sbyte)ReadByte();
}
public short ReadShort()
{
CheckReaderIndex(2);
short result = BitConverter.ToInt16(_buffer, _readerIndex);
_readerIndex += 2;
return result;
}
public ushort ReadUShort()
{
CheckReaderIndex(2);
ushort result = BitConverter.ToUInt16(_buffer, _readerIndex);
_readerIndex += 2;
return result;
}
public int ReadInt()
{
CheckReaderIndex(4);
int result = BitConverter.ToInt32(_buffer, _readerIndex);
_readerIndex += 4;
return result;
}
public uint ReadUInt()
{
CheckReaderIndex(4);
uint result = BitConverter.ToUInt32(_buffer, _readerIndex);
_readerIndex += 4;
return result;
}
public long ReadLong()
{
CheckReaderIndex(8);
long result = BitConverter.ToInt64(_buffer, _readerIndex);
_readerIndex += 8;
return result;
}
public ulong ReadULong()
{
CheckReaderIndex(8);
ulong result = BitConverter.ToUInt64(_buffer, _readerIndex);
_readerIndex += 8;
return result;
}
public float ReadFloat()
{
CheckReaderIndex(4);
float result = BitConverter.ToSingle(_buffer, _readerIndex);
_readerIndex += 4;
return result;
}
public double ReadDouble()
{
CheckReaderIndex(8);
double result = BitConverter.ToDouble(_buffer, _readerIndex);
_readerIndex += 8;
return result;
}
public string ReadUTF()
{
ushort count = ReadUShort();
CheckReaderIndex(count);
string result = Encoding.UTF8.GetString(_buffer, _readerIndex, count - 1); // 注意:读取的时候忽略字符串末尾写入结束符
_readerIndex += count;
return result;
}
public List<int> ReadListInt()
{
List<int> result = new List<int>();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
result.Add(ReadInt());
}
return result;
}
public List<long> ReadListLong()
{
List<long> result = new List<long>();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
result.Add(ReadLong());
}
return result;
}
public List<float> ReadListFloat()
{
List<float> result = new List<float>();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
result.Add(ReadFloat());
}
return result;
}
public List<double> ReadListDouble()
{
List<double> result = new List<double>();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
result.Add(ReadDouble());
}
return result;
}
public List<string> ReadListUTF()
{
List<string> result = new List<string>();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
result.Add(ReadUTF());
}
return result;
}
public Vector2 ReadVector2()
{
float x = ReadFloat();
float y = ReadFloat();
return new Vector2(x, y);
}
public Vector3 ReadVector3()
{
float x = ReadFloat();
float y = ReadFloat();
float z = ReadFloat();
return new Vector3(x, y, z);
}
public Vector4 ReadVector4()
{
float x = ReadFloat();
float y = ReadFloat();
float z = ReadFloat();
float w = ReadFloat();
return new Vector4(x, y, z, w);
}
#endregion
#region
[Conditional("DEBUG")]
private void CheckWriterIndex(int length)
{
if (_writerIndex + length > Capacity)
{
throw new IndexOutOfRangeException();
}
}
public void WriteBytes(byte[] data)
{
WriteBytes(data, 0, data.Length);
}
public void WriteBytes(byte[] data, int offset, int count)
{
CheckWriterIndex(count);
Buffer.BlockCopy(data, offset, _buffer, _writerIndex, count);
_writerIndex += count;
}
public void WriteBool(bool value)
{
WriteByte((byte)(value ? 1 : 0));
}
public void WriteByte(byte value)
{
CheckWriterIndex(1);
_buffer[_writerIndex++] = value;
}
public void WriteSbyte(sbyte value)
{
// 注意从sbyte强转到byte不会有数据变化或丢失
WriteByte((byte)value);
}
public void WriteShort(short value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteUShort(ushort value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteInt(int value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteUInt(uint value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteLong(long value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteULong(ulong value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteFloat(float value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteDouble(double value)
{
byte[] bytes = BitConverter.GetBytes(value);
WriteBytes(bytes);
}
public void WriteUTF(string value)
{
byte[] bytes = Encoding.UTF8.GetBytes(value);
int num = bytes.Length + 1; // 注意:字符串末尾写入结束符
if (num > ushort.MaxValue)
throw new FormatException($"String length cannot be greater than {ushort.MaxValue} !");
WriteUShort(Convert.ToUInt16(num));
WriteBytes(bytes);
WriteByte((byte)'\0');
}
public void WriteListInt(List<int> values)
{
int count = 0;
if (values != null)
count = values.Count;
WriteInt(count);
for (int i = 0; i < count; i++)
{
WriteInt(values[i]);
}
}
public void WriteListLong(List<long> values)
{
int count = 0;
if (values != null)
count = values.Count;
WriteInt(count);
for (int i = 0; i < count; i++)
{
WriteLong(values[i]);
}
}
public void WriteListFloat(List<float> values)
{
int count = 0;
if (values != null)
count = values.Count;
WriteInt(count);
for (int i = 0; i < count; i++)
{
WriteFloat(values[i]);
}
}
public void WriteListDouble(List<double> values)
{
int count = 0;
if (values != null)
count = values.Count;
WriteInt(count);
for (int i = 0; i < count; i++)
{
WriteDouble(values[i]);
}
}
public void WriteListUTF(List<string> values)
{
int count = 0;
if (values != null)
count = values.Count;
WriteInt(count);
for (int i = 0; i < count; i++)
{
WriteUTF(values[i]);
}
}
#if MOTION_SERVER
public void WriteVector2(Vector2 value)
{
WriteFloat(value.X);
WriteFloat(value.Y);
}
public void WriteVector3(Vector3 value)
{
WriteFloat(value.X);
WriteFloat(value.Y);
WriteFloat(value.Z);
}
public void WriteVector4(Vector4 value)
{
WriteFloat(value.X);
WriteFloat(value.Y);
WriteFloat(value.Z);
WriteFloat(value.W);
}
#else
public void WriteVector2(Vector2 value)
{
WriteFloat(value.x);
WriteFloat(value.y);
}
public void WriteVector3(Vector3 value)
{
WriteFloat(value.x);
WriteFloat(value.y);
WriteFloat(value.z);
}
public void WriteVector4(Vector4 value)
{
WriteFloat(value.x);
WriteFloat(value.y);
WriteFloat(value.z);
WriteFloat(value.w);
}
#endif
#endregion
/// <summary>
/// 大小端转换
/// </summary>
public static void ReverseOrder(byte[] data)
{
ReverseOrder(data, 0, data.Length);
}
public static void ReverseOrder(byte[] data, int offset, int length)
{
if (length <= 1)
return;
int end = offset + length - 1;
int max = offset + length / 2;
byte temp;
for (int index = offset; index < max; index++, end--)
{
temp = data[end];
data[end] = data[index];
data[index] = temp;
}
}
}
}