Fix warnings and improve style in makeMp3File()

This commit is contained in:
Martchus 2018-04-29 18:57:22 +02:00
parent ae65ad0408
commit 30553c947c
1 changed files with 228 additions and 223 deletions

View File

@ -1478,14 +1478,30 @@ void MediaFileInfo::invalidated()
void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &progress)
{
static const string context("making MP3/FLAC file");
// there's no need to rewrite the complete file if there are no ID3v2 tags present or to be written
// don't rewrite the complete file if there are no ID3v2/FLAC tags present or to be written
if (!isForcingRewrite() && m_id3v2Tags.empty() && m_actualId3v2TagOffsets.empty() && m_saveFilePath.empty()
&& m_containerFormat != ContainerFormat::Flac) {
// alter ID3v1 tag
if (!m_id3v1Tag) {
// remove ID3v1 tag
if (!m_actualExistingId3v1Tag) {
diag.emplace_back(DiagLevel::Information, "Nothing to be changed.", context);
return;
}
progress.updateStep("Removing ID3v1 tag ...");
stream().close();
if (truncate(path().data(), static_cast<std::streamoff>(size() - 128)) == 0) {
reportSizeChanged(size() - 128);
} else {
diag.emplace_back(DiagLevel::Critical, "Unable to truncate file to remove ID3v1 tag.", context);
throwIoFailure("Unable to truncate file to remove ID3v1 tag.");
}
return;
} else {
// add or update ID3v1 tag
if (m_actualExistingId3v1Tag) {
// there is currently an ID3v1 tag at the end of the file
if (m_id3v1Tag) {
// the file shall still have an ID3v1 tag
progress.updateStep("Updating ID3v1 tag ...");
progress.updateStep("Updating existing ID3v1 tag ...");
// ensure the file is still open / not readonly
open();
stream().seekp(-128, ios_base::end);
@ -1495,21 +1511,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
diag.emplace_back(DiagLevel::Warning, "Unable to write ID3v1 tag.", context);
}
} else {
// the currently existing ID3v1 tag shall be removed
progress.updateStep("Removing ID3v1 tag ...");
stream().close();
if (truncate(path().c_str(), size() - 128) == 0) {
reportSizeChanged(size() - 128);
} else {
diag.emplace_back(DiagLevel::Critical, "Unable to truncate file to remove ID3v1 tag.", context);
throwIoFailure("Unable to truncate file to remove ID3v1 tag.");
}
}
} else {
// there is currently no ID3v1 tag at the end of the file
if (m_id3v1Tag) {
progress.updateStep("Adding ID3v1 tag ...");
progress.updateStep("Adding new ID3v1 tag ...");
// ensure the file is still open / not readonly
open();
stream().seekp(0, ios_base::end);
@ -1518,14 +1520,14 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
} catch (const Failure &) {
diag.emplace_back(DiagLevel::Warning, "Unable to write ID3v1 tag.", context);
}
} else {
diag.emplace_back(DiagLevel::Information, "Nothing to be changed.", context);
}
}
return;
}
} else {
// ID3v2 needs to be modified
progress.updateStep("Updating ID3v2 tags ...");
FlacStream *const flacStream = (m_containerFormat == ContainerFormat::Flac ? static_cast<FlacStream *>(m_singleTrack.get()) : nullptr);
progress.updateStep(flacStream ? "Updating FLAC tags ..." : "Updating ID3v2 tags ...");
// prepare ID3v2 tags
vector<Id3v2TagMaker> makers;
@ -1539,13 +1541,11 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
}
}
// check whether it is a raw FLAC stream
FlacStream *flacStream = (m_containerFormat == ContainerFormat::Flac ? static_cast<FlacStream *>(m_singleTrack.get()) : nullptr);
// determine stream offset and make track/format specific metadata
uint32 streamOffset; // where the actual stream starts
stringstream flacMetaData(ios_base::in | ios_base::out | ios_base::binary);
flacMetaData.exceptions(ios_base::badbit | ios_base::failbit);
uint32 startOfLastMetaDataBlock;
if (flacStream) {
// if it is a raw FLAC stream, make FLAC metadata
startOfLastMetaDataBlock = flacStream->makeHeader(flacMetaData, diag);
@ -1558,7 +1558,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// check whether rewrite is required
bool rewriteRequired = isForcingRewrite() || !m_saveFilePath.empty() || (tagsSize > streamOffset);
uint32 padding = 0;
size_t padding = 0;
if (!rewriteRequired) {
// rewriting is not forced and new tag is not too big for available space
// -> calculate new padding
@ -1607,7 +1607,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// recreate original file, define buffer variables
outputStream.open(path(), ios_base::out | ios_base::binary | ios_base::trunc);
} catch (...) {
const char *what = catchIoFailure();
const char *const what = catchIoFailure();
diag.emplace_back(DiagLevel::Critical, "Creation of temporary file (to rewrite the original file) failed.", context);
throwIoFailure(what);
}
@ -1619,7 +1619,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
backupStream.open(path(), ios_base::in | ios_base::binary);
outputStream.open(m_saveFilePath, ios_base::out | ios_base::binary | ios_base::trunc);
} catch (...) {
const char *what = catchIoFailure();
const char *const what = catchIoFailure();
diag.emplace_back(DiagLevel::Critical, "Opening streams to write output file failed.", context);
throwIoFailure(what);
}
@ -1631,7 +1631,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
close();
outputStream.open(path(), ios_base::in | ios_base::out | ios_base::binary);
} catch (...) {
const char *what = catchIoFailure();
const char *const what = catchIoFailure();
diag.emplace_back(DiagLevel::Critical, "Opening the file with write permissions failed.", context);
throwIoFailure(what);
}
@ -1639,6 +1639,11 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// start actual writing
try {
// ensure we can cast padding safely to uint32
if (padding > numeric_limits<uint32>::max()) {
padding = numeric_limits<uint32>::max();
}
if (!makers.empty()) {
// write ID3v2 tags
progress.updateStep("Writing ID3v2 tag ...");
@ -1646,7 +1651,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
i->make(outputStream, 0, diag);
}
// include padding into the last ID3v2 tag
makers.back().make(outputStream, (flacStream && padding && padding < 4) ? 0 : padding, diag);
makers.back().make(outputStream, (flacStream && padding && padding < 4) ? 0 : static_cast<uint32>(padding), diag);
}
if (flacStream) {
@ -1663,7 +1668,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// write padding
if (padding) {
flacStream->makePadding(outputStream, padding, true, diag);
flacStream->makePadding(outputStream, static_cast<uint32>(padding), true, diag);
}
}
@ -1696,7 +1701,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
bind(&AbortableProgressFeedback::updateStepPercentage, ref(progress), _1));
} else {
// just skip actual stream data
outputStream.seekp(mediaDataSize, ios_base::cur);
outputStream.seekp(static_cast<std::streamoff>(mediaDataSize), ios_base::cur);
}
// write ID3v1 tag
@ -1712,7 +1717,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// handle streams
if (rewriteRequired) {
// report new size
reportSizeChanged(outputStream.tellp());
reportSizeChanged(static_cast<uint64>(outputStream.tellp()));
// "save as path" is now the regular path
if (!saveFilePath().empty()) {
reportPathChanged(saveFilePath());
@ -1727,7 +1732,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
// -> close stream before truncating
outputStream.close();
// -> truncate file
if (truncate(path().c_str(), newSize) == 0) {
if (truncate(path().c_str(), static_cast<std::streamoff>(newSize)) == 0) {
reportSizeChanged(newSize);
} else {
diag.emplace_back(DiagLevel::Critical, "Unable to truncate the file.", context);
@ -1741,6 +1746,6 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr
} catch (...) {
BackupHelper::handleFailureAfterFileModified(*this, backupPath, outputStream, backupStream, diag, context);
}
}
}
} // namespace TagParser