#region << 版 本 注 释 >>
|
/*----------------------------------------------------------------
|
* 命名空间:WIDESEAWCS_QuartzJob.DeviceBase
|
* 创建者:胡童庆
|
* 创建时间:2024/8/2 16:13:36
|
* 版本:V1.0.0
|
* 描述:
|
*
|
* ----------------------------------------------------------------
|
* 修改人:
|
* 修改时间:
|
* 版本:V1.0.1
|
* 修改说明:
|
*
|
*----------------------------------------------------------------*/
|
#endregion << 版 本 注 释 >>
|
|
using HslCommunication;
|
using HslCommunication.Core;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace WIDESEAWCS_QuartzJob.DeviceBase
|
{
|
public class DeviceCommand : IDataTransfer
|
{
|
#region <Const>
|
#endregion <Const>
|
|
#region <Private Member>
|
public ushort ReadCount { get; }
|
|
private IByteTransform byteTransform = new ReverseBytesTransform();
|
#endregion <Private Member>
|
|
#region <Public Menber>
|
|
#endregion <Public Menber>
|
|
#region <Constructor function>
|
public DeviceCommand()
|
{
|
ushort readCount = 0;
|
PropertyInfo[] propertyInfos = GetType().GetProperties().Where(x => x.CanWrite).ToArray();
|
foreach (PropertyInfo propertyInfo in propertyInfos)
|
{
|
object? obj = propertyInfo.GetValue(this);
|
TypeCode typeCode = Type.GetTypeCode(propertyInfo.PropertyType);
|
switch (typeCode)
|
{
|
case TypeCode.Byte:
|
case TypeCode.SByte:
|
case TypeCode.Char:
|
readCount += sizeof(byte);
|
break;
|
case TypeCode.Int16:
|
case TypeCode.UInt16:
|
readCount += 2;
|
break;
|
case TypeCode.Single:
|
case TypeCode.Int32:
|
case TypeCode.UInt32:
|
readCount += 4;
|
break;
|
case TypeCode.String:
|
ushort dataLength = CheckStringAttribute(propertyInfo);
|
readCount += dataLength;
|
break;
|
default:
|
throw new NotSupportedException("Unsupported primitive type: " + propertyInfo.PropertyType);
|
}
|
}
|
ReadCount = readCount;
|
}
|
#endregion <Constructor function>
|
|
#region <Private Method>
|
private ushort CheckStringAttribute(PropertyInfo propertyInfo)
|
{
|
Attribute? attribute = propertyInfo.GetCustomAttribute(typeof(DataLengthAttribute));
|
if (attribute == null)
|
{
|
throw new Exception($"字符串需要配置【DataLength】特性");
|
}
|
ushort dataLength = ((DataLengthAttribute)attribute).DataLength;
|
if (dataLength <= 0 || dataLength > 256)
|
{
|
throw new Exception($"【DataLength】特性请配置有效参数,参数范围【1-256】");
|
}
|
if (dataLength % 2 != 0)
|
{
|
dataLength += 1;
|
}
|
dataLength += 2;
|
|
return dataLength;
|
}
|
#endregion <Private Method>
|
|
#region <Public Method>
|
public void ParseSource(byte[] Content)
|
{
|
PropertyInfo[] propertyInfos = GetType().GetProperties().Where(x => x.CanWrite).ToArray();
|
int index = 0;
|
for (int i = 0; i < propertyInfos.Length; i++)
|
{
|
PropertyInfo propertyInfo = propertyInfos[i];
|
|
TypeCode typeCode = Type.GetTypeCode(propertyInfo.PropertyType);
|
switch (typeCode)
|
{
|
case TypeCode.Byte:
|
case TypeCode.SByte:
|
propertyInfo.SetValue(this, Content[index]);
|
index += sizeof(byte);
|
break;
|
case TypeCode.Char:
|
propertyInfo.SetValue(this, (char)Content[index]);
|
index += sizeof(char);
|
break;
|
case TypeCode.Int16:
|
propertyInfo.SetValue(this, byteTransform.TransInt16(Content, index));
|
index += sizeof(short);
|
break;
|
case TypeCode.UInt16:
|
propertyInfo.SetValue(this, byteTransform.TransUInt16(Content, index));
|
index += sizeof(ushort);
|
break;
|
case TypeCode.Single:
|
propertyInfo.SetValue(this, byteTransform.TransSingle(Content, index));
|
index += sizeof(float);
|
break;
|
case TypeCode.Int32:
|
propertyInfo.SetValue(this, byteTransform.TransInt32(Content, index));
|
index += sizeof(int);
|
break;
|
case TypeCode.UInt32:
|
propertyInfo.SetValue(this, byteTransform.TransUInt32(Content, index));
|
index += sizeof(uint);
|
break;
|
case TypeCode.String:
|
ushort dataLength = CheckStringAttribute(propertyInfo);
|
propertyInfo.SetValue(this, Encoding.Default.GetString(Content, index + 2, Content[index + 1]));
|
index += dataLength;
|
break;
|
default:
|
throw new NotSupportedException("Unsupported primitive type: " + propertyInfo.PropertyType);
|
}
|
}
|
}
|
|
public byte[] ToSource()
|
{
|
int propertyValueHasNull = -1;
|
List<byte> bytes = new List<byte>();
|
PropertyInfo[] propertyInfos = GetType().GetProperties().Where(x => x.CanWrite).ToArray();
|
foreach (PropertyInfo propertyInfo in propertyInfos)
|
{
|
object? obj = propertyInfo.GetValue(this);
|
if (obj == null && propertyValueHasNull != -1)
|
{
|
throw new Exception($"{nameof(DeviceCommand)}错误");
|
}
|
else
|
{
|
if (propertyValueHasNull == -1)
|
propertyValueHasNull = 2;
|
}
|
TypeCode typeCode = Type.GetTypeCode(propertyInfo.PropertyType);
|
switch (typeCode)
|
{
|
case TypeCode.Byte:
|
case TypeCode.SByte:
|
case TypeCode.Char:
|
if (obj != null)
|
{
|
bytes.Add((byte)obj);
|
}
|
else
|
{ propertyValueHasNull = 1; }
|
break;
|
case TypeCode.Int16:
|
case TypeCode.UInt16:
|
if (obj != null)
|
{
|
byte[] bytesShort = BitConverter.GetBytes(Convert.ToUInt16(obj));
|
Array.Reverse(bytesShort);
|
bytes.AddRange(bytesShort);
|
}
|
else
|
{ propertyValueHasNull = 1; }
|
break;
|
case TypeCode.Single:
|
if (obj != null)
|
{
|
byte[] bytesSingle = BitConverter.GetBytes(Convert.ToSingle(obj));
|
Array.Reverse(bytesSingle);
|
bytes.AddRange(bytesSingle);
|
}
|
else
|
{ propertyValueHasNull = 1; }
|
break;
|
case TypeCode.Int32:
|
case TypeCode.UInt32:
|
if (obj != null)
|
{
|
byte[] bytesInt = BitConverter.GetBytes(Convert.ToUInt32(obj));
|
Array.Reverse(bytesInt);
|
bytes.AddRange(bytesInt);
|
}
|
else
|
{ propertyValueHasNull = 1; }
|
break;
|
case TypeCode.String:
|
|
if (obj != null)
|
{
|
ushort dataLength = CheckStringAttribute(propertyInfo);
|
byte[] bytesString = Encoding.Default.GetBytes(obj.ToString());
|
bytes.Add(Convert.ToByte(dataLength));
|
bytes.Add(Convert.ToByte(obj.ToString().Length));
|
bytes.AddRange(bytesString);
|
for (int i = 0; i < dataLength - obj.ToString().Length - 2; i++)
|
{
|
bytes.Add(0);
|
}
|
}
|
else
|
{ propertyValueHasNull = 1; }
|
break;
|
default:
|
throw new NotSupportedException("Unsupported primitive type: " + propertyInfo.PropertyType);
|
}
|
}
|
|
return bytes.ToArray();
|
}
|
#endregion <Public Method>
|
|
#region <Event>
|
#endregion <Event>
|
}
|
}
|