?? 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>
/* 內(nèi)部用于管理 HEX 的記錄 */
typedef struct _HEXRecord // Intel HEX 文件記錄
{
unsigned char length; // 記錄長度
unsigned long offset; // 記錄數(shù)據(jù)偏移地址
unsigned char type; // 記錄數(shù)據(jù)類型
unsigned char * data; // 記錄數(shù)據(jù).
} HEXRecord;
class HEXFile
{
protected:
volatile HANDLE _handleFile; // 文件句柄
unsigned char * data ; // 數(shù)據(jù)指針.
long start, end; // 緩沖區(qū)有用數(shù)據(jù)起始位置和結(jié)束位置
long size; // 數(shù)據(jù)緩沖區(qū)長度.
/* 字符串轉(zhuǎn)換為十六進制數(shù),長整型 */
long convertHex( CString txt )
{
long result = 0;
long digit;
long i;
if( txt.GetLength() == 0 )
{
AfxMessageBox( "不能轉(zhuǎn)換0長度的hex字符串至數(shù)值!" );
return result;
}
if( txt.GetLength() > 8 )
{
AfxMessageBox( "轉(zhuǎn)換溢出! 字符太多." );
return result;
}
char t;
for( i = 0; i < txt.GetLength(); i++ )
{
/* 轉(zhuǎn)換為十六進制數(shù) */
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( "發(fā)現(xiàn)無效的十六進制字符!" );
return result;
}
/* 結(jié)果至少4位有效 */
result = (result << 4) | digit;
}
return result;
}
/* 長整型十六進制數(shù)轉(zhuǎn)換為字符串 */
CString convertLong( long num, long radix = 10 )
{
char buf[18];
CString res;
itoa( num, buf, radix );
res = buf;
return res;
}
//文件的一行轉(zhuǎn)換為一個記錄
BOOL parseRecord( CString hexLine, HEXRecord * recp )
{
unsigned char checksum;
long recordPos; // 記錄內(nèi)數(shù)據(jù)位置
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 文件格式, 數(shù)據(jù)不完整! ");
return false;
}
/* 處理校驗和 */
checksum = recp->length;
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
checksum += (unsigned char) (recp->offset & 0xff);
checksum += recp->type;
/* 分析數(shù)據(jù)區(qū) */
if( recp->length )
{
recp->data = new unsigned char[ recp->length ];
/* 讀數(shù)據(jù)至記錄 */
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; // 記錄內(nèi)數(shù)據(jù)位置
/* 計算校驗和 */
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;
/* 寫記錄數(shù)據(jù) */
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:
/* 結(jié)構(gòu) */
HEXFile()
{
size = 0;
}
/* 析構(gòu) */
~HEXFile()
{
//if( data ) delete data;
closeFile();
}
void setHEXFile( long buffersize, long value = 0xff )
{
//if( data ) {delete [] data;} //???為什么執(zhí)行有錯誤???
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);
}
//關(guān)閉文件
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:
/* 方法 */
// 設(shè)定使用范圍.
void setUsedRange( long _start, long _end )
{
if( _start < 0 || _end >= size || _start > _end )
AfxMessageBox( "無效范圍! 起始必須不小于0,結(jié)束必須在內(nèi)存允許范圍." );
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -