#include "stdchronodurationconverter_p.h" #include "cborserializer.h" #include using namespace QtJsonSerializer; using namespace QtJsonSerializer::TypeConverters; using namespace std::chrono; Q_DECLARE_METATYPE(std::chrono::nanoseconds) Q_DECLARE_METATYPE(std::chrono::microseconds) Q_DECLARE_METATYPE(std::chrono::milliseconds) Q_DECLARE_METATYPE(std::chrono::seconds) Q_DECLARE_METATYPE(std::chrono::minutes) Q_DECLARE_METATYPE(std::chrono::hours) bool StdChronoDurationConverter::canConvert(int metaTypeId) const { static const QSet metaTypeIdList { qMetaTypeId(), qMetaTypeId(), qMetaTypeId(), qMetaTypeId(), qMetaTypeId(), qMetaTypeId() }; return metaTypeIdList.contains(metaTypeId); } QList StdChronoDurationConverter::allowedCborTags(int metaTypeId) const { static const QList tags { static_cast(CborSerializer::ChronoNanoSeconds), static_cast(CborSerializer::ChronoMicroSeconds), static_cast(CborSerializer::ChronoMilliSeconds), static_cast(CborSerializer::ChronoSeconds), static_cast(CborSerializer::ChronoMinutes), static_cast(CborSerializer::ChronoHours) }; if (metaTypeId == qMetaTypeId()) return tags; else if (metaTypeId == qMetaTypeId()) return tags.mid(1); else if (metaTypeId == qMetaTypeId()) return tags.mid(2); else if (metaTypeId == qMetaTypeId()) return tags.mid(3); else if (metaTypeId == qMetaTypeId()) return tags.mid(4); else if (metaTypeId == qMetaTypeId()) return tags.mid(5); else Q_UNREACHABLE(); } QList StdChronoDurationConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const { Q_UNUSED(metaTypeId) Q_UNUSED(tag) return {QCborValue::Integer}; } int StdChronoDurationConverter::guessType(QCborTag tag, QCborValue::Type dataType) const { if (dataType != QCborValue::Integer) return QMetaType::UnknownType; switch (static_cast(tag)) { case CborSerializer::ChronoNanoSeconds: return qMetaTypeId(); case CborSerializer::ChronoMicroSeconds: return qMetaTypeId(); case CborSerializer::ChronoMilliSeconds: return qMetaTypeId(); case CborSerializer::ChronoSeconds: return qMetaTypeId(); case CborSerializer::ChronoMinutes: return qMetaTypeId(); case CborSerializer::ChronoHours: return qMetaTypeId(); default: return QMetaType::UnknownType; } } QCborValue StdChronoDurationConverter::serialize(int propertyType, const QVariant &value) const { const auto tag = tagForType(propertyType); switch (static_cast(tag)) { case CborSerializer::ChronoNanoSeconds: return {tag, static_cast(value.value().count())}; case CborSerializer::ChronoMicroSeconds: return {tag, static_cast(value.value().count())}; case CborSerializer::ChronoMilliSeconds: return {tag, static_cast(value.value().count())}; case CborSerializer::ChronoSeconds: return {tag, static_cast(value.value().count())}; case CborSerializer::ChronoMinutes: return {tag, static_cast(value.value().count())}; case CborSerializer::ChronoHours: return {tag, static_cast(value.value().count())}; default: Q_UNREACHABLE(); } } QVariant StdChronoDurationConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const { Q_UNUSED(parent) const auto metaDuration = parseValue(propertyType, value, helper()); if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else if (propertyType == qMetaTypeId()) return QVariant::fromValue(cast(metaDuration)); else throw SerializationException{"Invalid type id"}; } QCborTag StdChronoDurationConverter::tagForType(int metaTypeId) const { if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoNanoSeconds); else if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoMicroSeconds); else if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoMilliSeconds); else if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoSeconds); else if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoMinutes); else if (metaTypeId == qMetaTypeId()) return static_cast(CborSerializer::ChronoHours); else throw SerializationException{"Invalid type id"}; } StdChronoDurationConverter::MetaDuration StdChronoDurationConverter::parseValue(int propertyType, const QCborValue &value, const TypeConverter::SerializationHelper *localHelper) const { const auto rTag = value.isTag() ? value.tag() : NoTag; switch (static_cast(rTag)) { case CborSerializer::ChronoNanoSeconds: return create(value); case CborSerializer::ChronoMicroSeconds: return create(value); case CborSerializer::ChronoMilliSeconds: return create(value); case CborSerializer::ChronoSeconds: return create(value); case CborSerializer::ChronoMinutes: return create(value); case CborSerializer::ChronoHours: return create(value); default: if (!localHelper || rTag != localHelper->typeTag(propertyType)) throw DeserializationException{"Invalid CBOR tag " + QByteArray::number(static_cast(value.tag()))}; Q_FALLTHROUGH(); case static_cast(NoTag): if (auto vTag = tagForType(propertyType); vTag != NoTag) return parseValue(QMetaType::UnknownType, {vTag, value.isTag() ? value.taggedValue() : value}, nullptr); else throw SerializationException{"Invalid state reached - no CBOR tag was given, but the property type is not a chrono type"}; } }