mapconverter.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "mapconverter_p.h"
  2. #include "exception.h"
  3. #include "cborserializer.h"
  4. #include "metawriters.h"
  5. #include <QtCore/QJsonObject>
  6. using namespace QtJsonSerializer;
  7. using namespace QtJsonSerializer::TypeConverters;
  8. using namespace QtJsonSerializer::MetaWriters;
  9. bool MapConverter::canConvert(int metaTypeId) const
  10. {
  11. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  12. const QVariant tValue{metaTypeId, nullptr};
  13. return (tValue.canConvert(QMetaType::QVariantMap) ||
  14. tValue.canConvert(QMetaType::QVariantHash)) &&
  15. AssociativeWriter::canWrite(metaTypeId);
  16. #else
  17. const QVariant tValue{QMetaType(metaTypeId), nullptr};
  18. return (tValue.canConvert(QMetaType(QMetaType::QVariantMap)) ||
  19. tValue.canConvert(QMetaType(QMetaType::QVariantHash))) &&
  20. AssociativeWriter::canWrite(metaTypeId);
  21. #endif
  22. }
  23. QList<QCborTag> MapConverter::allowedCborTags(int metaTypeId) const
  24. {
  25. Q_UNUSED(metaTypeId)
  26. return {NoTag, static_cast<QCborTag>(CborSerializer::ExplicitMap)};
  27. }
  28. QList<QCborValue::Type> MapConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  29. {
  30. Q_UNUSED(metaTypeId)
  31. Q_UNUSED(tag)
  32. return {QCborValue::Map};
  33. }
  34. QCborValue MapConverter::serialize(int propertyType, const QVariant &value) const
  35. {
  36. const auto info = AssociativeWriter::getInfo(propertyType);
  37. // verify is readable
  38. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  39. if (!value.canConvert(QMetaType::QVariantMap) &&
  40. !value.canConvert(QMetaType::QVariantHash)) {
  41. #else
  42. if (!value.canConvert(QMetaType(QMetaType::QVariantMap)) &&
  43. !value.canConvert(QMetaType(QMetaType::QVariantHash))) {
  44. #endif
  45. throw SerializationException(QByteArray("Given type ") +
  46. QMetaTypeName(propertyType) +
  47. QByteArray(" cannot be processed via QAssociativeIterable - make shure to register the container type via Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE"));
  48. }
  49. // write from map to cbor
  50. const auto iterable = value.value<QAssociativeIterable>();
  51. QCborMap cborMap;
  52. for (auto it = iterable.begin(), end = iterable.end(); it != end; ++it) {
  53. const QByteArray keyStr = "[" + it.key().toString().toUtf8() + "]";
  54. cborMap.insert(helper()->serializeSubtype(info.keyType, it.key(), keyStr + ".key"),
  55. helper()->serializeSubtype(info.valueType, it.value(), keyStr + ".value"));
  56. }
  57. return cborMap;
  58. }
  59. QVariant MapConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  60. {
  61. //generate the map
  62. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  63. QVariant map{propertyType, nullptr};
  64. #else
  65. QVariant map{QMetaType(propertyType), nullptr};
  66. #endif
  67. auto writer = AssociativeWriter::getWriter(map);
  68. if (!writer) {
  69. throw DeserializationException(QByteArray("Given type ") +
  70. QMetaTypeName(propertyType) +
  71. QByteArray(" cannot be accessed via QAssociativeWriter - make shure to register it via QJsonSerializerBase::registerMapConverters"));
  72. }
  73. // write from cbor into the map
  74. const auto info = writer->info();
  75. const auto cborMap = (value.isTag() ? value.taggedValue() : value).toMap();
  76. for (const auto entry : cborMap) {
  77. const QByteArray keyStr = "[" + entry.first.toVariant().toString().toUtf8() + "]";
  78. writer->add(helper()->deserializeSubtype(info.keyType, entry.first, parent, keyStr + ".key"),
  79. helper()->deserializeSubtype(info.valueType, entry.second, parent, keyStr + ".value"));
  80. }
  81. return map;
  82. }