⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hexparser.h

📁 上位机软件 for avricp 根据功能设定熔丝
💻 H
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
*
* 由 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 + -