#include "stdafx.h"
#define HEX_TRANSLATE_ERROR_NONE 0 //无错误返回
#define HEX_TRANSLATE_ERROR_NOSPACE -1 //未指定存储空间
#define HEX_TRANSLATE_ERROR_OVERFLOW -2 //存储空间溢出
#define HEX_TRANSLATE_ERROR_SYNTAX -3 //语法错误
#define HEX_TRANSLATE_ERROR_CHECKSUM -4 //校验和错误
#define HEX_TRANSLATE_ERROR_OPENFILE -5 //文件打开失败
//INT ReadHexFileInBuff(LPCTSTR filename, BYTE* pData, UINT MaxDataSize)
INT ReadHexFile(LPCTSTR filename, BYTE* pData, UINT MaxDataSize);
UINT Hex2Bin(CString hexstr);
bool ReadLineInBuff(CString& strLine, const CHAR* pBuff, UINT nSize, bool bInit);
//===============================================================================
//从文S本缓冲区中读取一行HEX文本
bool ReadLineInBuff(CString& strLine, const CHAR* pBuff, UINT nSize, bool bInit)
{
static UINT nStart;
static UINT nPos;
if(bInit)
{
nStart = 0;
nPos = 0;
return true;
}
if(nStart >= nSize)
{
return false;
}
for(nPos=nStart; nPos<nSize; nPos++)
{
if(pBuff[nPos] == '\r' && pBuff[nPos+1] == '\n')
{
UINT len = nPos - nStart;
memcpy(strLine.GetBufferSetLength(len), pBuff+nStart, len);
strLine.ReleaseBufferSetLength(len);
nStart = nPos+2;
return true;
}
}
//最后一行没"\r\n"
UINT len = nPos-nStart;
memcpy(strLine.GetBufferSetLength(len), pBuff+nStart,len); //拷贝数据
strLine.ReleaseBufferSetLength(len);
nStart = nSize;
return true;
}
//------------------------------------------------------------------------------
//转换HEX码到二进制数据,并把这些数据写到指定缓冲中的指定位置,该位置同HEX文档指定,仅需提供一个缓冲区指针pData
INT ReadHexFile(LPCTSTR filename, BYTE* pData, UINT MaxDataSize)
{
CFile hexfile;
UINT nSize;
CHAR* pDataBuff = NULL;
if(hexfile.Open(filename,CFile::modeRead))
{
nSize = (UINT)hexfile.GetLength();
if(nSize > 0)
{
pDataBuff = new CHAR[nSize]; //申请空间
hexfile.Read(pDataBuff, nSize); //内容读取到缓冲中
hexfile.Close();
}
else
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_SYNTAX; //空字节,语法错误
}
}
else
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_OPENFILE;
}
if(MaxDataSize == 0 || pData == NULL)
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_NOSPACE; //无有效存储空间
}
UINT bytecount; //某行的数据字节数d
BYTE checksum; //二进制数据
UINT linetype; //行的类型
UINT32 addr,exaddr=0; //标示地址和护展地址
CString strHexLine;
ReadLineInBuff(strHexLine, pDataBuff, nSize, TRUE); //初始化
while(ReadLineInBuff(strHexLine, pDataBuff, nSize, false))
{
strHexLine.Trim(); //去除首尾空格
strHexLine.MakeUpper(); //全部大写
if(strHexLine.IsEmpty())
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_NONE; //空行不处理
}
UINT ch_count = strHexLine.GetLength();
if(strHexLine[0] != ':' || ch_count<11)
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_SYNTAX; //首字符不为":",语法错误
}
checksum = 0;
for(UINT i=1; i<ch_count-3; i+=2)
{
checksum += Hex2Bin(CString(strHexLine
)+strHexLine[i+1]);
}
checksum = (~checksum)+1;
if(checksum != Hex2Bin(CString(strHexLine[ch_count-2])+strHexLine[ch_count-1]))
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_CHECKSUM; //校验和错误
}
linetype = Hex2Bin(CString(strHexLine[7])+strHexLine[8]);
bytecount = Hex2Bin(CString(strHexLine[1])+strHexLine[2]);
addr = Hex2Bin(CString(strHexLine[3])+strHexLine[4]+strHexLine[5]+strHexLine[6]);
switch(linetype)
{
case 0: //数据记录
{
UINT32 cur_addr = addr + exaddr;
if(cur_addr >= MaxDataSize)
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_OVERFLOW;//数据超出界限
}
for(UINT i=0; i<(bytecount+bytecount); i+=2)
{
pData[cur_addr] = Hex2Bin(CString(strHexLine[i+9]) + strHexLine[i + 10]);
cur_addr++;
}
}
break;
case 1:
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_NONE; //HEX文件结束记录
break;
case 2: //计算扩展地址,并左移4位
if(bytecount != 2) //后面必须有扩展的地址
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_SYNTAX;
}
exaddr = Hex2Bin(CString(strHexLine[9])+ strHexLine[10] + strHexLine[11] + strHexLine[12]);
exaddr <<= 4;
break;
case 4: //计算扩展地址,并左移16位
if(bytecount != 2) //后面必须有扩展的地址
{
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_SYNTAX;
}
exaddr = Hex2Bin(CString(strHexLine[9])+ strHexLine[10] + strHexLine[11] + strHexLine[12]);
exaddr <<= 16;
break;
case 3:
break;
default:
break;
}
}
if(pDataBuff != NULL)delete[] pDataBuff;
return HEX_TRANSLATE_ERROR_NONE; //正常结束
}
//------------------------------------------------------------------------------
//16进制字串转二进制
UINT Hex2Bin(CString hexstr)
{ //0 1 2 3 4 5 6 7 8 9 A B C D E F
static UINT numtab[]={0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15};
static UINT powtab[]={1,16,256,4096};
ULONG value=0;
hexstr.MakeUpper(); //转换为大写
if(hexstr.GetLength()> 4)return 0; //不能超过四位的长度
for(INT i=0; i<hexstr.GetLength(); i++)
{
if(hexstr<'0')return 0;
if(hexstr>'F')return 0;
if(hexstr>'9' && hexstr<'A')return 0;
}
UINT j=0;
for(UINT i=hexstr.GetLength(); i>0; i--)
{
value += (numtab[hexstr[i-1]-'0'] * powtab[j++]);
}
return value;
}
//
//CString Bin2Hex(UINT value, UINT len)
//{
// CString hexstr;
// hexstr.Format("%X",value);
// return hexstr;
//}