From 3175e640bbc6d84935b3bd7c28cf5abcd8e1b3f7 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sat, 6 Feb 2016 18:25:04 +0000 Subject: [PATCH] refs #581, #592, #545 CAtomicFile can support ReadWrite mode by first copying the file. --- src/blackmisc/atomicfile.cpp | 10 +++++++--- src/blackmisc/valuecache.cpp | 17 ++++++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/blackmisc/atomicfile.cpp b/src/blackmisc/atomicfile.cpp index 55d7f2240..05cf29d4c 100644 --- a/src/blackmisc/atomicfile.cpp +++ b/src/blackmisc/atomicfile.cpp @@ -22,14 +22,18 @@ namespace BlackMisc bool CAtomicFile::open(CAtomicFile::OpenMode mode) { - Q_ASSERT_X(!(mode & (ReadOnly | Append)), Q_FUNC_INFO, "ReadOnly and Append flags are incompatible with CAtomicFile"); - m_originalFilename = fileName(); QFileInfo fileInfo(fileName()); setFileName(QFileInfo(fileInfo.dir(), ".tmp." + fileInfo.fileName() + "." + randomSuffix()).filePath()); if (exists()) { remove(); } - bool ok = QFile::open(mode); + bool ok = true; + if (mode & ReadOnly) + { + if (exists(m_originalFilename) && ! copy(m_originalFilename, fileName())) { ok = false; } + } + + if (ok && ! QFile::open(mode)) { ok = false; } if (! ok) { setFileName(m_originalFilename); } return ok; } diff --git a/src/blackmisc/valuecache.cpp b/src/blackmisc/valuecache.cpp index 227856a97..be2eeeb88 100644 --- a/src/blackmisc/valuecache.cpp +++ b/src/blackmisc/valuecache.cpp @@ -241,25 +241,24 @@ namespace BlackMisc } for (auto it = namespaces.cbegin(); it != namespaces.cend(); ++it) { - QFile readFile(dir + "/" + it.key() + ".json"); - if (! readFile.open(QFile::ReadWrite | QFile::Text)) + CAtomicFile file(dir + "/" + it.key() + ".json"); + if (! file.open(QFile::ReadWrite | QFile::Text)) { - return CLogMessage(this).error("Failed to open %1: %2") << readFile.fileName() << readFile.errorString(); + return CLogMessage(this).error("Failed to open %1: %2") << file.fileName() << file.errorString(); } - auto json = QJsonDocument::fromJson(readFile.readAll()); + auto json = QJsonDocument::fromJson(file.readAll()); if (json.isArray() || (json.isNull() && ! json.isEmpty())) { - return CLogMessage(this).error("Invalid JSON format in %1") << readFile.fileName(); + return CLogMessage(this).error("Invalid JSON format in %1") << file.fileName(); } CVariantMap storedValues; storedValues.convertFromJson(json.object()); storedValues.insert(*it); json.setObject(storedValues.toJson()); - readFile.close(); - CAtomicFile writeFile(readFile.fileName()); - if (! (writeFile.open(QFile::WriteOnly | QFile::Text) && writeFile.write(json.toJson()) > 0 && writeFile.checkedClose())) + + if (! (file.seek(0) && file.resize(0) && file.write(json.toJson()) > 0 && file.checkedClose())) { - return CLogMessage(this).error("Failed to write to %1: %2") << writeFile.fileName() << writeFile.errorString(); + return CLogMessage(this).error("Failed to write to %1: %2") << file.fileName() << file.errorString(); } } return {};