├── .gitignore
├── LICENSE
├── QSerializer
├── README.md
├── _config.yml
├── benchmarks
├── bench.cpp
├── bench.h
├── benchmarks.pro
└── testclasses.h
├── example
├── QSerializeExample.pro
├── classes.h
├── general.json
├── general.xml
└── main.cpp
├── qserializer.pri
└── src
└── qserializer.h
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by Visual Studio
5 | *.obj
6 | ;*.exe
7 | *.pdb
8 | *.user
9 | *.aps
10 | *.pch
11 | *.vspscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | #*.tlb
17 | *.tlh
18 | *.bak
19 | *.cache
20 | *.ilk
21 | *.log
22 | *.tlog
23 | ;[Bb]in
24 | [Dd]ebug*/
25 | ;*.lib
26 | *.sbr
27 | obj/
28 | [Rr]elease*/
29 | _ReSharper*/
30 | [Tt]est[Rr]esult*
31 | doc/
32 | *.rar
33 | *.arj
34 | *.arh
35 | *.scc
36 | *.ipch
37 | *.opensdf
38 | *.sdf
39 | *.opt
40 | *.plg
41 | *.vssscc
42 | *.cd
43 | *.tli
44 | *.crc
45 | Makefile
46 | Makefile.*
47 | #--- *.filters
48 | [Bb]uild-*
49 | .*
50 | *.pro.*
51 | ipch/
52 | Virtual/
53 | VSS_BD/
54 | __WPF__/
55 | Векторная графика/
56 |
57 | *.autosave
58 | pictures/log/*
59 |
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020-2021 Agadzhanov Vladimir
4 | Portions Copyright (c) 2021 Jerry Jacobs
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/QSerializer:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "src/qserializer.h"
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [
]()
2 | This project is designed to convert data from an object view to JSON or XML and opposite in the Qt/C++ ecosystem. C ++ classes by default do not have the required meta-object information for serializing class fields, but Qt is equipped with its own highly efficient meta-object system.
3 | An important feature of the QSerializer is the ability to specify serializable fields of the class without having to serialize the entire class. QSerilaizer generate code and declare `Q_PROPERTY` for every declared member of class. This is convenient because you do not need to create separate structures or classes for serialization of write some code to serialize every class, it's just included to QSerializer.
4 |
5 | ## Installation
6 | Download repository
7 | ```bash
8 | $ git clone https://github.com/smurfomen/QSerializer.git
9 | ```
10 | Just include qserializer.h in your project and enjoy simple serialization. qserializer.h located in src folder.
11 | Set compiler define `QS_HAS_JSON` or `QS_HAS_XML` for enabling support for xml or json. Enable both at the same time
12 | [is not supported](https://github.com/smurfomen/QSerializer/issues/7).
13 |
14 | A demo project for using QSerializer located in example folder.
15 |
16 | ## Workflow
17 | To get started, include qserializer.h in your code.
18 | ## Create serialization class
19 | For create serializable member of class and generate propertyes, use macro:
20 | - __QS_FIELD__
21 | - __QS_COLLECTION__
22 | - __QS_OBJECT__
23 | - __QS_COLLECTION_OBJECTS__
24 | - __QS_QT_DICT__
25 | - __QS_QT_DICT_OBJECTS__
26 | - __QS_STL_DICT__
27 | - __QS_STL_DICT_OBJECTS__
28 |
29 | If you want only declare exists fields - use macro QS_JSON_FIELD, QS_XML_FIELD, QS_JSON_COLLECTION and other (look at qserializer.h)
30 | ### Inherit from QSerializer
31 | Inherit from QSerializer, use macro QS_SERIALIZABLE or override metaObject method and declare some serializable fields.
32 | In this case you must use Q_GADGET in your class.
33 | ```C++
34 | class User : public QSerializer
35 | {
36 | Q_GADGET
37 | QS_SERIALIZABLE
38 | // Create data members to be serialized - you can use this members in code
39 | QS_FIELD(int, age)
40 | QS_COLLECTION(QVector, QString, parents)
41 | };
42 | ```
43 | ## **Serialize**
44 | Now you can serialize object of this class to JSON or XML.
45 | For example:
46 | ```C++
47 | User u;
48 | u.age = 20;
49 | u.parents.append("Mary");
50 | u.parents.append("Jeff");
51 |
52 | /* case: json value */
53 | QJsonObject jsonUser = u.toJson();
54 |
55 | /* case: raw json data */
56 | QByteArray djson = u.toRawJson();
57 |
58 | /* case: xml-dom */
59 | QDomNode xmlUser = u.toXml();
60 |
61 | /* case: raw xml data */
62 | QByteArray dxml = u.toRawXml();
63 | ```
64 |
65 | ## **Deserialize**
66 | Opposite of the serialization procedure is the deserialization procedure.
67 | You can deserialize object from JSON or XML, declared fields will be modified or resets to default for this type values.
68 | For example:
69 | ```C++
70 | ...
71 | User u;
72 |
73 | /* case: json value */
74 | QJsonObject json;
75 | u.fromJson(json);
76 |
77 | /* case: raw json data */
78 | QByteArray rawJson;
79 | u.fromJson(rawJson);
80 |
81 | /* case: xml-dom */
82 | QDomNode xml;
83 | u.fromXml(xml);
84 |
85 | /* case: raw xml data */
86 | QByteArray rawXml;
87 | u.fromXml(rawXml);
88 | ```
89 | ## Macro description
90 | | Macro | Description |
91 | | --------------------- | ------------------------------------------------------------ |
92 | | QSERIALIZABLE | Make class or struct is serializable to QSerializer (override QMetaObject method and define Q_GADGET macro) |
93 | | QS_FIELD | Create serializable simple field |
94 | | QS_COLLECTION | Create serializable collection values of primitive types |
95 | | QS_OBJECT | Create serializable inner custom type object |
96 | | QS_COLLECTION_OBJECTS | Create serializable collection of custom type objects |
97 | | QS_QT_DICT | Create serializable dictionary of primitive type values FOR QT DICTIONARY TYPES |
98 | | QS_QT_DICT_OBJECTS | Create serializable dictionary of custom type values FOR QT DICTIONARY TYPES |
99 | | QS_STL_DICT | Create serializable dictionary of primitive type values FOR STL DICTIONARY TYPES |
100 | | QS_STL_DICT_OBJECTS | Create serializable dictionary of custom type values FOR STL DICTIONARY TYPES |
101 | | QS_SERIALIZABLE | Override method metaObject and make class serializable |
102 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/benchmarks/bench.cpp:
--------------------------------------------------------------------------------
1 | #include "bench.h"
2 | #include
3 |
4 | void Bench::bench_field_int_toJson() {
5 | TestField_int test;
6 | test.field_int = 999;
7 | QBENCHMARK{
8 | test.toJson();
9 | }
10 | }
11 |
12 | void Bench::bench_field_int_toXml() {
13 | TestField_int test;
14 | test.field_int = 999;
15 | QBENCHMARK{
16 | test.toXml();
17 | }
18 | }
19 |
20 | void Bench::bench_field_int_fromJson() {
21 | TestField_int test;
22 | test.field_int = 999;
23 | QJsonObject json = test.toJson();
24 | TestField_int dest;
25 | QBENCHMARK{
26 | dest.fromJson(json);
27 | }
28 | }
29 |
30 | void Bench::bench_field_int_fromXml() {
31 | TestField_int test;
32 | test.field_int = 999;
33 | QDomNode xml = test.toXml();
34 | TestField_int dest;
35 | QBENCHMARK{
36 | dest.fromXml(QSerializer::toByteArray(xml));
37 | }
38 | }
39 |
40 | void Bench::bench_field_string_toJson() {
41 | TestField_string test;
42 | test.field_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
43 | QBENCHMARK{
44 | test.toJson();
45 | }
46 | }
47 |
48 | void Bench::bench_field_string_toXml() {
49 | TestField_string test;
50 | test.field_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
51 | QBENCHMARK{
52 | test.toXml();
53 | }
54 | }
55 |
56 | void Bench::bench_field_string_fromJson() {
57 | TestField_string test;
58 | test.field_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
59 | QJsonObject json = test.toJson();
60 | TestField_string dest;
61 | QBENCHMARK{
62 | dest.fromJson(json);
63 | }
64 | }
65 |
66 | void Bench::bench_field_string_fromXml() {
67 | TestField_string test;
68 | test.field_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
69 | QDomNode xml = test.toXml();
70 | TestField_string dest;
71 | QBENCHMARK{
72 | dest.fromXml(QSerializer::toByteArray(xml));
73 | }
74 | }
75 |
76 | void Bench::bench_collection_vector_int_toJson() {
77 | TestCollection_vector_int test;
78 | for(int i = 0; i < 100; i++)
79 | test.vector_int.append(i);
80 | QBENCHMARK{
81 | test.toJson();
82 | }
83 | }
84 |
85 | void Bench::bench_collection_vector_int_toXml() {
86 | TestCollection_vector_int test;
87 | for(int i = 0; i < 100; i++)
88 | test.vector_int.append(i);
89 | QBENCHMARK{
90 | test.toXml();
91 | }
92 | }
93 |
94 | void Bench::bench_collection_vector_int_fromJson() {
95 | TestCollection_vector_int test;
96 | for(int i = 0; i < 100; i++)
97 | test.vector_int.append(i);
98 | QJsonObject json = test.toJson();
99 | TestCollection_vector_int dest;
100 | QBENCHMARK{
101 | dest.fromJson(json);
102 | }
103 | }
104 |
105 | void Bench::bench_collection_vector_int_fromXml() {
106 | TestCollection_vector_int test;
107 | for(int i = 0; i < 100; i++)
108 | test.vector_int.append(i);
109 | QDomNode xml = test.toXml();
110 | TestCollection_vector_int dest;
111 | QBENCHMARK{
112 | dest.fromXml(QSerializer::toByteArray(xml));
113 | }
114 | }
115 |
116 | void Bench::bench_collection_vector_string_toJson() {
117 | TestCollection_vector_string test;
118 | for(int i = 0; i < 100; i++)
119 | test.vector_string.append(QString::number(i));
120 | QBENCHMARK{
121 | test.toJson();
122 | }
123 | }
124 |
125 | void Bench::bench_collection_vector_string_toXml() {
126 | TestCollection_vector_string test;
127 | for(int i = 0; i < 100; i++)
128 | test.vector_string.append(QString::number(i));
129 | QBENCHMARK{
130 | test.toXml();
131 | }
132 | }
133 |
134 | void Bench::bench_collection_vector_string_fromJson() {
135 | TestCollection_vector_string test;
136 | for(int i = 0; i < 100; i++)
137 | test.vector_string.append(QString::number(i));
138 | QJsonObject json = test.toJson();
139 | TestCollection_vector_string dest;
140 | QBENCHMARK{
141 | dest.fromJson(json);
142 | }
143 | }
144 |
145 | void Bench::bench_collection_vector_string_fromXml() {
146 | TestCollection_vector_string test;
147 | for(int i = 0; i < 100; i++)
148 | test.vector_string.append(QString::number(i));
149 | QDomNode xml = test.toXml();
150 | TestCollection_vector_string dest;
151 | QBENCHMARK{
152 | dest.fromXml(QSerializer::toByteArray(xml));
153 | }
154 | }
155 |
156 | void Bench::bench_object_field_toJson() {
157 | TestObject_field test;
158 |
159 | test.f_object.f_int = 999;
160 | test.f_object.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
161 | for(int i = 0; i< 100; i++)
162 | {
163 | test.f_object.v_int.append(i);
164 | test.f_object.v_string.append(QString::number(i));
165 | }
166 | QBENCHMARK{
167 | test.toJson();
168 | }
169 | }
170 |
171 | void Bench::bench_object_field_toXml() {
172 | TestObject_field test;
173 |
174 | test.f_object.f_int = 999;
175 | test.f_object.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
176 | for(int i = 0; i< 100; i++)
177 | {
178 | test.f_object.v_int.append(i);
179 | test.f_object.v_string.append(QString::number(i));
180 | }
181 | QBENCHMARK{
182 | test.toXml();
183 | }
184 | }
185 |
186 | void Bench::bench_object_field_fromJson() {
187 | TestObject_field test;
188 |
189 | test.f_object.f_int = 999;
190 | test.f_object.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
191 | for(int i = 0; i< 100; i++)
192 | {
193 | test.f_object.v_int.append(i);
194 | test.f_object.v_string.append(QString::number(i));
195 | }
196 | QJsonObject json = test.toJson();
197 | TestObject_field dest;
198 | QBENCHMARK{
199 | dest.fromJson(json);
200 | }
201 | }
202 |
203 | void Bench::bench_object_field_fromXml() {
204 | TestObject_field test;
205 |
206 | test.f_object.f_int = 999;
207 | test.f_object.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
208 | for(int i = 0; i< 100; i++)
209 | {
210 | test.f_object.v_int.append(i);
211 | test.f_object.v_string.append(QString::number(i));
212 | }
213 |
214 | QDomNode xml = test.toXml();
215 | TestObject_field dest;
216 | QBENCHMARK{
217 | dest.fromXml(QSerializer::toByteArray(xml));
218 | }
219 | }
220 |
221 | void Bench::bench_collection_objects_toJson() {
222 | TestObject_collection test;
223 | for(int i = 0; i < 100; i++)
224 | {
225 | Object obj;
226 | obj.f_int = 999;
227 | obj.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
228 | for(int i = 0; i< 100; i++)
229 | {
230 | obj.v_int.append(i);
231 | obj.v_string.append(QString::number(i));
232 | }
233 | test.vector_object.append(obj);
234 | }
235 | QBENCHMARK{
236 | test.toJson();
237 | }
238 | }
239 |
240 | void Bench::bench_collection_objects_toXml() {
241 | TestObject_collection test;
242 | for(int i = 0; i < 100; i++)
243 | {
244 | Object obj;
245 | obj.f_int = 999;
246 | obj.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
247 | for(int i = 0; i< 100; i++)
248 | {
249 | obj.v_int.append(i);
250 | obj.v_string.append(QString::number(i));
251 | }
252 | test.vector_object.append(obj);
253 | }
254 | QBENCHMARK{
255 | test.toXml();
256 | }
257 | }
258 |
259 | void Bench::bench_collection_objects_fromJson() {
260 | TestObject_collection test;
261 | for(int i = 0; i < 100; i++)
262 | {
263 | Object obj;
264 | obj.f_int = 999;
265 | obj.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
266 | for(int i = 0; i< 100; i++)
267 | {
268 | obj.v_int.append(i);
269 | obj.v_string.append(QString::number(i));
270 | }
271 | test.vector_object.append(obj);
272 | }
273 | QJsonObject json = test.toJson();
274 | TestObject_collection dest;
275 | QBENCHMARK{
276 | dest.fromJson(json);
277 | }
278 | }
279 |
280 | void Bench::bench_collection_objects_fromXml() {
281 | TestObject_collection test;
282 | for(int i = 0; i < 100; i++)
283 | {
284 | Object obj;
285 | obj.f_int = 999;
286 | obj.f_string = "QWERTYUIOP{ASDFGHJKL:ZXCVBNM<>?";
287 | for(int i = 0; i< 5; i++)
288 | {
289 | obj.v_int.append(i);
290 | obj.v_string.append(QString::number(i));
291 | }
292 | test.vector_object.append(obj);
293 | }
294 | QDomNode xml = test.toXml();
295 | TestObject_collection dest;
296 | QBENCHMARK{
297 | dest.fromXml(xml);
298 | }
299 | }
300 |
301 |
302 |
303 | QTEST_MAIN(Bench);
304 |
--------------------------------------------------------------------------------
/benchmarks/bench.h:
--------------------------------------------------------------------------------
1 | #ifndef BENCH_H
2 | #define BENCH_H
3 | #include
4 | #include
5 | #include "testclasses.h"
6 |
7 | class Bench : public QObject {
8 | Q_OBJECT
9 | private Q_SLOTS:
10 | //========================================================================================================================================
11 | void bench_field_int_toJson();
12 |
13 | void bench_field_int_toXml();
14 |
15 | void bench_field_int_fromJson();
16 |
17 | void bench_field_int_fromXml();
18 | //========================================================================================================================================
19 |
20 |
21 |
22 | //========================================================================================================================================
23 | void bench_field_string_toJson();
24 |
25 | void bench_field_string_toXml();
26 |
27 | void bench_field_string_fromJson();
28 |
29 | void bench_field_string_fromXml();
30 | //========================================================================================================================================
31 |
32 |
33 |
34 | //========================================================================================================================================
35 | void bench_collection_vector_int_toJson();
36 |
37 | void bench_collection_vector_int_toXml();
38 |
39 | void bench_collection_vector_int_fromJson();
40 |
41 | void bench_collection_vector_int_fromXml();
42 | //========================================================================================================================================
43 |
44 |
45 |
46 | //========================================================================================================================================
47 | void bench_collection_vector_string_toJson();
48 |
49 | void bench_collection_vector_string_toXml();
50 |
51 | void bench_collection_vector_string_fromJson();
52 |
53 | void bench_collection_vector_string_fromXml();
54 | //========================================================================================================================================
55 |
56 |
57 | //========================================================================================================================================
58 | void bench_object_field_toJson();
59 |
60 | void bench_object_field_toXml();
61 |
62 | void bench_object_field_fromJson();
63 |
64 | void bench_object_field_fromXml();
65 | //========================================================================================================================================
66 |
67 |
68 |
69 | //========================================================================================================================================
70 | void bench_collection_objects_toJson();
71 |
72 | void bench_collection_objects_toXml();
73 |
74 | void bench_collection_objects_fromJson();
75 | void bench_collection_objects_fromXml();
76 | //========================================================================================================================================
77 |
78 | };
79 |
80 | #endif // BENCH_H
81 |
--------------------------------------------------------------------------------
/benchmarks/benchmarks.pro:
--------------------------------------------------------------------------------
1 | QT -= gui
2 | QT += testlib
3 | CONFIG += c++11 console
4 | CONFIG -= app_bundle
5 |
6 | # The following define makes your compiler emit warnings if you use
7 | # any Qt feature that has been marked deprecated (the exact warnings
8 | # depend on your compiler). Please consult the documentation of the
9 | # deprecated API in order to know how to port your code away from it.
10 | DEFINES += QT_DEPRECATED_WARNINGS
11 |
12 | # You can also make your code fail to compile if it uses deprecated APIs.
13 | # In order to do so, uncomment the following line.
14 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
15 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
16 |
17 | SOURCES += \
18 | bench.cpp
19 |
20 | # Default rules for deployment.
21 | qnx: target.path = /tmp/$${TARGET}/bin
22 | else: unix:!android: target.path = /opt/$${TARGET}/bin
23 | !isEmpty(target.path): INSTALLS += target
24 |
25 | include(../src/QSerializer.pri)
26 |
27 | HEADERS += \
28 | bench.h \
29 | testclasses.h
30 |
--------------------------------------------------------------------------------
/benchmarks/testclasses.h:
--------------------------------------------------------------------------------
1 | #ifndef TESTCLASSES_H
2 | #define TESTCLASSES_H
3 |
4 | #include "../src/qserializer.h"
5 | #include
6 |
7 | class TestField_int {
8 | Q_GADGET
9 | QS_CLASS
10 | QS_FIELD(int, field_int)
11 | };
12 |
13 | class TestField_string{
14 | Q_GADGET
15 | QS_CLASS
16 | QS_FIELD(QString, field_string)
17 | };
18 |
19 | class TestCollection_vector_int {
20 | Q_GADGET
21 | QS_CLASS
22 | QS_COLLECTION(QVector, int, vector_int)
23 | };
24 |
25 | class TestCollection_vector_string {
26 | Q_GADGET
27 | QS_CLASS
28 | QS_COLLECTION(QVector, QString, vector_string)
29 | };
30 |
31 |
32 |
33 | class Object
34 | {
35 | Q_GADGET
36 | QS_CLASS
37 | QS_FIELD(int, f_int)
38 | QS_FIELD(QString, f_string)
39 | QS_COLLECTION(QVector, int, v_int)
40 | QS_COLLECTION(QVector, QString, v_string)
41 | };
42 |
43 |
44 | class TestObject_field {
45 | Q_GADGET
46 | QS_CLASS
47 | QS_OBJECT(Object, f_object)
48 | };
49 |
50 |
51 | class TestObject_collection{
52 | Q_GADGET
53 | QS_CLASS
54 | QS_COLLECTION_OBJECTS(QVector, Object, vector_object)
55 | };
56 |
57 |
58 | #endif // TESTCLASSES_H
59 |
--------------------------------------------------------------------------------
/example/QSerializeExample.pro:
--------------------------------------------------------------------------------
1 | QT -= gui
2 | QT += core
3 | CONFIG += c++11 console
4 | CONFIG -= app_bundle
5 |
6 | # The following define makes your compiler emit warnings if you use
7 | # any Qt feature that has been marked deprecated (the exact warnings
8 | # depend on your compiler). Please consult the documentation of the
9 | # deprecated API in order to know how to port your code away from it.
10 | #DEFINES += QT_DEPRECATED_WARNINGS
11 |
12 | # You can also make your code fail to compile if it uses deprecated APIs.
13 | # In order to do so, uncomment the following line.
14 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
15 | # DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060201 # disables all the APIs deprecated before Qt 6.2.1
16 | DEFINES += QS_HAS_JSON
17 | DEFINES += QS_HAS_XML
18 |
19 | include(../qserializer.pri)
20 |
21 | SOURCES += \
22 | main.cpp
23 |
24 | HEADERS += \
25 | $$PWD/classes.h
26 |
27 | DISTFILES += \
28 | $$PWD/general.json \
29 | $$PWD/general.xml \
30 |
31 | # Default rules for deployment.
32 | qnx: target.path = /tmp/$${TARGET}/bin
33 | else: unix:!android: target.path = /opt/$${TARGET}/bin
34 | !isEmpty(target.path): INSTALLS += target
35 |
--------------------------------------------------------------------------------
/example/classes.h:
--------------------------------------------------------------------------------
1 | #ifndef CLASSES_H
2 | #define CLASSES_H
3 | #include
4 | #include
5 | #include
6 |
7 | class Parent : public QSerializer{
8 | Q_GADGET
9 | QS_SERIALIZABLE
10 | public:
11 | Parent(){ }
12 | Parent(int age, const QString & name, bool isMale)
13 | : age(age),
14 | name(name),
15 | male(isMale) { }
16 | QS_FIELD(int, age)
17 | QS_FIELD(QString, name)
18 | QS_FIELD(bool, male)
19 | };
20 |
21 | class Student : public QSerializer {
22 | Q_GADGET
23 | QS_SERIALIZABLE
24 | public:
25 | Student() {}
26 | Student(int age, const QString & name, QStringList links, Parent mom, Parent dad)
27 | : age(age),
28 | name(name),
29 | links(links)
30 | {
31 | parents.append(mom);
32 | parents.append(dad);
33 | }
34 | QS_FIELD(int, age)
35 | QS_FIELD(QString, name)
36 | QS_COLLECTION(QList, QString, links)
37 | QS_COLLECTION_OBJECTS(QList, Parent, parents)
38 | };
39 |
40 | class Dictionaries : public QSerializer {
41 | Q_GADGET
42 | QS_SERIALIZABLE
43 | QS_QT_DICT(QHash, QString, QString, qt_hash)
44 | QS_QT_DICT(QMap, QString, QString, qt_map)
45 | QS_QT_DICT_OBJECTS(QMap, QString, Student, qt_map_objects);
46 | QS_STL_DICT(std::map, int, QString, std_map)
47 | QS_STL_DICT_OBJECTS(std::map, QString, Student, std_map_objects);
48 | };
49 |
50 |
51 | class Field : public QSerializer {
52 | Q_GADGET
53 | QS_SERIALIZABLE
54 | QS_FIELD(int, digit)
55 | QS_FIELD(QString, string)
56 | QS_FIELD(bool, flag)
57 | QS_FIELD(double, d_digit)
58 | };
59 |
60 |
61 | class Collection : public QSerializer{
62 | Q_GADGET
63 | QS_SERIALIZABLE
64 | QS_COLLECTION(QVector, int, vector)
65 | QS_COLLECTION(QList, QString, list)
66 | QS_COLLECTION(QStack, double, stack)
67 | };
68 |
69 |
70 | class CustomObject : public QSerializer {
71 | Q_GADGET
72 | QS_SERIALIZABLE
73 | QS_FIELD(int, digit)
74 | QS_COLLECTION(QVector, QString, string)
75 | };
76 |
77 |
78 | class CollectionOfObjects : public QSerializer{
79 | Q_GADGET
80 | QS_SERIALIZABLE
81 | QS_COLLECTION_OBJECTS(QVector, CustomObject, objects)
82 | };
83 |
84 |
85 | class General : public QSerializer{
86 | Q_GADGET
87 | QS_SERIALIZABLE
88 | QS_OBJECT(Field, field)
89 | QS_OBJECT(Collection, collection)
90 | QS_OBJECT(CustomObject, object)
91 | QS_OBJECT(CollectionOfObjects, collectionObjects)
92 | QS_OBJECT(Dictionaries, dictionaries)
93 | };
94 |
95 | class TestXmlObject : public QSerializer{
96 | Q_GADGET
97 | QS_SERIALIZABLE
98 | QS_FIELD(int, digit)
99 | QS_COLLECTION(QVector, QString, string)
100 | };
101 |
102 | class TestXml : public QSerializer{
103 | Q_GADGET
104 | QS_SERIALIZABLE
105 | QS_FIELD(int, field)
106 | QS_COLLECTION(QVector, int, collection)
107 | QS_OBJECT(TestXmlObject, object)
108 | };
109 |
110 |
111 |
112 | #endif // CLASSES_H
113 |
--------------------------------------------------------------------------------
/example/general.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "list": [
4 | "first",
5 | "second",
6 | "third"
7 | ],
8 | "stack": [
9 | 2.44,
10 | 4.42,
11 | 77
12 | ],
13 | "vector": [
14 | 0,
15 | 1,
16 | 2,
17 | 3,
18 | 4,
19 | 5
20 | ]
21 | },
22 | "collectionObjects": {
23 | "objects": [
24 | {
25 | "digit": 0,
26 | "string": [
27 | "so it's just index number in binary 0",
28 | "so it's just index number in binary 1",
29 | "so it's just index number in binary 10",
30 | "so it's just index number in binary 11",
31 | "so it's just index number in binary 100"
32 | ]
33 | },
34 | {
35 | "digit": 1,
36 | "string": [
37 | "so it's just index number in binary 1",
38 | "so it's just index number in binary 10",
39 | "so it's just index number in binary 11",
40 | "so it's just index number in binary 100",
41 | "so it's just index number in binary 101"
42 | ]
43 | },
44 | {
45 | "digit": 2,
46 | "string": [
47 | "so it's just index number in binary 10",
48 | "so it's just index number in binary 11",
49 | "so it's just index number in binary 100",
50 | "so it's just index number in binary 101",
51 | "so it's just index number in binary 110"
52 | ]
53 | },
54 | {
55 | "digit": 3,
56 | "string": [
57 | "so it's just index number in binary 11",
58 | "so it's just index number in binary 100",
59 | "so it's just index number in binary 101",
60 | "so it's just index number in binary 110",
61 | "so it's just index number in binary 111"
62 | ]
63 | },
64 | {
65 | "digit": 4,
66 | "string": [
67 | "so it's just index number in binary 100",
68 | "so it's just index number in binary 101",
69 | "so it's just index number in binary 110",
70 | "so it's just index number in binary 111",
71 | "so it's just index number in binary 1000"
72 | ]
73 | }
74 | ]
75 | },
76 | "dictionaries": {
77 | "qt_hash": {
78 | },
79 | "qt_map": {
80 | "abra": "kadabra",
81 | "ping": "pong"
82 | },
83 | "qt_map_objects": {
84 | "+7(909)000-01-00": {
85 | "age": 22,
86 | "links": [
87 | "http://katelink.com"
88 | ],
89 | "name": "Kate",
90 | "parents": [
91 | {
92 | "age": 44,
93 | "male": false,
94 | "name": "Marlin"
95 | },
96 | {
97 | "age": 48,
98 | "male": true,
99 | "name": "Jake"
100 | }
101 | ]
102 | },
103 | "+7(909)100-00-10": {
104 | "age": 22,
105 | "links": [
106 | "http://bobsite.com"
107 | ],
108 | "name": "Bob",
109 | "parents": [
110 | {
111 | "age": 44,
112 | "male": false,
113 | "name": "Mary"
114 | },
115 | {
116 | "age": 48,
117 | "male": true,
118 | "name": "Koul"
119 | }
120 | ]
121 | }
122 | },
123 | "std_map": {
124 | "1": "first",
125 | "2": "second"
126 | },
127 | "std_map_objects": {
128 | "+7(909)000-10-00": {
129 | "age": 21,
130 | "links": [
131 | "http://somelink.com"
132 | ],
133 | "name": "Jane",
134 | "parents": [
135 | {
136 | "age": 38,
137 | "male": false,
138 | "name": "Elie"
139 | },
140 | {
141 | "age": 48,
142 | "male": true,
143 | "name": "John"
144 | }
145 | ]
146 | },
147 | "+7(909)001-00-00": {
148 | "age": 22,
149 | "links": [
150 | "http://github.com/smurfomen"
151 | ],
152 | "name": "Ken",
153 | "parents": [
154 | {
155 | "age": 44,
156 | "male": false,
157 | "name": "Olga"
158 | },
159 | {
160 | "age": 48,
161 | "male": true,
162 | "name": "Alex"
163 | }
164 | ]
165 | }
166 | }
167 | },
168 | "field": {
169 | "d_digit": 88.99,
170 | "digit": 34,
171 | "flag": false,
172 | "string": "some string"
173 | },
174 | "object": {
175 | "digit": 8,
176 | "string": [
177 | "third",
178 | "second",
179 | "first"
180 | ]
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/example/general.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34
4 | some string
5 | false
6 | 88.99
7 |
8 |
9 |
10 | - 0
11 | - 1
12 | - 2
13 | - 3
14 | - 4
15 | - 5
16 |
17 |
18 | - first
19 | - second
20 | - third
21 |
22 |
23 | - 2.44
24 | - 4.42
25 | - 77
26 |
27 |
28 |
29 | 8
30 |
31 | - third
32 | - second
33 | - first
34 |
35 |
36 |
37 |
38 |
39 | 0
40 |
41 | - so it's just index number in binary 0
42 | - so it's just index number in binary 1
43 | - so it's just index number in binary 10
44 | - so it's just index number in binary 11
45 | - so it's just index number in binary 100
46 |
47 |
48 |
49 | 1
50 |
51 | - so it's just index number in binary 1
52 | - so it's just index number in binary 10
53 | - so it's just index number in binary 11
54 | - so it's just index number in binary 100
55 | - so it's just index number in binary 101
56 |
57 |
58 |
59 | 2
60 |
61 | - so it's just index number in binary 10
62 | - so it's just index number in binary 11
63 | - so it's just index number in binary 100
64 | - so it's just index number in binary 101
65 | - so it's just index number in binary 110
66 |
67 |
68 |
69 | 3
70 |
71 | - so it's just index number in binary 11
72 | - so it's just index number in binary 100
73 | - so it's just index number in binary 101
74 | - so it's just index number in binary 110
75 | - so it's just index number in binary 111
76 |
77 |
78 |
79 | 4
80 |
81 | - so it's just index number in binary 100
82 | - so it's just index number in binary 101
83 | - so it's just index number in binary 110
84 | - so it's just index number in binary 111
85 | - so it's just index number in binary 1000
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | -
98 |
99 | 22
100 | Kate
101 |
102 |
- http://katelink.com
103 |
104 |
105 |
106 | 44
107 | Marlin
108 | false
109 |
110 |
111 | 48
112 | Jake
113 | true
114 |
115 |
116 |
117 |
118 | -
119 |
120 | 22
121 | Bob
122 |
123 |
- http://bobsite.com
124 |
125 |
126 |
127 | 44
128 | Mary
129 | false
130 |
131 |
132 | 48
133 | Koul
134 | true
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | -
146 |
147 | 21
148 | Jane
149 |
150 |
- http://somelink.com
151 |
152 |
153 |
154 | 38
155 | Elie
156 | false
157 |
158 |
159 | 48
160 | John
161 | true
162 |
163 |
164 |
165 |
166 | -
167 |
168 | 22
169 | Ken
170 |
171 |
- http://github.com/smurfomen
172 |
173 |
174 |
175 | 44
176 | Olga
177 | false
178 |
179 |
180 | 48
181 | Alex
182 | true
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/example/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "classes.h"
3 |
4 | #include
5 | #include
6 |
7 | #ifdef QS_HAS_JSON
8 | void json_example() {
9 | qDebug() << "==================================== json_example ====================================";
10 | Student stud;
11 | stud.age = 23;
12 | stud.name = "Vlad";
13 | stud.links.append("https:/github.com/smurfomen");
14 |
15 | Parent mother;
16 | mother.age = 43;
17 | mother.male = false;
18 | mother.name = "Olga";
19 |
20 | Parent father;
21 | father.age = 48;
22 | father.male = true;
23 | father.name = "Alex";
24 | stud.parents.append(mother);
25 | stud.parents.append(father);
26 |
27 | qDebug() << "json from object:";
28 | QByteArray d = stud.toRawJson();
29 | qDebug() << d.constData();
30 |
31 | qDebug() << "creation new object using raw json:";
32 | Student copy;
33 | copy.fromJson(d);
34 | qDebug() << copy.toRawJson().constData();
35 | qDebug() << "=============================================================================";
36 | }
37 | #endif
38 |
39 | #ifdef QS_HAS_XML
40 | void xml_example(){
41 | qDebug() << "==================================== xml_example ====================================";
42 | TestXml src;
43 | src.field = 10;
44 | for(int i = 0; i < src.field; i ++)
45 | src.collection.append(i);
46 | src.object.digit = 666;
47 | src.object.string.append("it's first note in string array");
48 | src.object.string.append("it's second note in string array");
49 |
50 | // make hat if need this
51 | QDomDocument node = QSerializer::appendXmlHat(src.toXml(), "UTF-8");
52 | qDebug() << "xml from object:";
53 | qDebug() << QSerializer::toByteArray(node).constData();
54 |
55 | qDebug() << "creation new object using raw xml:";
56 | TestXml copy;
57 | copy.fromXml(node);
58 | qDebug() << copy.toRawXml().constData();
59 | qDebug() << "=============================================================================";
60 | }
61 | #endif
62 |
63 | void serialize_to_file() {
64 | /* OBJECT */
65 | Field field;
66 | field.flag = false;
67 | field.digit = 34;
68 | field.string = "some string";
69 | field.d_digit = 88.99;
70 | /*.........................................................................................................................*/
71 |
72 | /* COLLECTION*/
73 | Collection collection;
74 | collection.list.append("first");
75 | collection.list.append("second");
76 | collection.list.append("third");
77 | for(int i = 0; i < 6; i ++)
78 | collection.vector.append(i);
79 | collection.stack.append(2.44);
80 | collection.stack.append(4.42);
81 | collection.stack.append(77);
82 | /*.........................................................................................................................*/
83 |
84 |
85 | /* OBJECT */
86 | CustomObject object;
87 | object.digit = 8;
88 | object.string.append("third");
89 | object.string.append("second");
90 | object.string.append("first");
91 | /*.........................................................................................................................*/
92 |
93 |
94 | /* COLLECTION OF OBJECTS */
95 | CollectionOfObjects collectionObjects;
96 | for(int i = 0; i < 5 ; i ++)
97 | {
98 | CustomObject o;
99 | o.digit = i;
100 | for(int k = 0; k < 5; k ++)
101 | o.string.append(QString("so it's just index number in binary %1").arg(QString::number(k+i,2)));
102 | collectionObjects.objects.append(o);
103 | }
104 | /*.........................................................................................................................*/
105 |
106 |
107 |
108 | /* DICTIONARIES */
109 | Dictionaries dict;
110 | dict.std_map.insert(std::pair(1,"first"));
111 | dict.std_map.insert(std::pair(2,"second"));
112 | dict.std_map_objects.insert(std::pair("+7(909)001-00-00", Student(22,
113 | "Ken",
114 | QStringList("http://github.com/smurfomen"),
115 | Parent(44, "Olga", false),
116 | Parent(48, "Alex", true))));
117 | dict.std_map_objects.insert(std::pair("+7(909)000-10-00", Student(21,
118 | "Jane",
119 | QStringList("http://somelink.com"),
120 | Parent(38, "Elie", false),
121 | Parent(48, "John", true))));
122 | // fill QMap
123 | dict.qt_map_objects.insert("+7(909)000-01-00", Student(22,
124 | "Kate",
125 | QStringList("http://katelink.com"),
126 | Parent(44, "Marlin", false),
127 | Parent(48, "Jake", true)));
128 | dict.qt_map_objects.insert("+7(909)100-00-10", Student(22,
129 | "Bob",
130 | QStringList("http://bobsite.com"),
131 | Parent(44, "Mary", false),
132 | Parent(48, "Koul", true)));
133 | dict.qt_map.insert("ping","pong");
134 | dict.qt_map.insert("abra","kadabra");
135 | /*.........................................................................................................................*/
136 |
137 | General general;
138 | general.field = field;
139 | general.object = object;
140 | general.collection = collection;
141 | general.collectionObjects = collectionObjects;
142 | general.dictionaries = dict;
143 |
144 | #ifdef QS_HAS_JSON
145 | {
146 | qDebug() << "==================================== serialize_to_file : general.json ====================================";
147 | qDebug() << general.toRawJson().constData();
148 |
149 | QFile json("general.json");
150 | if(json.exists())
151 | json.remove();
152 | if(json.open(QIODevice::WriteOnly))
153 | {
154 | json.write(general.toRawJson());
155 | json.close();
156 | }
157 | qDebug() << "=============================================================================";
158 | }
159 | #endif
160 |
161 | #ifdef QS_HAS_XML
162 | {
163 | qDebug() << "==================================== serialize_to_file : general.xml ====================================";
164 | qDebug() << general.toRawXml().constData();
165 |
166 | QFile xml("general.xml");
167 | if(xml.exists())
168 | xml.remove();
169 | if(xml.open(QIODevice::WriteOnly))
170 | {
171 | xml.write(general.toRawXml());
172 | xml.close();
173 | }
174 | qDebug() << "=============================================================================";
175 | }
176 | #endif
177 | }
178 |
179 | void deserialize_from_file()
180 | {
181 | #ifdef QS_HAS_JSON
182 | {
183 | QFile json ("general.json");
184 | if(!json.exists())
185 | qWarning() << "ERROR: general.json is not exist";
186 | if(json.open(QIODevice::ReadOnly))
187 | {
188 | // empty object
189 | General general;
190 | qDebug() << "empty json object:";
191 | qDebug() << general.toRawJson().constData();
192 |
193 |
194 | general.fromJson(json.readAll());
195 | qDebug() << "serialized json object from file: general.json";
196 | qDebug() << general.toRawJson().constData();
197 | json.close();
198 | }
199 | }
200 | #endif
201 |
202 | #ifdef QS_HAS_XML
203 | {
204 | QFile xml ("general.xml");
205 | if(!xml.exists())
206 | qWarning() << "ERROR: general.xml is not exist";
207 | if(xml.open(QIODevice::ReadOnly))
208 | {
209 | // empty object
210 | General general;
211 | qDebug() << "empty xml object:";
212 | qDebug() << general.toRawXml().constData();
213 |
214 | qDebug() << "contains in file: general.xml";
215 | QByteArray d = xml.readAll();
216 | qDebug() << d << "\n";
217 |
218 | general.fromXml(d);
219 | qDebug() << "serialized json object from file: general.xml";
220 | qDebug() << general.toRawXml().constData();
221 |
222 | xml.close();
223 | }
224 | }
225 | #endif
226 | }
227 |
228 | int main(int argc, char *argv[])
229 | {
230 | QCoreApplication a(argc, argv);
231 | qDebug() << "==================================== SERIALIZE EXAMPLES ====================================";
232 | #ifdef QS_HAS_XML
233 | xml_example();
234 | #endif
235 |
236 | #ifdef QS_HAS_JSON
237 | json_example();
238 | #endif
239 |
240 | serialize_to_file();
241 | deserialize_from_file();
242 | qDebug() << "=============================================================================";
243 |
244 | return 0;
245 | }
246 |
247 |
248 |
249 |
--------------------------------------------------------------------------------
/qserializer.pri:
--------------------------------------------------------------------------------
1 | contains(DEFINES, QS_HAS_XML) {
2 | QT += xml
3 | }
4 |
5 | HEADERS += \
6 | $$PWD/src/qserializer.h
7 |
8 | INCLUDEPATH += $$PWD/
9 |
10 | DISTFILES += \
11 | $$PWD/QSerializer
12 |
13 | CONFIG += QSERIALIZER_INCLUDED
14 | DEFINES += QSERIALIZER_INCLUDED
15 |
--------------------------------------------------------------------------------
/src/qserializer.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020-2021 Agadzhanov Vladimir
5 | Portions Copyright (c) 2021 Jerry Jacobs
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 | */
25 |
26 | #ifndef QSERIALIZER_H
27 | #define QSERIALIZER_H
28 |
29 | /* JSON */
30 | #ifdef QS_HAS_JSON
31 | #include
32 | #include
33 | #include
34 | #include
35 | #endif
36 |
37 | /* XML */
38 | #ifdef QS_HAS_XML
39 | #include
40 | #include
41 | #endif
42 |
43 | /* META OBJECT SYSTEM */
44 | #include
45 | #include
46 | #include
47 | #include
48 |
49 | #include
50 | #include
51 |
52 | #define QS_VERSION "1.2"
53 |
54 | /* Generate metaObject method */
55 | #define QS_META_OBJECT_METHOD \
56 | virtual const QMetaObject * metaObject() const { \
57 | return &this->staticMetaObject; \
58 | } \
59 |
60 | #define QSERIALIZABLE \
61 | Q_GADGET \
62 | QS_META_OBJECT_METHOD
63 |
64 | /* Mark class as serializable */
65 | #define QS_SERIALIZABLE QS_META_OBJECT_METHOD
66 |
67 | #ifdef QS_HAS_XML
68 | Q_DECLARE_METATYPE(QDomNode)
69 | Q_DECLARE_METATYPE(QDomElement)
70 | #endif
71 |
72 | class QSerializer {
73 | Q_GADGET
74 | QS_SERIALIZABLE
75 | public:
76 | virtual ~QSerializer() = default;
77 |
78 | #ifdef QS_HAS_JSON
79 | /*! \brief Convert QJsonValue in QJsonDocument as QByteArray. */
80 | static QByteArray toByteArray(const QJsonValue & value){
81 | return QJsonDocument(value.toObject()).toJson();
82 | }
83 | #endif
84 |
85 | #ifdef QS_HAS_XML
86 | /*! \brief Convert QDomNode in QDomDocument as QByteArray. */
87 | static QByteArray toByteArray(const QDomNode & value) {
88 | QDomDocument doc = value.toDocument();
89 | return doc.toByteArray();
90 | }
91 |
92 | /*! \brief Make xml processing instruction (hat) and returns new XML QDomDocument. On deserialization procedure all processing instructions will be ignored. */
93 | static QDomDocument appendXmlHat(const QDomNode &node, const QString & encoding, const QString & version = "1.0"){
94 | QDomDocument doc = node.toDocument();
95 | QDomNode xmlNode = doc.createProcessingInstruction("xml", QString("version=\"%1\" encoding=\"%2\"").arg(version).arg(encoding));
96 | doc.insertBefore(xmlNode, doc.firstChild());
97 | return doc;
98 | }
99 | #endif
100 |
101 |
102 | #ifdef QS_HAS_JSON
103 | /*! \brief Serialize all accessed JSON propertyes for this object. */
104 | QJsonObject toJson() const {
105 | QJsonObject json;
106 | for(int i = 0; i < metaObject()->propertyCount(); i++)
107 | {
108 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
109 | if(QString(metaObject()->property(i).typeName()) != QMetaType::typeName(qMetaTypeId())) {
110 | continue;
111 | }
112 | #else
113 | if(metaObject()->property(i).metaType().id() != QMetaType::QJsonValue) {
114 | continue;
115 | }
116 | #endif
117 |
118 | json.insert(metaObject()->property(i).name(), metaObject()->property(i).readOnGadget(this).toJsonValue());
119 | }
120 | return json;
121 | }
122 |
123 | /*! \brief Returns QByteArray representation this object using json-serialization. */
124 | QByteArray toRawJson() const {
125 | return toByteArray(toJson());
126 | }
127 |
128 | /*! \brief Deserialize all accessed XML propertyes for this object. */
129 | void fromJson(const QJsonValue & val) {
130 | if(val.isObject())
131 | {
132 | QJsonObject json = val.toObject();
133 | QStringList keys = json.keys();
134 | int propCount = metaObject()->propertyCount();
135 | for(int i = 0; i < propCount; i++)
136 | {
137 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
138 | if(QString(metaObject()->property(i).typeName()) != QMetaType::typeName(qMetaTypeId())) {
139 | continue;
140 | }
141 | #else
142 | if(metaObject()->property(i).metaType().id() != QMetaType::QJsonValue) {
143 | continue;
144 | }
145 | #endif
146 |
147 | for(auto key : json.keys())
148 | {
149 | if(key == metaObject()->property(i).name())
150 | {
151 | metaObject()->property(i).writeOnGadget(this, json.value(key));
152 | break;
153 | }
154 | }
155 | }
156 | }
157 | }
158 |
159 | /*! \brief Deserialize all accessed JSON propertyes for this object. */
160 | void fromJson(const QByteArray & data) {
161 | fromJson(QJsonDocument::fromJson(data).object());
162 | }
163 | #endif // QS_HAS_JSON
164 |
165 | #ifdef QS_HAS_XML
166 | /*! \brief Serialize all accessed XML propertyes for this object. */
167 | QDomNode toXml() const {
168 | QDomDocument doc;
169 | QDomElement el = doc.createElement(metaObject()->className());
170 | for(int i = 0; i < metaObject()->propertyCount(); i++)
171 | {
172 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
173 | if(QString(metaObject()->property(i).typeName()) != QMetaType::typeName(qMetaTypeId())) {
174 | continue;
175 | }
176 | #else
177 | if(metaObject()->property(i).metaType().id() != qMetaTypeId()) {
178 | continue;
179 | }
180 | #endif
181 | el.appendChild(QDomNode(metaObject()->property(i).readOnGadget(this).value()));
182 | }
183 | doc.appendChild(el);
184 | return doc;
185 | }
186 |
187 | /*! \brief Returns QByteArray representation this object using xml-serialization. */
188 | QByteArray toRawXml() const {
189 | return toByteArray(toXml());
190 | }
191 |
192 | /*! \brief Deserialize all accessed XML propertyes for this object. */
193 | void fromXml(const QDomNode & val) {
194 | QDomNode doc = val;
195 |
196 | auto n = doc.firstChildElement(metaObject()->className());
197 |
198 | if(!n.isNull()) {
199 | for(int i = 0; i < metaObject()->propertyCount(); i++) {
200 | QString name = metaObject()->property(i).name();
201 | QDomElement tmp = metaObject()->property(i).readOnGadget(this).value().firstChildElement();
202 |
203 | auto f = n.firstChildElement(tmp.tagName());
204 | metaObject()->property(i).writeOnGadget(this, QVariant::fromValue(f));
205 | }
206 | }
207 | else
208 | {
209 | for(int i = 0; i < metaObject()->propertyCount(); i++) {
210 | QString name = metaObject()->property(i).name();
211 | auto f = doc.firstChildElement(name);
212 | metaObject()->property(i).writeOnGadget(this, QVariant::fromValue(f));
213 | }
214 | }
215 | }
216 |
217 | /*! \brief Deserialize all accessed XML propertyes for this object. */
218 | void fromXml(const QByteArray & data) {
219 | QDomDocument d;
220 | d.setContent(data);
221 | fromXml(d);
222 | }
223 | #endif // QS_HAS_XML
224 | };
225 |
226 | #define GET(prefix, name) get_##prefix##_##name
227 | #define SET(prefix, name) set_##prefix##_##name
228 |
229 | /* Create variable */
230 | #define QS_DECLARE_MEMBER(type, name) \
231 | public : \
232 | type name = type(); \
233 |
234 | /* Create JSON property and methods for primitive type field*/
235 | #ifdef QS_HAS_JSON
236 | #define QS_JSON_FIELD(type, name) \
237 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json, name)) \
238 | private: \
239 | QJsonValue GET(json, name)() const { \
240 | QJsonValue val = QJsonValue::fromVariant(QVariant(name)); \
241 | return val; \
242 | } \
243 | void SET(json, name)(const QJsonValue & varname){ \
244 | name = varname.toVariant().value(); \
245 | }
246 | #else
247 | #define QS_JSON_FIELD(type, name)
248 | #endif
249 |
250 | /* Create XML property and methods for primitive type field*/
251 | #ifdef QS_HAS_XML
252 | #define QS_XML_FIELD(type, name) \
253 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
254 | private: \
255 | QDomNode GET(xml, name)() const { \
256 | QDomDocument doc; \
257 | QString strname = #name; \
258 | QDomElement element = doc.createElement(strname); \
259 | QDomText valueOfProp = doc.createTextNode(QVariant(name).toString()); \
260 | element.appendChild(valueOfProp); \
261 | doc.appendChild(element); \
262 | return QDomNode(doc); \
263 | } \
264 | void SET(xml, name)(const QDomNode &node) { \
265 | if(!node.isNull() && node.isElement()){ \
266 | QDomElement domElement = node.toElement(); \
267 | if(domElement.tagName() == #name) \
268 | name = QVariant(domElement.text()).value(); \
269 | } \
270 | }
271 | #else
272 | #define QS_XML_FIELD(type, name)
273 | #endif
274 |
275 | /* Generate JSON-property and methods for primitive type objects */
276 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
277 | #ifdef QS_HAS_JSON
278 | #define QS_JSON_ARRAY(itemType, name) \
279 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json, name)) \
280 | private: \
281 | QJsonValue GET(json, name)() const { \
282 | QJsonArray val; \
283 | for(int i = 0; i < name.size(); i++) \
284 | val.push_back(name.at(i)); \
285 | return QJsonValue::fromVariant(val); \
286 | } \
287 | void SET(json, name)(const QJsonValue & varname) { \
288 | if(!varname.isArray()) \
289 | return; \
290 | name.clear(); \
291 | QJsonArray val = varname.toArray(); \
292 | for(auto item : val) { \
293 | itemType tmp; \
294 | tmp = item.toVariant().value(); \
295 | name.append(tmp); \
296 | } \
297 | }
298 | #else
299 | #define QS_JSON_ARRAY(itemType, name)
300 | #endif
301 |
302 | /* Generate XML-property and methods for primitive type objects */
303 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
304 | #ifdef QS_HAS_XML
305 | #define QS_XML_ARRAY(itemType, name) \
306 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
307 | private: \
308 | QDomNode GET(xml, name)() const { \
309 | QDomDocument doc; \
310 | QString strname = #name; \
311 | QDomElement arrayXml = doc.createElement(QString(strname)); \
312 | arrayXml.setAttribute("type", "array"); \
313 | \
314 | for(int i = 0; i < name.size(); i++) { \
315 | itemType item = name.at(i); \
316 | QDomElement itemXml = doc.createElement("item"); \
317 | itemXml.setAttribute("type", #itemType); \
318 | itemXml.setAttribute("index", i); \
319 | itemXml.appendChild(doc.createTextNode(QVariant(item).toString())); \
320 | arrayXml.appendChild(itemXml); \
321 | } \
322 | \
323 | doc.appendChild(arrayXml); \
324 | return QDomNode(doc); \
325 | } \
326 | void SET(xml, name)(const QDomNode & node) { \
327 | QDomNode domNode = node.firstChild(); \
328 | name.clear(); \
329 | while(!domNode.isNull()) { \
330 | if(domNode.isElement()) { \
331 | QDomElement domElement = domNode.toElement(); \
332 | name.append(QVariant(domElement.text()).value()); \
333 | } \
334 | domNode = domNode.nextSibling(); \
335 | } \
336 | }
337 | #else
338 | #define QS_XML_ARRAY(itemType, name)
339 | #endif
340 |
341 |
342 | /* Generate JSON-property and methods for some custom class */
343 | /* Custom type must be provide methods fromJson and toJson or inherit from QSerializer */
344 | #ifdef QS_HAS_JSON
345 | #define QS_JSON_OBJECT(type, name) \
346 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json, name)) \
347 | private: \
348 | QJsonValue GET(json, name)() const { \
349 | QJsonObject val = name.toJson(); \
350 | return QJsonValue(val); \
351 | } \
352 | void SET(json, name)(const QJsonValue & varname) { \
353 | if(!varname.isObject()) \
354 | return; \
355 | name.fromJson(varname); \
356 | }
357 | #else
358 | #define QS_JSON_OBJECT(type, name)
359 | #endif
360 |
361 | /* Generate XML-property and methods for some custom class */
362 | /* Custom type must be provide methods fromJson and toJson or inherit from QSerializer */
363 | #ifdef QS_HAS_XML
364 | #define QS_XML_OBJECT(type, name) \
365 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
366 | private: \
367 | QDomNode GET(xml, name)() const { \
368 | return name.toXml(); \
369 | } \
370 | void SET(xml, name)(const QDomNode & node){ \
371 | name.fromXml(node); \
372 | }
373 | #else
374 | #define QS_XML_OBJECT(type, name)
375 | #endif
376 |
377 | /* Generate JSON-property and methods for collection of custom type objects */
378 | /* Custom item type must be provide methods fromJson and toJson or inherit from QSerializer */
379 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
380 | #ifdef QS_HAS_JSON
381 | #define QS_JSON_ARRAY_OBJECTS(itemType, name) \
382 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json, name)) \
383 | private: \
384 | QJsonValue GET(json, name)() const { \
385 | QJsonArray val; \
386 | for(int i = 0; i < name.size(); i++) \
387 | val.push_back(name.at(i).toJson()); \
388 | return QJsonValue::fromVariant(val); \
389 | } \
390 | void SET(json, name)(const QJsonValue & varname) { \
391 | if(!varname.isArray()) \
392 | return; \
393 | name.clear(); \
394 | QJsonArray val = varname.toArray(); \
395 | for(int i = 0; i < val.size(); i++) { \
396 | itemType tmp; \
397 | tmp.fromJson(val.at(i)); \
398 | name.append(tmp); \
399 | } \
400 | }
401 | #else
402 | #define QS_JSON_ARRAY_OBJECTS(itemType, name)
403 | #endif
404 |
405 | /* Generate XML-property and methods for collection of custom type objects */
406 | /* Custom type must be provide methods fromXml and toXml or inherit from QSerializer */
407 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
408 | #ifdef QS_HAS_XML
409 | #define QS_XML_ARRAY_OBJECTS(itemType, name) \
410 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
411 | private: \
412 | QDomNode GET(xml, name)() const { \
413 | QDomDocument doc; \
414 | QDomElement element = doc.createElement(#name); \
415 | element.setAttribute("type", "array"); \
416 | for(int i = 0; i < name.size(); i++) \
417 | element.appendChild(name.at(i).toXml()); \
418 | doc.appendChild(element); \
419 | return QDomNode(doc); \
420 | } \
421 | void SET(xml, name)(const QDomNode & node) { \
422 | name.clear(); \
423 | QDomNodeList nodesList = node.childNodes(); \
424 | for(int i = 0; i < nodesList.size(); i++) { \
425 | itemType tmp; \
426 | tmp.fromXml(nodesList.at(i)); \
427 | name.append(tmp); \
428 | } \
429 | }
430 | #else
431 | #define QS_XML_ARRAY_OBJECTS(itemType, name)
432 | #endif
433 |
434 | /* Generate JSON-property and methods for dictionary of simple fields (int, bool, QString, ...) */
435 | /* Custom type must be inherit from QSerializer */
436 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be QMap, QHash) */
437 | /* THIS IS FOR QT DICTIONARY TYPES, for example QMap, QMap, ...*/
438 | #ifdef QS_HAS_JSON
439 | #define QS_JSON_QT_DICT(map, name) \
440 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json,name)) \
441 | private: \
442 | QJsonValue GET(json, name)() const { \
443 | QJsonObject val; \
444 | for(auto p = name.constBegin(); p != name.constEnd(); ++p) { \
445 | val.insert( \
446 | QVariant(p.key()).toString(), \
447 | QJsonValue::fromVariant(QVariant(p.value()))); \
448 | } \
449 | return val; \
450 | } \
451 | void SET(json, name)(const QJsonValue & varname) { \
452 | QJsonObject val = varname.toObject(); \
453 | name.clear(); \
454 | for(auto p = val.constBegin() ;p != val.constEnd(); ++p) { \
455 | name.insert( \
456 | QVariant(p.key()).value(), \
457 | QVariant(p.value()).value()); \
458 | } \
459 | }
460 | #else
461 | #define QS_JSON_QT_DICT(map, name)
462 | #endif
463 |
464 | /* Generate XML-property and methods for dictionary of simple fields (int, bool, QString, ...) */
465 | /* Custom type must be inherit from QSerializer */
466 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be QMap, QHash) */
467 | /* THIS IS FOR QT DICTIONARY TYPES, for example QMap, QMap, ...*/
468 | #ifdef QS_HAS_XML
469 | #define QS_XML_QT_DICT(map, name) \
470 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
471 | private: \
472 | QDomNode GET(xml, name)() const { \
473 | QDomDocument doc; \
474 | QDomElement element = doc.createElement(#name); \
475 | element.setAttribute("type", "map"); \
476 | for(auto p = name.begin(); p != name.end(); ++p) \
477 | { \
478 | QDomElement e = doc.createElement("item"); \
479 | e.setAttribute("key", QVariant(p.key()).toString()); \
480 | e.setAttribute("value", QVariant(p.value()).toString()); \
481 | element.appendChild(e); \
482 | } \
483 | doc.appendChild(element); \
484 | return QDomNode(doc); \
485 | } \
486 | void SET(xml, name)(const QDomNode & node) { \
487 | if(!node.isNull() && node.isElement()) \
488 | { \
489 | QDomElement root = node.toElement(); \
490 | if(root.tagName() == #name) \
491 | { \
492 | QDomNodeList childs = root.childNodes(); \
493 | \
494 | for(int i = 0; i < childs.size(); ++i) { \
495 | QDomElement item = childs.at(i).toElement(); \
496 | name.insert(QVariant(item.attributeNode("key").value()).value(), \
497 | QVariant(item.attributeNode("value").value()).value()); \
498 | } \
499 | } \
500 | } \
501 | }
502 | #else
503 | #define QS_XML_QT_DICT(map, name)
504 | #endif
505 |
506 |
507 | /* Generate JSON-property and methods for dictionary of custom type objects */
508 | /* Custom type must be inherit from QSerializer */
509 | /* This collection must be provide method inserv(KeyT, ValueT) (it's can be QMap, QHash) */
510 | /* THIS IS FOR QT DICTIONARY TYPES, for example QMap */
511 | #ifdef QS_HAS_JSON
512 | #define QS_JSON_QT_DICT_OBJECTS(map, name) \
513 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json,name)) \
514 | private: \
515 | QJsonValue GET(json, name)() const { \
516 | QJsonObject val; \
517 | for(auto p = name.begin(); p != name.end(); ++p) { \
518 | val.insert( \
519 | QVariant::fromValue(p.key()).toString(), \
520 | p.value().toJson()); \
521 | } \
522 | return val; \
523 | } \
524 | void SET(json, name)(const QJsonValue & varname) { \
525 | QJsonObject val = varname.toObject(); \
526 | name.clear(); \
527 | for(auto p = val.constBegin();p != val.constEnd(); ++p) { \
528 | map::mapped_type tmp; \
529 | tmp.fromJson(p.value()); \
530 | name.insert( \
531 | QVariant(p.key()).value(), \
532 | tmp); \
533 | } \
534 | }
535 | #else
536 | #define QS_JSON_QT_DICT_OBJECTS(map, name)
537 | #endif
538 |
539 | /* Generate XML-property and methods for dictionary of custom type objects */
540 | /* Custom type must be inherit from QSerializer */
541 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be QMap, QHash) */
542 | /* THIS IS FOR QT DICTIONARY TYPES, for example QMap */
543 | #ifdef QS_HAS_XML
544 | #define QS_XML_QT_DICT_OBJECTS(map, name) \
545 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
546 | private: \
547 | QDomNode GET(xml, name)() const { \
548 | QDomDocument doc; \
549 | QDomElement element = doc.createElement(#name); \
550 | element.setAttribute("type", "map"); \
551 | for(auto p = name.begin(); p != name.end(); ++p) \
552 | { \
553 | QDomElement e = doc.createElement("item"); \
554 | e.setAttribute("key", QVariant(p.key()).toString()); \
555 | e.appendChild(p.value().toXml()); \
556 | element.appendChild(e); \
557 | } \
558 | doc.appendChild(element); \
559 | return QDomNode(doc); \
560 | } \
561 | void SET(xml, name)(const QDomNode & node) { \
562 | if(!node.isNull() && node.isElement()) \
563 | { \
564 | QDomElement root = node.toElement(); \
565 | if(root.tagName() == #name) \
566 | { \
567 | QDomNodeList childs = root.childNodes(); \
568 | \
569 | for(int i = 0; i < childs.size(); ++i) { \
570 | QDomElement item = childs.at(i).toElement(); \
571 | map::mapped_type tmp; \
572 | tmp.fromXml(item.firstChild()); \
573 | name.insert(QVariant(item.attributeNode("key").value()).value(), \
574 | tmp); \
575 | } \
576 | } \
577 | } \
578 | }
579 | #else
580 | #define QS_XML_QT_DICT_OBJECTS(map, name)
581 | #endif
582 |
583 | /* Generate JSON-property and methods for dictionary of simple fields (int, bool, QString, ...) */
584 | /* Custom type must be inherit from QSerializer */
585 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be std::map) */
586 | /* THIS IS FOR STL DICTIONARY TYPES, for example std::map, std::map, ...*/
587 | #ifdef QS_HAS_JSON
588 | #define QS_JSON_STL_DICT(map, name) \
589 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json,name)) \
590 | private: \
591 | QJsonValue GET(json, name)() const { \
592 | QJsonObject val; \
593 | for(auto p : name){ \
594 | val.insert( \
595 | QVariant::fromValue(p.first).toString(), \
596 | QJsonValue::fromVariant(QVariant(p.second))); \
597 | } \
598 | return val; \
599 | } \
600 | void SET(json, name)(const QJsonValue & varname) { \
601 | QJsonObject val = varname.toObject(); \
602 | name.clear(); \
603 | for(auto p = val.constBegin();p != val.constEnd(); ++p) { \
604 | name.insert(std::pair( \
605 | QVariant(p.key()).value(), \
606 | QVariant(p.value()).value())); \
607 | } \
608 | }
609 | #else
610 | #define QS_JSON_STL_DICT(map, name)
611 | #endif
612 |
613 | #ifdef QS_HAS_XML
614 | #define QS_XML_STL_DICT(map, name) \
615 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
616 | private: \
617 | QDomNode GET(xml, name)() const { \
618 | QDomDocument doc; \
619 | QDomElement element = doc.createElement(#name); \
620 | element.setAttribute("type", "map"); \
621 | for(auto p : name) \
622 | { \
623 | QDomElement e = doc.createElement("item"); \
624 | e.setAttribute("key", QVariant(p.first).toString()); \
625 | e.setAttribute("value", QVariant(p.second).toString()); \
626 | element.appendChild(e); \
627 | } \
628 | doc.appendChild(element); \
629 | return QDomNode(doc); \
630 | } \
631 | void SET(xml, name)(const QDomNode & node) { \
632 | if(!node.isNull() && node.isElement()) \
633 | { \
634 | QDomElement root = node.toElement(); \
635 | if(root.tagName() == #name) \
636 | { \
637 | QDomNodeList childs = root.childNodes(); \
638 | \
639 | for(int i = 0; i < childs.size(); ++i) { \
640 | QDomElement item = childs.at(i).toElement(); \
641 | name.insert(std::pair( \
642 | QVariant(item.attributeNode("key").value()).value(), \
643 | QVariant(item.attributeNode("value").value()).value())); \
644 | } \
645 | } \
646 | } \
647 | }
648 | #else
649 | #define QS_XML_STL_DICT(map, name)
650 | #endif
651 |
652 | /* Generate JSON-property and methods for dictionary of custom type objects */
653 | /* Custom type must be inherit from QSerializer */
654 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be std::map) */
655 | /* THIS IS FOR STL DICTIONARY TYPES, for example std::map */
656 | #ifdef QS_HAS_JSON
657 | #define QS_JSON_STL_DICT_OBJECTS(map, name) \
658 | Q_PROPERTY(QJsonValue name READ GET(json, name) WRITE SET(json,name)) \
659 | private: \
660 | QJsonValue GET(json, name)() const { \
661 | QJsonObject val; \
662 | for(auto p : name){ \
663 | val.insert( \
664 | QVariant::fromValue(p.first).toString(), \
665 | p.second.toJson()); \
666 | } \
667 | return val; \
668 | } \
669 | void SET(json, name)(const QJsonValue & varname) { \
670 | QJsonObject val = varname.toObject(); \
671 | name.clear(); \
672 | for(auto p = val.constBegin(); p != val.constEnd(); ++p) { \
673 | map::mapped_type tmp; \
674 | tmp.fromJson(p.value()); \
675 | name.insert(std::pair( \
676 | QVariant(p.key()).value(), \
677 | tmp)); \
678 | } \
679 | }
680 | #else
681 | #define QS_JSON_STL_DICT_OBJECTS(map, name)
682 | #endif
683 |
684 | /* Generate XML-property and methods for dictionary of custom type objects */
685 | /* Custom type must be inherit from QSerializer */
686 | /* This collection must be provide method insert(KeyT, ValueT) (it's can be std::map) */
687 | /* THIS IS FOR STL DICTIONARY TYPES, for example std::map */
688 | #ifdef QS_HAS_XML
689 | #define QS_XML_STL_DICT_OBJECTS(map, name) \
690 | Q_PROPERTY(QDomNode name READ GET(xml, name) WRITE SET(xml, name)) \
691 | private: \
692 | QDomNode GET(xml, name)() const { \
693 | QDomDocument doc; \
694 | QDomElement element = doc.createElement(#name); \
695 | element.setAttribute("type", "map"); \
696 | for(auto p : name) \
697 | { \
698 | QDomElement e = doc.createElement("item"); \
699 | e.setAttribute("key", QVariant(p.first).toString()); \
700 | e.appendChild(p.second.toXml()); \
701 | element.appendChild(e); \
702 | } \
703 | doc.appendChild(element); \
704 | return QDomNode(doc); \
705 | } \
706 | void SET(xml, name)(const QDomNode & node) { \
707 | if(!node.isNull() && node.isElement()) \
708 | { \
709 | QDomElement root = node.toElement(); \
710 | if(root.tagName() == #name) \
711 | { \
712 | QDomNodeList childs = root.childNodes(); \
713 | \
714 | for(int i = 0; i < childs.size(); ++i) { \
715 | QDomElement item = childs.at(i).toElement(); \
716 | map::mapped_type tmp; \
717 | tmp.fromXml(item.firstChild()); \
718 | name.insert(std::pair ( \
719 | QVariant(item.attributeNode("key").value()).value(), \
720 | tmp)); \
721 | } \
722 | } \
723 | } \
724 | }
725 | #else
726 | #define QS_XML_STL_DICT_OBJECTS(map, name)
727 | #endif
728 |
729 |
730 | /* BIND: */
731 | /* generate serializable propertyes JSON and XML for primitive type field */
732 | #define QS_BIND_FIELD(type, name) \
733 | QS_JSON_FIELD(type, name) \
734 | QS_XML_FIELD(type, name) \
735 |
736 | /* BIND: */
737 | /* generate serializable propertyes JSON and XML for collection of primitive type fields */
738 | #define QS_BIND_COLLECTION(itemType, name) \
739 | QS_JSON_ARRAY(itemType, name) \
740 | QS_XML_ARRAY(itemType, name) \
741 |
742 | /* BIND: */
743 | /* generate serializable propertyes JSON and XML for custom type object */
744 | #define QS_BIND_OBJECT(type, name) \
745 | QS_JSON_OBJECT(type, name) \
746 | QS_XML_OBJECT(type, name) \
747 |
748 | /* BIND: */
749 | /* generate serializable propertyes JSON and XML for collection of custom type objects */
750 | #define QS_BIND_COLLECTION_OBJECTS(itemType, name) \
751 | QS_JSON_ARRAY_OBJECTS(itemType, name) \
752 | QS_XML_ARRAY_OBJECTS(itemType, name) \
753 |
754 | /* BIND: */
755 | /* generate serializable propertyes JSON and XML for dictionary with primitive value type for QT DICTIONARY TYPES */
756 | #define QS_BIND_QT_DICT(map, name) \
757 | QS_JSON_QT_DICT(map, name) \
758 | QS_XML_QT_DICT(map, name) \
759 |
760 | /* BIND: */
761 | /* generate serializable propertyes JSON and XML for dictionary of custom type objects for QT DICTIONARY TYPES */
762 | #define QS_BIND_QT_DICT_OBJECTS(map, name) \
763 | QS_JSON_QT_DICT_OBJECTS(map, name) \
764 | QS_XML_QT_DICT_OBJECTS(map,name) \
765 |
766 |
767 | /* BIND: */
768 | /* generate serializable propertyes JSON and XML for dictionary with primitive value type for STL DICTIONARY TYPES */
769 | #define QS_BIND_STL_DICT(map, name) \
770 | QS_JSON_STL_DICT(map, name) \
771 | QS_XML_STL_DICT(map, name) \
772 |
773 |
774 | /* BIND: */
775 | /* generate serializable propertyes JSON and XML for dictionary of custom type objects for STL DICTIONARY TYPES */
776 | #define QS_BIND_STL_DICT_OBJECTS(map, name) \
777 | QS_JSON_STL_DICT_OBJECTS(map, name) \
778 | QS_XML_STL_DICT_OBJECTS(map,name) \
779 |
780 |
781 |
782 | /* CREATE AND BIND: */
783 | /* Make primitive field and generate serializable propertyes */
784 | /* For example: QS_FIELD(int, digit), QS_FIELD(bool, flag) */
785 | #define QS_FIELD(type, name) \
786 | QS_DECLARE_MEMBER(type, name) \
787 | QS_BIND_FIELD(type, name) \
788 |
789 | /* CREATE AND BIND: */
790 | /* Make collection of primitive type objects [collectionType name] and generate serializable propertyes for this collection */
791 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
792 | #define QS_COLLECTION(collectionType, itemType, name) \
793 | QS_DECLARE_MEMBER(collectionType, name) \
794 | QS_BIND_COLLECTION(itemType, name) \
795 |
796 | /* CREATE AND BIND: */
797 | /* Make custom class object and bind serializable propertyes */
798 | /* This class must be inherited from QSerializer */
799 | #define QS_OBJECT(type,name) \
800 | QS_DECLARE_MEMBER(type, name) \
801 | QS_BIND_OBJECT(type, name) \
802 |
803 | /* CREATE AND BIND: */
804 | /* Make collection of custom class objects [collectionType name] and bind serializable propertyes */
805 | /* This collection must be provide method append(T) (it's can be QList, QVector) */
806 | #define QS_COLLECTION_OBJECTS(collectionType, itemType, name) \
807 | QS_DECLARE_MEMBER(collectionType, name) \
808 | QS_BIND_COLLECTION_OBJECTS(itemType, name) \
809 |
810 |
811 | /* CREATE AND BIND: */
812 | /* Make dictionary collection of simple types [dictionary name] and bind serializable propertyes */
813 | /* This collection must be QT DICTIONARY TYPE */
814 | #define QS_QT_DICT(map, first, second, name) \
815 | public: \
816 | typedef map dict_##name##_t; \
817 | dict_##name##_t name = dict_##name##_t(); \
818 | QS_BIND_QT_DICT(dict_##name##_t, name) \
819 |
820 | /* CREATE AND BIND: */
821 | /* Make dictionary collection of custom class objects [dictionary name] and bind serializable propertyes */
822 | /* This collection must be QT DICTIONARY TYPE */
823 | #define QS_QT_DICT_OBJECTS(map, first, second, name) \
824 | public: \
825 | typedef map dict_##name##_t; \
826 | dict_##name##_t name = dict_##name##_t(); \
827 | QS_BIND_QT_DICT_OBJECTS(dict_##name##_t, name) \
828 |
829 | /* CREATE AND BIND: */
830 | /* Make dictionary collection of simple types [dictionary name] and bind serializable propertyes */
831 | /* This collection must be STL DICTIONARY TYPE */
832 | #define QS_STL_DICT(map, first, second, name) \
833 | public: \
834 | typedef map dict_##name##_t; \
835 | dict_##name##_t name = dict_##name##_t(); \
836 | QS_BIND_STL_DICT(dict_##name##_t, name) \
837 |
838 | /* CREATE AND BIND: */
839 | /* Make dictionary collection of custom class objects [dictionary name] and bind serializable propertyes */
840 | /* This collection must be STL DICTIONARY TYPE */
841 | #define QS_STL_DICT_OBJECTS(map, first, second, name) \
842 | public: \
843 | typedef map dict_##name##_t; \
844 | dict_##name##_t name = dict_##name##_t(); \
845 | QS_BIND_STL_DICT_OBJECTS(dict_##name##_t, name) \
846 |
847 |
848 |
849 | #endif // QSERIALIZER_H
850 |
851 |
--------------------------------------------------------------------------------