refs #784 CVariant can detect whether a value object supports memoized JSON and pick the appropriate methods to call.

This commit is contained in:
Mathew Sutcliffe
2016-10-25 22:43:35 +01:00
committed by Klaus Basan
parent 5d7289adb3
commit 72a5a0e670
5 changed files with 121 additions and 0 deletions

View File

@@ -205,6 +205,48 @@ namespace BlackMisc
}
}
QJsonObject CVariant::toMemoizedJson() const
{
auto *meta = getValueObjectMetaInfo();
if (meta)
{
try
{
QJsonObject json;
json.insert("type", this->typeName());
json.insert("value", meta->toMemoizedJson(data()));
return json;
}
catch (const Private::CVariantException &ex)
{
CLogMessage(this).debug() << ex.what();
return {};
}
}
else
{
return toJson();
}
}
void CVariant::convertFromMemoizedJson(const QJsonObject &json)
{
QString typeName = json.value("type").toString();
if (typeName.isEmpty()) { m_v.clear(); return; }
int typeId = QMetaType::type(qPrintable(typeName));
auto *meta = Private::getValueObjectMetaInfo(typeId);
if (meta)
{
m_v = QVariant(typeId, nullptr);
meta->convertFromMemoizedJson(json.value("value").toObject(), data());
}
else
{
convertFromJson(json);
}
}
uint CVariant::getValueHash() const
{
switch (m_v.type())

View File

@@ -277,6 +277,12 @@ namespace BlackMisc
//! \copydoc BlackMisc::Mixin::JsonByMetaClass::convertFromJson
void convertFromJson(const QJsonObject &json);
//! To compact JSON format.
QJsonObject toMemoizedJson() const;
//! From compact JSON format.
void convertFromMemoizedJson(const QJsonObject &json);
//! \copydoc BlackMisc::Mixin::DBusByMetaClass::marshallToDbus
void marshallToDbus(QDBusArgument &argument) const;

View File

@@ -54,4 +54,44 @@ namespace BlackMisc
}
}
QJsonObject &CVariantMap::mergeToMemoizedJson(QJsonObject &json) const
{
for (auto it = cbegin(); it != cend(); ++it)
{
json.insert(it.key(), it.value().toMemoizedJson());
}
return json;
}
QJsonObject CVariantMap::toMemoizedJson() const
{
QJsonObject json;
mergeToMemoizedJson(json);
return json;
}
void CVariantMap::convertFromMemoizedJson(const QJsonObject &json)
{
clear();
for (auto it = json.begin(); it != json.end(); ++it)
{
CVariant value;
value.convertFromMemoizedJson(it.value().toObject());
implementationOf(*this).insert(cend(), it.key(), value);
}
}
void CVariantMap::convertFromMemoizedJson(const QJsonObject &json, const QStringList &keys)
{
clear();
for (const auto &key : keys)
{
auto value = json.value(key);
if (value.isUndefined()) { continue; }
CVariant var;
var.convertFromMemoizedJson(value.toObject());
insert(key, var);
}
}
}

View File

@@ -68,6 +68,19 @@ namespace BlackMisc
//! \copydoc BlackMisc::CValueObject::convertFromJson
//! Convert only keys present in list argument.
void convertFromJson(const QJsonObject &json, const QStringList &keys);
//! Insert values from this map into an existing compact JSON object.
QJsonObject &mergeToMemoizedJson(QJsonObject &json) const;
//! To compact JSON format.
QJsonObject toMemoizedJson() const;
//! From compact JSON format.
void convertFromMemoizedJson(const QJsonObject &json);
//! From compact JSON format.
//! Convert only keys present in list argument.
void convertFromMemoizedJson(const QJsonObject &json, const QStringList &keys);
};
}

View File

@@ -46,6 +46,8 @@ namespace BlackMisc
virtual QString toQString(const void *object, bool i18n) const = 0;
virtual QJsonObject toJson(const void *object) const = 0;
virtual void convertFromJson(const QJsonObject &json, void *object) const = 0;
virtual QJsonObject toMemoizedJson(const void *object) const = 0;
virtual void convertFromMemoizedJson(const QJsonObject &json, void *object) const = 0;
virtual void unmarshall(const QDBusArgument &arg, void *object) const = 0;
virtual uint getValueHash(const void *object) const = 0;
virtual int getMetaTypeId() const = 0;
@@ -93,6 +95,16 @@ namespace BlackMisc
template <typename T>
static void convertFromJson(const QJsonObject &, T &object, ...) { throw CVariantException(object, "convertFromJson"); }
template <typename T>
static QJsonObject toMemoizedJson(const T &object, decltype(static_cast<void>(object.toMemoizedJson()), 0)) { return object.toMemoizedJson(); }
template <typename T>
static QJsonObject toMemoizedJson(const T &object, ...) { return toJson(object, 0); }
template <typename T>
static void convertFromMemoizedJson(const QJsonObject &json, T &object, decltype(static_cast<void>(object.convertFromMemoizedJson(json)), 0)) { object.convertFromMemoizedJson(json); }
template <typename T>
static void convertFromMemoizedJson(const QJsonObject &json, T &object, ...) { convertFromJson(json, object, 0); }
template <typename T>
static uint getValueHash(const T &object, decltype(static_cast<void>(qHash(object)), 0)) { return qHash(object); }
template <typename T>
@@ -145,6 +157,14 @@ namespace BlackMisc
{
CValueObjectMetaInfoHelper::convertFromJson(json, cast(object), 0);
}
virtual QJsonObject toMemoizedJson(const void *object) const override
{
return CValueObjectMetaInfoHelper::toMemoizedJson(cast(object), 0);
}
virtual void convertFromMemoizedJson(const QJsonObject &json, void *object) const override
{
CValueObjectMetaInfoHelper::convertFromMemoizedJson(json, cast(object), 0);
}
virtual void unmarshall(const QDBusArgument &arg, void *object) const override
{
arg >> cast(object);