versionnumberconverter.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "versionnumberconverter_p.h"
  2. #include "exception.h"
  3. #include "cborserializer.h"
  4. #include <QtCore/QVersionNumber>
  5. using namespace QtJsonSerializer;
  6. using namespace QtJsonSerializer::TypeConverters;
  7. Q_LOGGING_CATEGORY(QtJsonSerializer::TypeConverters::logVersionConverter, "qt.jsonserializer.converter.versionnumber")
  8. bool VersionNumberConverter::canConvert(int metaTypeId) const
  9. {
  10. return metaTypeId == qMetaTypeId<QVersionNumber>();
  11. }
  12. QList<QCborTag> VersionNumberConverter::allowedCborTags(int metaTypeId) const
  13. {
  14. Q_UNUSED(metaTypeId)
  15. return {static_cast<QCborTag>(CborSerializer::VersionNumber)};
  16. }
  17. QList<QCborValue::Type> VersionNumberConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  18. {
  19. Q_UNUSED(metaTypeId)
  20. Q_UNUSED(tag)
  21. return {QCborValue::Array, QCborValue::String};
  22. }
  23. int VersionNumberConverter::guessType(QCborTag tag, QCborValue::Type dataType) const
  24. {
  25. if (tag == static_cast<QCborTag>(CborSerializer::VersionNumber) &&
  26. allowedCborTypes(QMetaType::UnknownType, tag).contains(dataType))
  27. return qMetaTypeId<QVersionNumber>();
  28. else
  29. return QMetaType::UnknownType;
  30. }
  31. QCborValue VersionNumberConverter::serialize(int propertyType, const QVariant &value) const
  32. {
  33. Q_UNUSED(propertyType)
  34. const auto version = value.value<QVersionNumber>();
  35. if (helper()->getProperty("versionAsString").toBool())
  36. return {static_cast<QCborTag>(CborSerializer::VersionNumber), version.toString()};
  37. else {
  38. QCborArray array;
  39. for (const auto segment : version.segments())
  40. array.append(segment);
  41. return {static_cast<QCborTag>(CborSerializer::VersionNumber), array};
  42. }
  43. }
  44. QVariant VersionNumberConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  45. {
  46. Q_UNUSED(propertyType)
  47. Q_UNUSED(parent)
  48. const auto cValue = (value.isTag() ? value.taggedValue() : value);
  49. if (cValue.type() == QCborValue::Array) {
  50. const auto cArray = cValue.toArray();
  51. QVector<int> segments;
  52. segments.reserve(static_cast<int>(cArray.size()));
  53. auto i = 0;
  54. for (const auto cElem : cArray) {
  55. if (!cElem.isInteger()) {
  56. throw DeserializationException{"Segment at position " + QByteArray::number(i) +
  57. " is not an integer - a version number must be integers only!"};
  58. }
  59. segments.append(static_cast<int>(cElem.toInteger()));
  60. ++i;
  61. }
  62. return QVariant::fromValue(QVersionNumber{std::move(segments)});
  63. } else if (cValue.type() == QCborValue::String) {
  64. const auto strValue = cValue.toString();
  65. if (!strValue.isEmpty()) {
  66. int suffixIndex = -1;
  67. const auto version = QVersionNumber::fromString(strValue, &suffixIndex);
  68. if (version.isNull())
  69. throw DeserializationException("Invalid version number, no segments found");
  70. if (suffixIndex < strValue.size())
  71. qCWarning(logVersionConverter) << "Parsed QVersionNumber with suffix - suffixes are discarded!";
  72. return QVariant::fromValue(version);
  73. } else
  74. return QVariant::fromValue(QVersionNumber{});
  75. } else
  76. throw DeserializationException{"Invalid type id"};
  77. }