typeconverter.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #ifndef QTJSONSERIALIZER_TYPECONVERTER_H
  2. #define QTJSONSERIALIZER_TYPECONVERTER_H
  3. #include "qtjsonserializer_global.h"
  4. #include <type_traits>
  5. #include <limits>
  6. #include <QtCore/qmetatype.h>
  7. #include <QtCore/qmetaobject.h>
  8. #include <QtCore/qjsonvalue.h>
  9. #include <QtCore/qcborvalue.h>
  10. #include <QtCore/qvariant.h>
  11. #include <QtCore/qsharedpointer.h>
  12. namespace QtJsonSerializer {
  13. //! Interface to extract data from any generic container
  14. class Q_JSONSERIALIZER_EXPORT TypeExtractor
  15. {
  16. Q_DISABLE_COPY(TypeExtractor)
  17. public:
  18. TypeExtractor();
  19. virtual ~TypeExtractor();
  20. //! Returns the identifier of the general type this extractor is for
  21. virtual QByteArray baseType() const = 0;
  22. //! Returns an ordered list of subtypes found in types handled by this extractor
  23. virtual QList<int> subtypes() const = 0;
  24. //! Extracts the data of a value of the extractors type at the given index
  25. virtual QVariant extract(const QVariant &value, int index = -1) const = 0;
  26. //! Emplaces the value into the target of the extractors type at the given index
  27. virtual void emplace(QVariant &target, const QVariant &value, int index = -1) const = 0;
  28. };
  29. class TypeConverterPrivate;
  30. //! An interface to create custom serializer type converters
  31. class Q_JSONSERIALIZER_EXPORT TypeConverter
  32. {
  33. Q_DISABLE_COPY(TypeConverter)
  34. public:
  35. //! A placeholder tag to be used if no tag is expected/allowed/given
  36. static constexpr auto NoTag = static_cast<QCborTag>(std::numeric_limits<std::underlying_type_t<QCborTag>>::max());
  37. //! Sample values for a priority value (default converters are mostly Standard and are guaranteed to be between Low and High)
  38. enum Priority : int {
  39. ExtremlyLow = -0x00FFFFFF,
  40. VeryLow = -0x0000FFFF,
  41. Low = -0x000000FF,
  42. Standard = 0x00000000,
  43. High = 0x000000FF,
  44. VeryHigh = 0x0000FFFF,
  45. ExtremlyHigh = 0x00FFFFFF
  46. };
  47. //! The possible results of canDeserialize(), used internally only
  48. enum DeserializationCapabilityResult : int {
  49. Positive = 1, //!< The converter can deserialize the given data
  50. Guessed = 2, //!< The converter guessed a type for the given data
  51. Negative = -1, //!< The converter cannot deserialize the given data
  52. WrongTag = -2 //!< The converter could deserialize the given data, but the tag does not match
  53. };
  54. //! Helper class passed to the type converter by the serializer. Do not implement yourself
  55. class Q_JSONSERIALIZER_EXPORT SerializationHelper
  56. {
  57. Q_DISABLE_COPY(SerializationHelper)
  58. public:
  59. SerializationHelper();
  60. virtual ~SerializationHelper();
  61. //! Returns true, if de/serializing to JSON, and false for CBOR
  62. virtual bool jsonMode() const = 0;
  63. //! Returns a property from the serializer
  64. virtual QVariant getProperty(const char *name) const = 0;
  65. //! Returns a tag registered for the given metaTypeId
  66. virtual QCborTag typeTag(int metaTypeId) const = 0;
  67. //! Returns a reference to an extractor for the given type, or nullptr
  68. virtual QSharedPointer<const TypeExtractor> extractor(int metaTypeId) const = 0;
  69. //! Serialize a subvalue, represented by a meta property
  70. virtual QCborValue serializeSubtype(const QMetaProperty &property, const QVariant &value) const = 0;
  71. //! Serialize a subvalue, represented by a type id
  72. virtual QCborValue serializeSubtype(int propertyType, const QVariant &value, const QByteArray &traceHint = {}) const = 0;
  73. //! Deserialize a subvalue, represented by a meta property
  74. virtual QVariant deserializeSubtype(const QMetaProperty &property, const QCborValue &value, QObject *parent) const = 0;
  75. //! Deserialize a subvalue, represented by a type id
  76. virtual QVariant deserializeSubtype(int propertyType, const QCborValue &value, QObject *parent, const QByteArray &traceHint = {}) const = 0;
  77. };
  78. //! Constructor
  79. TypeConverter();
  80. //! Destructor
  81. virtual ~TypeConverter();
  82. //! The name of the converter. Used for debugging purpose
  83. virtual QByteArray name() const = 0;
  84. //! Returns the priority of this converter
  85. int priority() const;
  86. //! Sets the priority of this converter
  87. void setPriority(int priority);
  88. //! Returns the helper associated with this converter
  89. const SerializationHelper *helper() const;
  90. //! @private
  91. void setHelper(const SerializationHelper *helper);
  92. //! Returns true, if this implementation can convert the given type
  93. virtual bool canConvert(int metaTypeId) const = 0;
  94. //! Returns a list of allowed tags for the given type
  95. virtual QList<QCborTag> allowedCborTags(int metaTypeId) const;
  96. //! Returns a list of allowed types for the given type and tag
  97. virtual QList<QCborValue::Type> allowedCborTypes(int metaTypeId, QCborTag tag) const = 0;
  98. //! Returns a type guessed from the tag and data, that is supported by the converter
  99. virtual int guessType(QCborTag tag, QCborValue::Type dataType) const;
  100. //! @private
  101. DeserializationCapabilityResult canDeserialize(int &metaTypeId,
  102. QCborTag tag,
  103. QCborValue::Type dataType) const;
  104. //! Called by the serializer to serializer your given type to CBOR
  105. virtual QCborValue serialize(int propertyType, const QVariant &value) const = 0;
  106. //! Called by the serializer to deserializer your given type from CBOR
  107. virtual QVariant deserializeCbor(int propertyType, const QCborValue &value, QObject *parent) const = 0;
  108. //! Called by the serializer to deserializer your given type from JSON
  109. virtual QVariant deserializeJson(int propertyType, const QCborValue &value, QObject *parent) const;
  110. private:
  111. QScopedPointer<TypeConverterPrivate> d;
  112. void mapTypesToJson(QList<QCborValue::Type> &typeList) const;
  113. };
  114. //! Macro to implement the TypeConverter::name method in a subclass
  115. #define QT_JSONSERIALIZER_TYPECONVERTER_NAME(className) inline QByteArray name() const override { \
  116. static_assert(std::is_same_v<className, std::decay_t<decltype(*this)>>); \
  117. return QByteArrayLiteral(#className); \
  118. }
  119. //! A factory interface to create instances of QJsonTypeConverters
  120. class Q_JSONSERIALIZER_EXPORT TypeConverterFactory
  121. {
  122. Q_DISABLE_COPY(TypeConverterFactory)
  123. public:
  124. TypeConverterFactory();
  125. virtual ~TypeConverterFactory();
  126. //! The primary factory method to create converters
  127. virtual QSharedPointer<TypeConverter> createConverter() const = 0;
  128. };
  129. //! A template implementation of TypeConverterFactory to generically create simply converters
  130. template <typename TConverter, int OverwritePriority = TypeConverter::Priority::Standard>
  131. class TypeConverterStandardFactory : public TypeConverterFactory
  132. {
  133. public:
  134. QSharedPointer<TypeConverter> createConverter() const override;
  135. };
  136. // ------------- GENERIC IMPLEMENTATION -------------
  137. template<typename TConverter, int OverwritePriority>
  138. QSharedPointer<TypeConverter> TypeConverterStandardFactory<TConverter, OverwritePriority>::createConverter() const
  139. {
  140. auto converter = QSharedPointer<TConverter>::create();
  141. if (OverwritePriority != TypeConverter::Priority::Standard)
  142. converter->setPriority(OverwritePriority);
  143. return converter;
  144. }
  145. }
  146. #endif // QTJSONSERIALIZER_TYPECONVERTER_H