259 lines
5.8 KiB
C++
259 lines
5.8 KiB
C++
#include "HexFile.h"
|
|
#include <QTextStream>
|
|
#include <QMessageBox>
|
|
|
|
#define USE_BIG_RECORDS
|
|
#define MAX_RECORDS_IN_BIG_RECORDS 512 //16 bytes by record, 512 bytes by row --> 16 rows / big record
|
|
|
|
CHexFile::CHexFile(void)
|
|
{
|
|
mFileOpened = false;
|
|
mFileParsed = false;
|
|
mRecordsListValid = false;
|
|
mHighAddress = 0;
|
|
mDiscardedRecords = 0;
|
|
mTotalParsedRecords = 0;
|
|
|
|
}
|
|
|
|
CHexFile::~CHexFile(void)
|
|
{
|
|
for(int i = 0; i < mRecordsList.size(); i++)
|
|
delete mRecordsList.at(i);
|
|
|
|
}
|
|
|
|
int CHexFile::CloseOpenedHexFile()
|
|
{
|
|
for(int i = 0; i < mRecordsList.size(); i++)
|
|
delete mRecordsList.at(i);
|
|
|
|
mFileOpened = false;
|
|
mFileParsed = false;
|
|
mHexfileHandle = 0;
|
|
mRecordsListValid = false;
|
|
mHighAddress = 0;
|
|
mDiscardedRecords = 0;
|
|
mTotalParsedRecords = 0;
|
|
}
|
|
|
|
int CHexFile::OpenDataFile(QString FilePath, bool CloseIfAlreadyParsed)
|
|
{
|
|
|
|
//Check if file exists
|
|
if(QFile::exists(FilePath) == false)
|
|
return 0;
|
|
|
|
if(mFileParsed == true)
|
|
{
|
|
if(CloseIfAlreadyParsed == false)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
CloseOpenedHexFile();
|
|
}
|
|
}
|
|
|
|
mHexfileHandle = new QFile(FilePath);
|
|
|
|
if(mHexfileHandle->open(QIODevice::ReadOnly|QIODevice::Text|QIODevice::Unbuffered) == false)
|
|
{
|
|
delete mHexfileHandle;
|
|
mHexfileHandle = 0;
|
|
qDebug("Cannot open specified HEX file...");
|
|
return 0;
|
|
}
|
|
|
|
mHexFileSize = mHexfileHandle->size();
|
|
|
|
mFileOpened = true;
|
|
|
|
mRecordsTableSize = 0;
|
|
mFirmwareDataSize = 0;
|
|
|
|
return ParseData();
|
|
|
|
}
|
|
|
|
int CHexFile::ParseData(void)
|
|
{
|
|
if(!mFileOpened)
|
|
return 0;
|
|
|
|
int Ret;
|
|
bool Finished = false;
|
|
unsigned int CurAddress;
|
|
|
|
// CArray<CHexRecord*,CHexRecord*> TempArray;
|
|
QList<CHexRecord*> TempList;
|
|
QString RecordString;
|
|
QTextStream RecordFileStream(mHexfileHandle);
|
|
// CArchive ar(&mHexfileHandle,CArchive::load);
|
|
|
|
while(!Finished)
|
|
{
|
|
CHexRecord *NewRecord = new CHexRecord;
|
|
RecordString.clear();
|
|
// ar.ReadString(mRecordString);
|
|
RecordString = RecordFileStream.readLine();
|
|
// Ret = NewRecord.DecodeRawRecord(&mRecordString,mHighAddress);
|
|
Ret = NewRecord->DecodeRawRecord(&RecordString,mHighAddress);
|
|
mTotalParsedRecords++;
|
|
|
|
switch(Ret)
|
|
{
|
|
case CHexRecord::RET_DATA_RECORD:
|
|
{
|
|
#ifdef USE_BIG_RECORDS
|
|
TempList.append(NewRecord);
|
|
// mRecordsTable[mRecordsTableSize] = NewRecord;
|
|
// mRecordsTableSize++;
|
|
#else
|
|
mRecordsList.append(NewRecord);
|
|
mRecordsTable[mRecordsTableSize] = NewRecord;
|
|
mRecordsTableSize++;
|
|
#endif
|
|
break;
|
|
}
|
|
case CHexRecord::RET_EOF_RECORD:
|
|
{
|
|
mHexfileHandle->close();
|
|
mFileOpened = false;
|
|
delete mHexfileHandle;
|
|
mRecordsListValid = true;
|
|
Finished = true;
|
|
delete NewRecord;
|
|
|
|
break;
|
|
}
|
|
|
|
case CHexRecord::RET_EXTENDED_LINEAR_ADDRESS:
|
|
{
|
|
// mHighAddress = NewRecord.GetExtenedAddress();
|
|
mHighAddress = NewRecord->GetExtenedAddress();
|
|
CurAddress = mHighAddress;
|
|
delete NewRecord;
|
|
break;
|
|
}
|
|
case CHexRecord::RET_IGNORED_ALL_FF_RECORD:
|
|
{
|
|
delete NewRecord;
|
|
mDiscardedRecords++;
|
|
break;
|
|
}
|
|
case CHexRecord::RET_EXTENDED_ADDRESS:
|
|
case CHexRecord::RET_START_SEGMENT_ADDRESS:
|
|
case CHexRecord::RET_START_LINEAR_ADDRESS:
|
|
case CHexRecord::RET_UNKNOWN_RECORD_TYPE:
|
|
case CHexRecord::RET_INVALID_RECORD:
|
|
case CHexRecord::RET_BAD_RECORD_CHECKSUM:
|
|
case CHexRecord::RET_UNMANAGED_RECORD_TYPE:
|
|
{
|
|
mHexfileHandle->close();
|
|
mFileOpened = false;
|
|
delete mHexfileHandle;
|
|
Finished = true;
|
|
//MessageBox(NULL,"Parsing Error", "Cannot Parse Hex File",MB_OK);
|
|
QMessageBox::warning(0,"Parsing Error","Cannot parse HEX file",QMessageBox::Ok);
|
|
delete NewRecord;
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
#ifdef USE_BIG_RECORDS
|
|
int i;
|
|
int RecordCount;
|
|
CHexRecord *TempRecordPtr;
|
|
CHexRecord *BigRecord = new CHexRecord;
|
|
|
|
TempRecordPtr = TempList.at(0);
|
|
CurAddress = TempRecordPtr->GetStartAddress();
|
|
*BigRecord = *TempRecordPtr;
|
|
RecordCount = 1;
|
|
|
|
for(i = 1; i < TempList.size(); i++)
|
|
{
|
|
// if(CurAddress == 0x1d0097F0)
|
|
// {
|
|
// CurAddress = CurAddress;
|
|
// }
|
|
CurAddress += (TempRecordPtr->GetRecordSizeInBytes());
|
|
TempRecordPtr = TempList.at(i);
|
|
if(CurAddress == TempRecordPtr->GetStartAddress() && RecordCount<MAX_RECORDS_IN_BIG_RECORDS && (i != (TempList.size()-1)))
|
|
{
|
|
BigRecord->AppendRecord(TempRecordPtr);
|
|
RecordCount++;
|
|
}
|
|
else
|
|
{
|
|
RecordCount = 1; //Init to 1 because we load the record right below...
|
|
mRecordsList.append(BigRecord);
|
|
BigRecord = new CHexRecord;
|
|
|
|
if(i == TempList.size()-1) //Manage the last record.
|
|
{
|
|
*BigRecord = *TempRecordPtr;
|
|
mRecordsList.append(BigRecord);
|
|
BigRecord->mRecordSize += TempRecordPtr->mRecordSize;
|
|
|
|
}
|
|
else
|
|
{
|
|
*BigRecord = *TempRecordPtr;
|
|
CurAddress = TempRecordPtr->GetStartAddress();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
for(i = 0; i < TempList.size(); i++)
|
|
{
|
|
delete TempList[i];
|
|
}
|
|
|
|
for(i = 0; i < mRecordsList.size(); i++)
|
|
{
|
|
mFirmwareDataSize += mRecordsList.at(i)->GetRecordSizeInBytes();
|
|
}
|
|
|
|
mFileParsed = true;
|
|
return 1;
|
|
}
|
|
|
|
unsigned int CHexFile::GetNBRecords(void)
|
|
{
|
|
// return mRecordsTableSize;
|
|
|
|
return mRecordsList.size();
|
|
|
|
}
|
|
|
|
unsigned long CHexFile::GetFileSize(void)
|
|
{
|
|
return mHexFileSize;
|
|
}
|
|
|
|
CHexRecord * CHexFile::GetRecord(int RecordIndex, int &Status)
|
|
{
|
|
|
|
if(RecordIndex > mRecordsList.size())
|
|
// if(RecordIndex > mRecordsTableSize)
|
|
{
|
|
Status = ERR_INDEX_OUT_OF_BOUND;
|
|
return 0;
|
|
}
|
|
//CHexRecord *mRecordPtr = (CHexRecord*)&mRecordsList.GetAt(RecordIndex);
|
|
CHexRecord *mRecordPtr = mRecordsList.at(RecordIndex);
|
|
// CHexRecord *mRecordPtr = mRecordsTable[RecordIndex];
|
|
return mRecordPtr;
|
|
}
|
|
|
|
|
|
|
|
|
|
|