#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
#endregion
#region
///
/// 数据长度
///
public ushort ReadCount { get; }
private IByteTransform byteTransform = new ReverseBytesTransform();
#endregion
#region
#endregion
#region
///
/// 构造函数
///
///
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
#region
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
#region
///
/// 数据装换
///
///
///
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 bytes = new List();
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
#region
#endregion
}
}