Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
46namespace 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/*
58template <class TStream>
59void Serialize(TStream& buf, const bool& val)
60{
61 buf.write((char*)&val, sizeof(bool));
62}
63
64template <class TStream>
65void Deserialize(TStream& buf, bool& valOut)
66{
67 buf.read((char*)&valOut, sizeof(bool));
68}
69
70template <class TStream>
71void Serialize(TStream& buf, const char& val)
72{
73 buf.write((char*)&val, sizeof(char));
74}
75
76template <class TStream>
77void Deserialize(TStream& buf, char& valOut)
78{
79 buf.read((char*)&valOut, sizeof(char));
80}
81
82template <class TStream>
83void Serialize(TStream& buf, const unsigned char& val)
84{
85 buf.write((char*)&val, sizeof(unsigned char));
86}
87
88template <class TStream>
89void Deserialize(TStream& buf, unsigned char& valOut)
90{
91 buf.read((char*)&valOut, sizeof(unsigned char));
92}
93
94template <class TStream>
95void Serialize(TStream& buf, const int& val)
96{
97 buf.write((char*)&val, sizeof(int));
98}
99
100template <class TStream>
101void Deserialize(TStream& buf, int& valOut)
102{
103 buf.read((char*)&valOut, sizeof(int));
104}
105
106template <class TStream>
107void Serialize(TStream& buf, const unsigned int& val)
108{
109 buf.write((char*)&val, sizeof(unsigned int));
110}
111
112template <class TStream>
113void Deserialize(TStream& buf, unsigned int& valOut)
114{
115 buf.read((char*)&valOut, sizeof(unsigned int));
116}
117
118template <class TStream>
119void Serialize(TStream& buf, const size_t& val)
120{
121 buf.write((char*)&val, sizeof(size_t));
122}
123
124template <class TStream>
125void Deserialize(TStream& buf, size_t& valOut)
126{
127 buf.read((char*)&valOut, sizeof(size_t));
128}
129
130template <class TStream>
131void Serialize(TStream& buf, const float& val)
132{
133 buf.write((char*)&val, sizeof(float));
134}
135
136template <class TStream>
137void Deserialize(TStream& buf, float& valOut)
138{
139 buf.read((char*)&valOut, sizeof(float));
140}
141
142template <class TStream>
143void Serialize(TStream& buf, const double& val)
144{
145 buf.write((char*)&val, sizeof(int));
146}
147
148template <class TStream>
149void Deserialize(TStream& buf, double& valOut)
150{
151 buf.read((char*)&valOut, sizeof(double));
152}
153*/
154
155template <class TStream, class T>
156void Serialize(TStream& buf, const T& val)
157{
158 buf.write((char*)&val, sizeof(T));
159}
160
161template <class TStream, class T>
162void Deserialize(TStream& buf, T& valOut)
163{
164 buf.read((char*)&valOut, sizeof(T));
165}
166
168template<typename T, class TIStream>
169T Deserialize(TIStream &stream)
170{
171 T t;
172 Deserialize(stream, t);
173 return t;
174}
175
177
178template <class TStream, class T>
179void 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.
185template <class T1, class T2, class TOStream>
186void Serialize(TOStream& buf, const std::pair<T1, T2>& v);
187
188template <class T1, class T2, class TIStream>
189void Deserialize(TIStream& buf, std::pair<T1, T2>& v);
190
191template <class T, class TOStream>
192void Serialize(TOStream& buf, const std::set<T>& m);
193
194template <class T, class TIStream>
195void Deserialize(TIStream& buf, std::set<T>& myset);
196
197template <class TOStream>
198void Serialize(TOStream& buf, const std::string& str);
199
200template <class TIStream>
201void Deserialize(TIStream& buf, std::string& str);
202
203template <class TOStream>
204void Serialize(TOStream& buf, const Variant& v);
205
206template <class TIStream>
207void Deserialize(TIStream& buf, Variant& v);
208
209template <class T, class TOStream>
210void Serialize(TOStream& buf, const std::vector<T>& vec);
211
212template <class T, class TIStream>
213void Deserialize(TIStream& buf, std::vector<T>& vec);
214
215template <class TOStream>
216inline void Serialize(TOStream& buf, const std::vector<bool>::reference& boolRef);
217
218template <class TIStream>
219inline void Deserialize(TIStream& buf, std::vector<bool>::reference boolRef);
220
221template <class Key, class T, class TOStream>
222void Serialize(TOStream& buf, const std::map<Key, T>& m);
223
224template <class Key, class T, class TIStream>
225void Deserialize(TIStream& buf, std::map<Key, T>& m);
227
228
229
231template <class T1, class T2, class TOStream>
232void Serialize(TOStream& buf, const std::pair<T1, T2>& v)
233{
234 Serialize(buf, v.first);
235 Serialize(buf, v.second);
236}
237
238template <class T1, class T2, class TIStream>
239void Deserialize(TIStream& buf, std::pair<T1, T2>& v)
240{
241 Deserialize(buf, v.first);
242 Deserialize(buf, v.second);
243}
244
246
251template <class T, class TOStream>
252void 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
260template <class T, class TIStream>
261void 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
276template <class TOStream>
277void 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
286template <class TIStream>
287void 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
324template <class TOStream>
325void 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
348template <class TIStream>
349void 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
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
378template <class T, class TOStream>
379void 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
389template <class T, class TIStream>
390void 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
401template<class TIStream>
402void 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
421template<class TIStream>
422void 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
447template <class TOStream>
448inline 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.
457template <class TIStream>
458inline 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
472template <class Key, class T, class TOStream>
473void 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
485template <class Key, class T, class TIStream>
486void 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