NE alpha10

- added FIT messages widget and related messages
- corrected small text issues
This commit is contained in:
Nikolaj Schlej 2015-09-13 16:36:43 +02:00
parent cc49cbcdd1
commit f6c429f00c
6 changed files with 100 additions and 30 deletions

View File

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("0.30.0_alpha9")) version(tr("0.30.0_alpha10"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -72,6 +72,7 @@ version(tr("0.30.0_alpha9"))
ui->infoEdit->setFont(font); ui->infoEdit->setFont(font);
ui->parserMessagesListWidget->setFont(font); ui->parserMessagesListWidget->setFont(font);
ui->finderMessagesListWidget->setFont(font); ui->finderMessagesListWidget->setFont(font);
ui->fitMessagesListWidget->setFont(font);
ui->fitTableWidget->setFont(font); ui->fitTableWidget->setFont(font);
ui->structureTreeView->setFont(font); ui->structureTreeView->setFont(font);
searchDialog->ui->guidEdit->setFont(font); searchDialog->ui->guidEdit->setFont(font);
@ -143,6 +144,8 @@ void UEFITool::init()
connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
connect(ui->fitMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
connect(ui->fitMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
} }
void UEFITool::populateUi(const QModelIndex &current) void UEFITool::populateUi(const QModelIndex &current)
@ -662,8 +665,11 @@ void UEFITool::openImageFile(QString path)
// Parse FIT // Parse FIT
//!TODO: expand and chek errors //!TODO: expand and chek errors
result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf()); result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf());
if (!result) showFitMessages();
if (!result) {
showFitTable(); showFitTable();
}
// Enable search ... // Enable search ...
if (ffsFinder) if (ffsFinder)
@ -686,6 +692,8 @@ void UEFITool::copyMessage()
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text()); clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 1) // Search tab else if (ui->messagesTabWidget->currentIndex() == 1) // Search tab
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text()); clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab
clipboard->setText(ui->fitMessagesListWidget->currentItem()->text());
} }
void UEFITool::copyAllMessages() void UEFITool::copyAllMessages()
@ -702,6 +710,11 @@ void UEFITool::copyAllMessages()
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
else if (ui->messagesTabWidget->currentIndex() == 2) { // FIT tab
for (INT32 i = 0; i < ui->fitMessagesListWidget->count(); i++)
text.append(ui->fitMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text);
}
} }
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item) void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
@ -768,6 +781,22 @@ void UEFITool::showFinderMessages()
ui->finderMessagesListWidget->scrollToBottom(); ui->finderMessagesListWidget->scrollToBottom();
} }
void UEFITool::showFitMessages()
{
ui->fitMessagesListWidget->clear();
if (!fitParser)
return;
QVector<QPair<QString, QModelIndex> > messages = fitParser->getMessages();
QPair<QString, QModelIndex> msg;
foreach(msg, messages) {
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
}
ui->messagesTabWidget->setCurrentIndex(2);
ui->fitMessagesListWidget->scrollToBottom();
}
void UEFITool::scrollTreeView(QListWidgetItem* item) void UEFITool::scrollTreeView(QListWidgetItem* item)
{ {
MessageListItem* messageItem = static_cast<MessageListItem*>(item); MessageListItem* messageItem = static_cast<MessageListItem*>(item);
@ -862,9 +891,9 @@ void UEFITool::showFitTable()
// Set up the FIT table // Set up the FIT table
ui->fitTableWidget->clear(); ui->fitTableWidget->clear();
ui->fitTableWidget->setRowCount(fitTable.length()); ui->fitTableWidget->setRowCount(fitTable.length());
ui->fitTableWidget->setColumnCount(6); ui->fitTableWidget->setColumnCount(5);
//ui->fitTableWidget->verticalHeader()->setVisible(false); //ui->fitTableWidget->verticalHeader()->setVisible(false);
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum") << tr("Remark")); ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum"));
ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
@ -872,7 +901,7 @@ void UEFITool::showFitTable()
// Add all data to the table widget // Add all data to the table widget
for (INT32 i = 0; i < fitTable.length(); i++) { for (INT32 i = 0; i < fitTable.length(); i++) {
for (UINT8 j = 0; j < 6; j++) { for (UINT8 j = 0; j < 5; j++) {
ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j])); ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j]));
} }
} }

View File

@ -119,6 +119,7 @@ private:
void readSettings(); void readSettings();
void showParserMessages(); void showParserMessages();
void showFinderMessages(); void showFinderMessages();
void showFitMessages();
void showFitTable(); void showFitTable();
}; };

