//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; namespace TouchSocket.Core { /// /// 字节块流 /// [DebuggerDisplay("Len={Len},Pos={Pos},Capacity={Capacity}")] public ref partial struct ValueByteBlock { private static float m_ratio = 1.5f; private readonly bool m_needDis; private byte[] m_buffer; private int m_dis; private bool m_holding; private long m_length; private long m_position; private bool m_using; /// /// 构造函数 /// /// /// public ValueByteBlock(int byteSize = 1024 * 64, bool equalSize = false) { m_dis = 1; m_needDis = true; m_buffer = BytePool.Default.GetByteCore(byteSize, equalSize); m_using = true; m_length = 0; m_holding = false; m_position = 0; } /// /// 实例化一个已知内存的对象。且该内存不会被回收。 /// /// public ValueByteBlock(byte[] bytes) { m_dis = 0; m_needDis = false; m_buffer = bytes ?? throw new ArgumentNullException(nameof(bytes)); m_length = bytes.Length; m_using = true; m_length = 0; m_holding = false; m_position = 0; } /// /// 扩容增长比,默认为1.5, /// min:1.5 /// public static float Ratio { get => m_ratio; set { if (value < 1.5) { value = 1.5f; } m_ratio = value; } } /// /// 字节实例 /// public byte[] Buffer => m_buffer; /// /// 仅当内存块可用,且>0时为True。 /// public bool CanRead => m_using && CanReadLen > 0; /// /// 还能读取的长度,计算为的差值。 /// public int CanReadLen => Len - Pos; /// /// 还能读取的长度,计算为的差值。 /// public long CanReadLength => m_length - m_position; /// /// 支持查找 /// public bool CanSeek => m_using; /// /// 可写入 /// public bool CanWrite => m_using; /// /// 容量 /// public int Capacity => m_buffer.Length; /// /// 空闲长度,准确掌握该值,可以避免内存扩展,计算为的差值。 /// public int FreeLength => Capacity - Pos; /// /// 表示持续性持有,为True时,Dispose将调用无效。 /// public bool Holding => m_holding; /// /// Int真实长度 /// public int Len => (int)m_length; /// /// 真实长度 /// public long Length => m_length; /// /// int型流位置 /// public int Pos { get => (int)m_position; set => m_position = value; } /// /// 流位置 /// public long Position { get => m_position; set => m_position = value; } /// /// 使用状态 /// public bool Using => m_using; /// /// 创建一个来自于内存池的成员。 /// /// /// /// public static ValueByteBlock Create(int byteSize = 1024 * 64, bool equalSize = false) { return new ValueByteBlock(byteSize, equalSize); } /// /// 直接完全释放,游离该对象,然后等待GC /// public void AbsoluteDispose() { if (Interlocked.Decrement(ref m_dis) == 0) { Dis(); } } /// /// 清空所有内存数据 /// /// 内存块已释放 public void Clear() { if (!m_using) { throw new ObjectDisposedException(nameof(ValueByteBlock)); } Array.Clear(m_buffer, 0, m_buffer.Length); } /// /// /// public void Dispose() { if (m_holding) { return; } if (m_needDis) { if (Interlocked.Decrement(ref m_dis) == 0) { BytePool.Default.Recycle(m_buffer); Dis(); } } } /// /// 释放当前内存到指定内存池 /// /// public void Dispose(BytePool bytePool) { if (m_holding) { return; } if (m_needDis) { if (Interlocked.Decrement(ref m_dis) == 0) { bytePool.Recycle(m_buffer); Dis(); } } } /// /// 读取数据,然后递增Pos /// /// /// /// /// /// public int Read(byte[] buffer, int offset, int length) { if (!m_using) { throw new ObjectDisposedException(nameof(ValueByteBlock)); } int len = m_length - m_position > length ? length : CanReadLen; Array.Copy(m_buffer, m_position, buffer, offset, len); m_position += len; return len; } /// /// 读取数据,然后递增Pos /// /// /// public int Read(byte[] buffer) { return Read(buffer, 0, buffer.Length); } /// /// 读取数据,然后递增Pos /// /// /// /// public int Read(out byte[] buffer, int length) { buffer = new byte[length]; return Read(buffer, 0, buffer.Length); } /// /// 从当前流位置读取一个值 /// public int ReadByte() { byte value = m_buffer[m_position]; m_position++; return value; } /// /// 将内存块初始化到刚申请的状态。 /// 仅仅重置属性。 /// /// 内存块已释放 public void Reset() { if (!m_using) { throw new ObjectDisposedException(nameof(ValueByteBlock)); } m_position = 0; m_length = 0; } /// /// 设置流位置 /// /// /// /// /// public long Seek(long offset, SeekOrigin origin) { if (!m_using) { throw new ObjectDisposedException(nameof(ValueByteBlock)); } switch (origin) { case SeekOrigin.Begin: m_position = offset; break; case SeekOrigin.Current: m_position += offset; break; case SeekOrigin.End: m_position = m_length + offset; break; } return m_position; } /// /// 移动游标 /// /// /// public void Seek(int position) { Position = position; } /// /// 设置游标到末位 /// /// public void SeekToEnd() { Position = Length; } /// /// 设置游标到首位 /// /// public void SeekToStart() { Position = 0; } /// /// 重新设置容量 /// /// 新尺寸 /// 是否保留元数据 /// public void SetCapacity(int size, bool retainedData = false) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } byte[] bytes = new byte[size]; if (retainedData) { Array.Copy(m_buffer, 0, bytes, 0, m_buffer.Length); } if (m_needDis) { BytePool.Default.Recycle(m_buffer); } m_buffer = bytes; } /// /// 设置持续持有属性,当为True时,调用Dispose会失效,表示该对象将长期持有,直至设置为False。 /// 当为False时,会自动调用Dispose。 /// /// /// public void SetHolding(bool holding) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } m_holding = holding; if (!holding) { Dispose(); } } /// /// 设置实际长度 /// /// /// public void SetLength(long value) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } if (value > m_buffer.Length) { throw new Exception("设置值超出容量"); } m_length = value; } /// /// 从指定位置转化到指定长度的有效内存 /// /// /// /// public byte[] ToArray(int offset, int length) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } byte[] buffer = new byte[length]; Array.Copy(m_buffer, offset, buffer, 0, buffer.Length); return buffer; } /// /// 转换为有效内存 /// /// public byte[] ToArray() { return ToArray(0, Len); } /// /// 从指定位置转化到有效内存 /// /// /// /// public byte[] ToArray(int offset) { return ToArray(offset, Len - offset); } /// /// 转换为UTF-8字符 /// /// public override string ToString() { return ToString(0, Len); } /// /// 转换为UTF-8字符 /// /// 偏移量 /// 长度 /// public string ToString(int offset, int length) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } return Encoding.UTF8.GetString(m_buffer, offset, length); } /// /// 转换为UTF-8字符 /// /// 偏移量 /// public string ToString(int offset) { if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } return Encoding.UTF8.GetString(m_buffer, offset, Len - offset); } /// /// 写入 /// /// /// /// /// public void Write(byte[] buffer, int offset, int count) { if (count == 0) { return; } if (!m_using) { throw new ObjectDisposedException("ValueByteBlock"); } if (m_buffer.Length - m_position < count) { int need = m_buffer.Length + count - ((int)(m_buffer.Length - m_position)); int lend = m_buffer.Length; while (need > lend) { lend = (int)(lend * m_ratio); } SetCapacity(lend, true); } Array.Copy(buffer, offset, m_buffer, m_position, count); m_position += count; m_length = Math.Max(m_position, m_length); } /// /// /// /// /// public void Write(byte[] buffer) { Write(buffer, 0, buffer.Length); } private void Dis() { m_holding = false; m_using = false; m_position = 0; m_length = 0; m_buffer = null; } #region BytesPackage /// /// 从当前流位置读取一个独立的数组包 /// public byte[] ReadBytesPackage() { byte status = (byte)ReadByte(); if (status == 0) { return null; } int length = ReadInt32(); byte[] data = new byte[length]; Array.Copy(Buffer, Pos, data, 0, length); Pos += length; return data; } /// /// 尝试获取数据包信息,方便从Buffer操作数据 /// /// /// /// public bool TryReadBytesPackageInfo(out int pos, out int len) { byte status = (byte)ReadByte(); if (status == 0) { pos = 0; len = 0; return false; } len = ReadInt32(); pos = Pos; return true; } /// /// 写入一个独立的数组包,值可以为null。 /// /// /// /// public void WriteBytesPackage(byte[] value, int offset, int length) { if (value == null) { Write((byte)0); } else { Write((byte)1); Write(length); Write(value, offset, length); } } /// /// 写入一个独立的数组包。值可以为null。 /// /// public void WriteBytesPackage(byte[] value) { if (value == null) { WriteBytesPackage(value, 0, 0); } WriteBytesPackage(value, 0, value.Length); } #endregion BytesPackage #region Int32 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public int ReadInt32(bool? bigEndian = null) { int value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToInt32(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToInt32(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToInt32(Buffer, Pos); break; } m_position += 4; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(int value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Int32 #region Int16 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public short ReadInt16(bool? bigEndian = null) { short value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToInt16(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToInt16(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToInt16(Buffer, Pos); break; } Pos += 2; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(short value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Int16 #region Int64 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public long ReadInt64(bool? bigEndian = null) { long value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToInt64(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToInt64(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToInt64(Buffer, Pos); break; } Pos += 8; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(long value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Int64 #region Boolean /// /// 从当前流位置读取一个值 /// public bool ReadBoolean() { bool value = TouchSocketBitConverter.Default.ToBoolean(Buffer, Pos); Pos += 1; return value; } /// /// 写入值 /// /// public void Write(bool value) { Write(TouchSocketBitConverter.Default.GetBytes(value)); } #endregion Boolean #region Byte /// /// 写入值 /// /// /// public void Write(byte value) { Write(new byte[] { value }, 0, 1); } #endregion Byte #region String /// /// 从当前流位置读取一个值 /// public string ReadString() { int len = this.ReadInt32(); if (len < 0) { return null; } else { string str = Encoding.UTF8.GetString(Buffer, Pos, len); Pos += len; return str; } } /// /// 写入值。值可以为null,或者空。 /// 注意:该操作不具备通用性,读取时必须使用ReadString。或者得先做出判断,由默认端序的int32值标识,具体如下: /// /// 小于0,表示字符串为null /// 等于0,表示字符串为"" /// 大于0,表示字符串在utf-8编码下的字节长度。 /// /// /// public void Write(string value) { if (value == null) { Write(-1); } else { byte[] buffer = Encoding.UTF8.GetBytes(value); Write(buffer.Length); Write(buffer); } } /// /// 写入值。值必须为有效值。可通用解析。 /// /// /// public void WriteString(string value, Encoding encoding = null) { Write((encoding ?? Encoding.UTF8).GetBytes(value)); } #endregion String #region Char /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public char ReadChar(bool? bigEndian = null) { char value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToChar(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToChar(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToChar(Buffer, Pos); break; } Pos += 2; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(char value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Char #region Double /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public double ReadDouble(bool? bigEndian = null) { double value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToDouble(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToDouble(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToDouble(Buffer, Pos); break; } Pos += 8; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(double value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Double #region Float /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public float ReadFloat(bool? bigEndian = null) { float value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToSingle(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToSingle(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToSingle(Buffer, Pos); break; } Pos += 4; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(float value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion Float #region UInt16 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public ushort ReadUInt16(bool? bigEndian = null) { ushort value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToUInt16(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToUInt16(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToUInt16(Buffer, Pos); break; } Pos += 2; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(ushort value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion UInt16 #region UInt32 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public uint ReadUInt32(bool? bigEndian = null) { uint value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToUInt32(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToUInt32(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToUInt32(Buffer, Pos); break; } Pos += 4; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(uint value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion UInt32 #region UInt64 /// /// 从当前流位置读取一个值 /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public ulong ReadUInt64(bool? bigEndian = null) { ulong value; switch (bigEndian) { case true: value = TouchSocketBitConverter.BigEndian.ToUInt64(Buffer, Pos); break; case false: value = TouchSocketBitConverter.LittleEndian.ToUInt64(Buffer, Pos); break; default: value = TouchSocketBitConverter.Default.ToUInt64(Buffer, Pos); break; } Pos += 8; return value; } /// /// 写入值 /// /// /// 是否为指定大端编码。允许true(大端),false(小端),null(默认端序)三种赋值。默认为null。 public void Write(ulong value, bool? bigEndian = null) { switch (bigEndian) { case true: Write(TouchSocketBitConverter.BigEndian.GetBytes(value)); break; case false: Write(TouchSocketBitConverter.LittleEndian.GetBytes(value)); break; default: Write(TouchSocketBitConverter.Default.GetBytes(value)); break; } } #endregion UInt64 #region Null /// /// 从当前流位置读取一个标识值,判断是否为null。 /// public bool ReadIsNull() { var status = ReadByte(); if (status == 0) { return true; } else if (status == 1) { return false; } else { throw new Exception("标识既非Null,也非NotNull,可能是流位置发生了错误。"); } } /// /// 判断该值是否为Null,然后写入标识值 /// public void WriteIsNull(T t) where T : class { if (t == null) { WriteNull(); } else { WriteNotNull(); } } /// /// 写入一个标识非Null值 /// public void WriteNotNull() { Write((byte)1); } /// /// 写入一个标识Null值 /// public void WriteNull() { Write((byte)0); } #endregion Null #region DateTime /// /// 从当前流位置读取一个值 /// public DateTime ReadDateTime() { long value = TouchSocketBitConverter.Default.ToInt64(Buffer, Pos); Pos += 8; return DateTime.FromBinary(value); } /// /// 写入值 /// /// public void Write(DateTime value) { Write(TouchSocketBitConverter.Default.GetBytes(value.ToBinary())); } #endregion DateTime #region TimeSpan /// /// 从当前流位置读取一个值 /// public TimeSpan ReadTimeSpan() { long value = TouchSocketBitConverter.Default.ToInt64(Buffer, Pos); Pos += 8; return TimeSpan.FromTicks(value); } /// /// 写入值 /// /// public void Write(TimeSpan value) { Write(TouchSocketBitConverter.Default.GetBytes(value.Ticks)); } #endregion TimeSpan #region Object /// /// 从当前流位置读取一个泛型值 /// /// /// /// public T ReadObject(SerializationType serializationType = SerializationType.FastBinary) { int length = ReadInt32(); if (length == 0) { return default; } T obj; switch (serializationType) { case SerializationType.FastBinary: { obj = SerializeConvert.FastBinaryDeserialize(Buffer, Pos); } break; case SerializationType.Json: { string jsonString = Encoding.UTF8.GetString(Buffer, Pos, length); obj = SerializeConvert.JsonDeserializeFromString(jsonString); } break; case SerializationType.Xml: { string jsonString = Encoding.UTF8.GetString(Buffer, Pos, length); obj = SerializeConvert.XmlDeserializeFromString(jsonString); } break; case SerializationType.SystemBinary: { obj = SerializeConvert.BinaryDeserialize(Buffer, Pos, length); } break; default: throw new Exception("未定义的序列化类型"); } Pos += length; return obj; } /// /// 写入值 /// /// /// public void WriteObject(object value, SerializationType serializationType = SerializationType.FastBinary) { if (value == null) { Write(0); } byte[] data; switch (serializationType) { case SerializationType.FastBinary: { data = SerializeConvert.FastBinarySerialize(value); } break; case SerializationType.Json: { data = SerializeConvert.JsonSerializeToBytes(value); } break; case SerializationType.Xml: { data = Encoding.UTF8.GetBytes(SerializeConvert.XmlSerializeToString(value)); } break; case SerializationType.SystemBinary: { data = SerializeConvert.BinarySerialize(value); } break; default: throw new Exception("未定义的序列化类型"); } Write(data.Length); Write(data); } #endregion Object } }