#ifndef QTJSONSERIALIZER_CBORSERIALIZER_H #define QTJSONSERIALIZER_CBORSERIALIZER_H #include "qtjsonserializer_global.h" #include "jsonserializer/serializerbase.h" namespace QtJsonSerializer { class CborSerializerPrivate; //! A class to serialize and deserialize c++ classes to and from CBOR class Q_JSONSERIALIZER_EXPORT CborSerializer : public SerializerBase { Q_OBJECT //! If enabled, specially tagged number types will be automatically deserialized to their type Q_PROPERTY(bool handleSpecialNumbers READ handleSpecialNumbers WRITE setHandleSpecialNumbers NOTIFY handleSpecialNumbersChanged) public: //! Additional official CBOR-Tags, taken from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml enum ExtendedTags : std::underlying_type_t { GenericObject = 27, //!< Serialised language-independent object with type name and constructor arguments RationaleNumber = 30, //!< Rational number Identifier = 39, //!< Identifier Homogeneous = 41, //!< Homogeneous Array Set = 258, //!< Mathematical finite set ExplicitMap = 259, //!< Map datatype with key-value operations (e.g. `.get()/.set()/.delete()`) NetworkAddress = 260, //!< Network Address (IPv4 or IPv6 or MAC Address) NetworkAddressPrefix = 261, //!< Network Address Prefix (IPv4 or IPv6 Address + Mask Length) }; Q_ENUM(ExtendedTags) // Additional unofficial CBOR-Tags, as defined by this library to tag Qt types for better typesafety enum CustomTags : std::underlying_type_t { Color = 10000, //!< Tag used for QColor Font = 10001, //!< Tag used for QFont Enum = 10002, //!< Tag used for enums Flags = 10003, //!< Tag used for flags ConstructedObject = 10004, //!< Tag used for constructed object (GenericObject + standard object) Pair = 10005, //!< Tag used for QPair/std::pair MultiMap = 10006, //!< Tag used for QMultiMap/QMultiHash VersionNumber = 10007, //!< Tag used for QVersionNumber Tuple = 10008, //!< Tag used for std::tuple BitArray = 10009, //!< Tag used for QBitArray Date = 10010, //!< Tag used for QDate (short ISO format) Time = 10011, //!< Tag used for QTime (short ISO format) LocaleISO = 10100, //!< Tag used for QLocale, encoded via the ISO format LocaleBCP47 = 10101, //!< Tag used for QLocale, encoded via the BCP47 format GeomSize = 10110, //!< Tag used for QSize/QSizeF GeomPoint = 10111, //!< Tag used for QPoint/QPointF GeomLine = 10112, //!< Tag used for QLine/QLineF GeomRect = 10113, //!< Tag used for QRect/QRectF ChronoNanoSeconds = 10120, //!< Tag used for std::chrono::nanoseconds ChronoMicroSeconds = 10121, //!< Tag used for std::chrono::microseconds ChronoMilliSeconds = 10122, //!< Tag used for std::chrono::milliseconds ChronoSeconds = 10123, //!< Tag used for std::chrono::seconds ChronoMinutes = 10124, //!< Tag used for std::chrono::minutes ChronoHours = 10125, //!< Tag used for std::chrono::hours NoTag = std::numeric_limits>::max() //!< Used as placeholder for setTypeTag to not change the tag }; Q_ENUM(CustomTags) //! Default constructor explicit CborSerializer(QObject *parent = nullptr); //! @readAcFn{CborSerializer::handleSpecialNumbers} bool handleSpecialNumbers() const; //! Set a tag to always be used when serializing the given type template void setTypeTag(QCborTag tag = static_cast(NoTag)); //! @copybrief CborSerializer::setTypeTag(QCborTag) void setTypeTag(int metaTypeId, QCborTag tag = static_cast(NoTag)); //! @copybrief TypeConverter::SerializationHelper::typeTag template QCborTag typeTag() const; QCborTag typeTag(int metaTypeId) const override; //! Serializers a QVariant value to a QCborValue QCborValue serialize(const QVariant &data) const; //! Serializers a QVariant value to a device void serializeTo(QIODevice *device, const QVariant &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const; //! Serializers a QVariant value to a byte array QByteArray serializeTo(const QVariant &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const; //! Serializers a c++ type to cbor template QCborValue serialize(const T &data) const; //! Serializers a c++ type to a device template void serializeTo(QIODevice *device, const T &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const; //! Serializers a c++ type to a byte array template QByteArray serializeTo(const T &data, QCborValue::EncodingOptions options = QCborValue::NoTransformation) const; //! Deserializes a QCborValue to a QVariant value, based on the given type id QVariant deserialize(const QCborValue &cbor, int metaTypeId, QObject *parent = nullptr) const; //! Deserializes data from a device to a QVariant value, based on the given type id QVariant deserializeFrom(QIODevice *device, int metaTypeId, QObject *parent = nullptr) const; //! Deserializes data from a device to a QVariant value, based on the given type id QVariant deserializeFrom(const QByteArray &data, int metaTypeId, QObject *parent = nullptr) const; //! Deserializes cbor to the given c++ type template T deserialize(const QCborValue &cbor, QObject *parent = nullptr) const; //! Deserializes data from a device to the given c++ type template T deserializeFrom(QIODevice *device, QObject *parent = nullptr) const; //! Deserializes data from a byte array to the given c++ type template T deserializeFrom(const QByteArray &data, QObject *parent = nullptr) const; std::variant serializeGeneric(const QVariant &value) const override; QVariant deserializeGeneric(const std::variant &value, int metaTypeId, QObject *parent) const override; public Q_SLOTS: //! @writeAcFn{CborSerializer::handleSpecialNumbers} void setHandleSpecialNumbers(bool handleSpecialNumbers); Q_SIGNALS: //! @notifyAcFn{CborSerializer::handleSpecialNumbers} void handleSpecialNumbersChanged(bool handleSpecialNumbers, QPrivateSignal); protected: // protected implementation -> internal use for the type converters bool jsonMode() const override; QList typesForTag(QCborTag tag) const override; private: Q_DECLARE_PRIVATE(CborSerializer) }; // ------------- generic implementation ------------- template void CborSerializer::setTypeTag(QCborTag tag) { setTypeTag(qMetaTypeId(), tag); } template QCborTag CborSerializer::typeTag() const { return typeTag(qMetaTypeId()); } template QCborValue CborSerializer::serialize(const T &data) const { static_assert(__private::is_serializable::value, "T cannot be serialized"); return serialize(__private::variant_helper::toVariant(data)); } template void CborSerializer::serializeTo(QIODevice *device, const T &data, QCborValue::EncodingOptions options) const { static_assert(__private::is_serializable::value, "T cannot be serialized"); serializeTo(device, __private::variant_helper::toVariant(data), options); } template QByteArray CborSerializer::serializeTo(const T &data, QCborValue::EncodingOptions options) const { static_assert(__private::is_serializable::value, "T cannot be serialized"); return serializeTo(__private::variant_helper::toVariant(data), options); } template T CborSerializer::deserialize(const QCborValue &cbor, QObject *parent) const { static_assert(__private::is_serializable::value, "T cannot be deserialized"); return __private::variant_helper::fromVariant(deserialize(cbor, qMetaTypeId(), parent)); } template T CborSerializer::deserializeFrom(QIODevice *device, QObject *parent) const { static_assert(__private::is_serializable::value, "T cannot be deserialized"); return __private::variant_helper::fromVariant(deserializeFrom(device, qMetaTypeId(), parent)); } template T CborSerializer::deserializeFrom(const QByteArray &data, QObject *parent) const { static_assert(__private::is_serializable::value, "T cannot be deserialized"); return __private::variant_helper::fromVariant(deserializeFrom(data, qMetaTypeId(), parent)); } } #endif // QTJSONSERIALIZER_CBORSERIALIZER_H