cborserializer.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #ifndef QTJSONSERIALIZER_CBORSERIALIZER_H
  2. #define QTJSONSERIALIZER_CBORSERIALIZER_H
  3. #include "qtjsonserializer_global.h"
  4. #include "jsonserializer/serializerbase.h"
  5. namespace QtJsonSerializer {
  6. class CborSerializerPrivate;
  7. //! A class to serialize and deserialize c++ classes to and from CBOR
  8. class Q_JSONSERIALIZER_EXPORT CborSerializer : public SerializerBase
  9. {
  10. Q_OBJECT
  11. //! If enabled, specially tagged number types will be automatically deserialized to their type
  12. Q_PROPERTY(bool handleSpecialNumbers READ handleSpecialNumbers WRITE setHandleSpecialNumbers NOTIFY handleSpecialNumbersChanged)
  13. public:
  14. //! Additional official CBOR-Tags, taken from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
  15. enum ExtendedTags : std::underlying_type_t<QCborTag> {
  16. GenericObject = 27, //!< Serialised language-independent object with type name and constructor arguments
  17. RationaleNumber = 30, //!< Rational number
  18. Identifier = 39, //!< Identifier
  19. Homogeneous = 41, //!< Homogeneous Array
  20. Set = 258, //!< Mathematical finite set
  21. ExplicitMap = 259, //!< Map datatype with key-value operations (e.g. `.get()/.set()/.delete()`)
  22. NetworkAddress = 260, //!< Network Address (IPv4 or IPv6 or MAC Address)
  23. NetworkAddressPrefix = 261, //!< Network Address Prefix (IPv4 or IPv6 Address + Mask Length)
  24. };
  25. Q_ENUM(ExtendedTags)
  26. // Additional unofficial CBOR-Tags, as defined by this library to tag Qt types for better typesafety
  27. enum CustomTags : std::underlying_type_t<QCborTag> {
  28. Color = 10000, //!< Tag used for QColor
  29. Font = 10001, //!< Tag used for QFont
  30. Enum = 10002, //!< Tag used for enums
  31. Flags = 10003, //!< Tag used for flags
  32. ConstructedObject = 10004, //!< Tag used for constructed object (GenericObject + standard object)
  33. Pair = 10005, //!< Tag used for QPair/std::pair
  34. MultiMap = 10006, //!< Tag used for QMultiMap/QMultiHash
  35. VersionNumber = 10007, //!< Tag used for QVersionNumber
  36. Tuple = 10008, //!< Tag used for std::tuple
  37. BitArray = 10009, //!< Tag used for QBitArray
  38. Date = 10010, //!< Tag used for QDate (short ISO format)
  39. Time = 10011, //!< Tag used for QTime (short ISO format)
  40. LocaleISO = 10100, //!< Tag used for QLocale, encoded via the ISO format
  41. LocaleBCP47 = 10101, //!< Tag used for QLocale, encoded via the BCP47 format
  42. GeomSize = 10110, //!< Tag used for QSize/QSizeF
  43. GeomPoint = 10111, //!< Tag used for QPoint/QPointF
  44. GeomLine = 10112, //!< Tag used for QLine/QLineF
  45. GeomRect = 10113, //!< Tag used for QRect/QRectF
  46. ChronoNanoSeconds = 10120, //!< Tag used for std::chrono::nanoseconds
  47. ChronoMicroSeconds = 10121, //!< Tag used for std::chrono::microseconds
  48. ChronoMilliSeconds = 10122, //!< Tag used for std::chrono::milliseconds
  49. ChronoSeconds = 10123, //!< Tag used for std::chrono::seconds
  50. ChronoMinutes = 10124, //!< Tag used for std::chrono::minutes
  51. ChronoHours = 10125, //!< Tag used for std::chrono::hours
  52. NoTag = std::numeric_limits<std::underlying_type_t<QCborTag>>::max() //!< Used as placeholder for setTypeTag to not change the tag
  53. };
  54. Q_ENUM(CustomTags)
  55. //! Default constructor
  56. explicit CborSerializer(QObject *parent = nullptr);
  57. //! @readAcFn{CborSerializer::handleSpecialNumbers}
  58. bool handleSpecialNumbers() const;
  59. //! Set a tag to always be used when serializing the given type
  60. template <typename T>
  61. void setTypeTag(QCborTag tag = static_cast<QCborTag>(NoTag));
  62. //! @copybrief CborSerializer::setTypeTag(QCborTag)
  63. void setTypeTag(int metaTypeId, QCborTag tag = static_cast<QCborTag>(NoTag));
  64. //! @copybrief TypeConverter::SerializationHelper::typeTag
  65. template <typename T>
  66. QCborTag typeTag() const;
  67. QCborTag typeTag(int metaTypeId) const override;
  68. //! Serializers a QVariant value to a QCborValue
  69. QCborValue serialize(const QVariant &data) const;
  70. //! Serializers a QVariant value to a device
  71. void serializeTo(QIODevice *device, const QVariant &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const;
  72. //! Serializers a QVariant value to a byte array
  73. QByteArray serializeTo(const QVariant &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const;
  74. //! Serializers a c++ type to cbor
  75. template <typename T>
  76. QCborValue serialize(const T &data) const;
  77. //! Serializers a c++ type to a device
  78. template <typename T>
  79. void serializeTo(QIODevice *device, const T &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const;
  80. //! Serializers a c++ type to a byte array
  81. template <typename T>
  82. QByteArray serializeTo(const T &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const;
  83. //! Deserializes a QCborValue to a QVariant value, based on the given type id
  84. QVariant deserialize(const QCborValue &cbor, int metaTypeId, QObject *parent = nullptr) const;
  85. //! Deserializes data from a device to a QVariant value, based on the given type id
  86. QVariant deserializeFrom(QIODevice *device, int metaTypeId, QObject *parent = nullptr) const;
  87. //! Deserializes data from a device to a QVariant value, based on the given type id
  88. QVariant deserializeFrom(const QByteArray &data, int metaTypeId, QObject *parent = nullptr) const;
  89. //! Deserializes cbor to the given c++ type
  90. template <typename T>
  91. T deserialize(const QCborValue &cbor, QObject *parent = nullptr) const;
  92. //! Deserializes data from a device to the given c++ type
  93. template <typename T>
  94. T deserializeFrom(QIODevice *device, QObject *parent = nullptr) const;
  95. //! Deserializes data from a byte array to the given c++ type
  96. template <typename T>
  97. T deserializeFrom(const QByteArray &data, QObject *parent = nullptr) const;
  98. std::variant<QCborValue, QJsonValue> serializeGeneric(const QVariant &value) const override;
  99. QVariant deserializeGeneric(const std::variant<QCborValue, QJsonValue> &value, int metaTypeId, QObject *parent) const override;
  100. public Q_SLOTS:
  101. //! @writeAcFn{CborSerializer::handleSpecialNumbers}
  102. void setHandleSpecialNumbers(bool handleSpecialNumbers);
  103. Q_SIGNALS:
  104. //! @notifyAcFn{CborSerializer::handleSpecialNumbers}
  105. void handleSpecialNumbersChanged(bool handleSpecialNumbers, QPrivateSignal);
  106. protected:
  107. // protected implementation -> internal use for the type converters
  108. bool jsonMode() const override;
  109. QList<int> typesForTag(QCborTag tag) const override;
  110. private:
  111. Q_DECLARE_PRIVATE(CborSerializer)
  112. };
  113. // ------------- generic implementation -------------
  114. template<typename T>
  115. void CborSerializer::setTypeTag(QCborTag tag)
  116. {
  117. setTypeTag(qMetaTypeId<T>(), tag);
  118. }
  119. template<typename T>
  120. QCborTag CborSerializer::typeTag() const
  121. {
  122. return typeTag(qMetaTypeId<T>());
  123. }
  124. template<typename T>
  125. QCborValue CborSerializer::serialize(const T &data) const
  126. {
  127. static_assert(__private::is_serializable<T>::value, "T cannot be serialized");
  128. return serialize(__private::variant_helper<T>::toVariant(data));
  129. }
  130. template<typename T>
  131. void CborSerializer::serializeTo(QIODevice *device, const T &data, QCborValue::EncodingOptions options) const
  132. {
  133. static_assert(__private::is_serializable<T>::value, "T cannot be serialized");
  134. serializeTo(device, __private::variant_helper<T>::toVariant(data), options);
  135. }
  136. template<typename T>
  137. QByteArray CborSerializer::serializeTo(const T &data, QCborValue::EncodingOptions options) const
  138. {
  139. static_assert(__private::is_serializable<T>::value, "T cannot be serialized");
  140. return serializeTo(__private::variant_helper<T>::toVariant(data), options);
  141. }
  142. template<typename T>
  143. T CborSerializer::deserialize(const QCborValue &cbor, QObject *parent) const
  144. {
  145. static_assert(__private::is_serializable<T>::value, "T cannot be deserialized");
  146. return __private::variant_helper<T>::fromVariant(deserialize(cbor, qMetaTypeId<T>(), parent));
  147. }
  148. template<typename T>
  149. T CborSerializer::deserializeFrom(QIODevice *device, QObject *parent) const
  150. {
  151. static_assert(__private::is_serializable<T>::value, "T cannot be deserialized");
  152. return __private::variant_helper<T>::fromVariant(deserializeFrom(device, qMetaTypeId<T>(), parent));
  153. }
  154. template<typename T>
  155. T CborSerializer::deserializeFrom(const QByteArray &data, QObject *parent) const
  156. {
  157. static_assert(__private::is_serializable<T>::value, "T cannot be deserialized");
  158. return __private::variant_helper<T>::fromVariant(deserializeFrom(data, qMetaTypeId<T>(), parent));
  159. }
  160. }
  161. #endif // QTJSONSERIALIZER_CBORSERIALIZER_H