From 74863e538ad737d00393fb540573b8ce3968c629 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Tue, 14 May 2019 18:57:04 -0400 Subject: [PATCH] Split PRS1Loader::ParseFile in to ParseFile/ParseChunk. --- oscar/SleepLib/loader_plugins/prs1_loader.cpp | 119 +++++++++++------- oscar/SleepLib/loader_plugins/prs1_loader.h | 5 + 2 files changed, 76 insertions(+), 48 deletions(-) diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.cpp b/oscar/SleepLib/loader_plugins/prs1_loader.cpp index 6d9acdd5..5a673b73 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.cpp +++ b/oscar/SleepLib/loader_plugins/prs1_loader.cpp @@ -3378,18 +3378,75 @@ QList PRS1Loader::ParseFile(const QString & path) PRS1DataChunk *chunk = nullptr, *lastchunk = nullptr; + int cnt = 0; + + int cruft = 0; + int firstsession = 0; + + do { + chunk = ParseChunk(f, cnt); + if (chunk == nullptr) { + break; + } + + if (lastchunk != nullptr) { + // If there's any mismatch between header information, try and skip the block + // This probably isn't the best approach for dealing with block corruption :/ + if ((lastchunk->fileVersion != chunk->fileVersion) + || (lastchunk->ext != chunk->ext) + || (lastchunk->family != chunk->family) + || (lastchunk->familyVersion != chunk->familyVersion) + || (lastchunk->htype != chunk->htype)) { + qWarning() << path << "unexpected header data, skipping"; + + // TODO: Find a sample of this problem to see if the below approach has any + // value, or whether we should just drop the chunk. + QByteArray junk = f.read(lastchunk->blockSize - chunk->m_header.size()); + + Q_UNUSED(junk) + if (lastchunk->ext == 5) { + // The data is random crap + // lastchunk->m_data.append(junk.mid(lastheadersize-16)); + } + ++cruft; + // quit after 3 attempts + if (cruft > 3) { + qWarning() << path << "too many unexpected headers, bailing"; + break; + } + + cnt++; + delete chunk; + continue; + // Corrupt header.. skip it. + } + } + + if (!firstsession) { + firstsession = chunk->sessionid; + } + + CHUNKS.append(chunk); + + lastchunk = chunk; + cnt++; + } while (!f.atEnd()); + + return CHUNKS; +} + + +PRS1DataChunk* PRS1Loader::ParseChunk(QFile & f, int cnt) +{ + QString path = QFileInfo(f).canonicalFilePath(); + PRS1DataChunk* chunk = nullptr; + PRS1DataChunk* out_chunk = nullptr; + quint8 fileVersion; quint16 blocksize; quint16 wvfm_signals=0; unsigned char * header; - int cnt = 0; - - //int lastheadersize = 0; - int lastblocksize = 0; - - int cruft = 0; - int firstsession = 0; int htype,family,familyVersion,ext,header_size = 0; quint8 achk=0; quint32 sessionid=0, timestamp=0; @@ -3519,36 +3576,6 @@ QList PRS1Loader::ParseFile(const QString & path) break; } - - if (lastchunk != nullptr) { - // If there's any mismatch between header information, try and skip the block - // This probably isn't the best approach for dealing with block corruption :/ - if ((lastchunk->fileVersion != fileVersion) - || (lastchunk->ext != ext) - || (lastchunk->family != family) - || (lastchunk->familyVersion != familyVersion) - || (lastchunk->htype != htype)) { - qWarning() << path << "unexpected header data, skipping"; - QByteArray junk = f.read(lastblocksize - header_size); - - Q_UNUSED(junk) - if (lastchunk->ext == 5) { - // The data is random crap - // lastchunk->m_data.append(junk.mid(lastheadersize-16)); - } - ++cruft; - // quit after 3 attempts - if (cruft > 3) { - qWarning() << path << "too many unexpected headers, bailing"; - break; - } - - cnt++; - continue; - // Corrupt header.. skip it. - } - } - chunk = new PRS1DataChunk(); chunk->m_path = path; @@ -3557,9 +3584,6 @@ QList PRS1Loader::ParseFile(const QString & path) chunk->sessionid = sessionid; - if (!firstsession) { - firstsession = chunk->sessionid; - } chunk->fileVersion = fileVersion; chunk->htype = htype; chunk->family = family; @@ -3576,8 +3600,9 @@ QList PRS1Loader::ParseFile(const QString & path) } } chunk->m_headerblock = headerB2; + chunk->m_header = headerBA; + chunk->blockSize = blocksize; - lastblocksize = blocksize; blocksize -= header_size; if (ext >= 5) { @@ -3616,14 +3641,12 @@ QList PRS1Loader::ParseFile(const QString & path) } #endif } + + // Only return the chunk if it has passed all tests above. + out_chunk = chunk; + } while (false); - CHUNKS.append(chunk); - - lastchunk = chunk; - cnt++; - } while (!f.atEnd()); - - return CHUNKS; + return out_chunk; } void InitModelMap() diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.h b/oscar/SleepLib/loader_plugins/prs1_loader.h index d0c5a55f..fabc6c00 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.h +++ b/oscar/SleepLib/loader_plugins/prs1_loader.h @@ -75,6 +75,7 @@ public: } inline int size() const { return m_data.size(); } + QByteArray m_header; QByteArray m_data; QByteArray m_headerblock; @@ -85,6 +86,7 @@ public: SessionID sessionid; quint8 fileVersion; + quint16 blockSize; quint8 ext; quint8 htype; quint8 family; @@ -230,6 +232,9 @@ class PRS1Loader : public CPAPLoader //! \brief Parse a PRS1 summary/event/waveform file and break into invidivual session or waveform chunks QList ParseFile(const QString & path); + //! \brief Parse and return the next chunk from a PRS1 file + PRS1DataChunk* ParseChunk(class QFile & f, int index=0); + //! \brief Register this Module to the list of Loaders, so it knows to search for PRS1 data. static void Register();