706 lines
18 KiB
C#
706 lines
18 KiB
C#
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();
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|