Line data Source code
1 : /* Copyright (C) 2020 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_SERIALIZED_TYPES
19 : #define INCLUDED_SERIALIZED_TYPES
20 :
21 : /**
22 : * @file
23 : * Provide specializations for some generic types and containers.
24 : */
25 :
26 : #include "simulation2/serialization/SerializeTemplates.h"
27 :
28 : #include "lib/types.h"
29 :
30 : #include <array>
31 : #include <map>
32 : #include <set>
33 : #include <string>
34 : #include <unordered_map>
35 : #include <vector>
36 :
37 : template<typename T, size_t N>
38 : struct SerializeHelper<std::array<T, N>>
39 : {
40 1 : void operator()(ISerializer& serialize, const char* name, std::array<T, N>& value)
41 : {
42 7 : for (size_t i = 0; i < N; ++i)
43 6 : Serializer(serialize, name, value[i]);
44 1 : }
45 :
46 0 : void operator()(IDeserializer& deserialize, const char* name, std::array<T, N>& value)
47 : {
48 0 : for (size_t i = 0; i < N; ++i)
49 0 : Serializer(deserialize, name, value[i]);
50 0 : }
51 : };
52 :
53 : template<typename T>
54 : struct SerializeHelper<std::vector<T>>
55 : {
56 2 : void operator()(ISerializer& serialize, const char* name, std::vector<T>& value)
57 : {
58 2 : size_t len = value.size();
59 2 : serialize.NumberU32_Unbounded("length", (u32)len);
60 9 : for (size_t i = 0; i < len; ++i)
61 7 : Serializer(serialize, name, value[i]);
62 2 : }
63 :
64 1 : void operator()(IDeserializer& deserialize, const char* name, std::vector<T>& value)
65 : {
66 1 : value.clear();
67 : u32 len;
68 1 : deserialize.NumberU32_Unbounded("length", len);
69 1 : value.reserve(len); // TODO: watch out for out-of-memory
70 2 : for (size_t i = 0; i < len; ++i)
71 : {
72 0 : T el;
73 1 : Serializer(deserialize, name, el);
74 1 : value.emplace_back(el);
75 : }
76 1 : }
77 : };
78 :
79 : template<typename T>
80 : struct SerializeHelper<std::set<T>>
81 : {
82 19 : void operator()(ISerializer& serialize, const char* name, const std::set<T>& value)
83 : {
84 19 : serialize.NumberU32_Unbounded("size", static_cast<u32>(value.size()));
85 24 : for (const T& elem : value)
86 5 : Serializer(serialize, name, elem);
87 19 : }
88 :
89 3 : void operator()(IDeserializer& deserialize, const char* name, std::set<T>& value)
90 : {
91 3 : value.clear();
92 : u32 size;
93 3 : deserialize.NumberU32_Unbounded("size", size);
94 3 : for (size_t i = 0; i < size; ++i)
95 : {
96 : T el;
97 0 : Serializer(deserialize, name, el);
98 0 : value.emplace(std::move(el));
99 : }
100 3 : }
101 : };
102 :
103 : template<typename K, typename V>
104 : struct SerializeHelper<std::map<K, V>>
105 : {
106 : template<typename... Args>
107 1 : void operator()(ISerializer& serialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
108 : {
109 1 : size_t len = value.size();
110 1 : serialize.NumberU32_Unbounded("length", (u32)len);
111 2 : for (typename std::map<K, V>::iterator it = value.begin(); it != value.end(); ++it)
112 : {
113 1 : Serializer(serialize, "key", it->first, std::forward<Args>(args)...);
114 1 : Serializer(serialize, "value", it->second, std::forward<Args>(args)...);
115 : }
116 1 : }
117 :
118 : template<typename... Args>
119 1 : void operator()(IDeserializer& deserialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
120 : {
121 1 : value.clear();
122 : u32 len;
123 1 : deserialize.NumberU32_Unbounded("length", len);
124 2 : for (size_t i = 0; i < len; ++i)
125 : {
126 2 : K k;
127 2 : V v;
128 1 : Serializer(deserialize, "key", k, std::forward<Args>(args)...);
129 1 : Serializer(deserialize, "value", v, std::forward<Args>(args)...);
130 1 : value.emplace(std::move(k), std::move(v));
131 : }
132 1 : }
133 : };
134 :
135 : // We have to order the map before serializing to make things consistent
136 : template<typename K, typename V>
137 : struct SerializeHelper<std::unordered_map<K, V>>
138 : {
139 : void operator()(ISerializer& serialize, const char* name, std::unordered_map<K, V>& value)
140 : {
141 : std::map<K, V> ordered_value(value.begin(), value.end());
142 : Serializer(serialize, name, ordered_value);
143 : }
144 :
145 : void operator()(IDeserializer& deserialize, const char* name, std::unordered_map<K, V>& value)
146 : {
147 : Serializer(deserialize, name, value);
148 : }
149 : };
150 :
151 : template<>
152 : struct SerializeHelper<u8>
153 : {
154 0 : void operator()(ISerializer& serialize, const char* name, u8 value)
155 : {
156 0 : serialize.NumberU8_Unbounded(name, value);
157 0 : }
158 :
159 0 : void operator()(IDeserializer& deserialize, const char* name, u8& value)
160 : {
161 0 : deserialize.NumberU8_Unbounded(name, value);
162 0 : }
163 : };
164 :
165 :
166 : template<typename Enum>
167 : struct SerializeHelper<Enum, std::enable_if_t<std::is_enum_v<Enum>>>
168 : {
169 0 : void operator()(ISerializer& serialize, const char* name, Enum value, Enum&& max)
170 : {
171 0 : serialize.NumberU8(name, static_cast<u8>(value), 0, static_cast<u8>(max));
172 0 : }
173 :
174 0 : void operator()(IDeserializer& deserialize, const char* name, Enum& value, Enum&& max)
175 : {
176 : u8 val;
177 0 : deserialize.NumberU8(name, val, 0, static_cast<u8>(max));
178 0 : value = static_cast<Enum>(val);
179 0 : }
180 : };
181 :
182 :
183 : template<>
184 : struct SerializeHelper<u16>
185 : {
186 6 : void operator()(ISerializer& serialize, const char* name, u16 value)
187 : {
188 6 : serialize.NumberU16_Unbounded(name, value);
189 6 : }
190 :
191 0 : void operator()(IDeserializer& deserialize, const char* name, u16& value)
192 : {
193 0 : deserialize.NumberU16_Unbounded(name, value);
194 0 : }
195 : };
196 :
197 : template<>
198 : struct SerializeHelper<u32>
199 : {
200 : template<typename... Args>
201 18 : void operator()(ISerializer& serialize, const char* name, u32 value, Args&&...)
202 : {
203 18 : serialize.NumberU32_Unbounded(name, value);
204 18 : }
205 :
206 : template<typename... Args>
207 1 : void operator()(IDeserializer& deserialize, const char* name, u32& value, Args&&...)
208 : {
209 1 : deserialize.NumberU32_Unbounded(name, value);
210 1 : }
211 : };
212 :
213 : template<>
214 : struct SerializeHelper<i32>
215 : {
216 : void operator()(ISerializer& serialize, const char* name, i32 value)
217 : {
218 : serialize.NumberI32_Unbounded(name, value);
219 : }
220 :
221 : void operator()(IDeserializer& deserialize, const char* name, i32& value)
222 : {
223 : deserialize.NumberI32_Unbounded(name, value);
224 : }
225 : };
226 :
227 : template<>
228 : struct SerializeHelper<bool>
229 : {
230 0 : void operator()(ISerializer& serialize, const char* name, bool value)
231 : {
232 0 : serialize.Bool(name, value);
233 0 : }
234 :
235 0 : void operator()(IDeserializer& deserialize, const char* name, bool& value)
236 : {
237 0 : deserialize.Bool(name, value);
238 0 : }
239 : };
240 :
241 : template<typename StringLike>
242 : struct SerializeHelper<StringLike, std::enable_if_t<std::is_base_of_v<std::string, StringLike>>>
243 : {
244 : template<typename T>
245 1 : void operator()(ISerializer& serialize, const char* name, T&& value)
246 : {
247 1 : serialize.StringASCII(name, value, 0, UINT32_MAX);
248 1 : }
249 :
250 : template<typename T>
251 1 : void operator()(IDeserializer& deserialize, const char* name, T& value)
252 : {
253 1 : deserialize.StringASCII(name, value, 0, UINT32_MAX);
254 1 : }
255 : };
256 :
257 : #endif // INCLUDED_SERIALIZED_TYPES
|