| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- #ifndef QTJSONSERIALIZER_METAWRITERS_H
- #define QTJSONSERIALIZER_METAWRITERS_H
- #include "qtjsonserializer_global.h"
- #include <QtCore/qmetatype.h>
- #include <QtCore/qvariant.h>
- #include <QtCore/qsharedpointer.h>
- #include <QtCore/qhash.h>
- #include <QtCore/qreadwritelock.h>
- #include <QtCore/qset.h>
- #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- #include <QtCore/qlinkedlist.h>
- #endif
- namespace QtJsonSerializer::MetaWriters {
- class SequentialWriterFactory;
- //! The writer class for sequential containers
- class Q_JSONSERIALIZER_EXPORT SequentialWriter
- {
- Q_DISABLE_COPY(SequentialWriter)
- public:
- //! Information about a sequential container
- struct SequenceInfo {
- //! The containers data type
- int type = QMetaType::UnknownType;
- //! Specifies if the container is a finite set
- bool isSet = false;
- };
- //! Registers a container factory for the given container and value classes
- template <template<typename> class TContainer, typename TClass>
- static void registerWriter();
- //! @copybrief SequentialWriter::registerWriter()
- static void registerWriter(int metaTypeId, SequentialWriterFactory *factory);
- //! Checks if a writer exists for the given type
- static bool canWrite(int metaTypeId);
- //! Returns a writer instance for the given data, or nullptr if none found
- static QSharedPointer<SequentialWriter> getWriter(QVariant &data);
- //! Returns the information details of the given type
- static SequenceInfo getInfo(int metaTypeId);
- virtual ~SequentialWriter();
- //! Return the information for the wrapped container
- virtual SequenceInfo info() const = 0;
- //! Reserves space for size elements in the container
- virtual void reserve(int size) = 0;
- //! Adds an element to the "end" of the container
- virtual void add(const QVariant &value) = 0;
- protected:
- //! @private
- SequentialWriter();
- };
- //! A factory to create sequential writer instances from variant data
- class Q_JSONSERIALIZER_EXPORT SequentialWriterFactory
- {
- Q_DISABLE_COPY(SequentialWriterFactory)
- public:
- SequentialWriterFactory();
- virtual ~SequentialWriterFactory();
- //! Factory method to create the instance. data can be null for read-only writers
- virtual QSharedPointer<SequentialWriter> create(void *data) const = 0;
- };
- class AssociativeWriterFactory;
- //! The writer class for associative containers
- class Q_JSONSERIALIZER_EXPORT AssociativeWriter
- {
- Q_DISABLE_COPY(AssociativeWriter)
- public:
- //! Information about a associative container
- struct AssociationInfo {
- //! The type of the associations keys
- int keyType = QMetaType::UnknownType;
- //! The type of the associations values
- int valueType = QMetaType::UnknownType;
- };
- //! Registers a container factory for the given container, key and value classes
- template <template<typename, typename> class TContainer, typename TKey, typename TValue>
- static void registerWriter();
- //! @copybrief AssociativeWriter::registerWriter()
- static void registerWriter(int metaTypeId, AssociativeWriterFactory *factory);
- //! Checks if a writer exists for the given type
- static bool canWrite(int metaTypeId);
- //! Returns a writer instance for the given data, or nullptr if none found
- static QSharedPointer<AssociativeWriter> getWriter(QVariant &data);
- //! Returns the information details of the given type
- static AssociationInfo getInfo(int metaTypeId);
- virtual ~AssociativeWriter();
- //! Return the information for the wrapped container
- virtual AssociationInfo info() const = 0;
- //! Inserts the given value for the given key into the container
- virtual void add(const QVariant &key, const QVariant &value) = 0;
- protected:
- //! @private
- AssociativeWriter();
- };
- //! A factory to create associative writer instances from variant data
- class Q_JSONSERIALIZER_EXPORT AssociativeWriterFactory
- {
- Q_DISABLE_COPY(AssociativeWriterFactory)
- public:
- AssociativeWriterFactory();
- virtual ~AssociativeWriterFactory();
- //! Factory method to create the instance. data can be null for read-only writers
- virtual QSharedPointer<AssociativeWriter> create(void *data) const = 0;
- };
- // ------------- Generic Implementation classes -------------
- namespace Implementations {
- template <template<typename> class TContainer, typename TClass>
- class SequentialWriterImpl final : public SequentialWriter
- {
- public:
- SequentialWriterImpl(TContainer<TClass> *data)
- : _data{data}
- {}
- SequenceInfo info() const final {
- return {qMetaTypeId<TClass>(), false};
- }
- void reserve(int size) final {
- _data->reserve(size);
- }
- void add(const QVariant &value) final {
- _data->append(value.template value<TClass>());
- }
- private:
- TContainer<TClass> *_data;
- };
- template <template<typename> class TContainer, typename TClass>
- class SequentialWriterFactoryImpl final : public SequentialWriterFactory
- {
- public:
- QSharedPointer<SequentialWriter> create(void *data) const final {
- return QSharedPointer<SequentialWriterImpl<TContainer, TClass>>::create(reinterpret_cast<TContainer<TClass>*>(data));
- }
- };
- template <template<typename, typename> class TContainer, typename TKey, typename TValue>
- class AssociativeWriterImpl final : public AssociativeWriter
- {
- public:
- AssociativeWriterImpl(TContainer<TKey, TValue> *data)
- : _data{data}
- {}
- AssociationInfo info() const final {
- return {qMetaTypeId<TKey>(), qMetaTypeId<TValue>()};
- }
- void add(const QVariant &key, const QVariant &value) final {
- _data->insert(key.template value<TKey>(),
- value.template value<TValue>());
- }
- private:
- TContainer<TKey, TValue> *_data;
- };
- template <template<typename, typename> class TContainer, typename TKey, typename TValue>
- class AssociativeWriterFactoryImpl final : public AssociativeWriterFactory
- {
- public:
- QSharedPointer<AssociativeWriter> create(void *data) const final {
- return QSharedPointer<AssociativeWriterImpl<TContainer, TKey, TValue>>::create(reinterpret_cast<TContainer<TKey, TValue>*>(data));
- }
- };
- // ------------- Specializations and base generic implementations -------------
- template <typename TClass>
- class SequentialWriterImpl<QSet, TClass> final : public SequentialWriter
- {
- public:
- SequentialWriterImpl(QSet<TClass> *data)
- : _data{data}
- {}
- SequenceInfo info() const final {
- return {qMetaTypeId<TClass>(), true};
- }
- void reserve(int size) final {
- _data->reserve(size);
- }
- void add(const QVariant &value) final {
- _data->insert(value.template value<TClass>());
- }
- private:
- QSet<TClass> *_data;
- };
- #if !defined(QT_NO_LINKED_LIST) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
- template <typename TClass>
- class SequentialWriterImpl<QLinkedList, TClass> final : public SequentialWriter
- {
- public:
- SequentialWriterImpl(QLinkedList<TClass> *data)
- : _data{data}
- {}
- SequenceInfo info() const final {
- return {qMetaTypeId<TClass>(), false};
- }
- void reserve(int) final {}
- void add(const QVariant &value) final {
- _data->append(value.template value<TClass>());
- }
- private:
- QLinkedList<TClass> *_data;
- };
- #endif
- template <>
- class SequentialWriterImpl<QList, QVariant> final : public SequentialWriter
- {
- public:
- SequentialWriterImpl(QVariantList *data);
- SequenceInfo info() const final;
- void reserve(int size) final;
- void add(const QVariant &value) final;
- private:
- QVariantList *_data;
- };
- template <>
- class AssociativeWriterImpl<QMap, QString, QVariant> final : public AssociativeWriter
- {
- public:
- AssociativeWriterImpl(QVariantMap *data);
- AssociationInfo info() const final;
- void add(const QVariant &key, const QVariant &value) final;
- private:
- QVariantMap *_data;
- };
- template <>
- class AssociativeWriterImpl<QHash, QString, QVariant> final : public AssociativeWriter
- {
- public:
- AssociativeWriterImpl(QVariantHash *data);
- AssociationInfo info() const final;
- void add(const QVariant &key, const QVariant &value) final;
- private:
- QVariantHash *_data;
- };
- }
- template<template<typename> class TContainer, typename TClass>
- void SequentialWriter::registerWriter()
- {
- registerWriter(qMetaTypeId<TContainer<TClass>>(),
- new Implementations::SequentialWriterFactoryImpl<TContainer, TClass>{});
- }
- template<template<typename, typename> class TContainer, typename TKey, typename TValue>
- void AssociativeWriter::registerWriter()
- {
- registerWriter(qMetaTypeId<TContainer<TKey, TValue>>(),
- new Implementations::AssociativeWriterFactoryImpl<TContainer, TKey, TValue>{});
- }
- }
- #endif // QTJSONSERIALIZER_METAWRITERS_H
|