ug4
serialization.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3  * Authors: Sebastian Reiter, Martin Rupp
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG__SERIALIZATION__
34 #define __H__UG__SERIALIZATION__
35 
36 #include <iostream>
37 #include <vector>
38 #include <set>
39 #include <map>
40 #include <string>
41 #include <cassert>
42 #include "log.h"
43 #include "util/variant.h"
44 #include "error.h"
45 
46 namespace ug
47 {
48 
51 
52 //todo It would probably be a good idea to replace the generic Serialize and
53 // Deserialize methods with concrete ones, since nasty and hard to trace
54 // bugs could be avoided this way. The following Serialize methods already
55 // implement serialization for common types. A rather big effort for all
56 // the custom types which have to be serialized has to be taken though...
57 /*
58 template <class TStream>
59 void Serialize(TStream& buf, const bool& val)
60 {
61  buf.write((char*)&val, sizeof(bool));
62 }
63 
64 template <class TStream>
65 void Deserialize(TStream& buf, bool& valOut)
66 {
67  buf.read((char*)&valOut, sizeof(bool));
68 }
69 
70 template <class TStream>
71 void Serialize(TStream& buf, const char& val)
72 {
73  buf.write((char*)&val, sizeof(char));
74 }
75 
76 template <class TStream>
77 void Deserialize(TStream& buf, char& valOut)
78 {
79  buf.read((char*)&valOut, sizeof(char));
80 }
81 
82 template <class TStream>
83 void Serialize(TStream& buf, const unsigned char& val)
84 {
85  buf.write((char*)&val, sizeof(unsigned char));
86 }
87 
88 template <class TStream>
89 void Deserialize(TStream& buf, unsigned char& valOut)
90 {
91  buf.read((char*)&valOut, sizeof(unsigned char));
92 }
93 
94 template <class TStream>
95 void Serialize(TStream& buf, const int& val)
96 {
97  buf.write((char*)&val, sizeof(int));
98 }
99 
100 template <class TStream>
101 void Deserialize(TStream& buf, int& valOut)
102 {
103  buf.read((char*)&valOut, sizeof(int));
104 }
105 
106 template <class TStream>
107 void Serialize(TStream& buf, const unsigned int& val)
108 {
109  buf.write((char*)&val, sizeof(unsigned int));
110 }
111 
112 template <class TStream>
113 void Deserialize(TStream& buf, unsigned int& valOut)
114 {
115  buf.read((char*)&valOut, sizeof(unsigned int));
116 }
117 
118 template <class TStream>
119 void Serialize(TStream& buf, const size_t& val)
120 {
121  buf.write((char*)&val, sizeof(size_t));
122 }
123 
124 template <class TStream>
125 void Deserialize(TStream& buf, size_t& valOut)
126 {
127  buf.read((char*)&valOut, sizeof(size_t));
128 }
129 
130 template <class TStream>
131 void Serialize(TStream& buf, const float& val)
132 {
133  buf.write((char*)&val, sizeof(float));
134 }
135 
136 template <class TStream>
137 void Deserialize(TStream& buf, float& valOut)
138 {
139  buf.read((char*)&valOut, sizeof(float));
140 }
141 
142 template <class TStream>
143 void Serialize(TStream& buf, const double& val)
144 {
145  buf.write((char*)&val, sizeof(int));
146 }
147 
148 template <class TStream>
149 void Deserialize(TStream& buf, double& valOut)
150 {
151  buf.read((char*)&valOut, sizeof(double));
152 }
153 */
154 
155 template <class TStream, class T>
156 void Serialize(TStream& buf, const T& val)
157 {
158  buf.write((char*)&val, sizeof(T));
159 }
160 
161 template <class TStream, class T>
162 void Deserialize(TStream& buf, T& valOut)
163 {
164  buf.read((char*)&valOut, sizeof(T));
165 }
166 
168 template<typename T, class TIStream>
169 T Deserialize(TIStream &stream)
170 {
171  T t;
172  Deserialize(stream, t);
173  return t;
174 }
175 
177 
178 template <class TStream, class T>
179 void Deserialize(TStream& buf, const T& valOut);
180 
181 
183 // All specializations should be pre-declared here!
184 // This is important, so that the different methods know of each other.
185 template <class T1, class T2, class TOStream>
186 void Serialize(TOStream& buf, const std::pair<T1, T2>& v);
187 
188 template <class T1, class T2, class TIStream>
189 void Deserialize(TIStream& buf, std::pair<T1, T2>& v);
190 
191 template <class T, class TOStream>
192 void Serialize(TOStream& buf, const std::set<T>& m);
193 
194 template <class T, class TIStream>
195 void Deserialize(TIStream& buf, std::set<T>& myset);
196 
197 template <class TOStream>
198 void Serialize(TOStream& buf, const std::string& str);
199 
200 template <class TIStream>
201 void Deserialize(TIStream& buf, std::string& str);
202 
203 template <class TOStream>
204 void Serialize(TOStream& buf, const Variant& v);
205 
206 template <class TIStream>
207 void Deserialize(TIStream& buf, Variant& v);
208 
209 template <class T, class TOStream>
210 void Serialize(TOStream& buf, const std::vector<T>& vec);
211 
212 template <class T, class TIStream>
213 void Deserialize(TIStream& buf, std::vector<T>& vec);
214 
215 template <class TOStream>
216 inline void Serialize(TOStream& buf, const std::vector<bool>::reference& boolRef);
217 
218 template <class TIStream>
219 inline void Deserialize(TIStream& buf, std::vector<bool>::reference boolRef);
220 
221 template <class Key, class T, class TOStream>
222 void Serialize(TOStream& buf, const std::map<Key, T>& m);
223 
224 template <class Key, class T, class TIStream>
225 void Deserialize(TIStream& buf, std::map<Key, T>& m);
227 
228 
229 
231 template <class T1, class T2, class TOStream>
232 void Serialize(TOStream& buf, const std::pair<T1, T2>& v)
233 {
234  Serialize(buf, v.first);
235  Serialize(buf, v.second);
236 }
237 
238 template <class T1, class T2, class TIStream>
239 void Deserialize(TIStream& buf, std::pair<T1, T2>& v)
240 {
241  Deserialize(buf, v.first);
242  Deserialize(buf, v.second);
243 }
244 
246 
251 template <class T, class TOStream>
252 void Serialize(TOStream& buf, const std::set<T>& m)
253 {
254  Serialize<size_t>(buf, m.size());
255  for(typename std::set<T>::const_iterator it = m.begin(); it != m.end(); ++it)
256  Serialize<T>(buf, *it);
257 }
258 
260 template <class T, class TIStream>
261 void Deserialize(TIStream& buf, std::set<T>& myset)
262 {
263  myset.clear();
264  size_t size = Deserialize<size_t>(buf);
265  T t;
266  for(size_t i = 0; i < size; ++i)
267  {
268  Deserialize<T>(buf, t);
269  // using myset.end() because data t is sorted.
270  myset.insert (myset.end(), t);
271  }
272 }
273 
275 
276 template <class TOStream>
277 void Serialize(TOStream& buf, const std::string& str)
278 {
279  size_t len = str.length();
280  Serialize(buf, len);
281  if(len > 0)
282  buf.write(str.c_str(), sizeof(char) * len);
283 }
284 
286 template <class TIStream>
287 void Deserialize(TIStream& buf, std::string& str)
288 {
289 // the buffers allow us to read small strings fast.
290 // for bigger ones we have to temporarily reserve memory.
291  char staticBuf[64];
292  char* flexBuf = NULL;
293  char* tBuf = staticBuf;
294 
295  size_t len = Deserialize<size_t>(buf);
296 
297 // check whether we have to allocate memory
298 // don't forget that we have to append a zero at the end
299  if(len >= 63){
300  flexBuf = new char[len + 1];
301  tBuf = flexBuf;
302  }
303 
304  if(len > 0)
305  buf.read(tBuf, sizeof(char) * len);
306  tBuf[len] = 0;
307 
308 // assign data to the out-string
309  str = tBuf;
310 
311 // clean up
312  if(flexBuf)
313  delete[] flexBuf;
314 }
315 
316 
318 
324 template <class TOStream>
325 void Serialize(TOStream& buf, const Variant& v)
326 {
327  Serialize(buf, int(v.type()));
328  switch(v.type()){
329  case Variant::VT_INVALID: break;
330  case Variant::VT_BOOL: Serialize(buf, v.to_bool()); break;
331  case Variant::VT_INT: Serialize(buf, v.to_int()); break;
332  case Variant::VT_FLOAT: Serialize(buf, v.to_float()); break;
333  case Variant::VT_DOUBLE: Serialize(buf, v.to_double()); break;
334  case Variant::VT_CSTRING: Serialize(buf, std::string(v.to_c_string())); break;
335  case Variant::VT_STDSTRING: Serialize(buf, v.to_std_string()); break;
336  case Variant::VT_POINTER: break;
337 
338  default:
339  UG_THROW("Unknown variant type in Serialize:" << v.type());
340  break;
341  }
342 }
343 
345 
348 template <class TIStream>
349 void Deserialize(TIStream& buf, Variant& v)
350 {
351  int type = Deserialize<int>(buf);
352  switch(type){
353  case Variant::VT_INVALID: v = Variant(); break;
354  case Variant::VT_BOOL: v = Variant(Deserialize<bool>(buf)); break;
355  case Variant::VT_INT: v = Variant(Deserialize<int>(buf)); break;
356  case Variant::VT_FLOAT: v = Variant(Deserialize<float>(buf)); break;
357  case Variant::VT_DOUBLE: v = Variant(Deserialize<double>(buf)); break;
358  case Variant::VT_CSTRING: // fallthrough
359  case Variant::VT_STDSTRING: v = Variant(Deserialize<std::string>(buf)); break;
360 
361  case Variant::VT_POINTER:{
362  void* val = NULL;
363  v = Variant(val);
364  } break;
365 
366  default:
367  UG_THROW("Unknown variant type in Deserialize: " << type);
368  break;
369  }
370 }
371 
373 
378 template <class T, class TOStream>
379 void Serialize(TOStream& buf, const std::vector<T>& vec)
380 {
381  size_t size = vec.size();
382  Serialize(buf, size);
383  for(size_t i = 0; i < size; ++i){
384  Serialize(buf, vec[i]);
385  }
386 }
387 
389 template <class T, class TIStream>
390 void Deserialize(TIStream& buf, std::vector<T>& vec)
391 {
392  vec.clear();
393  size_t size = Deserialize<size_t>(buf);
394  vec.resize(size);
395  for(size_t i = 0; i < size; ++i){
396  Deserialize(buf, vec[i]);
397  }
398 }
399 
400 
401 template<class TIStream>
402 void Serialize(TIStream &buf, const std::vector<bool> &vec)
403 {
404  size_t size=vec.size();
405  Serialize<size_t>(buf, size);
406  int j=0;
407  char a=0;
408  for(size_t i = 0; i < size; ++i)
409  {
410  if(vec[i]) a |= (1 << j);
411  if(++j == 8)
412  {
413  Serialize<char>(buf, a);
414  a = 0;
415  j = 0;
416  }
417  }
418  if(j) Serialize<char>(buf, a);
419 }
420 
421 template<class TIStream>
422 void Deserialize(TIStream &buf, std::vector<bool> &vec)
423 {
424  vec.clear();
425  size_t size = Deserialize<size_t>(buf);
426  vec.resize(size);
427  int j=8;
428  char a=0;
429  for(size_t i = 0; i < size; ++i, ++j)
430  {
431  if(j==8)
432  {
433  Deserialize<char>(buf, a);
434  j=0;
435  }
436  vec[i] = a & (1 << j);
437  j++;
438  }
439 }
440 
447 template <class TOStream>
448 inline void Serialize(TOStream& buf, const std::vector<bool>::reference& boolRef)
449 {
450  char b = ((bool)boolRef) ? 1 : 0;
451  buf.write(&b, sizeof(char));
452 }
453 
455 // * This function is to avoid surprises with vector<bool>
456 // note: boolRef is not &boolRef.
457 template <class TIStream>
458 inline void Deserialize(TIStream& buf, std::vector<bool>::reference boolRef)
459 {
460  char b;
461  buf.read(&b, sizeof(char));
462  boolRef = (bool)(b == 1);
463 }
464 
465 
467 
472 template <class Key, class T, class TOStream>
473 void Serialize(TOStream& buf, const std::map<Key, T>& m)
474 {
475  Serialize(buf, m.size());
476 
477  for(typename std::map<Key, T>::const_iterator it = m.begin(); it != m.end(); ++it)
478  {
479  Serialize(buf, it->first);
480  Serialize(buf, it->second);
481  }
482 }
483 
485 template <class Key, class T, class TIStream>
486 void Deserialize(TIStream& buf, std::map<Key, T>& m)
487 {
488  m.clear();
489  size_t size = Deserialize<size_t>(buf);
490  for(size_t i = 0; i < size; ++i)
491  {
492  Key k;
493  Deserialize(buf, k);
494  Deserialize(buf, m[k]);
495  }
496 }
497 
498 // end group ugbase_common
500 
501 }// end of namespace
502 
503 
504 #endif
A variant can represent variables of different types.
Definition: variant.h:87
double to_double() const
Definition: variant.cpp:291
float to_float() const
Definition: variant.cpp:259
bool to_bool() const
Definition: variant.cpp:213
@ VT_STDSTRING
Definition: variant.h:97
@ VT_BOOL
Definition: variant.h:91
@ VT_INT
Definition: variant.h:92
@ VT_CSTRING
Definition: variant.h:96
@ VT_DOUBLE
Definition: variant.h:95
@ VT_INVALID
Definition: variant.h:90
@ VT_FLOAT
Definition: variant.h:94
@ VT_POINTER
Definition: variant.h:98
Type type() const
Definition: variant.h:132
const char * to_c_string() const
Definition: variant.cpp:307
const std::string & to_std_string() const
Definition: variant.cpp:320
int to_int() const
Definition: variant.cpp:229
#define UG_THROW(msg)
Definition: error.h:57
the ug namespace
void Deserialize(TIStream &buf, ParallelVector< T > &v)
Deerialize for ParallelVector<T>
Definition: restart_bridge.cpp:112
void Serialize(TOStream &buf, const ParallelVector< T > &v)
Serialize for ParallelVector<T>
Definition: restart_bridge.cpp:103