63 lines
1.7 KiB
C++
63 lines
1.7 KiB
C++
#include "persistence/JsonFileAtomic.h"
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QFileInfo>
|
|
|
|
namespace core::persistence {
|
|
|
|
bool writeBytesAtomic(const QString& absolutePath, const QByteArray& bytes) {
|
|
if (absolutePath.isEmpty()) {
|
|
return false;
|
|
}
|
|
const QString parent = QFileInfo(absolutePath).absolutePath();
|
|
if (!QFileInfo(parent).exists()) {
|
|
QDir().mkpath(parent);
|
|
}
|
|
const QString tmpAbs = absolutePath + QStringLiteral(".tmp");
|
|
if (QFileInfo::exists(tmpAbs)) {
|
|
QFile::remove(tmpAbs);
|
|
}
|
|
QFile f(tmpAbs);
|
|
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
|
return false;
|
|
}
|
|
const bool ok = f.write(bytes) == bytes.size();
|
|
f.close();
|
|
if (!ok || f.error() != QFile::NoError) {
|
|
QFile::remove(tmpAbs);
|
|
return false;
|
|
}
|
|
QFile::remove(absolutePath);
|
|
if (!QFile::rename(tmpAbs, absolutePath)) {
|
|
QFile::remove(tmpAbs);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool writeJsonAtomic(const QString& absolutePath, const QJsonObject& obj, bool pretty) {
|
|
const QJsonDocument doc(obj);
|
|
const QByteArray bytes = doc.toJson(pretty ? QJsonDocument::Indented : QJsonDocument::Compact);
|
|
return writeBytesAtomic(absolutePath, bytes);
|
|
}
|
|
|
|
bool readJsonObject(const QString& absolutePath, QJsonObject& out) {
|
|
out = QJsonObject();
|
|
QFile f(absolutePath);
|
|
if (!f.open(QIODevice::ReadOnly)) {
|
|
return false;
|
|
}
|
|
const QByteArray data = f.readAll();
|
|
QJsonParseError err;
|
|
const QJsonDocument doc = QJsonDocument::fromJson(data, &err);
|
|
if (err.error != QJsonParseError::NoError || !doc.isObject()) {
|
|
return false;
|
|
}
|
|
out = doc.object();
|
|
return true;
|
|
}
|
|
|
|
} // namespace core::persistence
|
|
|