1 #ifndef _VKSSERIALIZER_HPP
2 #define _VKSSERIALIZER_HPP
3
4 /*-------------------------------------------------------------------------
5 * Vulkan CTS Framework
6 * --------------------
7 *
8 * Copyright (c) 2021 The Khronos Group Inc.
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *-------------------------------------------------------------------------*/
23
24 #include "vksCommon.hpp"
25 #include "vksEndian.hpp"
26
27 #include <cstring>
28 #include <map>
29 #include <set>
30
31 namespace vksc_server
32 {
33
34 struct ToWrite
35 {
36 typedef const void *VoidPointer;
SerializeDatavksc_server::ToWrite37 static void SerializeData(vector<u8> &buffer, msize &pos, VoidPointer data, msize size)
38 {
39 if (size == 0)
40 return;
41 if ((pos + size) > buffer.size())
42 buffer.resize(pos + size);
43 memmove(buffer.data() + pos, data, size);
44 pos += size;
45 }
46 };
47
48 struct ToRead
49 {
50 typedef void *VoidPointer;
SerializeDatavksc_server::ToRead51 static void SerializeData(vector<u8> &buffer, msize &pos, VoidPointer data, msize size)
52 {
53 if (size == 0)
54 return;
55
56 if ((pos + size) > buffer.size())
57 throw std::runtime_error("SerializeData::ToRead unexpected end");
58 memmove(data, buffer.data() + pos, size);
59 pos += size;
60 }
61 };
62
63 template <typename TYPE>
64 class Serializer
65 {
66 vector<u8> &Data;
67 msize Pos{};
68
69 public:
Serializer(vector<u8> & data)70 Serializer(vector<u8> &data) : Data(data)
71 {
72 }
SerializeRawData(typename TYPE::VoidPointer data,msize size)73 void SerializeRawData(typename TYPE::VoidPointer data, msize size)
74 {
75 TYPE::SerializeData(Data, Pos, data, size);
76 }
77 template <typename T>
SerializeObject(T & obj)78 void SerializeObject(T &obj)
79 {
80 obj.Serialize(*this);
81 }
82
Serialize()83 void Serialize()
84 {
85 }
86 template <typename ARG>
Serialize(ARG && arg)87 void Serialize(ARG &&arg)
88 {
89 SerializeItem(*this, arg);
90 }
91 template <typename ARG, typename... ARGs>
Serialize(ARG && first,ARGs &&...args)92 void Serialize(ARG &&first, ARGs &&...args)
93 {
94 SerializeItem(*this, first);
95 Serialize(args...);
96 }
97 };
98
99 template <typename TYPE>
SerializeItem(TYPE & serializer,u8 & val)100 inline void SerializeItem(TYPE &serializer, u8 &val)
101 {
102 serializer.SerializeRawData(&val, sizeof(u8));
103 }
104
SerializeItem(Serializer<ToRead> & serializer,u32 & val)105 inline void SerializeItem(Serializer<ToRead> &serializer, u32 &val)
106 {
107 u32 nval;
108 serializer.SerializeRawData(&nval, sizeof(u32));
109 val = NetworkToHost32(nval);
110 }
111
SerializeItem(Serializer<ToWrite> & serializer,u32 & val)112 inline void SerializeItem(Serializer<ToWrite> &serializer, u32 &val)
113 {
114 u32 nval = HostToNetwork32(val);
115 serializer.SerializeRawData(&nval, sizeof(u32));
116 }
117
SerializeItem(Serializer<ToRead> & serializer,u64 & val)118 inline void SerializeItem(Serializer<ToRead> &serializer, u64 &val)
119 {
120 u64 nval;
121 serializer.SerializeRawData(&nval, sizeof(u64));
122 val = NetworkToHost64(nval);
123 }
124
SerializeItem(Serializer<ToWrite> & serializer,u64 & val)125 inline void SerializeItem(Serializer<ToWrite> &serializer, u64 &val)
126 {
127 u64 nval = HostToNetwork64(val);
128 serializer.SerializeRawData(&nval, sizeof(u64));
129 }
130
SerializeItem(Serializer<ToRead> & serializer,s32 & val)131 inline void SerializeItem(Serializer<ToRead> &serializer, s32 &val)
132 {
133 u32 nval;
134 serializer.SerializeRawData(&nval, sizeof(u32));
135 val = static_cast<s32>(NetworkToHost32(nval));
136 }
137
SerializeItem(Serializer<ToWrite> & serializer,s32 & val)138 inline void SerializeItem(Serializer<ToWrite> &serializer, s32 &val)
139 {
140 u32 nval = HostToNetwork32(static_cast<u32>(val));
141 serializer.SerializeRawData(&nval, sizeof(u32));
142 }
143
SerializeItem(Serializer<ToRead> & serializer,bool & v)144 inline void SerializeItem(Serializer<ToRead> &serializer, bool &v)
145 {
146 u8 byte;
147 serializer.Serialize(byte);
148 if (byte == 0)
149 v = false;
150 else if (byte == 1)
151 v = true;
152 else
153 throw std::runtime_error("SerializeItem(Serializer<ToRead>, bool) invalid bool value");
154 }
155
SerializeItem(Serializer<ToWrite> & serializer,bool & v)156 inline void SerializeItem(Serializer<ToWrite> &serializer, bool &v)
157 {
158 u8 byte = v ? 1 : 0;
159 serializer.Serialize(byte);
160 }
161
SerializeSize(Serializer<ToWrite> & serializer,msize size)162 inline void SerializeSize(Serializer<ToWrite> &serializer, msize size)
163 {
164 if (size > std::numeric_limits<u32>::max())
165 throw std::runtime_error("length of a container is too big");
166 u32 size32 = (u32)size;
167 serializer.Serialize(size32);
168 }
169
SerializeSize(Serializer<ToRead> & serializer,msize & size)170 inline void SerializeSize(Serializer<ToRead> &serializer, msize &size)
171 {
172 u32 size32;
173 serializer.Serialize(size32);
174 size = size32;
175 }
176
SerializeItem(Serializer<ToRead> & serializer,string & str)177 inline void SerializeItem(Serializer<ToRead> &serializer, string &str)
178 {
179 msize size;
180 SerializeSize(serializer, size);
181
182 vector<char> v(size);
183 serializer.SerializeRawData(v.data(), v.size());
184 str.assign(v.begin(), v.end());
185 }
186
SerializeItem(Serializer<ToWrite> & serializer,const string & str)187 inline void SerializeItem(Serializer<ToWrite> &serializer, const string &str)
188 {
189 SerializeSize(serializer, str.size());
190 serializer.SerializeRawData(str.data(), str.size());
191 }
192
193 template <typename T>
SerializeItem(Serializer<ToWrite> & serializer,std::vector<T> & v)194 inline void SerializeItem(Serializer<ToWrite> &serializer, std::vector<T> &v)
195 {
196 msize ms = v.size();
197 SerializeSize(serializer, ms);
198
199 for (msize i{}; i < v.size(); ++i)
200 {
201 serializer.Serialize(v[i]);
202 }
203 }
204
205 template <typename T>
SerializeItem(Serializer<ToRead> & serializer,std::vector<T> & v)206 inline void SerializeItem(Serializer<ToRead> &serializer, std::vector<T> &v)
207 {
208 msize size;
209 SerializeSize(serializer, size);
210 v.clear();
211 for (msize i{}; i < size; ++i)
212 {
213 T item;
214 SerializeItem(serializer, item);
215 v.push_back(std::move(item));
216 }
217 }
218
219 template <>
SerializeItem(Serializer<ToWrite> & serializer,std::vector<u8> & v)220 inline void SerializeItem(Serializer<ToWrite> &serializer, std::vector<u8> &v)
221 {
222 SerializeSize(serializer, v.size());
223 serializer.SerializeRawData(v.data(), v.size());
224 }
225
226 template <>
SerializeItem(Serializer<ToRead> & serializer,std::vector<u8> & v)227 inline void SerializeItem(Serializer<ToRead> &serializer, std::vector<u8> &v)
228 {
229 msize size;
230 SerializeSize(serializer, size);
231
232 v.clear();
233 v.resize(size);
234 serializer.SerializeRawData(v.data(), v.size());
235 }
236
237 template <typename K, typename V>
SerializeItem(Serializer<ToRead> & serializer,std::map<K,V> & v)238 inline void SerializeItem(Serializer<ToRead> &serializer, std::map<K, V> &v)
239 {
240 msize size;
241 SerializeSize(serializer, size);
242 v.clear();
243 for (msize i{}; i < size; ++i)
244 {
245 std::pair<K, V> p;
246 serializer.Serialize(p.first, p.second);
247 v.insert(std::move(p));
248 }
249 }
250
251 template <typename K, typename V>
SerializeItem(Serializer<ToWrite> & serializer,std::map<K,V> & v)252 inline void SerializeItem(Serializer<ToWrite> &serializer, std::map<K, V> &v)
253 {
254 SerializeSize(serializer, v.size());
255 for (auto &p : v)
256 {
257 serializer.Serialize(p.first, p.second);
258 }
259 }
260
261 template <typename T>
SerializeItem(Serializer<ToRead> & serializer,std::set<T> & v)262 inline void SerializeItem(Serializer<ToRead> &serializer, std::set<T> &v)
263 {
264 msize size;
265 SerializeSize(serializer, size);
266 v.clear();
267 for (msize i{}; i < size; ++i)
268 {
269 T item;
270 SerializeItem(serializer, item);
271 v.insert(std::move(item));
272 }
273 }
274
275 template <typename T>
SerializeItem(Serializer<ToWrite> & serializer,std::set<T> & v)276 inline void SerializeItem(Serializer<ToWrite> &serializer, std::set<T> &v)
277 {
278 SerializeSize(serializer, v.size());
279 for (auto &i : v)
280 SerializeItem(serializer, i);
281 }
282
283 template <typename T>
Serialize(T & data)284 inline vector<u8> Serialize(T &data)
285 {
286 vector<u8> result;
287 Serializer<ToWrite>{result}.SerializeObject(data);
288 return result;
289 }
290
291 template <typename T>
Deserialize(vector<u8> & buffer)292 inline T Deserialize(vector<u8> &buffer)
293 {
294 T result;
295 Serializer<ToRead>{buffer}.SerializeObject(result);
296 return result;
297 }
298
299 } // namespace vksc_server
300
301 #endif // _VKSSERIALIZER_HPP
302