TPIE

2362a60
serialization.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2010, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 #ifndef __TPIE_SERIALIZATION_H__
20 #define __TPIE_SERIALIZATION_H__
21 
25 
26 #include <tpie/config.h>
27 #include <tpie/portability.h>
28 #include <tpie/hash_map.h>
29 #include <vector>
30 #include <utility>
31 #include <typeinfo>
32 
33 #include <type_traits>
34 #include <cstdint>
35 #include <istream>
36 #include <ostream>
37 #include <cstring>
38 
39 namespace tpie {
40 
44 
45 struct serialization_error: public std::runtime_error {
46  explicit serialization_error(const std::string & what): std::runtime_error(what) {}
47 };
48 
49 
50 
55 class serializer {
56 public:
60  serializer(std::ostream & out, bool typesafe=false): m_out(out), m_typesafe(false) {
61  *this << "TPIE Serialization" //File header
62  << (uint16_t)1 //File version
63  << typesafe; //Do we serialize typeids before each actual item?
64  m_typesafe = typesafe;
65  }
66 
67  template <typename T>
68  inline serializer & write(const T * data, size_t l) {
69  *this << (uint16_t)l;
70  for (size_t i=0; i < l; ++i)
71  *this << data[i];
72  return *this;
73  }
74  template <typename T>
75  inline typename std::enable_if<std::is_fundamental<T>::value || std::is_enum<T>::value,
76  serializer &>::type operator << (const T & x) {
77  write_type<T>();
78  m_out.write(reinterpret_cast<const char*>(&x), sizeof(T));
79  return * this;
80  }
81 
82  template <typename T1, typename T2>
83  inline serializer & operator <<(const std::pair<T1, T2> & p) {
84  write_type<std::pair<T1,T2> >();
85  return *this << p.first << p.second;
86  }
87 
88  template <typename T>
89  inline serializer & operator <<(const std::vector<T> & v) {
90  write_type<std::vector<T> >();
91  *this << (uint16_t)v.size();
92  for (size_t i=0; i < v.size(); ++i)
93  *this << v[i];
94  return *this;
95  }
96 
97  inline serializer & operator <<(const char * data) {write_type<std::string>(); return write(data, strlen(data));}
98  inline serializer & operator <<(const std::string & s) {write_type<std::string>(); return write(s.c_str(), s.size());}
99 private:
100  template <typename T>
101  void write_type() {
102  if (m_typesafe) {
103  hash<const char *> h;
104  m_out << (uint8_t)(h(typeid(T).name()) % 256);
105  }
106  }
107 
108  std::ostream & m_out;
109  bool m_typesafe;
110 };
111 
118 public:
122  unserializer(std::istream & in): m_in(in), m_typesafe(false) {
123  //Validate header;
124  *this << "TPIE Serialization"
125  << (uint16_t)1;
126  bool typesafe;
127  *this >> typesafe;
128  m_typesafe=typesafe;
129  }
130 
131  template <typename T>
132  inline unserializer & operator <<(const T & x) {
133  T y;
134  *this >> y;
135  if (y != x) throw serialization_error("Verification failed");
136  return *this;
137  }
138 
139  inline unserializer & operator <<(const char * x) {
140  std::string y;
141  *this >> y;
142  if (y != x) throw serialization_error("Verification failed");
143  return *this;
144  }
145 
146  template <typename T>
147  inline unserializer & read(T * array, size_t & size) {
148  uint16_t x;
149  *this >> x;
150  if (x > size) throw serialization_error("array too short");
151  size=x;
152  for (size_t i=0; i < size; ++i)
153  *this >> array[i];
154  return *this;
155  }
156 
157  template <typename T>
158  inline typename std::enable_if<std::is_fundamental<T>::value || std::is_enum<T>::value, unserializer &>::type operator >> (T & x) {
159  check_type<T>();
160  char * y = reinterpret_cast<char*>(&x);
161  m_in.read(y, sizeof(T));
162  if (m_in.eof() || m_in.fail()) throw serialization_error("Unexpected end-of-file");
163  return *this;
164  }
165 
166  template <typename T1, typename T2>
167  inline unserializer & operator >>(std::pair<T1, T2> & p) {
168  check_type<std::pair<T1, T2> >();
169  return *this >> p.first >> p.second;
170  }
171 
172  template <typename T>
173  inline unserializer & operator >> (std::vector<T> & v) {
174  check_type<std::vector<T> >();
175  uint16_t size;
176  *this >> size;
177  v.clear();
178  for (size_t i=0; i < size; ++i) {
179  v.push_back(T());
180  *this >> v.back();
181  }
182  return *this;
183  }
184 
185  inline unserializer & operator >>(std::string & s) {
186  check_type<std::string>();
187  s.clear();
188  uint16_t size;
189  *this >> size;
190  for (size_t i=0; i < size; ++i) {
191  char x;
192  *this >> x;
193  s.push_back(x);
194  }
195  return *this;
196  }
197 
198 private:
199  template <typename T>
200  void check_type() {
201  if (!m_typesafe) return;
202  hash<const char *> h;
203  uint8_t hash = h(typeid(T).name()) % 256;
204  uint8_t s_hash;
205  m_in >> s_hash;
206  if (s_hash == hash) return;
207  std::stringstream ss;
208  ss << "Serialization type error, input type did not match expected type: " << typeid(T).name();
209  throw serialization_error(ss.str());
210  }
211 
212  std::istream & m_in;
213  bool m_typesafe;
214 };
215 
216 } //namespace tpie
217 #endif /*__TPIE_SERIALIZATION_H__*/
unserializer(std::istream &in)
Construct a unserializer reading from the std::istream in.
Class to compute the disjunction between two std true/false types.
Definition: serialization.h:45
This file contains a few deprecated definitions for legacy code.
Class providing binary serialization to a std::ostream.
Definition: serialization.h:55
Internal hash map with guaranteed memory requirements.
serializer(std::ostream &out, bool typesafe=false)
Construct a serializer writing to out.
Definition: serialization.h:60
Class for unserializing binary data serialized with the serializer Data can be unserialized using the...