HONGRI_uds_tools/CAN_Tool/S19File.cs

706 lines
18 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace S19File
{
class S19FileStream
{
public List<string> FileText;
//数据大小
private int size;
public int Size
{
get
{
return size;
}
}
//起始地址
private int startAddr;
public int StartAddr
{
get
{
return startAddr;
}
}
//结束地址
private int endAddr;
public int EndAddr
{
get
{
return endAddr;
}
}
public S19FileStream()
{
FileText = new List<string>();
size = 0;
startAddr = 0;
endAddr = 0;
}
public S19FileStream(string FileName)
{
StreamReader StreamRead = new StreamReader(FileName, System.Text.Encoding.Default);
FileText = new List<string>();
string LineText;
while ((LineText = StreamRead.ReadLine()) != null)
{
if (0 != LineText.Length)
{
FileText.Add(LineText);
}
}
size = GetSize();
startAddr = GetStartAddr();
endAddr = GetEndAddr();
}
//清除读取到的S19数据
public void Clear()
{
this.FileText.Clear();
size = 0;
startAddr = 0;
endAddr = 0;
}
//获取S19文件的数据的大小
private int GetSize()
{
int size;
int startAddr;
int endAddr;
int endLineNum;
int endLineDataLen;
//获取起始地址
startAddr = this.GetStartAddr();
endAddr = this.GetEndAddr();
endLineNum = this.GetEndLineNum();
endLineDataLen = this.GetLineDataLen(endLineNum);
size = endAddr - startAddr + endLineDataLen;
return size;
}
//一字节转16进制字符串 小于0x10往前补零
private string ByteToStringHex(byte num)
{
string str;
if (num >= 0x10)
{
str = Convert.ToString(num, 16);
}
else
{
str = "0" + Convert.ToString(num, 16);
}
return str.ToUpper();
}
public byte[] ToBinByteArray(int size)
{
string s19Head;
int count = 0;
int lineAddrLen;
int lineDataLen;
List<byte> dataBuff = new List<byte>();
foreach (string line in this.FileText)
{
s19Head = line.Substring(0, 2);
lineDataLen = Convert.ToByte(line.Substring(2, 2), 16);
/*lineAddrLen = s19Head switch
{
"S1" => 4,
"S1"
}*/
switch (s19Head)
{
case "S1":
{
lineAddrLen = 4;
break;
}
case "S2":
{
lineAddrLen = 6;
break;
}
case "S3":
{
lineAddrLen = 8;
break;
}
default:
lineAddrLen = 0;
break;
}
if (0 != lineAddrLen)
{
for (int i = lineAddrLen + 4; i < (lineDataLen << 1) + 2; i += 2)
{
dataBuff.Add(Convert.ToByte(line.Substring(i, 2), 16));
count++;
if (count >= size)
{
return dataBuff.ToArray();
}
}
}
}
return dataBuff.ToArray();
}
//获取S19行存放地址的长度
private int GetLineAddrLen(int line)
{
string s19LineHead;
int lineAddrLen;
if ((line < this.FileText.Count)
&& (line >= 0)
)
{
s19LineHead = this.FileText[line].Substring(0, 2);
}
else
{
s19LineHead = "";
}
switch (s19LineHead)
{
case "S1":
{
lineAddrLen = 4;
break;
}
case "S2":
{
lineAddrLen = 6;
break;
}
case "S3":
{
lineAddrLen = 8;
break;
}
default:
lineAddrLen = 0;
break;
}
return lineAddrLen;
}
private int GetLineAddr(int line)
{
//一行的头 S0 S1 S2 S3 ...
//string s19LineHead;
//要读取的行的地址数据的长度
int lineAddrLen;
//要读取的行的地址
int lineAddr;
lineAddrLen = GetLineAddrLen(line);
if (0 == lineAddrLen)
{
lineAddr = 0;
}
else
{
lineAddr = Convert.ToInt32(this.FileText[line].Substring(4, lineAddrLen), 16);
}
return lineAddr;
}
private int GetStartAddr()
{
string s19Head;
//int lineAddrLen;
int startAddr;
int headLineNum = 0;
s19Head = this.FileText[0].Substring(0, 2);
if ("S0" == s19Head)
{
headLineNum = 1;
}
startAddr = GetLineAddr(headLineNum);
return startAddr;
}
//获取结束行数
private int GetEndLineNum()
{
int endLineNum = -1;
for (int i = this.FileText.Count - 1; i >= 0; i--)
{
if (("S1" == this.FileText[i].Substring(0, 2))
|| ("S2" == this.FileText[i].Substring(0, 2))
|| ("S3" == this.FileText[i].Substring(0, 2))
)
{
endLineNum = i;
break;
}
}
return endLineNum;
}
//获取结束行的地址大小
private int GetEndAddr()
{
int endLineNum = 0;
int endAddr;
endLineNum = GetEndLineNum();
if (0 == endLineNum)
{
endAddr = 0;
}
else
{
endAddr = this.GetLineAddr(endLineNum);
}
return endAddr;
}
private byte GetS19LineChecksum(string line)
{
byte lineDataLen;
int sum = 0;
lineDataLen = Convert.ToByte(line.Substring(2, 2), 16);
int len = line.Length;
for (int i = 2; i < (lineDataLen << 1) + 2; i += 2)
{
sum += Convert.ToByte(line.Substring(i, 2), 16);
}
sum = 0xff - (sum & 0xff);
//sum = temp - sum;
return (byte)sum;
}
//获取S19标识的行的长度
private int GetLineLen(int line)
{
int lineLen;
if ((line < this.FileText.Count)
&& (line >= 0)
)
{
lineLen = Convert.ToInt16(this.FileText[line].Substring(2, 2), 16);
}
else
{
lineLen = 0;
}
return lineLen;
}
//获取S19行的数据长度
private int GetLineDataLen(int line)
{
int lineLen;
int lineAddrLen;
int lineDataLen;
lineLen = GetLineLen(line);
lineAddrLen = this.GetLineAddrLen(line);
lineDataLen = lineLen - lineAddrLen / 2 - 1;
return lineDataLen;
}
public void AddHead(byte[] data, int size, byte fill)
{
string s19Head;
//string line = "";
int lineLen;
int lineDataLen;
int lineAddrLen;
int startAddr;
int addLineNum;
int dataIndex = 0;
int insertIndex;
int headLineNum = 0;
s19Head = this.FileText[0].Substring(0, 2);
if ("S0" == s19Head)
{
headLineNum = 1;
}
insertIndex = headLineNum;
s19Head = this.FileText[headLineNum].Substring(0, 2);
lineLen = Convert.ToByte(this.FileText[headLineNum].Substring(2, 2), 16);
switch (s19Head)
{
case "S1":
{
lineAddrLen = 4;
break;
}
case "S2":
{
lineAddrLen = 6;
break;
}
case "S3":
{
lineAddrLen = 8;
break;
}
default:
{
return;
}
}
lineDataLen = lineLen - (lineAddrLen >> 1) - 1;
startAddr = this.GetStartAddr();
if (size > startAddr)
{
return;
}
else
{
//需要增加的行数 向上取整
addLineNum = (size + lineDataLen - 1) / (lineDataLen);
startAddr = startAddr - addLineNum * lineDataLen;
for (int i = 0; i < addLineNum; i++)
{
//添加Sx和长度
string line = s19Head + this.ByteToStringHex((byte)lineLen);
//添加地址
for (int j = 0; j < (lineAddrLen >> 1); j++)
{
int addrNum = (startAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff;
line += this.ByteToStringHex((byte)addrNum);
}
startAddr += lineDataLen;
//添加数据
for (int k = 0; k < lineDataLen; k++)
{
if (dataIndex < data.Length)
{
line += this.ByteToStringHex(data[dataIndex]);
dataIndex++;
}
else
{
line += "FF";
}
}
//添加校验和
line += this.ByteToStringHex(this.GetS19LineChecksum(line));
//line += "\r\n";
this.FileText.Insert(insertIndex, line);
insertIndex++;
}
}
startAddr = GetStartAddr();
endAddr = GetEndAddr();
size = GetSize();
}
public void AddEnd(byte[] data, int size, byte fill)
{
string s19Head;
//string line = "";
int lineLen;
int lineDataLen;
int lineAddrLen;
int addAddr;
int addLineNum;
int dataIndex = 0;
int insertIndex;
int endLineNum;
int endLineLen;
int endLineAddLen;
char[] endLineTextData;
endLineNum = this.GetEndLineNum();
insertIndex = endLineNum + 1;
lineAddrLen = this.GetLineAddrLen(endLineNum);
lineDataLen = this.GetLineDataLen(endLineNum - 1);
endLineLen = this.GetLineLen(endLineNum);
lineLen = this.GetLineLen(endLineNum - 1);
s19Head = this.FileText[endLineNum].Substring(0, 2);
//最后一行未满
if (endLineLen < lineLen)
{
if (size > (lineLen - endLineLen))
{
endLineAddLen = lineLen - endLineLen;
}
else
{
endLineAddLen = size;
}
endLineTextData = this.FileText[endLineNum].Substring(0, endLineLen * 2 + 2).ToCharArray();
string temp = this.ByteToStringHex((byte)(endLineLen + endLineAddLen));
endLineTextData[2] = temp[0];
endLineTextData[3] = temp[1];
this.FileText[endLineNum] = new string(endLineTextData);
for (int k = 0; k < endLineAddLen; k++)
{
if (dataIndex < data.Length)
{
this.FileText[endLineNum] += this.ByteToStringHex(data[dataIndex]);
}
else
{
this.FileText[endLineNum] += "FF";
}
dataIndex++;
size--;
}
//添加校验和
this.FileText[endLineNum] += this.ByteToStringHex(this.GetS19LineChecksum(this.FileText[endLineNum]));
}
//需要增加的行数 向上取整
addLineNum = (size + lineDataLen - 1) / (lineDataLen);
//需要添加的地址
addAddr = this.GetEndAddr();
for (int i = 0; i < addLineNum; i++)
{
addAddr += lineDataLen;
//添加Sx和长度
string line = s19Head + this.ByteToStringHex((byte)lineLen);
//添加地址
for (int j = 0; j < (lineAddrLen >> 1); j++)
{
int addrNum = (addAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff;
line += this.ByteToStringHex((byte)addrNum);
}
//添加数据
for (int k = 0; k < lineDataLen; k++)
{
if (dataIndex < data.Length)
{
line += this.ByteToStringHex(data[dataIndex]);
dataIndex++;
}
else
{
line += "FF";
}
}
//添加校验和
line += this.ByteToStringHex(this.GetS19LineChecksum(line));
//line += "\r\n";
this.FileText.Insert(insertIndex, line);
insertIndex++;
}
startAddr = GetStartAddr();
endAddr = GetEndAddr();
size = GetSize();
}
public void ReadBinArray(string s19Head, byte[] data, int startAddr, int lineLen)
{
int addLineNum;
int lineAddrLen;
int lineDataLen;
int addAddr;
int dataIndex = 0;
switch (s19Head)
{
case "S1":
{
lineAddrLen = 4;
break;
}
case "S2":
{
lineAddrLen = 6;
break;
}
case "S3":
{
lineAddrLen = 8;
break;
}
default:
{
return;
}
}
//需要添加的地址
addAddr = startAddr;
lineDataLen = lineLen - (lineAddrLen >> 1) - 1;
//需要增加的行数 向上取整
addLineNum = (data.Length + lineDataLen - 1) / (lineDataLen);
this.FileText.Clear();
for (int i = 0; i < addLineNum; i++)
{
//添加Sx和长度
if ((data.Length - dataIndex) < (lineLen - 1))//最后一行数据未满
{
lineDataLen = data.Length - dataIndex;
lineLen = lineDataLen + (lineAddrLen >> 1) + 1;
}
string line = s19Head + this.ByteToStringHex((byte)lineLen);
//添加地址
for (int j = 0; j < (lineAddrLen >> 1); j++)
{
int addrNum = (addAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff;
line += this.ByteToStringHex((byte)addrNum);
}
//添加数据
for (int k = 0; k < lineDataLen; k++)
{
if (dataIndex < data.Length)
{
line += this.ByteToStringHex(data[dataIndex]);
dataIndex++;
}
else
{
line += "FF";
}
}
//添加校验和
line += this.ByteToStringHex(this.GetS19LineChecksum(line));
//line += "\r\n";
//this.FileText.Insert(insertIndex, line);
this.FileText.Add(line);
addAddr += lineDataLen;
}
startAddr = GetStartAddr();
endAddr = GetEndAddr();
size = GetSize();
}
}
}