View File

@ -142,7 +142,7 @@
</widget> </widget>
<widget class="QTabWidget" name="messagesTabWidget"> <widget class="QTabWidget" name="messagesTabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="parserTab"> <widget class="QWidget" name="parserTab">
<attribute name="title"> <attribute name="title">
@ -223,7 +223,17 @@
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTableWidget" name="fitTableWidget"/> <widget class="QTableWidget" name="fitTableWidget"/>
<widget class="QListWidget" name="fitMessagesListWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -99,7 +99,7 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
capsuleHeaderSize = capsuleHeader->HeaderSize; capsuleHeaderSize = capsuleHeader->HeaderSize;
QByteArray header = buffer.left(capsuleHeaderSize); QByteArray header = buffer.left(capsuleHeaderSize);
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize); QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
QString name = tr("UEFI capsule"); QString name = tr("Toshiba capsule");
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h") QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
.arg(guidToQString(capsuleHeader->CapsuleGuid)) .arg(guidToQString(capsuleHeader->CapsuleGuid))
.hexarg(buffer.size()).arg(buffer.size()) .hexarg(buffer.size()).arg(buffer.size())
@ -417,7 +417,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
if (descriptorVersion == 1) { if (descriptorVersion == 1) {
const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase); const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase);
info += tr("\nRegion access settings:"); info += tr("\nRegion access settings:");
info += tr("\nBIOS:%1h %2h ME:%3h %4h GbE:%5h %6h") info += tr("\nBIOS: %1h %2h ME: %3h %4h\nGbE: %5h %6h")
.hexarg2(masterSection->BiosRead, 2) .hexarg2(masterSection->BiosRead, 2)
.hexarg2(masterSection->BiosWrite, 2) .hexarg2(masterSection->BiosWrite, 2)
.hexarg2(masterSection->MeRead, 2) .hexarg2(masterSection->MeRead, 2)
@ -563,7 +563,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset)); if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
// Add tree item // Add tree item
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index); model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
} }
// Check if the last VTF is found // Check if the last VTF is found
@ -1040,7 +1040,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
QByteArray body = volume.mid(headerSize); QByteArray body = volume.mid(headerSize);
QString name = guidToQString(volumeHeader->FileSystemGuid); QString name = guidToQString(volumeHeader->FileSystemGuid);
QString info = tr("ZeroVector:\n%1 %2 %3 %4 %5 %6 %7 %8\n%9 %10 %11 %12 %13 %14 %15 %16\nFileSystem GUID: %17\nFull size: %18h (%19)\n" QString info = tr("ZeroVector:\n%1 %2 %3 %4 %5 %6 %7 %8\n%9 %10 %11 %12 %13 %14 %15 %16\nFileSystem GUID: %17\nFull size: %18h (%19)\n"
"Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26") "Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26\nChecksum: %27h, %28")
.hexarg2(volumeHeader->ZeroVector[0], 2).hexarg2(volumeHeader->ZeroVector[1], 2).hexarg2(volumeHeader->ZeroVector[2], 2).hexarg2(volumeHeader->ZeroVector[3], 2) .hexarg2(volumeHeader->ZeroVector[0], 2).hexarg2(volumeHeader->ZeroVector[1], 2).hexarg2(volumeHeader->ZeroVector[2], 2).hexarg2(volumeHeader->ZeroVector[3], 2)
.hexarg2(volumeHeader->ZeroVector[4], 2).hexarg2(volumeHeader->ZeroVector[5], 2).hexarg2(volumeHeader->ZeroVector[6], 2).hexarg2(volumeHeader->ZeroVector[7], 2) .hexarg2(volumeHeader->ZeroVector[4], 2).hexarg2(volumeHeader->ZeroVector[5], 2).hexarg2(volumeHeader->ZeroVector[6], 2).hexarg2(volumeHeader->ZeroVector[7], 2)
.hexarg2(volumeHeader->ZeroVector[8], 2).hexarg2(volumeHeader->ZeroVector[9], 2).hexarg2(volumeHeader->ZeroVector[10], 2).hexarg2(volumeHeader->ZeroVector[11], 2) .hexarg2(volumeHeader->ZeroVector[8], 2).hexarg2(volumeHeader->ZeroVector[9], 2).hexarg2(volumeHeader->ZeroVector[10], 2).hexarg2(volumeHeader->ZeroVector[11], 2)
@ -1051,7 +1051,9 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
.hexarg(volumeSize - headerSize).arg(volumeSize - headerSize) .hexarg(volumeSize - headerSize).arg(volumeSize - headerSize)
.arg(volumeHeader->Revision) .arg(volumeHeader->Revision)
.hexarg2(volumeHeader->Attributes, 8) .hexarg2(volumeHeader->Attributes, 8)
.arg(emptyByte ? "1" : "0"); .arg(emptyByte ? "1" : "0")
.hexarg2(volumeHeader->Checksum, 4)
.arg(msgInvalidChecksum ? tr("invalid") : tr("valid"));
// Extended header present // Extended header present
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
@ -1415,14 +1417,18 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
else else
name = tr("Pad-file"); name = tr("Pad-file");
info = tr("File GUID: %1\nType: %2h\nAttributes: %3h\nFull size: %4h (%5)\nHeader size: %6h (%7)\nBody size: %8h (%9)\nState: %10h") info = tr("File GUID: %1\nType: %2h\nAttributes: %3h\nFull size: %4h (%5)\nHeader size: %6h (%7)\nBody size: %8h (%9)\nState: %10h\nHeader checksum: %11h, %12\nData checksum: %13h, %14")
.arg(guidToQString(fileHeader->Name)) .arg(guidToQString(fileHeader->Name))
.hexarg2(fileHeader->Type, 2) .hexarg2(fileHeader->Type, 2)
.hexarg2(fileHeader->Attributes, 2) .hexarg2(fileHeader->Attributes, 2)
.hexarg(header.size() + body.size()).arg(header.size() + body.size()) .hexarg(header.size() + body.size()).arg(header.size() + body.size())
.hexarg(header.size()).arg(header.size()) .hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size()) .hexarg(body.size()).arg(body.size())
.hexarg2(fileHeader->State, 2); .hexarg2(fileHeader->State, 2)
.hexarg2(fileHeader->IntegrityCheck.Checksum.Header, 2)
.arg(msgInvalidHeaderChecksum ? tr("invalid") : tr("valid"))
.hexarg2(fileHeader->IntegrityCheck.Checksum.File, 2)
.arg(msgInvalidDataChecksum ? tr("invalid") : tr("valid"));
// Check if the file is a Volume Top File // Check if the file is a Volume Top File
QString text; QString text;
@ -2111,11 +2117,12 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
QByteArray body = model->body(index); QByteArray body = model->body(index);
UINT32 crc = crc32(0, (const UINT8*)body.constData(), body.size()); UINT32 crc = crc32(0, (const UINT8*)body.constData(), body.size());
// Check stored CRC32 // Check stored CRC32
if (crc == *(const UINT32*)(model->header(index).constData() + sizeof(EFI_GUID_DEFINED_SECTION))) { UINT32 stored = *(const UINT32*)(model->header(index).constData() + sizeof(EFI_GUID_DEFINED_SECTION));
info += tr("\nChecksum: valid"); if (crc == stored) {
info += tr("\nChecksum %1h: valid").hexarg2(stored, 8);
} }
else { else {
info += tr("\nChecksum: invalid"); info += tr("\nChecksum %1h: invalid").hexarg2(stored, 8);
msg(tr("parseGuidedSectionBody: GUID defined section with invalid CRC32"), index); msg(tr("parseGuidedSectionBody: GUID defined section with invalid CRC32"), index);
} }
} }

