legacygeomconverter.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "legacygeomconverter_p.h"
  2. #include "exception.h"
  3. #include <QtCore/QCborMap>
  4. using namespace QtJsonSerializer;
  5. using namespace QtJsonSerializer::TypeConverters;
  6. LegacyGeomConverter::LegacyGeomConverter()
  7. {
  8. setPriority(Priority::VeryLow);
  9. }
  10. bool LegacyGeomConverter::canConvert(int metaTypeId) const
  11. {
  12. static const QVector<int> types {
  13. QMetaType::QSize,
  14. QMetaType::QSizeF,
  15. QMetaType::QPoint,
  16. QMetaType::QPointF,
  17. QMetaType::QLine,
  18. QMetaType::QLineF,
  19. QMetaType::QRect,
  20. QMetaType::QRectF,
  21. };
  22. return types.contains(metaTypeId);
  23. }
  24. QList<QCborValue::Type> LegacyGeomConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  25. {
  26. Q_UNUSED(metaTypeId)
  27. Q_UNUSED(tag)
  28. return {QCborValue::Map};
  29. }
  30. QCborValue LegacyGeomConverter::serialize(int propertyType, const QVariant &value) const
  31. {
  32. Q_UNUSED(propertyType)
  33. Q_UNUSED(value)
  34. throw SerializationException{"The QJsonLegacyGeomConverter cannot serialize data"};
  35. }
  36. QVariant LegacyGeomConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  37. {
  38. Q_UNUSED(propertyType)
  39. Q_UNUSED(value)
  40. Q_UNUSED(parent)
  41. throw DeserializationException{"The QJsonLegacyGeomConverter cannot deserialize CBOR data"};
  42. }
  43. QVariant LegacyGeomConverter::deserializeJson(int propertyType, const QCborValue &value, QObject *parent) const
  44. {
  45. Q_UNUSED(parent)
  46. const auto map = value.toMap();
  47. switch (propertyType) {
  48. case QMetaType::QSize:
  49. return deserializeSize<QSize>(map);
  50. case QMetaType::QSizeF:
  51. return deserializeSize<QSizeF>(map);
  52. case QMetaType::QPoint:
  53. return deserializePoint<QPoint>(map);
  54. case QMetaType::QPointF:
  55. return deserializePoint<QPointF>(map);
  56. case QMetaType::QLine:
  57. return deserializeLine<QLine>(map);
  58. case QMetaType::QLineF:
  59. return deserializeLine<QLineF>(map);
  60. case QMetaType::QRect:
  61. return deserializeRect<QRect>(map);
  62. case QMetaType::QRectF:
  63. return deserializeRect<QRectF>(map);
  64. default:
  65. throw DeserializationException{"Invalid type id"};
  66. }
  67. }
  68. template<typename TSize>
  69. TSize LegacyGeomConverter::deserializeSize(const QCborMap &map) const
  70. {
  71. using TW = std::decay_t<decltype(TSize{}.width())>;
  72. using TH = std::decay_t<decltype(TSize{}.height())>;
  73. if (map.size() != 2 ||
  74. !map.contains(QStringLiteral("width")) ||
  75. !map.contains(QStringLiteral("height")))
  76. throw DeserializationException("JSON object has no width or height properties or does have extra properties");
  77. return {
  78. extract<TW>(map[QStringLiteral("width")]),
  79. extract<TH>(map[QStringLiteral("height")])
  80. };
  81. }
  82. template<typename TPoint>
  83. TPoint LegacyGeomConverter::deserializePoint(const QCborMap &map) const
  84. {
  85. using TX = std::decay_t<decltype(TPoint{}.x())>;
  86. using TY = std::decay_t<decltype(TPoint{}.y())>;
  87. if (map.size() != 2 ||
  88. !map.contains(QStringLiteral("x")) ||
  89. !map.contains(QStringLiteral("y")))
  90. throw DeserializationException("JSON object has no x or y properties or does have extra properties");
  91. return {
  92. extract<TX>(map[QStringLiteral("x")]),
  93. extract<TY>(map[QStringLiteral("y")])
  94. };
  95. }
  96. template<typename TLine>
  97. TLine LegacyGeomConverter::deserializeLine(const QCborMap &map) const
  98. {
  99. using TP1 = std::decay_t<decltype(TLine{}.p1())>;
  100. using TP2 = std::decay_t<decltype(TLine{}.p2())>;
  101. if (map.size() != 2 ||
  102. !map.contains(QStringLiteral("p1")) ||
  103. !map.contains(QStringLiteral("p2")))
  104. throw DeserializationException("JSON object has no p1 or p2 properties or does have extra properties");
  105. return {
  106. helper()->deserializeSubtype(qMetaTypeId<TP1>(), map[QStringLiteral("p1")], nullptr, "p1").template value<TP1>(),
  107. helper()->deserializeSubtype(qMetaTypeId<TP2>(), map[QStringLiteral("p2")], nullptr, "p2").template value<TP2>()
  108. };
  109. }
  110. template<typename TRect>
  111. TRect LegacyGeomConverter::deserializeRect(const QCborMap &map) const
  112. {
  113. using TTL = std::decay_t<decltype(TRect{}.topLeft())>;
  114. using TBR = std::decay_t<decltype(TRect{}.bottomRight())>;
  115. if (map.size() != 2 ||
  116. !map.contains(QStringLiteral("topLeft")) ||
  117. !map.contains(QStringLiteral("bottomRight")))
  118. throw DeserializationException("JSON object has no topLeft or bottomRight properties or does have extra properties");
  119. return {
  120. helper()->deserializeSubtype(qMetaTypeId<TTL>(), map[QStringLiteral("topLeft")], nullptr, "topLeft").template value<TTL>(),
  121. helper()->deserializeSubtype(qMetaTypeId<TBR>(), map[QStringLiteral("bottomRight")], nullptr, "bottomRight").template value<TBR>()
  122. };
  123. }
  124. template<>
  125. int LegacyGeomConverter::extract(const QCborValue &value) const
  126. {
  127. if (!value.isInteger())
  128. throw DeserializationException{"Expected integer, but got type " + QByteArray::number(value.type())};
  129. return static_cast<int>(value.toInteger());
  130. }
  131. template<>
  132. qreal LegacyGeomConverter::extract(const QCborValue &value) const
  133. {
  134. if (!value.isDouble() && !value.isInteger())
  135. throw DeserializationException{"Expected double, but got type " + QByteArray::number(value.type())};
  136. return value.toDouble();
  137. }