Bitstream Interpretation Library (BIL)  0.1
BinarySerialization.hpp
Go to the documentation of this file.
1 
6 #pragma once
7 #ifndef BIL_BINARYSERIALIZATION_HPP
8 #define BIL_BINARYSERIALIZATION_HPP
9 
10 #include <istream>
11 #include <ostream>
12 #include <map>
13 #include <string>
14 #include <vector>
15 #include <boost/type_traits/is_pod.hpp>
16 #include <boost/utility/enable_if.hpp>
18 
19 
20 namespace bil {
21 
29  template <typename T> inline
30  typename boost::enable_if<boost::is_pod<T>, void>::type
31  writeBinary(const T& data, std::ostream& outputStream)
32  {
33  // write data as one block
34  outputStream.write(reinterpret_cast<const char*>(&data), sizeof(T));
35  if (!outputStream) throw IOException();
36  }
37 
45  template <typename T> inline
46  typename boost::enable_if<boost::is_pod<T>, void>::type
47  writeBinary(const std::vector<T>& data, std::ostream& outputStream)
48  {
49  // write vector length
50  size_t length = data.size();
51  outputStream.write(reinterpret_cast<const char*>(&length), sizeof(length));
52  if (!outputStream) throw IOException();
53  // write vector data as one block
54  if (0 < length)
55  {
56  outputStream.write(reinterpret_cast<const char*>(&(data[0])), sizeof(T) * length);
57  if (!outputStream) throw IOException();
58  }
59  }
60 
68  template <typename T> inline
69  typename boost::disable_if<boost::is_pod<T>, void>::type
70  writeBinary(const std::vector<T>& data, std::ostream& outputStream)
71  {
72  // write vector length
73  size_t length = data.size();
74  outputStream.write(reinterpret_cast<const char*>(&length), sizeof(length));
75  if (!outputStream) throw IOException();
76  // write vector data one by one
77  for (size_t i = 0; i < length; ++i)
78  writeBinary(data[i], outputStream);
79  }
80 
89  template <typename K, typename V, typename C, typename A> inline
90  void writeBinary(const std::map<K, V, C, A>& data, std::ostream& outputStream)
91  {
92  // write map entry count
93  size_t length = data.size();
94  outputStream.write(reinterpret_cast<const char*>(&length), sizeof(length));
95  if (!outputStream) throw IOException();
96  // write map data one by one
97  std::map<K, V, C, A>::const_iterator it = data.begin();
98  std::map<K, V, C, A>::const_iterator itEnd = data.end();
99  for (; it != itEnd; ++it)
100  {
101  writeBinary(it->first, outputStream);
102  writeBinary(it->second, outputStream);
103  }
104  }
105 
113  void writeBinary(const std::string& data, std::ostream& outputStream);
114 
115 
123  template <typename T> inline
124  typename boost::enable_if<boost::is_pod<T>, void>::type
125  readBinary(T& data, std::istream& inputStream)
126  {
127  // read data as one block
128  inputStream.read(reinterpret_cast<char*>(&data), sizeof(T));
129  if (!inputStream) throw IOException();
130  }
131 
139  template <typename T> inline
140  typename boost::enable_if<boost::is_pod<T>, void>::type
141  readBinary(std::vector<T>& data, std::istream& inputStream)
142  {
143  // read vector length
144  size_t length;
145  inputStream.read(reinterpret_cast<char*>(&length), sizeof(length));
146  if (!inputStream) throw IOException();
147  // read vector data as one block
148  data.resize(length);
149  if (0 < length)
150  {
151  inputStream.read(reinterpret_cast<char*>(&(data[0])), sizeof(T) * length);
152  if (!inputStream) throw IOException();
153  }
154  }
155 
163  template <typename T> inline
164  typename boost::disable_if<boost::is_pod<T>, void>::type
165  readBinary(std::vector<T>& data, std::istream& inputStream)
166  {
167  // read vector length
168  size_t length;
169  inputStream.read(reinterpret_cast<char*>(&length), sizeof(length));
170  if (!inputStream) throw IOException();
171  // write vector data one by one
172  data.resize(length);
173  for (size_t i = 0; i < length; ++i)
174  readBinary(data[i], inputStream);
175  }
176 
185  template <typename K, typename V, typename C, typename A> inline
186  void readBinary(std::map<K, V, C, A>& data, std::istream& inputStream)
187  {
188  // read map entry count
189  size_t length = data.size();
190  inputStream.read(reinterpret_cast<char*>(&length), sizeof(length));
191  if (!inputStream) throw IOException();
192  // read map entries one by one
193  data.clear();
194  for (size_t i = 0; i < length; ++i)
195  {
196  // read key
197  K key;
198  readBinary(key, inputStream);
199  // add it to map
200  std::pair<std::map<K, V>::iterator, bool> ret =
201  data.insert(std::make_pair(key, V()));
202  V& value = (ret.first)->second;
203  // read value
204  readBinary(value, inputStream);
205  }
206  }
207 
214  void readBinary(std::string& data, std::istream& inputStream);
215 
216 }
217 
218 #endif