Prevent dropping Ogg pages which have been omitten during parsing when applying changes
See https://github.com/Martchus/tageditor/issues/69
This commit is contained in:
parent
9dfeb76209
commit
339995edf5
|
@ -416,13 +416,44 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback
|
|||
// define misc variables
|
||||
CopyHelper<65307> copyHelper;
|
||||
vector<std::uint64_t> updatedPageOffsets;
|
||||
const OggPage *lastPage = nullptr;
|
||||
std::uint64_t nextPageOffset;
|
||||
unordered_map<std::uint32_t, std::uint32_t> pageSequenceNumberBySerialNo;
|
||||
|
||||
// iterate through all pages of the original file
|
||||
for (m_iterator.setStream(backupStream), m_iterator.removeFilter(), m_iterator.reset(); m_iterator; m_iterator.nextPage()) {
|
||||
const OggPage ¤tPage = m_iterator.currentPage();
|
||||
|
||||
// check for gaps
|
||||
// note: This is not just to print diag messages but also for taking into account that the parser might skip pages
|
||||
// unless a full parse has been enforced.
|
||||
if (lastPage && currentPage.startOffset() != nextPageOffset) {
|
||||
m_iterator.pages().resize(m_iterator.currentPageIndex() - 1); // drop all further pages after the last consecutively parsed one
|
||||
if (m_iterator.resyncAt(nextPageOffset)) {
|
||||
// try again at the page we've just found
|
||||
const auto actuallyNextPageOffset = m_iterator.currentPageOffset();
|
||||
if (actuallyNextPageOffset != nextPageOffset) {
|
||||
diag.emplace_back(DiagLevel::Critical,
|
||||
argsToString("Expected OGG page at offset ", nextPageOffset, " but found the next OGG page only at offset ",
|
||||
actuallyNextPageOffset, ". Skipped ", (actuallyNextPageOffset - nextPageOffset), " invalid bytes."),
|
||||
context);
|
||||
nextPageOffset = actuallyNextPageOffset;
|
||||
}
|
||||
m_iterator.previousPage();
|
||||
continue;
|
||||
} else {
|
||||
diag.emplace_back(DiagLevel::Critical,
|
||||
argsToString(
|
||||
"Expected OGG page at offset ", nextPageOffset, " but could not find any further pages. Skipped the rest of the file."),
|
||||
context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto pageSize = currentPage.totalSize();
|
||||
std::uint32_t &pageSequenceNumber = pageSequenceNumberBySerialNo[currentPage.streamSerialNumber()];
|
||||
lastPage = ¤tPage;
|
||||
nextPageOffset = currentPage.startOffset() + pageSize;
|
||||
|
||||
// check whether the Vorbis Comment is present in this Ogg page
|
||||
if (currentComment && m_iterator.currentPageIndex() >= currentParams->firstPageIndex
|
||||
&& m_iterator.currentPageIndex() <= currentParams->lastPageIndex && !currentPage.segmentSizes().empty()) {
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
void previousPage();
|
||||
void previousSegment();
|
||||
const std::vector<OggPage> &pages() const;
|
||||
std::vector<OggPage> &pages();
|
||||
const OggPage ¤tPage() const;
|
||||
std::uint64_t currentPageOffset() const;
|
||||
std::vector<OggPage>::size_type currentPageIndex() const;
|
||||
|
@ -124,6 +125,14 @@ inline const std::vector<OggPage> &OggIterator::pages() const
|
|||
return m_pages;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a vector of containing the OGG pages that have been fetched yet.
|
||||
*/
|
||||
inline std::vector<OggPage> &OggIterator::pages()
|
||||
{
|
||||
return m_pages;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the current OGG page.
|
||||
* \remarks Calling this method when the iterator is invalid causes undefined behaviour.
|
||||
|
|
Loading…
Reference in New Issue