5#include <c++utilities/conversion/stringbuilder.h>
6#include <c++utilities/conversion/stringconversion.h>
32namespace BackupHelper {
53 const std::string &originalPath,
const std::string &backupPath, NativeFileStream &originalStream, NativeFileStream &backupStream)
56 if (originalStream.is_open()) {
57 originalStream.close();
61 backupStream.exceptions(ios_base::goodbit);
64 backupStream.open(backupPathForOpen.data(), ios_base::in | ios_base::binary);
65 if (backupStream.is_open()) {
68 throw std::ios_base::failure(
"Backup/temporary file has not been created.");
72 std::remove(originalPathForOpen.data());
73 if (std::rename(backupPathForOpen.data(), originalPathForOpen.data()) == 0) {
79 backupStream.exceptions(ios_base::failbit | ios_base::badbit);
80 originalStream.exceptions(ios_base::failbit | ios_base::badbit);
81 backupStream.open(backupPathForOpen.data(), ios_base::in | ios_base::binary);
82 originalStream.open(originalPathForOpen.data(), ios_base::out | ios_base::binary);
83 originalStream << backupStream.rdbuf();
84 originalStream.flush();
86 }
catch (
const std::ios_base::failure &failure) {
87 throw std::ios_base::failure(
"Unable to restore original file from backup file \"" % backupPath %
"\" after failure: " + failure.what());
94static bool isRelative(
const std::string &path)
96 return path.empty() || (path.front() !=
'/' && (path.size() < 2 || path[1] !=
':'));
124void createBackupFile(
const std::string &backupDir,
const std::string &originalPath, std::string &backupPath, NativeFileStream &originalStream,
125 NativeFileStream &backupStream)
128 const auto backupDirRelative(isRelative(backupDir));
132 for (
unsigned int i = 0;; ++i) {
133 if (backupDir.empty()) {
135 backupPath = originalPath %
'.' % i +
".bak";
137 backupPath = originalPath +
".bak";
143 if (backupDirRelative) {
144 backupPath = originalDir %
'/' % backupDir %
'/' % fileName %
'.' % i + ext;
146 backupPath = backupDir %
'/' % fileName %
'.' % i + ext;
149 if (backupDirRelative) {
150 backupPath = originalDir %
'/' % backupDir %
'/' + fileName;
152 backupPath = backupDir %
'/' + fileName;
158#ifdef PLATFORM_WINDOWS
161 struct stat backupStat;
169 if (originalStream.is_open()) {
170 originalStream.close();
177 backupStream.exceptions(ios_base::failbit | ios_base::badbit);
178 originalStream.exceptions(ios_base::failbit | ios_base::badbit);
180 if (backupStream.is_open()) {
181 backupStream.close();
187 backupStream << originalStream.rdbuf();
188 backupStream.flush();
191 }
catch (
const std::ios_base::failure &failure) {
192 throw std::ios_base::failure(argsToString(
"Unable to rename original file before rewriting it: ", failure.what()));
199 if (originalStream.is_open()) {
200 originalStream.close();
203 if (backupStream.is_open()) {
204 backupStream.close();
207 backupStream.exceptions(ios_base::failbit | ios_base::badbit);
209 }
catch (
const std::ios_base::failure &failure) {
213 throw std::ios_base::failure(
"Unable to restore original file from backup file \"" % backupPath %
"\" after failure: " + failure.what());
215 throw std::ios_base::failure(argsToString(
"Unable to open backup file: ", failure.what()));
240 NativeFileStream &backupStream,
Diagnostics &diag,
const std::string &context)
251 if (!backupPath.empty()) {
253 diag.emplace_back(
DiagLevel::Information,
"Rewriting the file to apply changed tag information has been aborted.", context);
256 diag.emplace_back(
DiagLevel::Warning,
"The original file has been restored.", context);
257 }
catch (
const std::ios_base::failure &failure) {
258 diag.emplace_back(
DiagLevel::Critical, argsToString(
"The original file could not be restored: ", failure.what()), context);
266 if (!backupPath.empty()) {
268 diag.emplace_back(
DiagLevel::Critical,
"Rewriting the file to apply changed tag information failed.", context);
271 diag.emplace_back(
DiagLevel::Warning,
"The original file has been restored.", context);
272 }
catch (
const std::ios_base::failure &failure) {
273 diag.emplace_back(
DiagLevel::Critical, argsToString(
"The original file could not be restored: ", failure.what()), context);
280 }
catch (
const std::ios_base::failure &) {
281 if (!backupPath.empty()) {
283 diag.emplace_back(
DiagLevel::Critical,
"An IO error occurred when rewriting the file to apply changed tag information.", context);
286 diag.emplace_back(
DiagLevel::Warning,
"The original file has been restored.", context);
287 }
catch (
const std::ios_base::failure &failure) {
288 diag.emplace_back(
DiagLevel::Critical, argsToString(
"The original file could not be restored: ", failure.what()), context);
291 diag.emplace_back(
DiagLevel::Critical,
"An IO error occurred when applying tag information.", context);
virtual void reset()
Discards all parsing results.
std::string containingDirectory() const
Returns the path of the directory containing the current file.
static std::string fileName(std::string_view path, bool cutExtension=false)
Returns the file name of the given file.
const std::string & path() const
Returns the path of the current file.
static std::string_view pathForOpen(std::string_view url)
Returns removes the "file:/" prefix from url to be able to pass it to functions like open(),...
std::string extension() const
Returns the extension of the current file.
The Diagnostics class is a container for DiagMessage.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
The exception that is thrown when an operation has been stopped and thus not successfully completed b...
TAG_PARSER_EXPORT void createBackupFile(const std::string &backupDir, const std::string &originalPath, std::string &backupPath, CppUtilities::NativeFileStream &originalStream, CppUtilities::NativeFileStream &backupStream)
TAG_PARSER_EXPORT void handleFailureAfterFileModified(MediaFileInfo &mediaFileInfo, const std::string &backupPath, CppUtilities::NativeFileStream &outputStream, CppUtilities::NativeFileStream &backupStream, Diagnostics &diag, const std::string &context="making file")
TAG_PARSER_EXPORT void restoreOriginalFileFromBackupFile(const std::string &originalPath, const std::string &backupPath, CppUtilities::NativeFileStream &originalStream, CppUtilities::NativeFileStream &backupStream)
Contains all classes and functions of the TagInfo library.