using ProjectBase.Data.Logs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SIASUN.Autopilot.Device { public static class MessageCoder { // can总线数据包长度 private static int ByteLength = 8; /// /// 序列化数据对象 /// /// 数据对象 public static byte[] Serialize(object dataModel) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); byte[] data = new byte[8]; foreach (System.Reflection.PropertyInfo field in dataModel.GetType().GetProperties()) { object[] objs = field.GetCustomAttributes(typeof(DataAttribute), false); if (objs.Length > 0) { DataAttribute fieldAttr = (DataAttribute)objs[0]; if (fieldAttr.DataType == "LIST") { System.Collections.IList fieldValues = field.GetValue(dataModel, null) as System.Collections.IList; foreach (object fieldValue in fieldValues) { byte[] bytefiled = Serialize(fieldValue); ms.Write(bytefiled, 0, bytefiled.Length); } } else if (fieldAttr.DataType == "binary") { string fieldValue = field.GetValue(dataModel, null) == null ? "" : field.GetValue(dataModel, null).ToString(); byte[] bytefiled = serializeField(fieldAttr.BitStart, fieldValue, fieldAttr.BitLength); ms.Write(bytefiled, fieldAttr.BitStart, bytefiled.Length); } else { LogHelper.log.Error("数据类型不是binary"); } } } return ms.ToArray(); } /// /// 反序列化数据对象 /// /// 数据对象 /// 数据流 public static object DeSerialize(object dataModel, byte[] bytes) { foreach (System.Reflection.PropertyInfo field in dataModel.GetType().GetProperties()) { object[] objs = field.GetCustomAttributes(typeof(DataAttribute), false); if (objs.Length > 0) { DataAttribute fieldAttr = (DataAttribute)objs[0]; if (fieldAttr.DataType == "binary") { int byteth = fieldAttr.BitStart / ByteLength; // 第几个字节 if (bytes.Length <= byteth) { LogHelper.log.Error(string.Format("代表{0}的字段长度出现错误", fieldAttr.Description)); return null; } field.SetValue(dataModel, de_serializeField(fieldAttr.BitStart, fieldAttr.BitLength, bytes), null); } else { LogHelper.log.Error("数据类型不是binary"); } } } return dataModel; } /// /// 解析位 /// /// /// /// /// private static string de_serializeField(int startBit, int lengthBit, byte[] bytedata) { int byteth = startBit / ByteLength; // 第几个字节 int bytesLength = (startBit%ByteLength + lengthBit )/ ByteLength + ((startBit % ByteLength + lengthBit) % ByteLength) > 0 ? 1 : 0; byte[] data = new byte[bytesLength]; byte[] resultByteData = new byte[bytesLength]; Buffer.BlockCopy(bytedata, byteth, data, 0, bytesLength); BitOR(resultByteData, RightShift(data, startBit % ByteLength)); return de_serialize_hex(resultByteData); } private static byte[] serializeField(int startBit, string value, int lengthBit) { int byteth = startBit / ByteLength; // 第几个字节 int bytesLength = (startBit % ByteLength + lengthBit) / ByteLength + ((startBit % ByteLength + lengthBit) % ByteLength) > 0 ? 1 : 0; byte[] byteArray = serialize_hex(value, bytesLength); byte[] resultByteData = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00}; if (byteth< 8) { resultByteData = BitOR(resultByteData, LeftShift (byteArray, startBit % ByteLength)); } else { LogHelper.log.Error(string.Format("第{0}位赋值不成功", startBit)); } return resultByteData; } public static byte[] serialize_hex(string value, int length) { byte[] returnBytes = new byte[length]; bool ishexstring = false; if (string.IsNullOrEmpty(value)) { return returnBytes; } ishexstring = true; value = value.Replace(" ", ""); if ((value.Length % 2) != 0) { value = "0" + value; } for (int i = 0; i < value.Length / 2; i++) { if (ishexstring) { returnBytes[i] = Convert.ToByte(value.Substring(i * 2, 2), 16); } else { returnBytes[i] = Convert.ToByte(value.Substring(i, 1), 16); } } return returnBytes; } public static string de_serialize_hex(byte[] bsdata) { string returnStr = ""; if (bsdata != null) { for (int i = 0; i < bsdata.Length; i++) { returnStr += bsdata[i].ToString("X2"); } } return returnStr; } /// /// byte转化成bit /// /// /// private static int byteToBit(byte bytedata, int bitLocation) { return (int)((bytedata) >> bitLocation) & 0x1; } private static byte[] BitAnd(this byte[] ba1, byte[] ba2) { if (ba1.Length != ba2.Length) { return new byte[0]; } var ba3 = new byte[ba1.Length]; for (int i = 0; i < ba3.Length; i++) { ba3[i] = (byte)((byte)ba1[i] & (byte)ba2[i]); } return ba3; } private static byte[] BitOR(this byte[] ba1, byte[] ba2) { if (ba1.Length != ba2.Length) { return new byte[0]; } var ba3 = new byte[ba1.Length]; for (int i = 0; i < ba3.Length; i++) { ba3[i] = (byte)((byte)ba1[i] | (byte)ba2[i]); } return ba3; } private static byte[] RightShift(this byte[] ba, int n) { if (n < 0) { return LeftShift(ba, Math.Abs(n)); } byte[] ba2 = null; ba2 = ba.Clone() as byte[]; int loop = (int)Math.Ceiling(n / 8.0); byte tempByte = 0; byte tempByte2 = 0; byte Header = 0; for (int i = 0; i < loop; i++) { var tempN = i + 1 == loop ? n % 8 : 8; if (tempN == 0 && n != 0) { tempN = 8; } for (int j = 0; j < ba.Length; j++) { if (j == 0) { Header = (byte)((ba2.First() & ((byte)(Math.Pow(2, tempN) - 1))) << (8 - tempN)); tempByte = (byte)((ba2[ba.Length - 1 - j] & ((byte)(Math.Pow(2, tempN) - 1))) << (8 - tempN)); ba2[ba.Length - 1 - j] >>= tempN; } else { tempByte2 = (byte)((ba2[ba.Length - 1 - j] & ((byte)(Math.Pow(2, tempN) - 1))) << (8 - tempN)); ba2[ba.Length - 1 - j] >>= tempN; ba2[ba.Length - 1 - j] |= tempByte; tempByte = tempByte2; if (j + 1 == ba.Length) { ba2[j] |= Header; } } } } return ba2; } private static byte[] LeftShift(this byte[] ba, int n) { if (n < 0) { return RightShift(ba, Math.Abs(n)); } byte[] ba2 = null; ba2 = ba.Clone() as byte[]; int loop = (int)Math.Ceiling(n / 8.0); byte tempByte = 0; byte tempByte2 = 0; byte Header = 0; for (int i = 0; i < loop; i++) { var tempN = i + 1 == loop ? n % 8 : 8; if (tempN == 0 && n != 0) { tempN = 8; } for (int j = 0; j < ba.Length; j++) { if (j == 0) { Header = (byte)(ba2.Last() & ((byte)(Math.Pow(2, tempN) - 1) << (8 - tempN))); tempByte = (byte)(ba2[j] & ((byte)(Math.Pow(2, tempN) - 1) << (8 - tempN))); ba2[j] <<= tempN; } else { tempByte2 = (byte)(ba2[j] & ((byte)(Math.Pow(2, tempN) - 1) << (8 - tempN))); ba2[j] <<= tempN; ba2[j] |= (byte)(tempByte >> (8 - tempN)); tempByte = tempByte2; if (j + 1 == ba.Length) { ba2[0] |= (byte)(Header >> (8 - tempN)); } } } } return ba2; } } }