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
|
// define misc variables
|
||||||
CopyHelper<65307> copyHelper;
|
CopyHelper<65307> copyHelper;
|
||||||
vector<std::uint64_t> updatedPageOffsets;
|
vector<std::uint64_t> updatedPageOffsets;
|
||||||
|
const OggPage *lastPage = nullptr;
|
||||||
|
std::uint64_t nextPageOffset;
|
||||||
unordered_map<std::uint32_t, std::uint32_t> pageSequenceNumberBySerialNo;
|
unordered_map<std::uint32_t, std::uint32_t> pageSequenceNumberBySerialNo;
|
||||||
|
|
||||||
// iterate through all pages of the original file
|
// iterate through all pages of the original file
|
||||||
for (m_iterator.setStream(backupStream), m_iterator.removeFilter(), m_iterator.reset(); m_iterator; m_iterator.nextPage()) {
|
for (m_iterator.setStream(backupStream), m_iterator.removeFilter(), m_iterator.reset(); m_iterator; m_iterator.nextPage()) {
|
||||||
const OggPage ¤tPage = m_iterator.currentPage();
|
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();
|
const auto pageSize = currentPage.totalSize();
|
||||||
std::uint32_t &pageSequenceNumber = pageSequenceNumberBySerialNo[currentPage.streamSerialNumber()];
|
std::uint32_t &pageSequenceNumber = pageSequenceNumberBySerialNo[currentPage.streamSerialNumber()];
|
||||||
|
lastPage = ¤tPage;
|
||||||
|
nextPageOffset = currentPage.startOffset() + pageSize;
|
||||||
|
|
||||||
// check whether the Vorbis Comment is present in this Ogg page
|
// check whether the Vorbis Comment is present in this Ogg page
|
||||||
if (currentComment && m_iterator.currentPageIndex() >= currentParams->firstPageIndex
|
if (currentComment && m_iterator.currentPageIndex() >= currentParams->firstPageIndex
|
||||||
&& m_iterator.currentPageIndex() <= currentParams->lastPageIndex && !currentPage.segmentSizes().empty()) {
|
&& m_iterator.currentPageIndex() <= currentParams->lastPageIndex && !currentPage.segmentSizes().empty()) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
void previousPage();
|
void previousPage();
|
||||||
void previousSegment();
|
void previousSegment();
|
||||||
const std::vector<OggPage> &pages() const;
|
const std::vector<OggPage> &pages() const;
|
||||||
|
std::vector<OggPage> &pages();
|
||||||
const OggPage ¤tPage() const;
|
const OggPage ¤tPage() const;
|
||||||
std::uint64_t currentPageOffset() const;
|
std::uint64_t currentPageOffset() const;
|
||||||
std::vector<OggPage>::size_type currentPageIndex() const;
|
std::vector<OggPage>::size_type currentPageIndex() const;
|
||||||
|
@ -124,6 +125,14 @@ inline const std::vector<OggPage> &OggIterator::pages() const
|
||||||
return m_pages;
|
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.
|
* \brief Returns the current OGG page.
|
||||||
* \remarks Calling this method when the iterator is invalid causes undefined behaviour.
|
* \remarks Calling this method when the iterator is invalid causes undefined behaviour.
|
||||||
|
|
Loading…
Reference in New Issue