using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MECF.Framework.RT.Core.IoProviders.Common.Net; using MECF.Framework.RT.Core.ThreadLock; namespace MECF.Framework.RT.Core.IoProviders.Common.Transfer { /// /// 一个线程安全的缓存数据块,支持批量动态修改,添加,并获取快照 /// /// /// 这个类可以实现什么功能呢,就是你有一个大的数组,作为你的应用程序的中间数据池,允许你往byte[]数组里存放指定长度的子byte[]数组,也允许从里面拿数据, /// 这些操作都是线程安全的,当然,本类扩展了一些额外的方法支持,也可以直接赋值或获取基本的数据类型对象。 /// /// /// 此处举例一些数据的读写说明,可以此处的数据示例。 /// /// public class SoftBuffer { #region Constructor /// /// 使用默认的大小初始化缓存空间 /// public SoftBuffer() { buffer = new byte[capacity]; hybirdLock = new SimpleHybirdLock(); byteTransform = new RegularByteTransform(); } /// /// 使用指定的容量初始化缓存数据块 /// /// 初始化的容量 public SoftBuffer(int capacity) { buffer = new byte[capacity]; this.capacity = capacity; hybirdLock = new SimpleHybirdLock(); byteTransform = new RegularByteTransform(); } #endregion #region Bool Operate Support /// /// 设置指定的位置的数据块,如果超出,则丢弃数据 /// /// bool值 /// 目标存储的索引 /// public void SetBool(bool value, int destIndex) { SetBool(new bool[] { value }, destIndex); } /// /// 设置指定的位置的数据块,如果超出,则丢弃数据 /// /// bool数组值 /// 目标存储的索引 /// public void SetBool(bool[] value, int destIndex) { if (value != null) { try { hybirdLock.Enter(); for (int i = 0; i < value.Length; i++) { int byteIndex = (destIndex + i) / 8; int offect = (destIndex + i) % 8; if (value[i]) { buffer[byteIndex] = (byte)(buffer[byteIndex] | getOrByte(offect)); } else { buffer[byteIndex] = (byte)(buffer[byteIndex] & getAndByte(offect)); } } hybirdLock.Leave(); } catch { hybirdLock.Leave(); throw; } } } /// /// 获取指定的位置的bool值,如果超出,则引发异常 /// /// 目标存储的索引 /// 获取索引位置的bool数据值 /// public bool GetBool(int destIndex) { return GetBool(destIndex, 1)[0]; } /// /// 获取指定位置的bool数组值,如果超过,则引发异常 /// /// 目标存储的索引 /// 读取的数组长度 /// /// bool数组值 public bool[] GetBool(int destIndex, int length) { bool[] result = new bool[length]; try { hybirdLock.Enter(); for (int i = 0; i < length; i++) { int byteIndex = (destIndex + i) / 8; int offect = (destIndex + i) % 8; result[i] = (buffer[byteIndex] & getOrByte(offect)) == getOrByte(offect); } hybirdLock.Leave(); } catch { hybirdLock.Leave(); throw; } return result; } private byte getAndByte(int offect) { switch (offect) { case 0: return 0xFE; case 1: return 0xFD; case 2: return 0xFB; case 3: return 0xF7; case 4: return 0xEF; case 5: return 0xDF; case 6: return 0xBF; case 7: return 0x7F; default: return 0xFF; } } private byte getOrByte(int offect) { switch (offect) { case 0: return 0x01; case 1: return 0x02; case 2: return 0x04; case 3: return 0x08; case 4: return 0x10; case 5: return 0x20; case 6: return 0x40; case 7: return 0x80; default: return 0x00; } } #endregion #region Byte Operate Support /// /// 设置指定的位置的数据块,如果超出,则丢弃数据 /// /// 数据块信息 /// 目标存储的索引 public void SetBytes(byte[] data, int destIndex) { if (destIndex < capacity && destIndex >= 0 && data != null) { hybirdLock.Enter(); if ((data.Length + destIndex) > buffer.Length) { Array.Copy(data, 0, buffer, destIndex, (buffer.Length - destIndex)); } else { data.CopyTo(buffer, destIndex); } hybirdLock.Leave(); } } /// /// 设置指定的位置的数据块,如果超出,则丢弃数据 /// /// 数据块信息 /// 目标存储的索引 /// 准备拷贝的数据长度 public void SetBytes(byte[] data, int destIndex, int length) { if (destIndex < capacity && destIndex >= 0 && data != null) { if (length > data.Length) length = data.Length; hybirdLock.Enter(); if ((length + destIndex) > buffer.Length) { Array.Copy(data, 0, buffer, destIndex, (buffer.Length - destIndex)); } else { Array.Copy(data, 0, buffer, destIndex, length); } hybirdLock.Leave(); } } /// /// 设置指定的位置的数据块,如果超出,则丢弃数据 /// /// 数据块信息 /// Data中的起始位置 /// 目标存储的索引 /// 准备拷贝的数据长度 /// public void SetBytes(byte[] data, int sourceIndex, int destIndex, int length) { if (destIndex < capacity && destIndex >= 0 && data != null) { if (length > data.Length) length = data.Length; hybirdLock.Enter(); Array.Copy(data, sourceIndex, buffer, destIndex, length); hybirdLock.Leave(); } } /// /// 获取内存指定长度的数据信息 /// /// 起始位置 /// 数组长度 /// 返回实际的数据信息 public byte[] GetBytes(int index, int length) { byte[] result = new byte[length]; if (length > 0) { hybirdLock.Enter(); if (index >= 0 && (index + length) <= buffer.Length) { Array.Copy(buffer, index, result, 0, length); } hybirdLock.Leave(); } return result; } /// /// 获取内存所有的数据信息 /// /// 实际的数据信息 public byte[] GetBytes() { return GetBytes(0, capacity); } #endregion #region BCL Set Support /// /// 设置byte类型的数据到缓存区 /// /// byte数值 /// 索引位置 public void SetValue(byte value, int index) { SetBytes(new byte[] { value }, index); } /// /// 设置short类型的数据到缓存区 /// /// short数组 /// 索引位置 public void SetValue(short[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置short类型的数据到缓存区 /// /// short数值 /// 索引位置 public void SetValue(short value, int index) { SetValue(new short[] { value }, index); } /// /// 设置ushort类型的数据到缓存区 /// /// ushort数组 /// 索引位置 public void SetValue(ushort[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置ushort类型的数据到缓存区 /// /// ushort数值 /// 索引位置 public void SetValue(ushort value, int index) { SetValue(new ushort[] { value }, index); } /// /// 设置int类型的数据到缓存区 /// /// int数组 /// 索引位置 public void SetValue(int[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置int类型的数据到缓存区 /// /// int数值 /// 索引位置 public void SetValue(int value, int index) { SetValue(new int[] { value }, index); } /// /// 设置uint类型的数据到缓存区 /// /// uint数组 /// 索引位置 public void SetValue(uint[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置uint类型的数据到缓存区 /// /// uint数值 /// 索引位置 public void SetValue(uint value, int index) { SetValue(new uint[] { value }, index); } /// /// 设置float类型的数据到缓存区 /// /// float数组 /// 索引位置 public void SetValue(float[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置float类型的数据到缓存区 /// /// float数值 /// 索引位置 public void SetValue(float value, int index) { SetValue(new float[] { value }, index); } /// /// 设置long类型的数据到缓存区 /// /// long数组 /// 索引位置 public void SetValue(long[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置long类型的数据到缓存区 /// /// long数值 /// 索引位置 public void SetValue(long value, int index) { SetValue(new long[] { value }, index); } /// /// 设置ulong类型的数据到缓存区 /// /// ulong数组 /// 索引位置 public void SetValue(ulong[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置ulong类型的数据到缓存区 /// /// ulong数值 /// 索引位置 public void SetValue(ulong value, int index) { SetValue(new ulong[] { value }, index); } /// /// 设置double类型的数据到缓存区 /// /// double数组 /// 索引位置 public void SetValue(double[] values, int index) { SetBytes(byteTransform.TransByte(values), index); } /// /// 设置double类型的数据到缓存区 /// /// double数值 /// 索引位置 public void SetValue(double value, int index) { SetValue(new double[] { value }, index); } #endregion #region BCL Get Support /// /// 获取byte类型的数据 /// /// 索引位置 /// byte数值 public byte GetByte(int index) { return GetBytes(index, 1)[0]; } /// /// 获取short类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// short数组 public short[] GetInt16(int index, int length) { byte[] tmp = GetBytes(index, length * 2); return byteTransform.TransInt16(tmp, 0, length); } /// /// 获取short类型的数据到缓存区 /// /// 索引位置 /// short数据 public short GetInt16(int index) { return GetInt16(index, 1)[0]; } /// /// 获取ushort类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// ushort数组 public ushort[] GetUInt16(int index, int length) { byte[] tmp = GetBytes(index, length * 2); return byteTransform.TransUInt16(tmp, 0, length); } /// /// 获取ushort类型的数据到缓存区 /// /// 索引位置 /// ushort数据 public ushort GetUInt16(int index) { return GetUInt16(index, 1)[0]; } /// /// 获取int类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// int数组 public int[] GetInt32(int index, int length) { byte[] tmp = GetBytes(index, length * 4); return byteTransform.TransInt32(tmp, 0, length); } /// /// 获取int类型的数据到缓存区 /// /// 索引位置 /// int数据 public int GetInt32(int index) { return GetInt32(index, 1)[0]; } /// /// 获取uint类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// uint数组 public uint[] GetUInt32(int index, int length) { byte[] tmp = GetBytes(index, length * 4); return byteTransform.TransUInt32(tmp, 0, length); } /// /// 获取uint类型的数据到缓存区 /// /// 索引位置 /// uint数据 public uint GetUInt32(int index) { return GetUInt32(index, 1)[0]; } /// /// 获取float类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// float数组 public float[] GetSingle(int index, int length) { byte[] tmp = GetBytes(index, length * 4); return byteTransform.TransSingle(tmp, 0, length); } /// /// 获取float类型的数据到缓存区 /// /// 索引位置 /// float数据 public float GetSingle(int index) { return GetSingle(index, 1)[0]; } /// /// 获取long类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// long数组 public long[] GetInt64(int index, int length) { byte[] tmp = GetBytes(index, length * 8); return byteTransform.TransInt64(tmp, 0, length); } /// /// 获取long类型的数据到缓存区 /// /// 索引位置 /// long数据 public long GetInt64(int index) { return GetInt64(index, 1)[0]; } /// /// 获取ulong类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// ulong数组 public ulong[] GetUInt64(int index, int length) { byte[] tmp = GetBytes(index, length * 8); return byteTransform.TransUInt64(tmp, 0, length); } /// /// 获取ulong类型的数据到缓存区 /// /// 索引位置 /// ulong数据 public ulong GetUInt64(int index) { return GetUInt64(index, 1)[0]; } /// /// 获取double类型的数组到缓存区 /// /// 索引位置 /// 数组长度 /// ulong数组 public double[] GetDouble(int index, int length) { byte[] tmp = GetBytes(index, length * 8); return byteTransform.TransDouble(tmp, 0, length); } /// /// 获取double类型的数据到缓存区 /// /// 索引位置 /// double数据 public double GetDouble(int index) { return GetDouble(index, 1)[0]; } #endregion #region Customer Support /// /// 读取自定义类型的数据,需要规定解析规则 /// /// 类型名称 /// 起始索引 /// 自定义的数据类型 public T GetCustomer(int index) where T : IDataTransfer, new() { T Content = new T(); byte[] read = GetBytes(index, Content.ReadCount); Content.ParseSource(read); return Content; } /// /// 写入自定义类型的数据到缓存中去,需要规定生成字节的方法 /// /// 自定义类型 /// 实例对象 /// 起始地址 public void SetCustomer(T data, int index) where T : IDataTransfer, new() { SetBytes(data.ToSource(), index); } #endregion #region Public Properties /// /// 获取或设置当前的数据缓存类的解析规则 /// public IByteTransform ByteTransform { get => byteTransform; set => byteTransform = value; } #endregion #region Private Member private int capacity = 10; // 缓存的容量 private byte[] buffer; // 缓存的数据 private SimpleHybirdLock hybirdLock; // 高效的混合锁 private IByteTransform byteTransform; // 数据转换类 #endregion } }