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
}
}