using HslCommunication.Core; using HslCommunication; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace WIDESEAWCS_Communicator { public class ModbusCustomModel { #region <Const> #endregion <Const> #region <Private Member> public ushort ReadCount { get; } private IByteTransform byteTransform = new ReverseWordTransform(); #endregion <Private Member> #region <Public Menber> #endregion <Public Menber> #region <Constructor function> public ModbusCustomModel() { 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("䏿”¯æŒçš„基础类型: " + 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】"); } 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, byteTransform.TransString(Content.SelectMiddle(index, dataLength), Encoding.Default)); index += dataLength; break; default: throw new NotSupportedException("䏿”¯æŒçš„基础类型: " + 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($"{GetType().Name}错误"); } 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 = byteTransform.TransByte(obj.ToString(), Encoding.Default); bytes.AddRange(bytesString); } else { propertyValueHasNull = 1; } break; default: throw new NotSupportedException("䏿”¯æŒçš„基础类型: " + propertyInfo.PropertyType); } } return bytes.ToArray(); } #endregion <Public Method> #region <Event> #endregion <Event> } }