ICF 3.0.5.47
Technical documentation of ICF Libraries
CPrimitiveTypesSerializer.h
Go to the documentation of this file.
1/********************************************************************************
2** This file is part of the ICF Framework. Copyright (C) Witold Gantzke & Kirill Lepskiy
3** ICF Framework may be used under the terms of the LGPL License v. 2.1 by the Free Software Foundation.
4********************************************************************************/
5
6#pragma once
7
8
9// STL includes
10#include <typeinfo>
11
12// Qt includes
13#include <QtCore/QDateTime>
14#include <QtCore/QPointF>
15#include <QtCore/QMetaObject>
16#include <QtCore/QMetaEnum>
17
18// ICF includes
19#include <istd/TRange.h>
20#include <istd/TRanges.h>
21#include <istd/TIndex.h>
22#include <iser/IArchive.h>
23#include <iser/CArchiveTag.h>
24
25
26namespace iser
27{
28
29
34{
35public:
39 static bool SerializeRange(iser::IArchive& archive, istd::CRange& range);
40
44 static bool SerializeIntRange(iser::IArchive& archive, istd::CIntRange& range);
45
49 static bool SerializeRanges(iser::IArchive& archive, istd::CRanges& ranges);
50
54 static bool SerializeIntRanges(iser::IArchive& archive, istd::CIntRanges& ranges);
55
59 static bool SerializeDateTime(iser::IArchive& archive, QDateTime& dateTime);
60
64 static bool SerializeDate(iser::IArchive& archive, QDate& date);
65
69 template <int Dimensions>
70 static bool SerializeIndex(iser::IArchive& archive, istd::TIndex<Dimensions>& index);
71
75 static bool SerializeQPointF(iser::IArchive& archive, QPointF& point);
76
87 template <typename ContainterType>
89 iser::IArchive& archive,
90 ContainterType& container,
91 const iser::CArchiveTag& elementsTag,
92 const iser::CArchiveTag& elementTag);
93
103 template <typename ContainterType>
105 iser::IArchive& archive,
106 ContainterType& container,
107 const iser::CArchiveTag& elementsTag,
108 const iser::CArchiveTag& elementTag);
109
116 template <typename EnumType, QByteArray (*ToString)(EnumType), bool (*FromString)(const QByteArray&, EnumType&)>
117 static bool SerializeEnum(
118 iser::IArchive& archive,
119 EnumType& enumValue);
120
126 template <typename EnumType>
127 static bool SerializeEnum(
128 iser::IArchive& archive,
129 EnumType& enumValue,
130 const QObject* objectPtr);
131};
132
133
134// public template methods
135
136template <int Dimensions>
138{
139 bool retVal = true;
140
141 for (int i = 0; i < Dimensions; ++i){
142 retVal = retVal && archive.Process(index[i]);
143 }
144
145 return retVal;
146}
147
148
149template <typename ContainerType>
151 iser::IArchive& archive,
152 ContainerType& container,
153 const iser::CArchiveTag& elementsTag,
154 const iser::CArchiveTag& elementTag)
155{
156 bool retVal = true;
157
158 int elementsCount = container.count();
159
160 retVal = retVal && archive.BeginMultiTag(elementsTag, elementTag, elementsCount);
161 if (!retVal){
162 return false;
163 }
164
165 if (archive.IsChanging()) {
166 container.clear();
167
168 for (int i = 0; i < elementsCount; ++i) {
169 typename ContainerType::value_type element;
170 retVal = retVal && archive.BeginTag(elementTag);
171 retVal = retVal && archive.Process(element);
172 retVal = retVal && archive.EndTag(elementTag);
173
174 if (retVal) {
175 container.push_back(element);
176 }
177 }
178 }
179 else{
180 for (int i = 0; i < elementsCount; ++i) {
181 typename ContainerType::value_type element = container[i];
182
183 retVal = retVal && archive.BeginTag(elementTag);
184 retVal = retVal && archive.Process(element);
185 retVal = retVal && archive.EndTag(elementTag);
186 }
187 }
188
189 retVal = retVal && archive.EndTag(elementsTag);
190
191 return retVal;
192}
193
194
195template <typename ContainerType>
197 iser::IArchive& archive,
198 ContainerType& container,
199 const iser::CArchiveTag& elementsTag,
200 const iser::CArchiveTag& elementTag)
201{
202 bool retVal = true;
203
204 int elementsCount = container.count();
205
206 retVal = retVal && archive.BeginMultiTag(elementsTag, elementTag, elementsCount);
207 if (!retVal){
208 return false;
209 }
210
211 if (archive.IsChanging()) {
212 container.clear();
213
214 for (int i = 0; i < elementsCount; ++i) {
215 typename ContainerType::value_type element;
216 retVal = retVal && archive.BeginTag(elementTag);
217 retVal = retVal && element.Serialize(archive);
218 retVal = retVal && archive.EndTag(elementTag);
219
220 if (retVal) {
221 container.push_back(element);
222 }
223 }
224 }
225 else{
226 for (int i = 0; i < elementsCount; ++i) {
227 typename ContainerType::value_type element = container[i];
228
229 retVal = retVal && archive.BeginTag(elementTag);
230 retVal = retVal && element.Serialize(archive);
231 retVal = retVal && archive.EndTag(elementTag);
232 }
233 }
234
235 retVal = retVal && archive.EndTag(elementsTag);
236
237 return retVal;
238}
239
240
241template <typename EnumType, QByteArray (*ToString)(EnumType), bool (*FromString)(const QByteArray&, EnumType&)>
243 iser::IArchive& archive,
244 EnumType& enumValue)
245{
246 QByteArray enumValueAsText;
247
248 bool retVal = true;
249
250 // Try to get enumeration text generated by I_DECLARE_ENUM macro:
251 if (enumValueAsText.isEmpty() && (ToString != nullptr)){
252 enumValueAsText = ToString(enumValue);
253 }
254
255 // Enum value is defined in textual form:
256 if (!enumValueAsText.isEmpty()){
257 retVal = retVal && archive.Process(enumValueAsText);
258
259 if (retVal && archive.IsChanging()){
260 if (FromString != nullptr){
261 retVal = FromString(enumValueAsText, enumValue);
262 }
263 else{
264 retVal = false;
265 }
266 }
267 }
268 else{
269 int value = enumValue;
270
271 retVal = retVal && archive.Process(value);
272
273 if (archive.IsChanging()){
274 // TODO: check if the readed value is in range of the enum values!
275 enumValue = EnumType(value);
276 }
277 }
278
279 return retVal;
280}
281
282
283template <typename EnumType>
285 iser::IArchive& archive,
286 EnumType& enumValue,
287 const QObject* objectPtr)
288{
289 QByteArray enumValueAsText;
290 QMetaEnum foundEnumMeta;
291
292 QString enumTypeName = typeid(EnumType).name();
293 enumTypeName = enumTypeName.mid(enumTypeName.lastIndexOf(":") + 1);
294
295 if (objectPtr != nullptr){
296 const QMetaObject* metaObjectPtr = objectPtr->metaObject();
297
298 // Iterate over all enums of the class:
299 int enumeratorsCount = metaObjectPtr->enumeratorCount();
300 for (int enumeratorIndex = 0; enumeratorIndex < enumeratorsCount; ++enumeratorIndex){
301 QMetaEnum enumMeta = metaObjectPtr->enumerator(enumeratorIndex);
302 QString enumName = enumMeta.name();
303
304 if (enumTypeName == enumName){
305 foundEnumMeta = enumMeta;
306
307 // Find the enum value:
308 int keysCount = enumMeta.keyCount();
309 for (int keyIndex = 0; keyIndex < keysCount; ++keyIndex){
310
311 if (enumMeta.value(keyIndex) == enumValue){
312 enumValueAsText = enumMeta.valueToKey(keyIndex);
313 break;
314 }
315 }
316 }
317 }
318 }
319
320 bool retVal = true;
321
322 // Enum value is defined in textual form:
323 if (!enumValueAsText.isEmpty()){
324 retVal = retVal && archive.Process(enumValueAsText);
325
326 if (retVal && archive.IsChanging()){
327 Q_ASSERT(foundEnumMeta.isValid());
328
329 enumValue = EnumType(foundEnumMeta.keyToValue(enumValueAsText.constData(), &retVal));
330 }
331 }
332 else{
333 int value = enumValue;
334
335 retVal = retVal && archive.Process(value);
336
337 if (archive.IsChanging()){
338 // TODO: check if the readed value is in range of the enum values!
339 enumValue = EnumType(value);
340 }
341 }
342
343 return retVal;
344}
345
346
347#define I_SERIALIZE_FLAG(Enum, archive, flag) iser::CPrimitiveTypesSerializer::SerializeEnum<int, Enum##ToString, Enum##FromString>(archive, flag);
348#define I_SERIALIZE_ENUM(Enum, archive, enumValue) iser::CPrimitiveTypesSerializer::SerializeEnum<Enum, ToString, FromString>(archive, enumValue);
349
350
351} // namespace iser
352
353
Process tag used to group data in archive stream.
Definition CArchiveTag.h:25
Implementation of serialize method for some common data types.
static bool SerializeIndex(iser::IArchive &archive, istd::TIndex< Dimensions > &index)
Serialize a generic index object.
static bool SerializeDateTime(iser::IArchive &archive, QDateTime &dateTime)
Serialize QDateTime object.
static bool SerializeEnum(iser::IArchive &archive, EnumType &enumValue)
Method for serialization of the enumerated value using ICF's meta information extensions for the C++ ...
static bool SerializeSimpleContainer(iser::IArchive &archive, ContainterType &container, const iser::CArchiveTag &elementsTag, const iser::CArchiveTag &elementTag)
Serialize container of simple types.
static bool SerializeRanges(iser::IArchive &archive, istd::CRanges &ranges)
Serialize list of range objects.
static bool SerializeIntRanges(iser::IArchive &archive, istd::CIntRanges &ranges)
Serialize list of integer-based ranges.
static bool SerializeContainer(iser::IArchive &archive, ContainterType &container, const iser::CArchiveTag &elementsTag, const iser::CArchiveTag &elementTag)
Serialize container of serializable elements.
static bool SerializeQPointF(iser::IArchive &archive, QPointF &point)
Serialize a QPointF object.
static bool SerializeIntRange(iser::IArchive &archive, istd::CIntRange &range)
Serialize an integer-based range object.
static bool SerializeDate(iser::IArchive &archive, QDate &date)
Serialize QDate object.
static bool SerializeRange(iser::IArchive &archive, istd::CRange &range)
Serialize a range object.
Represent input/output persistence archive.
Definition IArchive.h:33
virtual bool Process(bool &value)=0
Process primitive type.
virtual bool EndTag(const CArchiveTag &tag)=0
End of archive tag.
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begin of archive tag containing set of subelements of the same type.
virtual bool IsChanging() const =0
Check if this archive processing change the object state.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begin of archive tag.
Multidimensional index used to addressing fixed-size array.
Definition TIndex.h:22
Set of ranges.
Definition TRanges.h:30
Contains general persistence mechanism with basic archives implementations.

© Witold Gantzke and Kirill Lepskiy