typeconverter.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "typeconverter.h"
  2. #include "serializerbase_p.h"
  3. using namespace QtJsonSerializer;
  4. namespace QtJsonSerializer {
  5. class TypeConverterPrivate
  6. {
  7. public:
  8. int priority = TypeConverter::Standard;
  9. const TypeConverter::SerializationHelper *helper = nullptr;
  10. };
  11. }
  12. TypeConverter::TypeConverter() :
  13. d{new TypeConverterPrivate{}}
  14. {}
  15. TypeConverter::~TypeConverter() = default;
  16. int TypeConverter::priority() const
  17. {
  18. return d->priority;
  19. }
  20. void TypeConverter::setPriority(int priority)
  21. {
  22. d->priority = priority;
  23. }
  24. const TypeConverter::SerializationHelper *TypeConverter::helper() const
  25. {
  26. return d->helper;
  27. }
  28. void TypeConverter::setHelper(const TypeConverter::SerializationHelper *helper)
  29. {
  30. d->helper = helper;
  31. }
  32. QList<QCborTag> TypeConverter::allowedCborTags(int metaTypeId) const
  33. {
  34. Q_UNUSED(metaTypeId)
  35. return {};
  36. }
  37. int TypeConverter::guessType(QCborTag tag, QCborValue::Type dataType) const
  38. {
  39. Q_UNUSED(tag)
  40. Q_UNUSED(dataType)
  41. return QMetaType::UnknownType;
  42. }
  43. TypeConverter::DeserializationCapabilityResult TypeConverter::canDeserialize(int &metaTypeId, QCborTag tag, QCborValue::Type dataType) const
  44. {
  45. const auto asJson = helper()->jsonMode();
  46. const auto strict = helper()->getProperty("validationFlags")
  47. .value<SerializerBase::ValidationFlags>()
  48. .testFlag(SerializerBase::ValidationFlag::StrictBasicTypes);
  49. // case A: a metaTypeId is present
  50. if (metaTypeId != QMetaType::UnknownType) {
  51. // first: verify the given metatype is supported
  52. if (!canConvert(metaTypeId))
  53. return DeserializationCapabilityResult::Negative;
  54. // second: verify the tag if not in json mode
  55. if (!asJson) {
  56. // if either we are in strict mode or a tag is given, the tag is verified
  57. if (strict || tag != NoTag) {
  58. // If there is a list of allowed tags, the given tag must be in it
  59. auto aTags = allowedCborTags(metaTypeId);
  60. // also, add the type specific override tag if set
  61. if (const auto xTag = helper()->typeTag(metaTypeId); xTag != NoTag)
  62. aTags.append(xTag);
  63. if (!aTags.isEmpty()) {
  64. if (!aTags.contains(tag))
  65. return DeserializationCapabilityResult::WrongTag;
  66. // otherwise, if in strict mode, an empty allowed tag list means the tag must not be set
  67. } else if (strict && tag != NoTag)
  68. return DeserializationCapabilityResult::WrongTag;
  69. }
  70. }
  71. // third: verify the datatype, based on type and tag
  72. auto aTypes = allowedCborTypes(metaTypeId, tag);
  73. // if in json mode, convert the supported types to their json equivalent
  74. if (asJson)
  75. mapTypesToJson(aTypes);
  76. // then verify them
  77. if (!aTypes.contains(dataType))
  78. return DeserializationCapabilityResult::Negative;
  79. return DeserializationCapabilityResult::Positive;
  80. // case B: no metaTypeId is present, we are in cbor mode and have a tag
  81. } else if (!asJson && tag != NoTag){
  82. // try to guess the id from tag and type
  83. metaTypeId = guessType(tag, dataType);
  84. if (metaTypeId != QMetaType::UnknownType)
  85. return DeserializationCapabilityResult::Guessed;
  86. else
  87. return DeserializationCapabilityResult::Negative;
  88. // otherwise: cannot convert
  89. } else
  90. return DeserializationCapabilityResult::Negative;
  91. }
  92. QVariant TypeConverter::deserializeJson(int propertyType, const QCborValue &value, QObject *parent) const
  93. {
  94. return deserializeCbor(propertyType, value, parent);
  95. }
  96. void TypeConverter::mapTypesToJson(QList<QCborValue::Type> &typeList) const
  97. {
  98. auto hasDouble = false;
  99. auto hasInt = false;
  100. for (auto &type : typeList) {
  101. switch (type) {
  102. case QCborValue::Double:
  103. hasDouble = true;
  104. break;
  105. case QCborValue::Integer:
  106. hasInt = true;
  107. break;
  108. case QCborValue::ByteArray:
  109. case QCborValue::DateTime:
  110. case QCborValue::Url:
  111. case QCborValue::RegularExpression:
  112. case QCborValue::Uuid:
  113. type = QCborValue::String;
  114. break;
  115. default:
  116. break;
  117. }
  118. }
  119. if (hasInt && !hasDouble)
  120. typeList.append(QCborValue::Double);
  121. if (hasDouble && !hasInt)
  122. typeList.append(QCborValue::Integer);
  123. }
  124. TypeConverter::SerializationHelper::SerializationHelper() = default;
  125. TypeConverter::SerializationHelper::~SerializationHelper() = default;
  126. TypeConverterFactory::TypeConverterFactory() = default;
  127. TypeConverterFactory::~TypeConverterFactory() = default;
  128. TypeExtractor::TypeExtractor() = default;
  129. TypeExtractor::~TypeExtractor() = default;
  130. QList<int> TypeExtractor::subtypes() const
  131. {
  132. return {};
  133. }