#include "legacygeomconverter_p.h" #include "exception.h" #include using namespace QtJsonSerializer; using namespace QtJsonSerializer::TypeConverters; LegacyGeomConverter::LegacyGeomConverter() { setPriority(Priority::VeryLow); } bool LegacyGeomConverter::canConvert(int metaTypeId) const { static const QVector types { QMetaType::QSize, QMetaType::QSizeF, QMetaType::QPoint, QMetaType::QPointF, QMetaType::QLine, QMetaType::QLineF, QMetaType::QRect, QMetaType::QRectF, }; return types.contains(metaTypeId); } QList LegacyGeomConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const { Q_UNUSED(metaTypeId) Q_UNUSED(tag) return {QCborValue::Map}; } QCborValue LegacyGeomConverter::serialize(int propertyType, const QVariant &value) const { Q_UNUSED(propertyType) Q_UNUSED(value) throw SerializationException{"The QJsonLegacyGeomConverter cannot serialize data"}; } QVariant LegacyGeomConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const { Q_UNUSED(propertyType) Q_UNUSED(value) Q_UNUSED(parent) throw DeserializationException{"The QJsonLegacyGeomConverter cannot deserialize CBOR data"}; } QVariant LegacyGeomConverter::deserializeJson(int propertyType, const QCborValue &value, QObject *parent) const { Q_UNUSED(parent) const auto map = value.toMap(); switch (propertyType) { case QMetaType::QSize: return deserializeSize(map); case QMetaType::QSizeF: return deserializeSize(map); case QMetaType::QPoint: return deserializePoint(map); case QMetaType::QPointF: return deserializePoint(map); case QMetaType::QLine: return deserializeLine(map); case QMetaType::QLineF: return deserializeLine(map); case QMetaType::QRect: return deserializeRect(map); case QMetaType::QRectF: return deserializeRect(map); default: throw DeserializationException{"Invalid type id"}; } } template TSize LegacyGeomConverter::deserializeSize(const QCborMap &map) const { using TW = std::decay_t; using TH = std::decay_t; if (map.size() != 2 || !map.contains(QStringLiteral("width")) || !map.contains(QStringLiteral("height"))) throw DeserializationException("JSON object has no width or height properties or does have extra properties"); return { extract(map[QStringLiteral("width")]), extract(map[QStringLiteral("height")]) }; } template TPoint LegacyGeomConverter::deserializePoint(const QCborMap &map) const { using TX = std::decay_t; using TY = std::decay_t; if (map.size() != 2 || !map.contains(QStringLiteral("x")) || !map.contains(QStringLiteral("y"))) throw DeserializationException("JSON object has no x or y properties or does have extra properties"); return { extract(map[QStringLiteral("x")]), extract(map[QStringLiteral("y")]) }; } template TLine LegacyGeomConverter::deserializeLine(const QCborMap &map) const { using TP1 = std::decay_t; using TP2 = std::decay_t; if (map.size() != 2 || !map.contains(QStringLiteral("p1")) || !map.contains(QStringLiteral("p2"))) throw DeserializationException("JSON object has no p1 or p2 properties or does have extra properties"); return { helper()->deserializeSubtype(qMetaTypeId(), map[QStringLiteral("p1")], nullptr, "p1").template value(), helper()->deserializeSubtype(qMetaTypeId(), map[QStringLiteral("p2")], nullptr, "p2").template value() }; } template TRect LegacyGeomConverter::deserializeRect(const QCborMap &map) const { using TTL = std::decay_t; using TBR = std::decay_t; if (map.size() != 2 || !map.contains(QStringLiteral("topLeft")) || !map.contains(QStringLiteral("bottomRight"))) throw DeserializationException("JSON object has no topLeft or bottomRight properties or does have extra properties"); return { helper()->deserializeSubtype(qMetaTypeId(), map[QStringLiteral("topLeft")], nullptr, "topLeft").template value(), helper()->deserializeSubtype(qMetaTypeId(), map[QStringLiteral("bottomRight")], nullptr, "bottomRight").template value() }; } template<> int LegacyGeomConverter::extract(const QCborValue &value) const { if (!value.isInteger()) throw DeserializationException{"Expected integer, but got type " + QByteArray::number(value.type())}; return static_cast(value.toInteger()); } template<> qreal LegacyGeomConverter::extract(const QCborValue &value) const { if (!value.isDouble() && !value.isInteger()) throw DeserializationException{"Expected double, but got type " + QByteArray::number(value.type())}; return value.toDouble(); }