HEX文件转二进制的源码

#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;
//}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值