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