EUDAQ
 All Classes Namespaces Files Functions Variables Pages
Serializer.hh
1 #ifndef EUDAQ_INCLUDED_Serializer
2 #define EUDAQ_INCLUDED_Serializer
3 
4 #include <string>
5 #include <vector>
6 #include <map>
7 #include "eudaq/Serializable.hh"
8 
9 #include "eudaq/Time.hh"
10 #include "eudaq/Exception.hh"
11 #include "eudaq/Platform.hh"
12 
13 namespace eudaq {
14 
15  class InterruptedException : public std::exception {
16  const char *what() const throw() { return "InterruptedException"; }
17  };
18 
19  class DLLEXPORT Serializer {
20  public:
21  virtual void Flush() {}
22  void write(const Serializable &t) { t.Serialize(*this); }
23  template <typename T> void write(const T &t);
24  template <typename T> void write(const std::vector<T> &t);
25  template <typename T, typename U> void write(const std::map<T, U> &t);
26  template <typename T, typename U> void write(const std::pair<T, U> &t);
27 
28  void append(const unsigned char *data, size_t size) {
29  Serialize(data, size);
30  }
31 
32  virtual uint64_t GetCheckSum() { return 0; }
33 
34  virtual ~Serializer() {}
35 
36  private:
37  template <typename T> friend struct WriteHelper;
38  virtual void Serialize(const unsigned char *, size_t) = 0;
39  };
40 
41  template <typename T> struct WriteHelper {
42  typedef void (*writer)(Serializer &ser, const T &v);
43  static writer GetFunc(Serializable *) { return write_ser; }
44  static writer GetFunc(float *) { return write_float; }
45  static writer GetFunc(double *) { return write_double; }
46  static writer GetFunc(bool *) { return write_char; }
47  static writer GetFunc(uint8_t *) { return write_char; }
48  static writer GetFunc(int8_t *) { return write_char; }
49  static writer GetFunc(uint16_t *) { return write_int; }
50  static writer GetFunc(int16_t *) { return write_int; }
51  static writer GetFunc(uint32_t *) { return write_int; }
52  static writer GetFunc(int32_t *) { return write_int; }
53  static writer GetFunc(uint64_t *) { return write_int; }
54  static writer GetFunc(int64_t *) { return write_int; }
55 
56  static void write_ser(Serializer &sr, const T &v) { v.Serialize(sr); }
57  static void write_char(Serializer &sr, const T &v) {
58  static_assert(sizeof(v) == 1, "Called write_char() in Serializer.hh "
59  "which only supports integers of size == 1 "
60  "byte!");
61  unsigned char buf[sizeof(char)];
62  buf[0] = static_cast<unsigned char>(v & 0xff);
63  sr.Serialize(buf, sizeof(char));
64  }
65 
66  static void write_int(Serializer &sr, const T &v) {
67  static_assert(sizeof(v) > 1, "Called write_int() in Serializer.hh which "
68  "only supports integers of size > 1 byte!");
69  T t = v;
70  unsigned char buf[sizeof v];
71  for (size_t i = 0; i < sizeof v; ++i) {
72  buf[i] = static_cast<unsigned char>(t & 0xff);
73  t >>= 8;
74  }
75  sr.Serialize(buf, sizeof v);
76  }
77  static void write_float(Serializer &sr, const float &v) {
78  unsigned t = *(unsigned *)&v;
79  unsigned char buf[sizeof t];
80  for (size_t i = 0; i < sizeof t; ++i) {
81  buf[i] = t & 0xff;
82  t >>= 8;
83  }
84  sr.Serialize(buf, sizeof t);
85  }
86  static void write_double(Serializer &sr, const double &v) {
87  uint64_t t = *(uint64_t *)&v;
88  unsigned char buf[sizeof t];
89  for (size_t i = 0; i < sizeof t; ++i) {
90  buf[i] = t & 0xff;
91  t >>= 8;
92  }
93  sr.Serialize(buf, sizeof t);
94  }
95  };
96 
97  template <typename T> inline void Serializer::write(const T &v) {
98  WriteHelper<T>::GetFunc(static_cast<T *>(0))(*this, v);
99  }
100 
101  template <> inline void Serializer::write(const std::string &t) {
102  write((unsigned)t.length());
103  Serialize(reinterpret_cast<const unsigned char *>(&t[0]), t.length());
104  }
105 
106  template <> inline void Serializer::write(const Time &t) {
107  write((int)t.GetTimeval().tv_sec);
108  write((int)t.GetTimeval().tv_usec);
109  }
110 
111  template <> inline void Serializer::write(const std::vector<bool> &t) {
112  unsigned len = t.size();
113  write(len);
114  for (size_t i = 0; i < len; ++i) {
115  write((uint8_t)t[i]);
116  }
117  }
118 
119  template <typename T> inline void Serializer::write(const std::vector<T> &t) {
120  unsigned len = t.size();
121  write(len);
122  for (size_t i = 0; i < len; ++i) {
123  write(t[i]);
124  }
125  }
126 
127  template <>
128  inline void
129  Serializer::write<unsigned char>(const std::vector<unsigned char> &t) {
130  write((unsigned)t.size());
131  Serialize(&t[0], t.size());
132  }
133 
134  template <> inline void Serializer::write<char>(const std::vector<char> &t) {
135  write((unsigned)t.size());
136  Serialize(reinterpret_cast<const unsigned char *>(&t[0]), t.size());
137  }
138 
139  template <typename T, typename U>
140  inline void Serializer::write(const std::map<T, U> &t) {
141  unsigned len = (unsigned)t.size();
142  write(len);
143  for (typename std::map<T, U>::const_iterator i = t.begin(); i != t.end();
144  ++i) {
145  write(i->first);
146  write(i->second);
147  }
148  }
149 
150  template <typename T, typename U>
151  inline void Serializer::write(const std::pair<T, U> &t) {
152  write(t->first);
153  write(t->second);
154  }
155 
156  class DLLEXPORT Deserializer {
157  public:
158  Deserializer() : m_interrupting(false) {}
159  virtual bool HasData() = 0;
160  void Interrupt() { m_interrupting = true; }
161 
162  template <typename T> void read(T &t);
163 
164  template <typename T> void read(std::vector<T> &t);
165 
166  template <typename T, typename U> void read(std::map<T, U> &t);
167 
168  template <typename T, typename U> void read(std::pair<T, U> &t);
169 
170  template <typename T> T read() {
171  T t;
172  read(t);
173  return t;
174  }
175 
176  void read(unsigned char *dst, size_t size) { Deserialize(dst, size); }
177 
178  virtual ~Deserializer() {}
179 
180  protected:
181  bool m_interrupting;
182 
183  private:
184  template <typename T> friend struct ReadHelper;
185  virtual void Deserialize(unsigned char *, size_t) = 0;
186  };
187 
188  template <typename T> struct ReadHelper {
189  typedef T (*reader)(Deserializer &ser);
190  static reader GetFunc(Serializable *) { return read_ser; }
191  static reader GetFunc(float *) { return read_float; }
192  static reader GetFunc(double *) { return read_double; }
193  static reader GetFunc(bool *) { return read_char; }
194  static reader GetFunc(uint8_t *) { return read_char; }
195  static reader GetFunc(int8_t *) { return read_char; }
196  static reader GetFunc(uint16_t *) { return read_int; }
197  static reader GetFunc(int16_t *) { return read_int; }
198  static reader GetFunc(uint32_t *) { return read_int; }
199  static reader GetFunc(int32_t *) { return read_int; }
200  static reader GetFunc(uint64_t *) { return read_int; }
201  static reader GetFunc(int64_t *) { return read_int; }
202 
203  static T read_ser(Deserializer &ds) { return T(ds); }
204  static T read_char(Deserializer &ds) {
205  unsigned char buf[sizeof(char)];
206  ds.Deserialize(buf, sizeof(char));
207  T t = buf[0];
208  return t;
209  }
210  static T read_int(Deserializer &ds) {
211  // protect against types of 8 bit (or less) -- would cause indefined
212  // behaviour in bit shift below
213  static_assert(sizeof(T) > 1, "Called read_int() in Serializer.hh which "
214  "only supports integers of size > 1 byte!");
215  unsigned char buf[sizeof(T)];
216  ds.Deserialize(buf, sizeof(T));
217  T t = 0;
218  for (size_t i = 0; i < sizeof t; ++i) {
219  t <<= 8;
220  t += buf[sizeof t - 1 - i];
221  }
222  return t;
223  }
224  static float read_float(Deserializer &ds) {
225  unsigned char buf[sizeof(float)];
226  ds.Deserialize(buf, sizeof buf);
227  unsigned t = 0;
228  for (size_t i = 0; i < sizeof t; ++i) {
229  t <<= 8;
230  t += buf[sizeof t - 1 - i];
231  }
232  return *(float *)&t;
233  }
234  static double read_double(Deserializer &ds) {
235  union {
236  double d;
237  uint64_t i;
238  unsigned char b[sizeof(double)];
239  } u;
240  // unsigned char buf[sizeof (double)];
241  ds.Deserialize(u.b, sizeof u.b);
242  uint64_t t = 0;
243  for (size_t i = 0; i < sizeof t; ++i) {
244  t <<= 8;
245  t += u.b[sizeof t - 1 - i];
246  }
247  u.i = t;
248  return u.d;
249  }
250  };
251 
252  template <typename T> inline void Deserializer::read(T &t) {
253  t = ReadHelper<T>::GetFunc(static_cast<T *>(0))(*this);
254  }
255 
256  template <> inline void Deserializer::read(std::string &t) {
257  unsigned len = 0;
258  read(len);
259  t = std::string(len, ' ');
260  if (len)
261  Deserialize(reinterpret_cast<unsigned char *>(&t[0]), len);
262  }
263 
264  template <> inline void Deserializer::read(Time &t) {
265  int sec, usec;
266  read(sec);
267  read(usec);
268  t = Time(sec, usec);
269  }
270 
271  template <typename T> inline void Deserializer::read(std::vector<T> &t) {
272  unsigned len = 0;
273  read(len);
274  t.reserve(len);
275  for (size_t i = 0; i < len; ++i) {
276  t.push_back(read<T>());
277  }
278  }
279 
280  template <>
281  inline void Deserializer::read<unsigned char>(std::vector<unsigned char> &t) {
282  unsigned len = 0;
283  read(len);
284  t.resize(len);
285  Deserialize(&t[0], len);
286  }
287 
288  template <> inline void Deserializer::read<char>(std::vector<char> &t) {
289  unsigned len = 0;
290  read(len);
291  t.resize(len);
292  Deserialize(reinterpret_cast<unsigned char *>(&t[0]), len);
293  }
294 
295  template <typename T, typename U>
296  inline void Deserializer::read(std::map<T, U> &t) {
297  unsigned len = 0;
298  read(len);
299  for (size_t i = 0; i < len; ++i) {
300  std::string name = read<std::string>();
301  std::string val = read<std::string>();
302  t[name] = val;
303  }
304  }
305 
306  template <typename T, typename U>
307  inline void Deserializer::read(std::pair<T, U> &t) {
308  t.first = read<T>();
309  t.second = read<U>();
310  }
311 }
312 
313 #endif // EUDAQ_INCLUDED_Serializer
Definition: Serializer.hh:15
Definition: Serializer.hh:156
Definition: Serializer.hh:41
Definition: Serializable.hh:13
Definition: Serializer.hh:19
Definition: Serializer.hh:188