QtJsonSerializer  4.0.0
A library to perform generic seralization and deserialization of QObjects
metawriters.h
1 #ifndef QTJSONSERIALIZER_METAWRITERS_H
2 #define QTJSONSERIALIZER_METAWRITERS_H
3 
4 #include "QtJsonSerializer/qtjsonserializer_global.h"
5 
6 #include <QtCore/qmetatype.h>
7 #include <QtCore/qvariant.h>
8 #include <QtCore/qsharedpointer.h>
9 #include <QtCore/qhash.h>
10 #include <QtCore/qreadwritelock.h>
11 
12 #include <QtCore/qset.h>
13 #include <QtCore/qlinkedlist.h>
14 
16 
19 class Q_JSONSERIALIZER_EXPORT SequentialWriter
20 {
21  Q_DISABLE_COPY(SequentialWriter)
22 
23 public:
25  struct SequenceInfo {
27  int type = QMetaType::UnknownType;
29  bool isSet = false;
30  };
31 
33  template <template<typename> class TContainer, typename TClass>
34  static void registerWriter();
36  static void registerWriter(int metaTypeId, SequentialWriterFactory *factory);
38  static bool canWrite(int metaTypeId);
40  static QSharedPointer<SequentialWriter> getWriter(QVariant &data);
42  static SequenceInfo getInfo(int metaTypeId);
43 
44  virtual ~SequentialWriter();
46  virtual SequenceInfo info() const = 0;
48  virtual void reserve(int size) = 0;
50  virtual void add(const QVariant &value) = 0;
51 
52 protected:
55 };
56 
58 class Q_JSONSERIALIZER_EXPORT SequentialWriterFactory
59 {
60  Q_DISABLE_COPY(SequentialWriterFactory)
61 
62 public:
64  virtual ~SequentialWriterFactory();
66  virtual QSharedPointer<SequentialWriter> create(void *data) const = 0;
67 };
68 
69 
70 
73 class Q_JSONSERIALIZER_EXPORT AssociativeWriter
74 {
75  Q_DISABLE_COPY(AssociativeWriter)
76 
77 public:
79  struct AssociationInfo {
81  int keyType = QMetaType::UnknownType;
83  int valueType = QMetaType::UnknownType;
84  };
85 
87  template <template<typename, typename> class TContainer, typename TKey, typename TValue>
88  static void registerWriter();
90  static void registerWriter(int metaTypeId, AssociativeWriterFactory *factory);
92  static bool canWrite(int metaTypeId);
94  static QSharedPointer<AssociativeWriter> getWriter(QVariant &data);
96  static AssociationInfo getInfo(int metaTypeId);
97 
98  virtual ~AssociativeWriter();
100  virtual AssociationInfo info() const = 0;
102  virtual void add(const QVariant &key, const QVariant &value) = 0;
103 
104 protected:
107 };
108 
110 class Q_JSONSERIALIZER_EXPORT AssociativeWriterFactory
111 {
112  Q_DISABLE_COPY(AssociativeWriterFactory)
113 
114 public:
116  virtual ~AssociativeWriterFactory();
118  virtual QSharedPointer<AssociativeWriter> create(void *data) const = 0;
119 };
120 
121 // ------------- Generic Implementation classes -------------
122 
123 namespace Implementations {
124 
125 template <template<typename> class TContainer, typename TClass>
126 class SequentialWriterImpl final : public SequentialWriter
127 {
128 public:
129  SequentialWriterImpl(TContainer<TClass> *data)
130  : _data{data}
131  {}
132 
133  SequenceInfo info() const final {
134  return {qMetaTypeId<TClass>(), false};
135  }
136 
137  void reserve(int size) final {
138  _data->reserve(size);
139  }
140 
141  void add(const QVariant &value) final {
142  _data->append(value.template value<TClass>());
143  }
144 
145 private:
146  TContainer<TClass> *_data;
147 };
148 
149 template <template<typename> class TContainer, typename TClass>
150 class SequentialWriterFactoryImpl final : public SequentialWriterFactory
151 {
152 public:
153  QSharedPointer<SequentialWriter> create(void *data) const final {
154  return QSharedPointer<SequentialWriterImpl<TContainer, TClass>>::create(reinterpret_cast<TContainer<TClass>*>(data));
155  }
156 };
157 
158 
159 
160 template <template<typename, typename> class TContainer, typename TKey, typename TValue>
161 class AssociativeWriterImpl final : public AssociativeWriter
162 {
163 public:
164  AssociativeWriterImpl(TContainer<TKey, TValue> *data)
165  : _data{data}
166  {}
167 
168  AssociationInfo info() const final {
169  return {qMetaTypeId<TKey>(), qMetaTypeId<TValue>()};
170  }
171 
172  void add(const QVariant &key, const QVariant &value) final {
173  _data->insert(key.template value<TKey>(),
174  value.template value<TValue>());
175  }
176 
177 private:
178  TContainer<TKey, TValue> *_data;
179 };
180 
181 template <template<typename, typename> class TContainer, typename TKey, typename TValue>
182 class AssociativeWriterFactoryImpl final : public AssociativeWriterFactory
183 {
184 public:
185  QSharedPointer<AssociativeWriter> create(void *data) const final {
186  return QSharedPointer<AssociativeWriterImpl<TContainer, TKey, TValue>>::create(reinterpret_cast<TContainer<TKey, TValue>*>(data));
187  }
188 };
189 
190 // ------------- Specializations and base generic implementations -------------
191 
192 template <typename TClass>
193 class SequentialWriterImpl<QSet, TClass> final : public SequentialWriter
194 {
195 public:
196  SequentialWriterImpl(QSet<TClass> *data)
197  : _data{data}
198  {}
199 
200  SequenceInfo info() const final {
201  return {qMetaTypeId<TClass>(), true};
202  }
203 
204  void reserve(int size) final {
205  _data->reserve(size);
206  }
207 
208  void add(const QVariant &value) final {
209  _data->insert(value.template value<TClass>());
210  }
211 
212 private:
213  QSet<TClass> *_data;
214 };
215 
216 template <typename TClass>
217 class SequentialWriterImpl<QLinkedList, TClass> final : public SequentialWriter
218 {
219 public:
220  SequentialWriterImpl(QLinkedList<TClass> *data)
221  : _data{data}
222  {}
223 
224  SequenceInfo info() const final {
225  return {qMetaTypeId<TClass>(), false};
226  }
227 
228  void reserve(int) final {}
229 
230  void add(const QVariant &value) final {
231  _data->append(value.template value<TClass>());
232  }
233 
234 private:
235  QLinkedList<TClass> *_data;
236 };
237 
238 template <>
239 class SequentialWriterImpl<QList, QVariant> final : public SequentialWriter
240 {
241 public:
242  SequentialWriterImpl(QVariantList *data);
243 
244  SequenceInfo info() const final;
245  void reserve(int size) final;
246  void add(const QVariant &value) final;
247 
248 private:
249  QVariantList *_data;
250 };
251 
252 
253 
254 template <>
255 class AssociativeWriterImpl<QMap, QString, QVariant> final : public AssociativeWriter
256 {
257 public:
258  AssociativeWriterImpl(QVariantMap *data);
259 
260  AssociationInfo info() const final;
261  void add(const QVariant &key, const QVariant &value) final;
262 
263 private:
264  QVariantMap *_data;
265 };
266 
267 template <>
268 class AssociativeWriterImpl<QHash, QString, QVariant> final : public AssociativeWriter
269 {
270 public:
271  AssociativeWriterImpl(QVariantHash *data);
272 
273  AssociationInfo info() const final;
274  void add(const QVariant &key, const QVariant &value) final;
275 
276 private:
277  QVariantHash *_data;
278 };
279 
280 }
281 
282 template<template<typename> class TContainer, typename TClass>
283 void SequentialWriter::registerWriter()
284 {
285  registerWriter(qMetaTypeId<TContainer<TClass>>(),
286  new Implementations::SequentialWriterFactoryImpl<TContainer, TClass>{});
287 }
288 
289 template<template<typename, typename> class TContainer, typename TKey, typename TValue>
291 {
292  registerWriter(qMetaTypeId<TContainer<TKey, TValue>>(),
293  new Implementations::AssociativeWriterFactoryImpl<TContainer, TKey, TValue>{});
294 }
295 
296 }
297 
298 #endif // QTJSONSERIALIZER_METAWRITERS_H
QSet
QtJsonSerializer::MetaWriters::AssociativeWriter::info
virtual AssociationInfo info() const =0
Return the information for the wrapped container.
QtJsonSerializer::MetaWriters::AssociativeWriterFactory
A factory to create associative writer instances from variant data.
Definition: metawriters.h:110
QLinkedList::append
void append(const T &value)
QtJsonSerializer::MetaWriters::SequentialWriter::SequenceInfo
Information about a sequential container.
Definition: metawriters.h:25
QtJsonSerializer::MetaWriters
Contains the writer classes required to support serialization of generic containers.
Definition: metawriters.h:15
QtJsonSerializer::MetaWriters::AssociativeWriter::registerWriter
static void registerWriter()
Registers a container factory for the given container, key and value classes.
Definition: metawriters.h:290
QtJsonSerializer::MetaWriters::SequentialWriter::reserve
virtual void reserve(int size)=0
Reserves space for size elements in the container.
QtJsonSerializer::MetaWriters::SequentialWriter::info
virtual SequenceInfo info() const =0
Return the information for the wrapped container.
QSet::reserve
void reserve(int size)
QSharedPointer
QList
QtJsonSerializer::MetaWriters::SequentialWriterFactory
A factory to create sequential writer instances from variant data.
Definition: metawriters.h:58
QLinkedList
QtJsonSerializer::MetaWriters::AssociativeWriter
The writer class for associative containers.
Definition: metawriters.h:73
QString
QtJsonSerializer::MetaWriters::AssociativeWriter::AssociationInfo
Information about a associative container.
Definition: metawriters.h:79
QtJsonSerializer::MetaWriters::SequentialWriter
The writer class for sequential containers.
Definition: metawriters.h:19
QMap
QtJsonSerializer::MetaWriters::AssociativeWriterFactory::create
virtual QSharedPointer< AssociativeWriter > create(void *data) const =0
Factory method to create the instance. data can be null for read-only writers.
QtJsonSerializer::MetaWriters::AssociativeWriter::add
virtual void add(const QVariant &key, const QVariant &value)=0
Inserts the given value for the given key into the container.
QVariant
QtJsonSerializer::MetaWriters::SequentialWriter::add
virtual void add(const QVariant &value)=0
Adds an element to the "end" of the container.
QHash
QtJsonSerializer::MetaWriters::SequentialWriterFactory::create
virtual QSharedPointer< SequentialWriter > create(void *data) const =0
Factory method to create the instance. data can be null for read-only writers.