QtJsonSerializer  4.0.0
A library to perform generic seralization and deserialization of QObjects
serializerbase.h
Go to the documentation of this file.
1 #ifndef QTJSONSERIALIZER_SERIALIZERBASE_H
2 #define QTJSONSERIALIZER_SERIALIZERBASE_H
3 
4 #include "QtJsonSerializer/qtjsonserializer_global.h"
5 #include "QtJsonSerializer/exception.h"
6 #include "QtJsonSerializer/typeconverter.h"
7 #include "QtJsonSerializer/qtjsonserializer_helpertypes.h"
8 #include "QtJsonSerializer/metawriters.h"
9 #include "QtJsonSerializer/typeextractors.h"
10 
11 #include <tuple>
12 #include <optional>
13 #include <variant>
14 
15 #include <QtCore/qobject.h>
16 #include <QtCore/qmetaobject.h>
17 #include <QtCore/qcborvalue.h>
18 #include <QtCore/qvariant.h>
19 #include <QtCore/qsharedpointer.h>
20 #include <QtCore/qpointer.h>
21 #include <QtCore/qlist.h>
22 #include <QtCore/qlinkedlist.h>
23 #include <QtCore/qvector.h>
24 #include <QtCore/qset.h>
25 #include <QtCore/qqueue.h>
26 #include <QtCore/qstack.h>
27 #include <QtCore/qhash.h>
28 #include <QtCore/qmap.h>
29 
30 namespace QtJsonSerializer {
31 
32 class SerializerBasePrivate;
34 class Q_JSONSERIALIZER_EXPORT SerializerBase : public QObject, protected TypeConverter::SerializationHelper
35 {
36  Q_OBJECT
37 
39  Q_PROPERTY(bool allowDefaultNull READ allowDefaultNull WRITE setAllowDefaultNull NOTIFY allowDefaultNullChanged)
41  Q_PROPERTY(bool keepObjectName READ keepObjectName WRITE setKeepObjectName NOTIFY keepObjectNameChanged)
43  Q_PROPERTY(bool enumAsString READ enumAsString WRITE setEnumAsString NOTIFY enumAsStringChanged)
45  Q_PROPERTY(bool versionAsString READ versionAsString WRITE setVersionAsString NOTIFY versionAsStringChanged)
47  Q_PROPERTY(bool dateAsTimeStamp READ dateAsTimeStamp WRITE setDateAsTimeStamp NOTIFY dateAsTimeStampChanged)
49  Q_PROPERTY(bool useBcp47Locale READ useBcp47Locale WRITE setUseBcp47Locale NOTIFY useBcp47LocaleChanged)
51  Q_PROPERTY(ValidationFlags validationFlags READ validationFlags WRITE setValidationFlags NOTIFY validationFlagsChanged)
53  Q_PROPERTY(Polymorphing polymorphing READ polymorphing WRITE setPolymorphing NOTIFY polymorphingChanged)
55  Q_PROPERTY(MultiMapMode multiMapMode READ multiMapMode WRITE setMultiMapMode NOTIFY multiMapModeChanged)
57  Q_PROPERTY(bool ignoreStoredAttribute READ ignoresStoredAttribute WRITE setIgnoreStoredAttribute NOTIFY ignoreStoredAttributeChanged)
58 
59 public:
61  enum class ValidationFlag {
62  StandardValidation = 0x00,
63  NoExtraProperties = 0x01,
64  AllProperties = 0x02,
65  StrictBasicTypes = 0x04,
66 
67  FullPropertyValidation = (NoExtraProperties | AllProperties),
68  FullValidation = (FullPropertyValidation | StrictBasicTypes),
69  };
70  Q_DECLARE_FLAGS(ValidationFlags, ValidationFlag)
71  Q_FLAG(ValidationFlags)
72 
73 
74  enum class Polymorphing {
75  Disabled,
76  Enabled,
77  Forced
78  };
79  Q_ENUM(Polymorphing)
80 
81 
82  enum class MultiMapMode {
83  Map,
84  List,
85  DenseMap
86  };
87  Q_ENUM(MultiMapMode)
88 
89 
90  template<typename TType, typename TExtractor>
91  static void registerExtractor();
93  static void registerExtractor(int metaTypeId, const QSharedPointer<TypeExtractor> &extractor);
94 
96  template<typename T>
97  static inline void registerListConverters();
99  template<typename T>
100  static inline void registerSetConverters();
102  template<typename TKey, typename TValue, bool mapTypes = true, bool hashTypes = true>
103  static inline void registerMapConverters();
105  template<typename T>
106  static inline void registerPointerConverters();
108  template<typename T>
109  static inline void registerBasicConverters();
111  template<typename T, typename U>
112  static inline void registerPairConverters();
114  template<typename... TArgs>
115  static inline void registerTupleConverters();
117  template<typename T>
118  static inline void registerOptionalConverters();
120  template<typename... TArgs>
121  static inline void registerVariantConverters();
122 
124  virtual std::variant<QCborValue, QJsonValue> serializeGeneric(const QVariant &value) const = 0;
126  virtual QVariant deserializeGeneric(const std::variant<QCborValue, QJsonValue> &value, int metaTypeId, QObject *parent = nullptr) const = 0;
127 
129  bool allowDefaultNull() const;
131  bool keepObjectName() const;
133  bool enumAsString() const;
135  bool versionAsString() const;
137  bool dateAsTimeStamp() const;
139  bool useBcp47Locale() const;
141  ValidationFlags validationFlags() const;
143  Polymorphing polymorphing() const;
145  MultiMapMode multiMapMode() const;
147  bool ignoresStoredAttribute() const;
148 
150  template <typename TConverter, int Priority = TypeConverter::Priority::Standard>
151  static void addJsonTypeConverterFactory();
153  static void addJsonTypeConverterFactory(TypeConverterFactory *factory);
154 
156  template <typename TConverter>
157  void addJsonTypeConverter();
159  void addJsonTypeConverter(const QSharedPointer<TypeConverter> &converter);
160 
161 public Q_SLOTS:
163  void setAllowDefaultNull(bool allowDefaultNull);
165  void setKeepObjectName(bool keepObjectName);
167  void setEnumAsString(bool enumAsString);
169  void setVersionAsString(bool versionAsString);
171  void setDateAsTimeStamp(bool dateAsTimeStamp);
173  void setUseBcp47Locale(bool useBcp47Locale);
175  void setValidationFlags(ValidationFlags validationFlags);
177  void setPolymorphing(Polymorphing polymorphing);
179  void setMultiMapMode(MultiMapMode multiMapMode);
181  void setIgnoreStoredAttribute(bool ignoreStoredAttribute);
182 
183 Q_SIGNALS:
185  void allowDefaultNullChanged(bool allowDefaultNull, QPrivateSignal);
187  void keepObjectNameChanged(bool keepObjectName, QPrivateSignal);
189  void enumAsStringChanged(bool enumAsString, QPrivateSignal);
191  void versionAsStringChanged(bool versionAsString, QPrivateSignal);
193  void dateAsTimeStampChanged(bool dateAsTimeStamp, QPrivateSignal);
195  void useBcp47LocaleChanged(bool useBcp47Locale, QPrivateSignal);
197  void validationFlagsChanged(ValidationFlags validationFlags, QPrivateSignal);
199  void polymorphingChanged(Polymorphing polymorphing, QPrivateSignal);
201  void multiMapModeChanged(MultiMapMode multiMapMode, QPrivateSignal);
203  void ignoreStoredAttributeChanged(bool ignoreStoredAttribute, QPrivateSignal);
204 
205 protected:
207  explicit SerializerBase(QObject *parent = nullptr);
209  explicit SerializerBase(SerializerBasePrivate &dd, QObject *parent);
210 
211  virtual QList<int> typesForTag(QCborTag tag) const = 0;
212 
213  // protected implementation -> internal use for the type converters
214  QVariant getProperty(const char *name) const override;
215  QSharedPointer<const TypeExtractor> extractor(int metaTypeId) const override;
216  QCborValue serializeSubtype(const QMetaProperty &property, const QVariant &value) const override;
217  QCborValue serializeSubtype(int propertyType, const QVariant &value, const QByteArray &traceHint) const override;
218  QVariant deserializeSubtype(const QMetaProperty &property, const QCborValue &value, QObject *parent) const override;
219  QVariant deserializeSubtype(int propertyType, const QCborValue &value, QObject *parent, const QByteArray &traceHint) const override;
220 
222  QCborValue serializeVariant(int propertyType, const QVariant &value) const;
224  QVariant deserializeVariant(int propertyType, const QCborValue &value, QObject *parent, bool skipConversion = false) const;
225 
226 private:
227  Q_DECLARE_PRIVATE(SerializerBase)
228 
229  static void registerInverseTypedefImpl(int typeId, const char *normalizedTypeName);
230 };
231 
233 #define Q_JSON_POLYMORPHIC(x) \
234  static_assert(std::is_same<decltype(x), bool>::value, "x must be bool"); \
235  Q_CLASSINFO("polymorphic", #x)
236 
237 // ------------- Generic Implementation -------------
238 
239 template<typename TType, typename TExtractor>
241 {
242  registerExtractor(qMetaTypeId<TType>(), QSharedPointer<TExtractor>::create());
243 }
244 
245 template<typename T>
247 {
248  MetaWriters::SequentialWriter::registerWriter<QList, T>();
249  MetaWriters::SequentialWriter::registerWriter<QLinkedList, T>();
250  MetaWriters::SequentialWriter::registerWriter<QVector, T>();
251  MetaWriters::SequentialWriter::registerWriter<QStack, T>();
252  MetaWriters::SequentialWriter::registerWriter<QQueue, T>();
253 }
254 
255 template<typename T>
257 {
258  MetaWriters::SequentialWriter::registerWriter<QSet, T>();
259 }
260 
261 template<typename TKey, typename TValue, bool mapTypes, bool hashTypes>
263 {
264  if constexpr (mapTypes) {
265  MetaWriters::AssociativeWriter::registerWriter<QMap, TKey, TValue>();
266  MetaWriters::AssociativeWriter::registerWriter<QMultiMap, TKey, TValue>();
267  }
268  if constexpr (hashTypes) {
269  MetaWriters::AssociativeWriter::registerWriter<QHash, TKey, TValue>();
270  MetaWriters::AssociativeWriter::registerWriter<QMultiHash, TKey, TValue>();
271  }
272 }
273 
274 template<typename T>
276 {
277  registerExtractor<QSharedPointer<T>, TypeExtractors::SmartPointerExtractor<QSharedPointer, T>>();
278  if constexpr (std::is_base_of_v<QObject, T>)
279  registerExtractor<QPointer<T>, TypeExtractors::SmartPointerExtractor<QPointer, T>>();
280 }
281 
282 template<typename T>
284 {
285  if constexpr (std::is_base_of_v<QObject, T>) {
286  registerBasicConverters<T*>();
287  registerPointerConverters<T>();
288  registerBasicConverters<QSharedPointer<T>>();
289  registerBasicConverters<QPointer<T>>();
290  } else {
291  registerListConverters<T>();
292  registerSetConverters<T>();
293  registerMapConverters<QString, T>();
294  }
295 }
296 
297 template<typename T1, typename T2>
299 {
300  registerExtractor<QPair<T1, T2>, TypeExtractors::PairExtractor<QPair, T1, T2>>();
301  registerExtractor<std::pair<T1, T2>, TypeExtractors::PairExtractor<std::pair, T1, T2>>();
302 }
303 
304 template<typename... TArgs>
306 {
307  registerExtractor<std::tuple<TArgs...>, TypeExtractors::TupleExtractor<TArgs...>>();
308 }
309 
310 template<typename T>
312 {
313  registerExtractor<std::optional<T>, TypeExtractors::OptionalExtractor<T>>();
314 }
315 
316 template<typename... TArgs>
318 {
319  registerExtractor<std::variant<TArgs...>, TypeExtractors::VariantExtractor<TArgs...>>();
320 }
321 
322 template<typename TConverter, int Priority>
324 {
325  static_assert(std::is_base_of<TypeConverter, TConverter>::value, "T must implement QJsonTypeConverter");
327 }
328 
329 template<typename TConverter>
331 {
332  static_assert(std::is_base_of<TypeConverter, TConverter>::value, "T must implement QJsonTypeConverter");
334 }
335 
336 }
337 
338 Q_DECLARE_OPERATORS_FOR_FLAGS(QtJsonSerializer::SerializerBase::ValidationFlags)
339 
340 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMultiMap)
341 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMultiHash)
342 
343 #endif // QTJSONSERIALIZER_SERIALIZERBASE_H
QtJsonSerializer::SerializerBase::MultiMapMode
MultiMapMode
Enum to specify how multi maps and sets should be serialized.
Definition: serializerbase.h:82
QtJsonSerializer::SerializerBase::registerMapConverters
static void registerMapConverters()
Registers a custom type for map converisons.
Definition: serializerbase.h:262
QMultiMap
QtJsonSerializer::TypeConverter::SerializationHelper
Helper class passed to the type converter by the serializer. Do not implement yourself.
Definition: typeconverter.h:66
QtJsonSerializer::SerializerBase::ValidationFlag
ValidationFlag
Flags to specify how strict the serializer should validate when deserializing.
Definition: serializerbase.h:61
QMultiHash
QtJsonSerializer
The QtJsonSerializer namespace holds all classes of the module.
Definition: cborserializer.h:7
QMetaProperty
QtJsonSerializer::SerializerBase::registerVariantConverters
static void registerVariantConverters()
Registers a custom type for std::variant converisons.
Definition: serializerbase.h:317
QtJsonSerializer::SerializerBase::registerTupleConverters
static void registerTupleConverters()
Registers a number of types for std::tuple conversion.
Definition: serializerbase.h:305
QtJsonSerializer::SerializerBase
A base class for the CBOR/JSON serializers.
Definition: serializerbase.h:34
QtJsonSerializer::SerializerBase::registerBasicConverters
static void registerBasicConverters()
Registers a custom type for list, set map and optional converisons. Also include pointer converters,...
Definition: serializerbase.h:283
QSharedPointer
QList
QtJsonSerializer::SerializerBase::addJsonTypeConverterFactory
static void addJsonTypeConverterFactory()
Globally registers a converter factory to provide converters for all QJsonSerializer instances.
Definition: serializerbase.h:323
QtJsonSerializer::SerializerBase::registerPairConverters
static void registerPairConverters()
Registers two types for pair conversion.
Definition: serializerbase.h:298
QtJsonSerializer::TypeConverterFactory
A factory interface to create instances of QJsonTypeConverters.
Definition: typeconverter.h:143
QtJsonSerializer::SerializerBase::registerOptionalConverters
static void registerOptionalConverters()
Registers a custom type for std::optional converisons.
Definition: serializerbase.h:311
QtJsonSerializer::SerializerBase::Polymorphing
Polymorphing
Enum to specify the modes of polymorphism.
Definition: serializerbase.h:74
QCborValue
QtJsonSerializer::TypeConverterStandardFactory
A template implementation of TypeConverterFactory to generically create simply converters.
Definition: typeconverter.h:157
QtJsonSerializer::SerializerBase::addJsonTypeConverter
void addJsonTypeConverter()
Adds a custom type converter to this serializer.
Definition: serializerbase.h:330
QtJsonSerializer::SerializerBase::registerSetConverters
static void registerSetConverters()
Registers a custom type for set converisons.
Definition: serializerbase.h:256
QtJsonSerializer::SerializerBase::registerListConverters
static void registerListConverters()
Registers a custom type for list converisons.
Definition: serializerbase.h:246
QVariant
QObject
QtJsonSerializer::SerializerBase::registerExtractor
static void registerExtractor()
Registers a custom extractor for the given type.
Definition: serializerbase.h:240
QtJsonSerializer::SerializerBase::registerPointerConverters
static void registerPointerConverters()
Registers a custom type for QSharedPointer and QPointer converisons.
Definition: serializerbase.h:275
QByteArray