qtjsonsettings/qtjsonsettings.cpp

121 lines
3.2 KiB
C++

#include "qtjsonsettings.h"
#include <QtDebug>
#include <QJsonDocument>
namespace {
void processReadKey(QString& key, QSettings::SettingsMap &map, const QVariant& element)
{
switch (element.type())
{
case QVariant::Map:
{
auto vMap = element.toMap();
auto it = vMap.constBegin();
auto end = vMap.constEnd();
for (; it != end; ++it)
{
key.append(it.key());
key.append("/");
processReadKey(key, map, it.value());
}
break;
}
case QVariant::List:
{
QVariantList list = element.toList();
map.insert(key + "size", list.count());
for (int i = 0; i < list.count(); ++i)
{
key.append(QString::number(i + 1));
key.append("/");
processReadKey(key, map, list.at(i));
}
break;
}
default:
map.insert(key.left(key.size() - 1), element);
}
key.truncate(key.lastIndexOf("/", -2) + 1);
}
QVariant processWriteKey(QVariant& root, const QString& key, const QVariant& value)
{
int slashPos = key.indexOf('/');
// If it is key
if (slashPos < 0)
{
QVariantMap map = root.toMap();
/** TODO VERY UGLY array detecting method
* Key size always placed after all numeric keys (array indexes)
* Convert root map to list and return it.
* Warning. Index starts with 1
*/
if (key == "size")
{
QVariantList list;
for (int i = 1; i <= value.toInt(); ++i)
{
list.append(map.value(QString::number(i)));
}
return list;
}
else
{
map.insert(key, value);
return map;
}
}
// get group name
QString groupName = key.left(slashPos);
// if name is number then it's row of array, convert to list
QVariantMap map = root.toMap();
QVariant item = map.value(groupName);
map.insert(groupName, processWriteKey(item, key.mid(slashPos + 1), value));
return map;
}
}
const QSettings::Format QtJsonSettings::json_format = QSettings::registerFormat("json", readJsonFile, writeJsonFile);
bool QtJsonSettings::readJsonFile(QIODevice &device, QSettings::SettingsMap &map)
{
QJsonParseError error;
auto document = QJsonDocument::fromJson(device.readAll(), &error);
if (QJsonParseError::NoError == error.error)
{
if (!document.isEmpty()){
QString str;
processReadKey(str, map, document.toVariant());
}
}
else
{
qWarning() << error.errorString();
}
return true;
}
bool QtJsonSettings::writeJsonFile(QIODevice &device, const QSettings::SettingsMap &map)
{
QVariant resultMap;
auto it = map.constBegin();
auto end = map.constEnd();
for (; it != end; ++it)
{
resultMap = processWriteKey(resultMap, it.key(), it.value());
};
device.write(QJsonDocument::fromVariant(resultMap).toJson());
return true;
}