1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-30 15:52:12 +01:00

LP-597 Progress bar for GCS log replay - ensure the index vectors are emptied before adding elements to them. Caused problem when replaying multiple logfiles successively.

- Bugfix: ensure the index vectors are emptied before adding elements to them. Caused problem when replaying multiple logfiles successively.
- extra validations while indexing the logfile
- Define TIMESTAMP_SIZE_BYTES and use that instead of the hardcoded timestamp size of 4 bytes.
- modify variable case: updateBeginAndEndtimes -> updateBeginAndEndTimes
- improve qWarning messages for logfile.cpp: add the name of the function because we read the logfile in two separate functions.
This commit is contained in:
Jan NIJS 2018-04-29 16:27:51 +02:00
parent ef3cb8bf46
commit d540c2a043
4 changed files with 58 additions and 31 deletions

View File

@ -29,6 +29,8 @@
#include <QDataStream>
#include <QThread> // DEBUG: to display the thread ID
#define TIMESTAMP_SIZE_BYTES 4
LogFile::LogFile(QObject *parent) : QIODevice(parent),
m_timer(this),
m_previousTimeStamp(0),
@ -156,7 +158,7 @@ void LogFile::timerFired()
}
m_timer_tick++;
if (m_file.bytesAvailable() > 4) {
if (m_file.bytesAvailable() > TIMESTAMP_SIZE_BYTES) {
int time;
time = m_myTime.elapsed();
@ -182,7 +184,7 @@ void LogFile::timerFired()
// read data size
qint64 dataSize;
if (m_file.bytesAvailable() < (qint64)sizeof(dataSize)) {
qDebug() << "LogFile - end of log file reached";
qDebug() << "LogFile replay - end of log file reached";
stopReplay();
return;
}
@ -190,14 +192,14 @@ void LogFile::timerFired()
// check size consistency
if (dataSize < 1 || dataSize > (1024 * 1024)) {
qWarning() << "LogFile - corrupted log file! Unlikely packet size:" << dataSize;
qWarning() << "LogFile replay - corrupted log file! Unlikely packet size:" << dataSize;
stopReplay();
return;
}
// read data
if (m_file.bytesAvailable() < dataSize) {
qDebug() << "LogFile - end of log file reached";
qDebug() << "LogFile replay - end of log file reached";
stopReplay();
return;
}
@ -216,7 +218,7 @@ void LogFile::timerFired()
}
// read next timestamp
if (m_file.bytesAvailable() < (qint64)sizeof(m_nextTimeStamp)) {
qDebug() << "LogFile - end of log file reached";
qDebug() << "LogFile replay - end of log file reached";
stopReplay();
return;
}
@ -226,7 +228,7 @@ void LogFile::timerFired()
// some validity checks
if ((m_nextTimeStamp < m_previousTimeStamp) // logfile goes back in time
|| ((m_nextTimeStamp - m_previousTimeStamp) > 60 * 60 * 1000)) { // gap of more than 60 minutes
qWarning() << "LogFile - corrupted log file! Unlikely timestamp:" << m_nextTimeStamp << "after" << m_previousTimeStamp;
qWarning() << "LogFile replay - corrupted log file! Unlikely timestamp:" << m_nextTimeStamp << "after" << m_previousTimeStamp;
stopReplay();
return;
}
@ -235,7 +237,7 @@ void LogFile::timerFired()
time = m_myTime.elapsed(); // number of milliseconds since start of playback
}
} else {
qDebug() << "LogFile - end of log file reached";
qDebug() << "LogFile replay - end of log file reached";
stopReplay();
}
}
@ -324,12 +326,12 @@ bool LogFile::stopReplay()
* If no position is given, resumes from the last position
*
*/
bool LogFile::resumeReplay(quint32 desiredPosition)
{
if (m_timer.isActive()) {
return false;
}
qDebug() << "LogFile - resumeReplay";
// Clear the playout buffer:
m_mutex.lock();
@ -346,7 +348,11 @@ bool LogFile::resumeReplay(quint32 desiredPosition)
for (int i = 0; i < m_timeStamps.size(); i++) {
if (m_timeStamps.at(i) >= desiredPosition) {
m_file.seek(m_timeStampPositions.at(i));
int bytesToSkip = m_timeStampPositions.at(i);
bool seek_ok = m_file.seek(bytesToSkip);
if (!seek_ok) {
qWarning() << "LogFile resumeReplay - an error occurred while seeking through the logfile.";
}
m_lastPlayed = m_timeStamps.at(i);
break;
}
@ -401,6 +407,7 @@ bool LogFile::pauseAndResetPosition()
if (!m_file.isOpen() || !m_timer.isActive()) {
return false;
}
qDebug() << "LogFile - pauseAndResetPosition";
m_timer.stop();
m_replayStatus = STOPPED;
@ -426,11 +433,11 @@ ReplayState LogFile::getReplayStatus()
/**
* FUNCTION: buildIndex()
*
* Walk through the opened logfile and sets the start and end position timestamps
* Walk through the opened logfile and stores the first and last position timestamps.
* Also builds an index for quickly skipping to a specific position in the logfile.
*
* returns true when indexing has completed successfully
* returns false when a problem was encountered
* Returns true when indexing has completed successfully.
* Returns false when a problem was encountered.
*
*/
bool LogFile::buildIndex()
@ -439,18 +446,28 @@ bool LogFile::buildIndex()
qint64 totalSize;
qint64 readPointer = 0;
quint64 index = 0;
int bytesRead = 0;
qDebug() << "LogFile - buildIndex";
// Ensure empty vectors:
m_timeStampPositions.clear();
m_timeStamps.clear();
QByteArray arr = m_file.readAll();
totalSize = arr.size();
QDataStream dataStream(&arr, QIODevice::ReadOnly);
// set the start timestamp
if (totalSize - readPointer >= 4) {
dataStream.readRawData((char *)&timeStamp, 4);
// set the first timestamp
if (totalSize - readPointer >= TIMESTAMP_SIZE_BYTES) {
bytesRead = dataStream.readRawData((char *)&timeStamp, TIMESTAMP_SIZE_BYTES);
if (bytesRead != TIMESTAMP_SIZE_BYTES) {
qWarning() << "LogFile buildIndex - read first timeStamp: readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false;
}
m_timeStamps.append(timeStamp);
m_timeStampPositions.append(readPointer);
readPointer += 4;
readPointer += TIMESTAMP_SIZE_BYTES;
index++;
m_beginTimeStamp = timeStamp;
m_endTimeStamp = timeStamp;
@ -461,22 +478,27 @@ bool LogFile::buildIndex()
// Check if there are enough bytes remaining for a correct "dataSize" field
if (totalSize - readPointer < (qint64)sizeof(dataSize)) {
qDebug() << "Error: Logfile corrupted! Unexpected end of file";
qWarning() << "LogFile buildIndex - logfile corrupted! Unexpected end of file";
return false;
}
// Read the dataSize field and check for I/O errors
bytesRead = dataStream.readRawData((char *)&dataSize, sizeof(dataSize));
if (bytesRead != sizeof(dataSize)) {
qWarning() << "LogFile buildIndex - read dataSize: readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false;
}
// Read the dataSize field
dataStream.readRawData((char *)&dataSize, sizeof(dataSize));
readPointer += sizeof(dataSize);
if (dataSize < 1 || dataSize > (1024 * 1024)) {
qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n";
qWarning() << "LogFile buildIndex - logfile corrupted! Unlikely packet size: " << dataSize << "\n";
return false;
}
// Check if there are enough bytes remaining
if (totalSize - readPointer < dataSize) {
qDebug() << "Error: Logfile corrupted! Unexpected end of file";
qWarning() << "LogFile buildIndex - logfile corrupted! Unexpected end of file";
return false;
}
@ -484,18 +506,23 @@ bool LogFile::buildIndex()
readPointer += dataStream.skipRawData(dataSize);
// read the next timestamp
if (totalSize - readPointer >= 4) {
dataStream.readRawData((char *)&timeStamp, 4);
if (totalSize - readPointer >= TIMESTAMP_SIZE_BYTES) {
bytesRead = dataStream.readRawData((char *)&timeStamp, TIMESTAMP_SIZE_BYTES);
if (bytesRead != TIMESTAMP_SIZE_BYTES) {
qWarning() << "LogFile buildIndex - read timeStamp, readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false;
}
// some validity checks
if (timeStamp < m_endTimeStamp // logfile goes back in time
|| (timeStamp - m_endTimeStamp) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << timeStamp << " after " << m_endTimeStamp;
qWarning() << "LogFile buildIndex - logfile corrupted! Unlikely timestamp " << timeStamp << " after " << m_endTimeStamp;
return false;
}
m_timeStamps.append(timeStamp);
m_timeStampPositions.append(readPointer);
readPointer += 4;
readPointer += TIMESTAMP_SIZE_BYTES;
index++;
m_endTimeStamp = timeStamp;
} else {
@ -504,7 +531,7 @@ bool LogFile::buildIndex()
}
}
emit updateBeginAndEndtimes(m_beginTimeStamp, m_endTimeStamp);
emit updateBeginAndEndTimes(m_beginTimeStamp, m_endTimeStamp);
// reset the read pointer to the start of the file
m_file.seek(0);

View File

@ -100,7 +100,7 @@ signals:
void replayStarted();
void replayFinished();
void playbackPosition(quint32);
void updateBeginAndEndtimes(quint32, quint32);
void updateBeginAndEndTimes(quint32, quint32);
protected:
QByteArray m_dataBuffer;

View File

@ -79,7 +79,7 @@ void LoggingGadgetWidget::setPlugin(LoggingPlugin *p)
// Feedback from logfile to GUI
connect(loggingPlugin, &LoggingPlugin::stateChanged, this, &LoggingGadgetWidget::stateChanged);
connect(logFile, &LogFile::updateBeginAndEndtimes, this, &LoggingGadgetWidget::updateBeginAndEndtimes);
connect(logFile, &LogFile::updateBeginAndEndTimes, this, &LoggingGadgetWidget::updateBeginAndEndTimes);
connect(logFile, &LogFile::playbackPosition, this, &LoggingGadgetWidget::playbackPosition);
connect(logFile, &LogFile::replayStarted, this, &LoggingGadgetWidget::enableButtons);
connect(logFile, &LogFile::replayFinished, this, &LoggingGadgetWidget::disableButtons);
@ -174,7 +174,7 @@ void LoggingGadgetWidget::stateChanged(LoggingPlugin::State state)
}
}
void LoggingGadgetWidget::updateBeginAndEndtimes(quint32 startTimeStamp, quint32 endTimeStamp)
void LoggingGadgetWidget::updateBeginAndEndTimes(quint32 startTimeStamp, quint32 endTimeStamp)
{
int startSec, startMin, endSec, endMin;

View File

@ -49,7 +49,7 @@ public:
protected slots:
void stateChanged(LoggingPlugin::State state);
void updateBeginAndEndtimes(quint32 startTimeStamp, quint32 endTimeStamp);
void updateBeginAndEndTimes(quint32 startTimeStamp, quint32 endTimeStamp);
void playbackPosition(quint32 positionTimeStamp);
void playPauseButtonAction();
void stopButtonAction();