Pyrogenesis  trunk
SerializedTypes.h
Go to the documentation of this file.
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 
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  void operator()(ISerializer& serialize, const char* name, std::array<T, N>& value)
41  {
42  for (size_t i = 0; i < N; ++i)
43  Serializer(serialize, name, value[i]);
44  }
45 
46  void operator()(IDeserializer& deserialize, const char* name, std::array<T, N>& value)
47  {
48  for (size_t i = 0; i < N; ++i)
49  Serializer(deserialize, name, value[i]);
50  }
51 };
52 
53 template<typename T>
54 struct SerializeHelper<std::vector<T>>
55 {
56  void operator()(ISerializer& serialize, const char* name, std::vector<T>& value)
57  {
58  size_t len = value.size();
59  serialize.NumberU32_Unbounded("length", (u32)len);
60  for (size_t i = 0; i < len; ++i)
61  Serializer(serialize, name, value[i]);
62  }
63 
64  void operator()(IDeserializer& deserialize, const char* name, std::vector<T>& value)
65  {
66  value.clear();
67  u32 len;
68  deserialize.NumberU32_Unbounded("length", len);
69  value.reserve(len); // TODO: watch out for out-of-memory
70  for (size_t i = 0; i < len; ++i)
71  {
72  T el;
73  Serializer(deserialize, name, el);
74  value.emplace_back(el);
75  }
76  }
77 };
78 
79 template<typename T>
80 struct SerializeHelper<std::set<T>>
81 {
82  void operator()(ISerializer& serialize, const char* name, const std::set<T>& value)
83  {
84  serialize.NumberU32_Unbounded("size", static_cast<u32>(value.size()));
85  for (const T& elem : value)
86  Serializer(serialize, name, elem);
87  }
88 
89  void operator()(IDeserializer& deserialize, const char* name, std::set<T>& value)
90  {
91  value.clear();
92  u32 size;
93  deserialize.NumberU32_Unbounded("size", size);
94  for (size_t i = 0; i < size; ++i)
95  {
96  T el;
97  Serializer(deserialize, name, el);
98  value.emplace(std::move(el));
99  }
100  }
101 };
102 
103 template<typename K, typename V>
104 struct SerializeHelper<std::map<K, V>>
105 {
106  template<typename... Args>
107  void operator()(ISerializer& serialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
108  {
109  size_t len = value.size();
110  serialize.NumberU32_Unbounded("length", (u32)len);
111  for (typename std::map<K, V>::iterator it = value.begin(); it != value.end(); ++it)
112  {
113  Serializer(serialize, "key", it->first, std::forward<Args>(args)...);
114  Serializer(serialize, "value", it->second, std::forward<Args>(args)...);
115  }
116  }
117 
118  template<typename... Args>
119  void operator()(IDeserializer& deserialize, const char* UNUSED(name), std::map<K, V>& value, Args&&... args)
120  {
121  value.clear();
122  u32 len;
123  deserialize.NumberU32_Unbounded("length", len);
124  for (size_t i = 0; i < len; ++i)
125  {
126  K k;
127  V v;
128  Serializer(deserialize, "key", k, std::forward<Args>(args)...);
129  Serializer(deserialize, "value", v, std::forward<Args>(args)...);
130  value.emplace(std::move(k), std::move(v));
131  }
132  }
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<>
153 {
154  void operator()(ISerializer& serialize, const char* name, u8 value)
155  {
156  serialize.NumberU8_Unbounded(name, value);
157  }
158 
159  void operator()(IDeserializer& deserialize, const char* name, u8& value)
160  {
161  deserialize.NumberU8_Unbounded(name, value);
162  }
163 };
164 
165 
166 template<typename Enum>
167 struct SerializeHelper<Enum, std::enable_if_t<std::is_enum_v<Enum>>>
168 {
169  void operator()(ISerializer& serialize, const char* name, Enum value, Enum&& max)
170  {
171  serialize.NumberU8(name, static_cast<u8>(value), 0, static_cast<u8>(max));
172  }
173 
174  void operator()(IDeserializer& deserialize, const char* name, Enum& value, Enum&& max)
175  {
176  u8 val;
177  deserialize.NumberU8(name, val, 0, static_cast<u8>(max));
178  value = static_cast<Enum>(val);
179  }
180 };
181 
182 
183 template<>
185 {
186  void operator()(ISerializer& serialize, const char* name, u16 value)
187  {
188  serialize.NumberU16_Unbounded(name, value);
189  }
190 
191  void operator()(IDeserializer& deserialize, const char* name, u16& value)
192  {
193  deserialize.NumberU16_Unbounded(name, value);
194  }
195 };
196 
197 template<>
199 {
200  template<typename... Args>
201  void operator()(ISerializer& serialize, const char* name, u32 value, Args&&...)
202  {
203  serialize.NumberU32_Unbounded(name, value);
204  }
205 
206  template<typename... Args>
207  void operator()(IDeserializer& deserialize, const char* name, u32& value, Args&&...)
208  {
209  deserialize.NumberU32_Unbounded(name, value);
210  }
211 };
212 
213 template<>
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  void operator()(ISerializer& serialize, const char* name, bool value)
231  {
232  serialize.Bool(name, value);
233  }
234 
235  void operator()(IDeserializer& deserialize, const char* name, bool& value)
236  {
237  deserialize.Bool(name, value);
238  }
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  void operator()(ISerializer& serialize, const char* name, T&& value)
246  {
247  serialize.StringASCII(name, value, 0, UINT32_MAX);
248  }
249 
250  template<typename T>
251  void operator()(IDeserializer& deserialize, const char* name, T& value)
252  {
253  deserialize.StringASCII(name, value, 0, UINT32_MAX);
254  }
255 };
256 
257 #endif // INCLUDED_SERIALIZED_TYPES
virtual void StringASCII(const char *name, std::string &out, uint32_t minlength, uint32_t maxlength)
Definition: IDeserializer.cpp:162
virtual void Bool(const char *name, bool &out)
Definition: IDeserializer.cpp:155
Helper templates definitions for serializing/deserializing common objects.
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
Definition: code_annotation.h:38
void operator()(ISerializer &serialize, const char *name, std::array< T, N > &value)
Definition: SerializedTypes.h:40
void operator()(ISerializer &serialize, const char *name, bool value)
Definition: SerializedTypes.h:230
void operator()(IDeserializer &deserialize, const char *name, bool &value)
Definition: SerializedTypes.h:235
uint16_t u16
Definition: types.h:38
Serialization interface; see serialization overview.
Definition: ISerializer.h:120
void operator()(IDeserializer &deserialize, const char *name, std::map< K, V > &value, Args &&... args)
Definition: SerializedTypes.h:119
void Serializer(S &serialize, const char *name, Args &&... args)
Definition: SerializeTemplates.h:51
void NumberU8_Unbounded(const char *name, uint8_t value)
Serialize a number.
Definition: ISerializer.h:150
virtual void NumberU32_Unbounded(const char *name, uint32_t &out)
Definition: IDeserializer.cpp:124
Definition: ShaderDefines.cpp:30
virtual void NumberU8_Unbounded(const char *name, uint8_t &out)
Definition: IDeserializer.cpp:100
uint8_t u8
Definition: types.h:37
#define UINT32_MAX
Definition: wposix_types.h:73
void operator()(IDeserializer &deserialize, const char *name, u16 &value)
Definition: SerializedTypes.h:191
void operator()(IDeserializer &deserialize, const char *name, std::vector< T > &value)
Definition: SerializedTypes.h:64
void operator()(ISerializer &serialize, const char *name, std::map< K, V > &value, Args &&... args)
Definition: SerializedTypes.h:107
uint32_t u32
Definition: types.h:39
void operator()(ISerializer &serialize, const char *name, T &&value)
Definition: SerializedTypes.h:245
void StringASCII(const char *name, const std::string &value, uint32_t minlength, uint32_t maxlength)
Serialize an ASCII string.
Definition: ISerializer.cpp:70
void operator()(ISerializer &serialize, const char *name, Enum value, Enum &&max)
Definition: SerializedTypes.h:169
void operator()(ISerializer &serialize, const char *name, u16 value)
Definition: SerializedTypes.h:186
void operator()(ISerializer &serialize, const char *name, i32 value)
Definition: SerializedTypes.h:216
void operator()(ISerializer &serialize, const char *name, u8 value)
Definition: SerializedTypes.h:154
void operator()(ISerializer &serialize, const char *name, const std::set< T > &value)
Definition: SerializedTypes.h:82
void Bool(const char *name, bool value)
Serialize a boolean.
Definition: ISerializer.h:199
void operator()(IDeserializer &deserialize, const char *name, i32 &value)
Definition: SerializedTypes.h:221
void operator()(IDeserializer &deserialize, const char *name, std::set< T > &value)
Definition: SerializedTypes.h:89
void operator()(IDeserializer &deserialize, const char *name, std::unordered_map< K, V > &value)
Definition: SerializedTypes.h:145
void operator()(ISerializer &serialize, const char *name, u32 value, Args &&...)
Definition: SerializedTypes.h:201
#define T(string_literal)
Definition: secure_crt.cpp:77
void NumberU32_Unbounded(const char *name, uint32_t value)
Serialize a number.
Definition: ISerializer.h:171
Definition: SerializeTemplates.h:41
int32_t i32
Definition: types.h:34
void operator()(IDeserializer &deserialize, const char *name, Enum &value, Enum &&max)
Definition: SerializedTypes.h:174
virtual void NumberU8(const char *name, uint8_t &out, uint8_t lower, uint8_t upper)
Definition: IDeserializer.cpp:30
void NumberI32_Unbounded(const char *name, int32_t value)
Serialize a number.
Definition: ISerializer.h:176
void operator()(ISerializer &serialize, const char *name, std::vector< T > &value)
Definition: SerializedTypes.h:56
void operator()(IDeserializer &deserialize, const char *name, u8 &value)
Definition: SerializedTypes.h:159
void NumberU16_Unbounded(const char *name, uint16_t value)
Serialize a number.
Definition: ISerializer.h:161
void operator()(ISerializer &serialize, const char *name, std::unordered_map< K, V > &value)
Definition: SerializedTypes.h:139
void NumberU8(const char *name, uint8_t value, uint8_t lower, uint8_t upper)
Serialize a number, which must be lower <= value <= upper.
Definition: ISerializer.cpp:28
void operator()(IDeserializer &deserialize, const char *name, std::array< T, N > &value)
Definition: SerializedTypes.h:46
virtual void NumberU16_Unbounded(const char *name, uint16_t &out)
Definition: IDeserializer.cpp:110
void operator()(IDeserializer &deserialize, const char *name, u32 &value, Args &&...)
Definition: SerializedTypes.h:207
Deserialization interface; see serialization overview.
Definition: IDeserializer.h:34
virtual void NumberI32_Unbounded(const char *name, int32_t &out)
Definition: IDeserializer.cpp:131
void operator()(IDeserializer &deserialize, const char *name, T &value)
Definition: SerializedTypes.h:251