📄 hexparser.h
字号:
/*****************************************************************************
*
* 由 Atmel Corporation 的 AVR911 改编
*
* File : HEXParser.hpp
* Compiler : Microsoft Visual C++ 6.0
* Date : $Date: Sunday, January 20, 2008
*
* Support mail : helloshi@163.com
*
* Target platform : Win32
*
* Description : 一个简单的英特尔 HEX 格式文件 读/写.
*
*
****************************************************************************/
#ifndef HEXPARSER_HPP
#define HEXPARSER_HPP
#pragma warning(disable: 4018)
#include <assert.h>
#include <stdio.h>
#include <windows.h>
/* 内部用于管理 HEX 的记录 */
typedef struct _HEXRecord // Intel HEX 文件记录
{
unsigned char length; // 记录长度
unsigned long offset; // 记录数据偏移地址
unsigned char type; // 记录数据类型
unsigned char * data; // 记录数据.
} HEXRecord;
class HEXFile
{
protected:
volatile HANDLE _handleFile; // 文件句柄
unsigned char * data ; // 数据指针.
long start, end; // 缓冲区有用数据起始位置和结束位置
long size; // 数据缓冲区长度.
/* 字符串转换为十六进制数,长整型 */
long convertHex( CString txt )
{
long result = 0;
long digit;
long i;
if( txt.GetLength() == 0 )
{
AfxMessageBox( "不能转换0长度的hex字符串至数值!" );
return result;
}
if( txt.GetLength() > 8 )
{
AfxMessageBox( "转换溢出! 字符太多." );
return result;
}
char t;
for( i = 0; i < txt.GetLength(); i++ )
{
/* 转换为十六进制数 */
t=txt.GetAt(i);
if( txt.GetAt(i) >= '0' && txt.GetAt(i) <= '9' )
digit = txt.GetAt(i) - '0';
else if( txt.GetAt(i) >= 'a' && txt.GetAt(i) <= 'f' )
digit = txt.GetAt(i) - 'a' + 10;
else if( txt.GetAt(i) >= 'A' && txt.GetAt(i) <= 'F' )
digit = txt.GetAt(i) - 'A' + 10;
else{
AfxMessageBox( "发现无效的十六进制字符!" );
return result;
}
/* 结果至少4位有效 */
result = (result << 4) | digit;
}
return result;
}
/* 长整型十六进制数转换为字符串 */
CString convertLong( long num, long radix = 10 )
{
char buf[18];
CString res;
itoa( num, buf, radix );
res = buf;
return res;
}
//文件的一行转换为一个记录
BOOL parseRecord( CString hexLine, HEXRecord * recp )
{
unsigned char checksum;
long recordPos; // 记录内数据位置
if( hexLine.GetLength() < 11 ) // 至少11个字符.
{
AfxMessageBox( "Wrong HEX file format, missing fields! " );
return false;
}
/* 检查格式 */
if( hexLine[0] != ':' ) // 必须冒号开头.
{
AfxMessageBox( "错误的 HEX 文件格式, 不是冒号开头! ");
return false;
}
/* 分析 长度, 位置偏移 和 类型 */
recp->length = (unsigned char)convertHex( hexLine.Mid( 1, 2 ) );
recp->offset = convertHex( hexLine.Mid( 3, 4 ) );
recp->type = (unsigned char)convertHex( hexLine.Mid( 7, 2 ) );
/* 检查记录长度 */
if( hexLine.GetLength() < (11+recp->length*2) )
{
AfxMessageBox( "错误的 HEX 文件格式, 数据不完整! ");
return false;
}
/* 处理校验和 */
checksum = recp->length;
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
checksum += (unsigned char) (recp->offset & 0xff);
checksum += recp->type;
/* 分析数据区 */
if( recp->length )
{
recp->data = new unsigned char[ recp->length ];
/* 读数据至记录 */
for( recordPos = 0; recordPos < recp->length; recordPos++ )
{
recp->data[ recordPos ] = (unsigned char)convertHex( hexLine.Mid( 9 + recordPos*2, 2 ) );
checksum += recp->data[ recordPos ];
}
}
/* 正确的校验? */
checksum += (unsigned char)convertHex( hexLine.Mid( 9 + recp->length*2, 2 ) );
if( checksum != 0 )
{
AfxMessageBox( "HEX 记录校验和错误! " );
return false;
}
return true;
}
/* 写一个记录 */
bool writeRecord( HEXRecord * recp )
{
if(_handleFile==INVALID_HANDLE_VALUE)
{
AfxMessageBox( "文件错误! " );
return false;
}
DWORD nNumberOfBytesToWrite;
LPDWORD lpNumberOfBytesWritten=&nNumberOfBytesToWrite;
unsigned char checksum;
long recordPos; // 记录内数据位置
/* 计算校验和 */
checksum = recp->length;
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
checksum += (unsigned char) (recp->offset & 0xff);
checksum += recp->type;
/* 写记录头 */
char str[100];
sprintf(str,":%02X%04X%02X",(long) recp->length,(long) recp->offset,(long) recp->type);
nNumberOfBytesToWrite=strlen(str);
if(WriteFile(_handleFile,str,nNumberOfBytesToWrite,lpNumberOfBytesWritten,NULL)==NULL)
return false;
/* 写记录数据 */
for( recordPos = 0; recordPos < recp->length; recordPos++ )
{
checksum += recp->data[ recordPos ]; // Further checksum calculation
sprintf(str,"%02X",(long) recp->data[ recordPos ]);
nNumberOfBytesToWrite=strlen(str);
if(WriteFile(_handleFile,str,nNumberOfBytesToWrite,lpNumberOfBytesWritten,NULL)==NULL)
return false;
}
/* 写校验和 */
checksum = 0 - checksum; // Final checksum preparation
sprintf(str,"%02X",checksum);
nNumberOfBytesToWrite=strlen(str);
if(WriteFile(_handleFile,str,nNumberOfBytesToWrite,lpNumberOfBytesWritten,NULL)==NULL)
return false;
strcpy(str,"\r\n");
nNumberOfBytesToWrite=2;
if(WriteFile(_handleFile,str,nNumberOfBytesToWrite,lpNumberOfBytesWritten,NULL)==NULL)
return false;
return true;
}
public:
/* 结构 */
HEXFile()
{
size = 0;
}
/* 析构 */
~HEXFile()
{
//if( data ) delete data;
closeFile();
}
void setHEXFile( long buffersize, long value = 0xff )
{
//if( data ) {delete [] data;} //???为什么执行有错误???
if( buffersize <= 0 )
AfxMessageBox( "Cannot have zero-size HEX buffer!" );
data = new unsigned char[ buffersize ];
if( !data )
AfxMessageBox( "Memory allocation failed for HEX-line-buffer!" );
size = buffersize;
clearAll( value );
}
bool fileExists( CString filename )
{
/* 试图打开文件 */
HANDLE f=CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(f==INVALID_HANDLE_VALUE)
{
return false;
}
else {
CloseHandle(f);
return true;
}
}
//打开文件读
bool openFileRead( CString filename )
{
closeFile();
_handleFile=CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(_handleFile!=INVALID_HANDLE_VALUE)
{
DWORD filesize=GetFileSize(_handleFile,NULL);
if (filesize == 0xFFFFFFFF)
{
AfxMessageBox( "获取文件长度错误! " );
return false;
}
if (size <=0) setHEXFile( 1024*1024 );
return true;
}
else return false;
}
//打开文件写
//DEL bool openFileWrite( CString filename )
//DEL {
//DEL closeFile();
//DEL _handleFile=CreateFile(filename,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
//DEL return(_handleFile!=INVALID_HANDLE_VALUE);
//DEL }
//打开文件写
bool openFileWrite( CString filename, long filesize = 0 )
{
closeFile();
if (filesize)
{
start = 0;
end = filesize - 1 ;
if (size <=0) setHEXFile( 1024*1024 );
}
_handleFile=CreateFile(filename,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
return(_handleFile!=INVALID_HANDLE_VALUE);
}
//关闭文件
bool closeFile()
{
return(CloseHandle(_handleFile)!=0);
}
BOOL saveString( CString txt)
{
if(_handleFile==INVALID_HANDLE_VALUE)
{
AfxMessageBox( "文件错误! " );
return false;
}
DWORD nNumberOfBytesToWrite=txt.GetLength();
LPDWORD lpNumberOfBytesWritten=&nNumberOfBytesToWrite;
if(WriteFile(_handleFile,txt,nNumberOfBytesToWrite,lpNumberOfBytesWritten,NULL)==NULL)
return false;
}
public:
/* 方法 */
// 设定使用范围.
void setUsedRange( long _start, long _end )
{
if( _start < 0 || _end >= size || _start > _end )
AfxMessageBox( "无效范围! 起始必须不小于0,结束必须在内存允许范围." );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -