BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
Serialize.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Support/XML/Serialize.h
6 //! @brief Defines class Streamer
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2021
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifndef BORNAGAIN_GUI_SUPPORT_XML_SERIALIZE_H
16 #define BORNAGAIN_GUI_SUPPORT_XML_SERIALIZE_H
17 
19 #include <memory>
20 
21 //! Functions to serialize various data types.
22 //!
23 //! Serialization means writing to or reading from an XML stream.
24 //!
25 //! This namespace is spread over several source files
26 //! in order to keep include dependencies unidirectional.
27 
28 namespace Serialize {
29 
30 void rwValue(Streamer& s, const QString& tag, bool& val);
31 void rwValue(Streamer& s, const QString& tag, int& val);
32 void rwValue(Streamer& s, const QString& tag, double& val);
33 void rwValue(Streamer& s, const QString& tag, QString& val);
34 void rwValue(Streamer& s, const QString& tag, QColor& col);
35 void rwValue(Streamer& s, const QString& tag, QByteArray& val);
36 void rwValue(Streamer& s, const QString& tag, R3& val);
37 
38 //! Serializes an item from a class that provides the function `void serialize(Streamer&)`.
39 template <typename T>
40 void rwClass(Streamer& s, const QString& tag, T& t);
41 
42 //! Serializes part of an items that belongs to a given base class.
43 template <typename BaseClass>
44 void rwBaseClass(Streamer& s, const QString& tag, BaseClass* p);
45 
46 //! Serializes a list of items of known and fixed type.
47 //! Passes optional arguments to the constructor.
48 template <typename T, typename... Args>
49 void rwVector(Streamer& s, const QString& tag, QVector<T>& vec, Args... argsForConstructor);
50 
51 //! Serializes a list of items from a class hierarchy described by a catalog.
52 //! Passes optional arguments to the constructor.
53 template <typename Catalog, typename... Args>
54 void rwCatalogized(Streamer& s, const QString& tag, QVector<typename Catalog::CatalogedType*>& vec,
55  Args... argsForConstructor);
56 
57 //! Serializes an optional item of known type.
58 //! Passes optional arguments to the constructor.
59 template <typename ItemClass, typename... ArgsForConstructor>
60 void rwOptional(Streamer& s, const QString& tag, std::unique_ptr<ItemClass>& up,
61  ArgsForConstructor... argsForConstructor);
62 
63 //! Serializes an optional item of known type that needs an initializer.
64 //!
65 //! The initializer will be called after creation and before de-serialization
66 template <typename ItemClass>
67 void rwInitializable(Streamer& s, const QString& tag, std::unique_ptr<ItemClass>& up,
68  const std::function<void(ItemClass*)>& initializer);
69 
70 } // namespace Serialize
71 
72 // ************************************************************************************************
73 // Templates implementation
74 // ************************************************************************************************
75 
76 template <typename T>
77 void Serialize::rwClass(Streamer& s, const QString& tag, T& t)
78 {
79  s.start(tag);
80  t.serialize(s);
81  s.finish(tag);
82 }
83 
84 template <typename BaseClass>
85 void Serialize::rwBaseClass(Streamer& s, const QString& tag, BaseClass* p)
86 {
87  s.start(tag);
88  p->BaseClass::serialize(s);
89  s.finish(tag);
90 }
91 
92 template <typename T, typename... Args>
93 void Serialize::rwVector(Streamer& s, const QString& tag, QVector<T>& vec,
94  Args... argsForConstructor)
95 {
96  if (QXmlStreamWriter* w = s.xmlWriter()) {
97  w->writeStartElement(tag);
98  w->writeAttribute("n", QString::number(vec.size()));
99  int i = 0;
100  for (auto* p : vec)
101  Serialize::rwClass(s, "E" + QString::number(i++), *p);
102  w->writeEndElement();
103  } else if (QXmlStreamReader* r = s.xmlReader()) {
104  r->readNextStartElement();
105  s.assertCurrentTag(tag);
106  const int n = r->attributes().value("n").toInt();
107  for (int i = 0; i < n; i++) {
108  vec << new typename std::remove_pointer<T>::type(argsForConstructor...);
109  Serialize::rwClass(s, "E" + QString::number(i), *vec.last());
110  }
111  s.gotoEndElementOfTag(tag);
112  }
113 }
114 
115 template <typename Catalog, typename... Args>
116 void Serialize::rwCatalogized(Streamer& s, const QString& tag,
117  QVector<typename Catalog::CatalogedType*>& vec,
118  Args... argsForConstructor)
119 {
120  if (QXmlStreamWriter* w = s.xmlWriter()) {
121  w->writeStartElement(tag);
122  w->writeAttribute("n", QString::number(vec.size()));
123  int i = 0;
124  for (auto* p : vec) {
125  s.write<Catalog>("E" + QString::number(i++), p);
126  }
127  w->writeEndElement();
128  } else if (QXmlStreamReader* r = s.xmlReader()) {
129  r->readNextStartElement();
130  s.assertCurrentTag(tag);
131  const int n = r->attributes().value("n").toInt();
132  for (int i = 0; i < n; i++) {
133  typename Catalog::CatalogedType* p = nullptr;
134  s.read<Catalog>("E" + QString::number(i), p, argsForConstructor...);
135  vec << p;
136  }
137  s.gotoEndElementOfTag(tag);
138  }
139 }
140 
141 template <typename ItemClass, typename... ArgsForConstructor>
142 void Serialize::rwOptional(Streamer& s, const QString& tag, std::unique_ptr<ItemClass>& up,
143  ArgsForConstructor... argsForConstructor)
144 {
145  if (QXmlStreamWriter* w = s.xmlWriter()) {
146  w->writeStartElement(tag);
147  w->writeAttribute("valid", up ? "1" : "0");
148  if (up)
149  up->serialize(s);
150  w->writeEndElement();
151  } else if (QXmlStreamReader* r = s.xmlReader()) {
152  s.gotoStartElementOfTag(tag);
153  const bool valid = r->attributes().value("valid").toUInt() > 0;
154  if (valid) {
155  up.reset(new ItemClass(argsForConstructor...));
156  up->serialize(s);
157  } else
158  up.reset();
159  s.gotoEndElementOfTag(tag);
160  }
161 }
162 
163 template <typename ItemClass>
164 void Serialize::rwInitializable(Streamer& s, const QString& tag, std::unique_ptr<ItemClass>& up,
165  const std::function<void(ItemClass*)>& initializer)
166 {
167  if (QXmlStreamWriter* w = s.xmlWriter()) {
168  w->writeStartElement(tag);
169  w->writeAttribute("valid", up ? "1" : "0");
170  if (up)
171  up->serialize(s);
172  w->writeEndElement();
173  } else if (QXmlStreamReader* r = s.xmlReader()) {
174  s.gotoStartElementOfTag(tag);
175  const bool valid = r->attributes().value("valid").toUInt() > 0;
176  if (valid) {
177  up.reset(new ItemClass());
178  if (initializer)
179  initializer(up.get());
180  up->serialize(s);
181  } else
182  up.reset();
183  s.gotoEndElementOfTag(tag);
184  }
185 }
186 
187 #endif // BORNAGAIN_GUI_SUPPORT_XML_SERIALIZE_H
Defines class Streamer.
Supports serialization to or deserialization from QXmlStream.
Definition: Streamer.h:36
void gotoEndElementOfTag(const QString &tag)
Definition: Streamer.cpp:39
void start(const QString &tag)
Definition: Streamer.cpp:82
void write(const QString &tag, typename Catalog::CatalogedType *p)
Definition: Streamer.h:82
void assertCurrentTag(const QString &expectedTag) const
Definition: Streamer.cpp:62
void gotoStartElementOfTag(const QString &tag)
Definition: Streamer.cpp:54
QXmlStreamWriter * xmlWriter()
Returns stream writer or nullptr.
Definition: Streamer.h:47
QXmlStreamReader * xmlReader()
Returns stream reader or nullptr.
Definition: Streamer.h:48
void read(const QString &tag, typename Catalog::CatalogedType *&p, Args... argsForConstructor)
Definition: Streamer.h:93
void finish(const QString &tag)
Definition: Streamer.cpp:90
Functions to serialize various data types.
Definition: SessionItem.h:339
void rwVector(Streamer &s, const QString &tag, QVector< T > &vec, Args... argsForConstructor)
Serializes a list of items of known and fixed type. Passes optional arguments to the constructor.
Definition: Serialize.h:93
void rwBaseClass(Streamer &s, const QString &tag, BaseClass *p)
Serializes part of an items that belongs to a given base class.
Definition: Serialize.h:85
void rwValue(Streamer &s, const QString &tag, bool &val)
Definition: Serialize.cpp:19
void rwClass(Streamer &s, const QString &tag, T &t)
Serializes an item from a class that provides the function void serialize(Streamer&).
Definition: Serialize.h:77
void rwCatalogized(Streamer &s, const QString &tag, QVector< typename Catalog::CatalogedType * > &vec, Args... argsForConstructor)
Serializes a list of items from a class hierarchy described by a catalog. Passes optional arguments t...
Definition: Serialize.h:116
void rwOptional(Streamer &s, const QString &tag, std::unique_ptr< ItemClass > &up, ArgsForConstructor... argsForConstructor)
Serializes an optional item of known type. Passes optional arguments to the constructor.
Definition: Serialize.h:142
void rwInitializable(Streamer &s, const QString &tag, std::unique_ptr< ItemClass > &up, const std::function< void(ItemClass *)> &initializer)
Serializes an optional item of known type that needs an initializer.
Definition: Serialize.h:164