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