View File

@ -23,6 +23,21 @@ FitParser::~FitParser()
{ {
} }
void FitParser::msg(const QString & message, const QModelIndex & index)
{
messagesVector.push_back(QPair<QString, QModelIndex>(message, index));
}
QVector<QPair<QString, QModelIndex> > FitParser::getMessages() const
{
return messagesVector;
}
void FitParser::clearMessages()
{
messagesVector.clear();
}
STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIndex) STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIndex)
{ {
// Check sanity // Check sanity
@ -53,7 +68,6 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
model->setParsingData(fitIndex, parsingDataToQByteArray(pdata)); model->setParsingData(fitIndex, parsingDataToQByteArray(pdata));
// Special case of FIT header // Special case of FIT header
QString remark;
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset); const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset);
// Check FIT checksum, if present // Check FIT checksum, if present
@ -62,19 +76,15 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
// Calculate FIT entry checksum // Calculate FIT entry checksum
UINT8 calculated = calculateChecksum8((const UINT8*)fitHeader, fitSize); UINT8 calculated = calculateChecksum8((const UINT8*)fitHeader, fitSize);
if (calculated) { if (calculated) {
remark.append(tr("Invalid FIT table checksum, ")); msg(tr("Invalid FIT table checksum"), fitIndex);
} }
} }
// Check fit header type // Check fit header type
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) { if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) {
remark.append(tr("Invalid FIT header type, ")); msg(tr("Invalid FIT header type"), fitIndex);
} }
// Remove the last ", " from remark string, if needed
if (!remark.isEmpty())
remark = remark.left(remark.length() - 2);
// Add FIT header to fitTable // Add FIT header to fitTable
QVector<QString> currentStrings; QVector<QString> currentStrings;
currentStrings += tr("_FIT_ "); currentStrings += tr("_FIT_ ");
@ -82,19 +92,18 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
currentStrings += tr("%1").hexarg2(fitHeader->Version, 4); currentStrings += tr("%1").hexarg2(fitHeader->Version, 4);
currentStrings += fitEntryTypeToQString(fitHeader->Type); currentStrings += fitEntryTypeToQString(fitHeader->Type);
currentStrings += tr("%1").hexarg2(fitHeader->Checksum, 2); currentStrings += tr("%1").hexarg2(fitHeader->Checksum, 2);
currentStrings += remark;
fitTable.append(currentStrings); fitTable.append(currentStrings);
// Process all other entries // Process all other entries
bool modifiedImageMayNotWork = false;
for (UINT32 i = 1; i < fitHeader->Size; i++) { for (UINT32 i = 1; i < fitHeader->Size; i++) {
currentStrings.clear(); currentStrings.clear();
remark.clear();
const FIT_ENTRY* currentEntry = fitHeader + i; const FIT_ENTRY* currentEntry = fitHeader + i;
// Check entry type // Check entry type
switch (currentEntry->Type & 0x7F) { switch (currentEntry->Type & 0x7F) {
case FIT_TYPE_HEADER: case FIT_TYPE_HEADER:
remark.append(tr("Second FIT header found, the table is damaged")); msg(tr("Second FIT header found, the table is damaged"), fitIndex);
break; break;
case FIT_TYPE_EMPTY: case FIT_TYPE_EMPTY:
@ -109,7 +118,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
case FIT_TYPE_AC_KEY_MANIFEST: case FIT_TYPE_AC_KEY_MANIFEST:
case FIT_TYPE_AC_BOOT_POLICY: case FIT_TYPE_AC_BOOT_POLICY:
default: default:
remark.append(tr("Modified image may not work")); modifiedImageMayNotWork = true;
break; break;
} }
@ -119,10 +128,12 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
currentStrings += tr("%1").hexarg2(currentEntry->Version, 4); currentStrings += tr("%1").hexarg2(currentEntry->Version, 4);
currentStrings += fitEntryTypeToQString(currentEntry->Type); currentStrings += fitEntryTypeToQString(currentEntry->Type);
currentStrings += tr("%1").hexarg2(currentEntry->Checksum, 2); currentStrings += tr("%1").hexarg2(currentEntry->Checksum, 2);
currentStrings += remark;
fitTable.append(currentStrings); fitTable.append(currentStrings);
} }
if (modifiedImageMayNotWork)
msg(tr("Opened image may not work after any modification"));
return ERR_SUCCESS; return ERR_SUCCESS;
} }
@ -170,8 +181,11 @@ STATUS FitParser::findFitRecursive(const QModelIndex & index, QModelIndex & foun
if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) { if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) {
found = index; found = index;
fitOffset = offset; fitOffset = offset;
msg(tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found);
return ERR_SUCCESS; return ERR_SUCCESS;
} }
else
msg(tr("FIT table candidate found, but not referenced from LastVtf"), found);
} }
return ERR_SUCCESS; return ERR_SUCCESS;

View File

@ -36,16 +36,25 @@ public:
FitParser(TreeModel* treeModel, QObject *parent = 0); FitParser(TreeModel* treeModel, QObject *parent = 0);
~FitParser(); ~FitParser();
// Returns messages
QVector<QPair<QString, QModelIndex> > getMessages() const;
// Clears messages
void clearMessages();
STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf); STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf);
QVector<QVector<QString> > getFitTable() const { return fitTable; } QVector<QVector<QString> > getFitTable() const { return fitTable; }
private: private:
TreeModel *model; TreeModel *model;
QVector<QPair<QString, QModelIndex> > messagesVector;
QModelIndex lastVtf; QModelIndex lastVtf;
QVector<QVector<QString> > fitTable; QVector<QVector<QString> > fitTable;
STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset); STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset);
QString fitEntryTypeToQString(UINT8 type); QString fitEntryTypeToQString(UINT8 type);
// Message helper
void msg(const QString & message, const QModelIndex &index = QModelIndex());
}; };
#endif #endif