stdvariantconverter.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "stdvariantconverter_p.h"
  2. #include "exception.h"
  3. using namespace QtJsonSerializer;
  4. using namespace QtJsonSerializer::TypeConverters;
  5. bool StdVariantConverter::canConvert(int metaTypeId) const
  6. {
  7. const auto extractor = helper()->extractor(metaTypeId);
  8. return extractor && extractor->baseType() == "variant";
  9. }
  10. QList<QCborValue::Type> StdVariantConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  11. {
  12. Q_UNUSED(metaTypeId)
  13. Q_UNUSED(tag)
  14. QList<QCborValue::Type> types;
  15. const auto metaEnum = QMetaEnum::fromType<QCborValue::Type>();
  16. types.reserve(metaEnum.keyCount());
  17. for (auto i = 0; i < metaEnum.keyCount(); ++i) {
  18. if (const auto value = metaEnum.value(i); value != QCborValue::Invalid)
  19. types.append(static_cast<QCborValue::Type>(value));
  20. }
  21. return types;
  22. }
  23. QCborValue StdVariantConverter::serialize(int propertyType, const QVariant &value) const
  24. {
  25. const auto extractor = helper()->extractor(propertyType);
  26. if (!extractor) {
  27. throw SerializationException(QByteArray("Failed to get extractor for type ") +
  28. QMetaTypeName(propertyType) +
  29. QByteArray(". Make shure to register std::variant types via QJsonSerializer::registerVariantConverters"));
  30. }
  31. const auto metaTypes = extractor->subtypes();
  32. const auto cValue = extractor->extract(value);
  33. const auto mIndex = metaTypes.indexOf(cValue.userType());
  34. if (mIndex == -1) {
  35. throw SerializationException(QByteArray("Invalid value given for type ") +
  36. QMetaTypeName(propertyType) +
  37. QByteArray(" - was ") +
  38. value.typeName() +
  39. QByteArray(", which is not a type of the given variant"));
  40. }
  41. return helper()->serializeSubtype(metaTypes[mIndex], cValue, QByteArray{"<"} + QMetaTypeName(metaTypes[mIndex]) + QByteArray{">"});
  42. }
  43. QVariant StdVariantConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  44. {
  45. const auto extractor = helper()->extractor(propertyType);
  46. if (!extractor) {
  47. throw DeserializationException(QByteArray("Failed to get extractor for type ") +
  48. QMetaTypeName(propertyType) +
  49. QByteArray(". Make shure to register std::variant types via QJsonSerializer::registerVariantConverters"));
  50. }
  51. // try all types until one succeeds
  52. for (auto metaType : extractor->subtypes()) {
  53. // ignore exceptions and try with the next type
  54. try {
  55. auto result = helper()->deserializeSubtype(metaType, value, parent, QByteArray{"<"} + QMetaTypeName(metaType) + QByteArray{">"});
  56. extractor->emplace(result, result);
  57. return result;
  58. } catch (DeserializationException &) {}
  59. }
  60. throw DeserializationException(QByteArray("Failed to deserialze value to ") +
  61. QMetaTypeName(propertyType) +
  62. QByteArray(" because all possible sub-type converters rejected the passed value."));
  63. }