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;
}