Skip to content

Instantly share code, notes, and snippets.

@Diviector
Last active September 11, 2024 11:34
Show Gist options
  • Save Diviector/43798b4b56e5dff58f93a08826fef102 to your computer and use it in GitHub Desktop.
Save Diviector/43798b4b56e5dff58f93a08826fef102 to your computer and use it in GitHub Desktop.
Json QSettings::Format for QSettings
#include "qjsonsettingsformat.hpp"
#include <QMutex>
#include <QMutexLocker>
#include <QIODevice>
#include <QTextStream>
#include <QJsonObject>
#include <QJsonDocument>
static bool readFunc(QIODevice &device, QSettings::SettingsMap &map);
static bool writeFunc(QIODevice &device, const QSettings::SettingsMap &map);
static void jsonObjectToSettingsMap(const QJsonObject &jo,
QSettings::SettingsMap &map);
static void settingsMapToJsonObject(const QSettings::SettingsMap &map,
QJsonObject &jo);
QSettings::Format QJsonSettingsFormat::get()
{
static QMutex regMutex;
static QSettings::Format jsonFormat {QSettings::InvalidFormat};
QMutexLocker regLocker(&regMutex);
if (jsonFormat == QSettings::InvalidFormat)
{
jsonFormat = QSettings::registerFormat("json", &readFunc, &writeFunc);
}
return jsonFormat;
}
static bool readFunc(QIODevice &device, QSettings::SettingsMap &map)
{
QByteArray jsonValue = device.readAll();
QJsonParseError parseError;
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonValue, &parseError);
if (parseError.error != QJsonParseError::NoError)
return false;
QJsonObject root = jsonDocument.object();
jsonObjectToSettingsMap(root, map);
return true;
}
static bool writeFunc(QIODevice &device, const QSettings::SettingsMap &map)
{
QJsonObject root;
settingsMapToJsonObject(map, root);
QTextStream outStream(&device);
outStream << QJsonDocument(root).toJson();
return true;
}
static inline void jsonObjectToSettingsMapValue(const QJsonObject &jo,
QSettings::SettingsMap &map,
const QString &group)
{
for (auto joIter = jo.constBegin(); joIter != jo.constEnd(); ++joIter)
{
QString valueName = group + joIter.key();
QJsonValue jv = joIter.value();
if (jv.isObject())
jsonObjectToSettingsMapValue(jv.toObject(), map, valueName + '/');
else
map[valueName] = jv.toVariant();
}
}
static void jsonObjectToSettingsMap(const QJsonObject &jo,
QSettings::SettingsMap &map)
{
jsonObjectToSettingsMapValue(jo, map, "");
}
static inline void createJsonValue(QJsonObject &root,
const QString &valueName,
const QVariant &value)
{
int slashPos = valueName.indexOf('/');
if (slashPos == -1) {
root[valueName] = QJsonValue::fromVariant(value);
return;
}
auto group = valueName.left(slashPos);
auto name = valueName.mid(slashPos + 1);
auto group_root = root[group].toObject();
createJsonValue(group_root, name, value);
root[group] = group_root;
}
static void settingsMapToJsonObject(const QSettings::SettingsMap &map,
QJsonObject &jo)
{
for (auto mapIter = map.constBegin(); mapIter != map.constEnd(); ++mapIter)
{
QString groupName_valueName = mapIter.key();
QVariant value = mapIter.value();
createJsonValue(jo, groupName_valueName, value);
}
}
#pragma once
#include <QSettings>
class QJsonSettingsFormat
{
public:
static QSettings::Format get();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment