• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) return;
40 		if ((pos + size) > buffer.size()) buffer.resize(pos + size);
41 		memmove(buffer.data() + pos, data, size);
42 		pos += size;
43 	}
44 };
45 
46 struct ToRead
47 {
48 	typedef void* VoidPointer;
SerializeDatavksc_server::ToRead49 	static void SerializeData (vector<u8>& buffer, msize& pos, VoidPointer data, msize size)
50 	{
51 		if (size == 0) return;
52 
53 		if ( (pos + size) > buffer.size() ) throw std::runtime_error("SerializeData::ToRead unexpected end");
54 		memmove(data, buffer.data() + pos, size);
55 		pos += size;
56 	}
57 };
58 
59 template <typename TYPE>
60 class Serializer
61 {
62 	vector<u8>& Data;
63 	msize Pos{};
64 
65 public:
Serializer(vector<u8> & data)66 			Serializer			(vector<u8>& data) : Data(data) {}
SerializeRawData(typename TYPE::VoidPointer data,msize size)67 	void	SerializeRawData	(typename TYPE::VoidPointer data, msize size) { TYPE::SerializeData(Data, Pos, data, size); }
68 	template <typename T>
SerializeObject(T & obj)69 	void	SerializeObject		(T& obj) { obj.Serialize(*this); }
70 
Serialize()71 	void	Serialize			() { }
72 	template <typename ARG>
Serialize(ARG && arg)73 	void	Serialize			(ARG&& arg) { SerializeItem(*this, arg); }
74 	template <typename ARG, typename... ARGs>
Serialize(ARG && first,ARGs &&...args)75 	void	Serialize			(ARG&& first, ARGs&&... args)	{ SerializeItem(*this, first); Serialize(args...); }
76 };
77 
78 template <typename TYPE>
SerializeItem(TYPE & serializer,u8 & val)79 inline void SerializeItem (TYPE& serializer, u8& val)
80 {
81 	serializer.SerializeRawData(&val, sizeof(u8));
82 }
83 
SerializeItem(Serializer<ToRead> & serializer,u32 & val)84 inline void SerializeItem (Serializer<ToRead>& serializer, u32& val)
85 {
86 	u32 nval;
87 	serializer.SerializeRawData(&nval, sizeof(u32));
88 	val = NetworkToHost32(nval);
89 }
90 
SerializeItem(Serializer<ToWrite> & serializer,u32 & val)91 inline void SerializeItem (Serializer<ToWrite>& serializer, u32& val)
92 {
93 	u32 nval = HostToNetwork32(val);
94 	serializer.SerializeRawData(&nval, sizeof(u32));
95 }
96 
SerializeItem(Serializer<ToRead> & serializer,u64 & val)97 inline void SerializeItem (Serializer<ToRead>& serializer, u64& val)
98 {
99 	u64 nval;
100 	serializer.SerializeRawData(&nval, sizeof(u64));
101 	val = NetworkToHost64(nval);
102 }
103 
SerializeItem(Serializer<ToWrite> & serializer,u64 & val)104 inline void SerializeItem (Serializer<ToWrite>& serializer, u64& val)
105 {
106 	u64 nval = HostToNetwork64(val);
107 	serializer.SerializeRawData(&nval, sizeof(u64));
108 }
109 
SerializeItem(Serializer<ToRead> & serializer,s32 & val)110 inline void SerializeItem (Serializer<ToRead>& serializer, s32& val)
111 {
112 	u32 nval;
113 	serializer.SerializeRawData(&nval, sizeof(u32));
114 	val = static_cast<s32>(NetworkToHost32(nval));
115 }
116 
SerializeItem(Serializer<ToWrite> & serializer,s32 & val)117 inline void SerializeItem (Serializer<ToWrite>& serializer, s32& val)
118 {
119 	u32 nval = HostToNetwork32(static_cast<u32>(val));
120 	serializer.SerializeRawData(&nval, sizeof(u32));
121 }
122 
SerializeItem(Serializer<ToRead> & serializer,bool & v)123 inline void SerializeItem (Serializer<ToRead>& serializer, bool& v)
124 {
125 	u8 byte;
126 	serializer.Serialize(byte);
127 	if (byte == 0) v = false;
128 	else if (byte == 1) v = true;
129 	else throw std::runtime_error("SerializeItem(Serializer<ToRead>, bool) invalid bool value");
130 }
131 
SerializeItem(Serializer<ToWrite> & serializer,bool & v)132 inline void SerializeItem (Serializer<ToWrite>& serializer, bool& v)
133 {
134 	u8 byte = v?1:0;
135 	serializer.Serialize(byte);
136 }
137 
SerializeSize(Serializer<ToWrite> & serializer,msize size)138 inline void SerializeSize (Serializer<ToWrite>& serializer, msize size)
139 {
140 	if (size > std::numeric_limits<u32>::max()) throw std::runtime_error("length of a container is too big");
141 	u32 size32 = (u32)size;
142 	serializer.Serialize(size32);
143 }
144 
SerializeSize(Serializer<ToRead> & serializer,msize & size)145 inline void SerializeSize (Serializer<ToRead>& serializer, msize& size)
146 {
147 	u32 size32;
148 	serializer.Serialize(size32);
149 	size = size32;
150 }
151 
SerializeItem(Serializer<ToRead> & serializer,string & str)152 inline void SerializeItem (Serializer<ToRead>& serializer, string& str)
153 {
154 	msize size;
155 	SerializeSize(serializer, size);
156 
157 	vector<char> v(size);
158 	serializer.SerializeRawData(v.data(), v.size());
159 	str.assign(v.begin(), v.end());
160 }
161 
SerializeItem(Serializer<ToWrite> & serializer,const string & str)162 inline void SerializeItem (Serializer<ToWrite>& serializer, const string& str)
163 {
164 	SerializeSize(serializer, str.size());
165 	serializer.SerializeRawData(str.data(), str.size());
166 }
167 
168 template <typename T>
SerializeItem(Serializer<ToWrite> & serializer,std::vector<T> & v)169 inline void SerializeItem(Serializer<ToWrite>& serializer, std::vector<T>& v)
170 {
171 	msize ms = v.size();
172 	SerializeSize(serializer, ms);
173 
174 	for (msize i{}; i < v.size(); ++i)
175 	{
176 		serializer.Serialize(v[i]);
177 	}
178 }
179 
180 template <typename T>
SerializeItem(Serializer<ToRead> & serializer,std::vector<T> & v)181 inline void SerializeItem(Serializer<ToRead>& serializer, std::vector<T>& v)
182 {
183 	msize size;
184 	SerializeSize(serializer, size);
185 	v.clear();
186 	for (msize i{}; i < size; ++i)
187 	{
188 		T item;
189 		SerializeItem(serializer, item);
190 		v.push_back(std::move(item));
191 	}
192 }
193 
194 template <>
SerializeItem(Serializer<ToWrite> & serializer,std::vector<u8> & v)195 inline void SerializeItem (Serializer<ToWrite>& serializer, std::vector<u8>& v)
196 {
197 	SerializeSize(serializer, v.size());
198 	serializer.SerializeRawData(v.data(), v.size());
199 }
200 
201 template <>
SerializeItem(Serializer<ToRead> & serializer,std::vector<u8> & v)202 inline void SerializeItem (Serializer<ToRead>& serializer, std::vector<u8>& v)
203 {
204 	msize size;
205 	SerializeSize(serializer, size);
206 
207 	v.clear();
208 	v.resize(size);
209 	serializer.SerializeRawData(v.data(), v.size());
210 }
211 
212 template <typename K, typename V>
SerializeItem(Serializer<ToRead> & serializer,std::map<K,V> & v)213 inline void SerializeItem (Serializer<ToRead>& serializer, std::map<K, V>& v)
214 {
215 	msize size;
216 	SerializeSize(serializer, size);
217 	v.clear();
218 	for (msize i{}; i < size; ++i)
219 	{
220 		std::pair<K, V> p;
221 		serializer.Serialize(p.first, p.second);
222 		v.insert(std::move(p));
223 	}
224 }
225 
226 template <typename K, typename V>
SerializeItem(Serializer<ToWrite> & serializer,std::map<K,V> & v)227 inline void SerializeItem (Serializer<ToWrite>& serializer, std::map<K, V>& v)
228 {
229 	SerializeSize(serializer, v.size());
230 	for (auto& p : v)
231 	{
232 		serializer.Serialize(p.first, p.second);
233 	}
234 }
235 
236 template <typename T>
SerializeItem(Serializer<ToRead> & serializer,std::set<T> & v)237 inline void SerializeItem (Serializer<ToRead>& serializer, std::set<T>& v)
238 {
239 	msize size;
240 	SerializeSize(serializer, size);
241 	v.clear();
242 	for (msize i{}; i < size; ++i)
243 	{
244 		T item;
245 		SerializeItem(serializer, item);
246 		v.insert(std::move(item));
247 	}
248 }
249 
250 template <typename T>
SerializeItem(Serializer<ToWrite> & serializer,std::set<T> & v)251 inline void SerializeItem (Serializer<ToWrite>& serializer, std::set<T>& v)
252 {
253 	SerializeSize(serializer, v.size());
254 	for (auto& i : v) SerializeItem(serializer, i);
255 }
256 
257 template <typename T>
Serialize(T & data)258 inline vector<u8> Serialize(T& data)
259 {
260 	vector<u8> result;
261 	Serializer<ToWrite>{result}.SerializeObject(data);
262 	return result;
263 }
264 
265 template <typename T>
Deserialize(vector<u8> & buffer)266 inline T Deserialize(vector<u8>& buffer)
267 {
268 	T result;
269 	Serializer<ToRead>{buffer}.SerializeObject(result);
270 	return result;
271 }
272 
273 }
274 
275 #endif // _VKSSERIALIZER_HPP
276