From 3a8b238052163952831fb5924b2483a375e86ebd Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Thu, 28 May 2015 19:38:29 +0200 Subject: NOISSUE Various changes from multiauth that are unrelated to it --- logic/Json.h | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 logic/Json.h (limited to 'logic/Json.h') diff --git a/logic/Json.h b/logic/Json.h new file mode 100644 index 00000000..d22aa606 --- /dev/null +++ b/logic/Json.h @@ -0,0 +1,239 @@ +// Licensed under the Apache-2.0 license. See README.md for details. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Exception.h" + +namespace Json +{ +DECLARE_EXCEPTION(Json); + +enum Requirement +{ + Required +}; + +void write(const QJsonDocument &doc, const QString &filename); +void write(const QJsonObject &object, const QString &filename); +void write(const QJsonArray &array, const QString &filename); +QByteArray toBinary(const QJsonObject &obj); +QByteArray toBinary(const QJsonArray &array); +QByteArray toText(const QJsonObject &obj); +QByteArray toText(const QJsonArray &array); + +QJsonDocument ensureDocument(const QByteArray &data, const QString &what = "Document"); +QJsonDocument ensureDocument(const QString &filename, const QString &what = "Document"); +QJsonObject ensureObject(const QJsonDocument &doc, const QString &what = "Document"); +QJsonArray ensureArray(const QJsonDocument &doc, const QString &what = "Document"); + +/////////////////// WRITING //////////////////// + +void writeString(QJsonObject & to, const QString &key, const QString &value); +void writeStringList(QJsonObject & to, const QString &key, const QStringList &values); + +template +void writeObjectList(QJsonObject & to, QString key, QList> values) +{ + if (!values.isEmpty()) + { + QJsonArray array; + for (auto value: values) + { + array.append(value->toJson()); + } + to.insert(key, array); + } +} +template +void writeObjectList(QJsonObject & to, QString key, QList values) +{ + if (!values.isEmpty()) + { + QJsonArray array; + for (auto value: values) + { + array.append(value.toJson()); + } + to.insert(key, array); + } +} + +template +QJsonValue toJson(const T &t) +{ + return QJsonValue(t); +} +template<> +QJsonValue toJson(const QUrl &url); +template<> +QJsonValue toJson(const QByteArray &data); +template<> +QJsonValue toJson(const QDateTime &datetime); +template<> +QJsonValue toJson(const QDir &dir); +template<> +QJsonValue toJson(const QUuid &uuid); +template<> +QJsonValue toJson(const QVariant &variant); + +template +QJsonArray toJsonArray(const QList &container) +{ + QJsonArray array; + for (const T item : container) + { + array.append(toJson(item)); + } + return array; +} + +////////////////// READING //////////////////// + +template +T ensureIsType(const QJsonValue &value, const Requirement requirement = Required, const QString &what = "Value"); + +template<> double ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> bool ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> int ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QJsonObject ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QJsonArray ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QJsonValue ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QByteArray ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QDateTime ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QVariant ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QString ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QUuid ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QDir ensureIsType(const QJsonValue &value, const Requirement, const QString &what); +template<> QUrl ensureIsType(const QJsonValue &value, const Requirement, const QString &what); + +// the following functions are higher level functions, that make use of the above functions for +// type conversion +template +T ensureIsType(const QJsonValue &value, const T default_, const QString &what = "Value") +{ + if (value.isUndefined()) + { + return default_; + } + return ensureIsType(value, Required, what); +} +template +T ensureIsType(const QJsonObject &parent, const QString &key, + const Requirement requirement = Required, + const QString &what = "__placeholder__") +{ + const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); + if (!parent.contains(key)) + { + throw JsonException(localWhat + "s parent does not contain " + localWhat); + } + return ensureIsType(parent.value(key), requirement, localWhat); +} +template +T ensureIsType(const QJsonObject &parent, const QString &key, const T default_, + const QString &what = "__placeholder__") +{ + const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); + if (!parent.contains(key)) + { + return default_; + } + return ensureIsType(parent.value(key), default_, localWhat); +} + +template +QList ensureIsArrayOf(const QJsonDocument &doc) +{ + const QJsonArray array = ensureArray(doc); + QList out; + for (const QJsonValue val : array) + { + out.append(ensureIsType(val, Required, "Document")); + } + return out; +} +template +QList ensureIsArrayOf(const QJsonValue &value, const Requirement = Required, + const QString &what = "Value") +{ + const QJsonArray array = ensureIsType(value, Required, what); + QList out; + for (const QJsonValue val : array) + { + out.append(ensureIsType(val, Required, what)); + } + return out; +} +template +QList ensureIsArrayOf(const QJsonValue &value, const QList default_, + const QString &what = "Value") +{ + if (value.isUndefined()) + { + return default_; + } + return ensureIsArrayOf(value, Required, what); +} +template +QList ensureIsArrayOf(const QJsonObject &parent, const QString &key, + const Requirement requirement = Required, + const QString &what = "__placeholder__") +{ + const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); + if (!parent.contains(key)) + { + throw JsonException(localWhat + "s parent does not contain " + localWhat); + } + return ensureIsArrayOf(parent.value(key), requirement, localWhat); +} +template +QList ensureIsArrayOf(const QJsonObject &parent, const QString &key, + const QList &default_, const QString &what = "__placeholder__") +{ + const QString localWhat = QString(what).replace("__placeholder__", '\'' + key + '\''); + if (!parent.contains(key)) + { + return default_; + } + return ensureIsArrayOf(parent.value(key), default_, localWhat); +} + +// this macro part could be replaced by variadic functions that just pass on their arguments, but that wouldn't work well with IDE helpers +#define JSON_HELPERFUNCTIONS(NAME, TYPE) \ + inline TYPE ensure##NAME(const QJsonValue &value, const Requirement requirement = Required, const QString &what = "Value") \ +{ return ensureIsType(value, requirement, what); } \ + inline TYPE ensure##NAME(const QJsonValue &value, const TYPE default_, const QString &what = "Value") \ +{ return ensureIsType(value, default_, what); } \ + inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const Requirement requirement = Required, const QString &what = "__placeholder__") \ +{ return ensureIsType(parent, key, requirement, what); } \ + inline TYPE ensure##NAME(const QJsonObject &parent, const QString &key, const TYPE default_, const QString &what = "__placeholder") \ +{ return ensureIsType(parent, key, default_, what); } + +JSON_HELPERFUNCTIONS(Array, QJsonArray) +JSON_HELPERFUNCTIONS(Object, QJsonObject) +JSON_HELPERFUNCTIONS(JsonValue, QJsonValue) +JSON_HELPERFUNCTIONS(String, QString) +JSON_HELPERFUNCTIONS(Boolean, bool) +JSON_HELPERFUNCTIONS(Double, double) +JSON_HELPERFUNCTIONS(Integer, int) +JSON_HELPERFUNCTIONS(DateTime, QDateTime) +JSON_HELPERFUNCTIONS(Url, QUrl) +JSON_HELPERFUNCTIONS(ByteArray, QByteArray) +JSON_HELPERFUNCTIONS(Dir, QDir) +JSON_HELPERFUNCTIONS(Uuid, QUuid) +JSON_HELPERFUNCTIONS(Variant, QVariant) + +#undef JSON_HELPERFUNCTIONS + +} +using JSONValidationError = Json::JsonException; -- cgit v1.2.3