stdchronodurationconverter.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "stdchronodurationconverter_p.h"
  2. #include "cborserializer.h"
  3. #include <QtCore/QSet>
  4. using namespace QtJsonSerializer;
  5. using namespace QtJsonSerializer::TypeConverters;
  6. using namespace std::chrono;
  7. Q_DECLARE_METATYPE(std::chrono::nanoseconds)
  8. Q_DECLARE_METATYPE(std::chrono::microseconds)
  9. Q_DECLARE_METATYPE(std::chrono::milliseconds)
  10. Q_DECLARE_METATYPE(std::chrono::seconds)
  11. Q_DECLARE_METATYPE(std::chrono::minutes)
  12. Q_DECLARE_METATYPE(std::chrono::hours)
  13. bool StdChronoDurationConverter::canConvert(int metaTypeId) const
  14. {
  15. static const QSet<int> metaTypeIdList {
  16. qMetaTypeId<nanoseconds>(),
  17. qMetaTypeId<microseconds>(),
  18. qMetaTypeId<milliseconds>(),
  19. qMetaTypeId<seconds>(),
  20. qMetaTypeId<minutes>(),
  21. qMetaTypeId<hours>()
  22. };
  23. return metaTypeIdList.contains(metaTypeId);
  24. }
  25. QList<QCborTag> StdChronoDurationConverter::allowedCborTags(int metaTypeId) const
  26. {
  27. static const QList<QCborTag> tags {
  28. static_cast<QCborTag>(CborSerializer::ChronoNanoSeconds),
  29. static_cast<QCborTag>(CborSerializer::ChronoMicroSeconds),
  30. static_cast<QCborTag>(CborSerializer::ChronoMilliSeconds),
  31. static_cast<QCborTag>(CborSerializer::ChronoSeconds),
  32. static_cast<QCborTag>(CborSerializer::ChronoMinutes),
  33. static_cast<QCborTag>(CborSerializer::ChronoHours)
  34. };
  35. if (metaTypeId == qMetaTypeId<nanoseconds>())
  36. return tags;
  37. else if (metaTypeId == qMetaTypeId<microseconds>())
  38. return tags.mid(1);
  39. else if (metaTypeId == qMetaTypeId<milliseconds>())
  40. return tags.mid(2);
  41. else if (metaTypeId == qMetaTypeId<seconds>())
  42. return tags.mid(3);
  43. else if (metaTypeId == qMetaTypeId<minutes>())
  44. return tags.mid(4);
  45. else if (metaTypeId == qMetaTypeId<hours>())
  46. return tags.mid(5);
  47. else
  48. Q_UNREACHABLE();
  49. }
  50. QList<QCborValue::Type> StdChronoDurationConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  51. {
  52. Q_UNUSED(metaTypeId)
  53. Q_UNUSED(tag)
  54. return {QCborValue::Integer};
  55. }
  56. int StdChronoDurationConverter::guessType(QCborTag tag, QCborValue::Type dataType) const
  57. {
  58. if (dataType != QCborValue::Integer)
  59. return QMetaType::UnknownType;
  60. switch (static_cast<quint64>(tag)) {
  61. case CborSerializer::ChronoNanoSeconds:
  62. return qMetaTypeId<nanoseconds>();
  63. case CborSerializer::ChronoMicroSeconds:
  64. return qMetaTypeId<microseconds>();
  65. case CborSerializer::ChronoMilliSeconds:
  66. return qMetaTypeId<milliseconds>();
  67. case CborSerializer::ChronoSeconds:
  68. return qMetaTypeId<seconds>();
  69. case CborSerializer::ChronoMinutes:
  70. return qMetaTypeId<minutes>();
  71. case CborSerializer::ChronoHours:
  72. return qMetaTypeId<hours>();
  73. default:
  74. return QMetaType::UnknownType;
  75. }
  76. }
  77. QCborValue StdChronoDurationConverter::serialize(int propertyType, const QVariant &value) const
  78. {
  79. const auto tag = tagForType(propertyType);
  80. switch (static_cast<quint64>(tag)) {
  81. case CborSerializer::ChronoNanoSeconds:
  82. return {tag, static_cast<qint64>(value.value<nanoseconds>().count())};
  83. case CborSerializer::ChronoMicroSeconds:
  84. return {tag, static_cast<qint64>(value.value<microseconds>().count())};
  85. case CborSerializer::ChronoMilliSeconds:
  86. return {tag, static_cast<qint64>(value.value<milliseconds>().count())};
  87. case CborSerializer::ChronoSeconds:
  88. return {tag, static_cast<qint64>(value.value<seconds>().count())};
  89. case CborSerializer::ChronoMinutes:
  90. return {tag, static_cast<qint64>(value.value<minutes>().count())};
  91. case CborSerializer::ChronoHours:
  92. return {tag, static_cast<qint64>(value.value<hours>().count())};
  93. default:
  94. Q_UNREACHABLE();
  95. }
  96. }
  97. QVariant StdChronoDurationConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  98. {
  99. Q_UNUSED(parent)
  100. const auto metaDuration = parseValue(propertyType, value, helper());
  101. if (propertyType == qMetaTypeId<nanoseconds>())
  102. return QVariant::fromValue(cast<nanoseconds>(metaDuration));
  103. else if (propertyType == qMetaTypeId<microseconds>())
  104. return QVariant::fromValue(cast<microseconds>(metaDuration));
  105. else if (propertyType == qMetaTypeId<milliseconds>())
  106. return QVariant::fromValue(cast<milliseconds>(metaDuration));
  107. else if (propertyType == qMetaTypeId<seconds>())
  108. return QVariant::fromValue(cast<seconds>(metaDuration));
  109. else if (propertyType == qMetaTypeId<minutes>())
  110. return QVariant::fromValue(cast<minutes>(metaDuration));
  111. else if (propertyType == qMetaTypeId<hours>())
  112. return QVariant::fromValue(cast<hours>(metaDuration));
  113. else
  114. throw SerializationException{"Invalid type id"};
  115. }
  116. QCborTag StdChronoDurationConverter::tagForType(int metaTypeId) const
  117. {
  118. if (metaTypeId == qMetaTypeId<nanoseconds>())
  119. return static_cast<QCborTag>(CborSerializer::ChronoNanoSeconds);
  120. else if (metaTypeId == qMetaTypeId<microseconds>())
  121. return static_cast<QCborTag>(CborSerializer::ChronoMicroSeconds);
  122. else if (metaTypeId == qMetaTypeId<milliseconds>())
  123. return static_cast<QCborTag>(CborSerializer::ChronoMilliSeconds);
  124. else if (metaTypeId == qMetaTypeId<seconds>())
  125. return static_cast<QCborTag>(CborSerializer::ChronoSeconds);
  126. else if (metaTypeId == qMetaTypeId<minutes>())
  127. return static_cast<QCborTag>(CborSerializer::ChronoMinutes);
  128. else if (metaTypeId == qMetaTypeId<hours>())
  129. return static_cast<QCborTag>(CborSerializer::ChronoHours);
  130. else
  131. throw SerializationException{"Invalid type id"};
  132. }
  133. StdChronoDurationConverter::MetaDuration StdChronoDurationConverter::parseValue(int propertyType, const QCborValue &value, const TypeConverter::SerializationHelper *localHelper) const
  134. {
  135. const auto rTag = value.isTag() ? value.tag() : NoTag;
  136. switch (static_cast<quint64>(rTag)) {
  137. case CborSerializer::ChronoNanoSeconds:
  138. return create<nanoseconds>(value);
  139. case CborSerializer::ChronoMicroSeconds:
  140. return create<microseconds>(value);
  141. case CborSerializer::ChronoMilliSeconds:
  142. return create<milliseconds>(value);
  143. case CborSerializer::ChronoSeconds:
  144. return create<seconds>(value);
  145. case CborSerializer::ChronoMinutes:
  146. return create<minutes>(value);
  147. case CborSerializer::ChronoHours:
  148. return create<hours>(value);
  149. default:
  150. if (!localHelper || rTag != localHelper->typeTag(propertyType))
  151. throw DeserializationException{"Invalid CBOR tag " + QByteArray::number(static_cast<quint64>(value.tag()))};
  152. Q_FALLTHROUGH();
  153. case static_cast<quint64>(NoTag):
  154. if (auto vTag = tagForType(propertyType); vTag != NoTag)
  155. return parseValue(QMetaType::UnknownType, {vTag, value.isTag() ? value.taggedValue() : value}, nullptr);
  156. else
  157. throw SerializationException{"Invalid state reached - no CBOR tag was given, but the property type is not a chrono type"};
  158. }
  159. }