From 30ba404043f3d3f21036071808b3a99b44f1a352 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 12 Aug 2018 19:14:31 +0200 Subject: [PATCH] Ref T304, "no throw" JSON functions --- src/blackmisc/containerbase.h | 20 ++++++++++++++++++++ src/blackmisc/json.cpp | 1 - src/blackmisc/json.h | 21 +++++++++++++++++++++ src/blackmisc/jsonexception.cpp | 12 ++++++++++-- src/blackmisc/jsonexception.h | 3 +++ src/blackmisc/logcategory.h | 10 ++++++++++ src/blackmisc/logpattern.cpp | 1 + 7 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/blackmisc/containerbase.h b/src/blackmisc/containerbase.h index c76add068..bfc335fcf 100644 --- a/src/blackmisc/containerbase.h +++ b/src/blackmisc/containerbase.h @@ -123,6 +123,7 @@ namespace BlackMisc } //! \copydoc BlackMisc::Mixin::JsonByMetaClass::convertFromJson + //! \throws CJsonException void convertFromJson(const QJsonObject &json) { derived().clear(); @@ -167,6 +168,25 @@ namespace BlackMisc return obj; } + //! Static version of convertFromJson + static Derived fromJsonNoThrow(const QString &jsonString, bool acceptCacheJson, bool &success, QString &errMsg) + { + success = false; + Derived obj; + try + { + if (jsonString.isEmpty()) { return obj; } + const QJsonObject jsonObj = acceptCacheJson ? Json::swiftDataObjectValue(jsonString) : Json::jsonObjectFromString(jsonString); + obj.convertFromJson(jsonObj); + success = true; + } + catch (const CJsonException &ex) + { + errMsg = ex.toString("JSON conversion"); + } + return obj; + } + //! Call convertFromJson, catch any CJsonException that is thrown and return it as CStatusMessage. CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix); // implemented in statusmessage.h diff --git a/src/blackmisc/json.cpp b/src/blackmisc/json.cpp index d414653bb..92fa03802 100644 --- a/src/blackmisc/json.cpp +++ b/src/blackmisc/json.cpp @@ -393,7 +393,6 @@ namespace BlackMisc if (json.isEmpty()) { return QJsonObject();} const QJsonDocument jsonDoc(QJsonDocument::fromJson(json.toUtf8())); return acceptCacheFormat ? Json::unwrapCache(jsonDoc.object()) : jsonDoc.object(); - // return acceptCacheFormat ? Json::swiftDataObjectValue(jsonDoc.object()) : jsonDoc.object(); } QString stringFromJsonObject(const QJsonObject &jsonObject, QJsonDocument::JsonFormat format) diff --git a/src/blackmisc/json.h b/src/blackmisc/json.h index d5c76dd94..dcc040f54 100644 --- a/src/blackmisc/json.h +++ b/src/blackmisc/json.h @@ -463,11 +463,32 @@ namespace BlackMisc static DerivedObj fromJson(const QString &jsonString, bool acceptCacheJson = false) { DerivedObj obj; + if (jsonString.isEmpty()) { return obj; } const QJsonObject jsonObj = acceptCacheJson ? Json::swiftDataObjectValue(jsonString) : Json::jsonObjectFromString(jsonString); obj.convertFromJson(jsonObj); return obj; } + //! Get object from JSON string + template + static Derived fromJsonNoThrow(const QString &jsonString, bool acceptCacheJson, bool &success, QString &errMsg) + { + success = false; + Derived obj; + try + { + if (jsonString.isEmpty()) { return obj; } + const QJsonObject jsonObj = acceptCacheJson ? Json::swiftDataObjectValue(jsonString) : Json::jsonObjectFromString(jsonString); + obj.convertFromJson(jsonObj); + success = true; + } + catch (const CJsonException &ex) + { + errMsg = ex.toString("JSON conversion"); + } + return obj; + } + private: const Derived *derived() const { return static_cast(this); } Derived *derived() { return static_cast(this); } diff --git a/src/blackmisc/jsonexception.cpp b/src/blackmisc/jsonexception.cpp index 3da3199ac..f2c8f10ed 100644 --- a/src/blackmisc/jsonexception.cpp +++ b/src/blackmisc/jsonexception.cpp @@ -26,12 +26,20 @@ namespace BlackMisc CStatusMessage CJsonException::toStatusMessage(const CLogCategoryList &categories, const QString &prefix) const { - return CStatusMessage(categories).validationError("%1: %2 in '%3'") << prefix << what() << getStackTrace(); + return CStatusMessage(categories).validationError(toString(prefix)); + } + + QString CJsonException::toString(const QString &prefix) const + { + static const QString s("%1 in '%2'"); + static const QString sp("%1: %2 in '%3'"); + if (prefix.isEmpty()) { return s.arg(what()).arg(getStackTrace()); } + return sp.arg(prefix).arg(what()).arg(getStackTrace()); } void CJsonException::toLogMessage(const CLogCategoryList &categories, const QString &prefix) const { - CLogMessage(categories).validationError("%1: %2 in '%3'") << prefix << what() << getStackTrace(); + CLogMessage(categories).validationError(toString(prefix)); } QString CJsonException::stackString() diff --git a/src/blackmisc/jsonexception.h b/src/blackmisc/jsonexception.h index 2c0129e14..da631ac10 100644 --- a/src/blackmisc/jsonexception.h +++ b/src/blackmisc/jsonexception.h @@ -36,6 +36,9 @@ namespace BlackMisc //! Get a status message representation. CStatusMessage toStatusMessage(const CLogCategoryList &categories, const QString &prefix) const; + //! As string info + QString toString(const QString &prefix) const; + //! Write a message to the log. void toLogMessage(const CLogCategoryList &categories, const QString &prefix) const; diff --git a/src/blackmisc/logcategory.h b/src/blackmisc/logcategory.h index 99e784afb..c8096ee5e 100644 --- a/src/blackmisc/logcategory.h +++ b/src/blackmisc/logcategory.h @@ -208,6 +208,13 @@ namespace BlackMisc return cat; } + //! JSON and JSON conversions + static const CLogCategory &json() + { + static const CLogCategory cat { "swift.json" }; + return cat; + } + //! Startup of application static const CLogCategory &startup() { @@ -271,7 +278,10 @@ namespace BlackMisc dataInconsistency(), download(), driver(), + flightPlan(), guiComponent(), + interpolator(), + json(), mapping(), matching(), modelLoader(), diff --git a/src/blackmisc/logpattern.cpp b/src/blackmisc/logpattern.cpp index 5aca378af..51229a7ac 100644 --- a/src/blackmisc/logpattern.cpp +++ b/src/blackmisc/logpattern.cpp @@ -33,6 +33,7 @@ namespace BlackMisc { "driver", exactMatch(CLogCategory::driver()) }, { "flight plan", exactMatch(CLogCategory::flightPlan()) }, { "interpolator", exactMatch(CLogCategory::interpolator()) }, + { "JSON (conversion)", exactMatch(CLogCategory::json()) }, { "model cache", exactMatch(CLogCategory::modelCache()) }, { "model GUI", exactMatch(CLogCategory::modelGui()) }, { "model loader", exactMatch(CLogCategory::modelLoader()) },