stdtupleconverter.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "stdtupleconverter_p.h"
  2. #include "exception.h"
  3. #include "cborserializer.h"
  4. #include <QtCore/QCborArray>
  5. using namespace QtJsonSerializer;
  6. using namespace QtJsonSerializer::TypeConverters;
  7. bool StdTupleConverter::canConvert(int metaTypeId) const
  8. {
  9. const auto extractor = helper()->extractor(metaTypeId);
  10. return extractor && extractor->baseType() == "tuple";
  11. }
  12. QList<QCborTag> StdTupleConverter::allowedCborTags(int metaTypeId) const
  13. {
  14. Q_UNUSED(metaTypeId)
  15. return {static_cast<QCborTag>(CborSerializer::Tuple)};
  16. }
  17. QList<QCborValue::Type> StdTupleConverter::allowedCborTypes(int metaTypeId, QCborTag tag) const
  18. {
  19. Q_UNUSED(metaTypeId)
  20. Q_UNUSED(tag)
  21. return {QCborValue::Array};
  22. }
  23. QCborValue StdTupleConverter::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::tuple types via QJsonSerializer::registerTupleConverters"));
  30. }
  31. const auto metaTypes = extractor->subtypes();
  32. QCborArray array;
  33. auto max = metaTypes.size();
  34. for(auto i = 0; i < max; ++i)
  35. array.append(helper()->serializeSubtype(metaTypes[i], extractor->extract(value, i), "<" + QByteArray::number(i) + ">"));
  36. return {static_cast<QCborTag>(CborSerializer::Tuple), array};
  37. }
  38. QVariant StdTupleConverter::deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const
  39. {
  40. const auto extractor = helper()->extractor(propertyType);
  41. if (!extractor) {
  42. throw DeserializationException(QByteArray("Failed to get extractor for type ") +
  43. QMetaTypeName(propertyType) +
  44. QByteArray(". Make shure to register std::tuple types via QJsonSerializer::registerTupleConverters"));
  45. }
  46. const auto metaTypes = extractor->subtypes();
  47. const auto cArray = (value.isTag() ? value.taggedValue() : value).toArray();
  48. if (cArray.size() != metaTypes.size())
  49. throw DeserializationException{"Expected array with " + QByteArray::number(metaTypes.size()) +
  50. " elements, but got " + QByteArray::number(cArray.size()) + " instead"};
  51. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  52. QVariant tuple{propertyType, nullptr};
  53. #else
  54. QVariant tuple{QMetaType(propertyType), nullptr};
  55. #endif
  56. auto max = metaTypes.size();
  57. for(auto i = 0; i < max; ++i)
  58. extractor->emplace(tuple, helper()->deserializeSubtype(metaTypes[i], cArray[i], parent, "<" + QByteArray::number(i) + ">"), i);
  59. return tuple;
  60. }