Core Library  1.7.0.0
Library containing core utilities and tools for threading, networking, logging, INI and CSV file management etc.
SerializeToVector.h
Go to the documentation of this file.
1 // This file is part of CoreLibrary containing useful reusable utility
2 // classes.
3 //
4 // Copyright (C) 2014 to present, Duncan Crutchley
5 // Contact <dac1976github@outlook.com>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Lesser General Public License as published
9 // by the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License and GNU Lesser General Public License
16 // for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // and GNU Lesser General Public License along with this program. If
20 // not, see <http://www.gnu.org/licenses/>.
21 
27 #ifndef SERIALIZETOVECTOR
28 #define SERIALIZETOVECTOR
29 
30 #include "CoreLibraryDllGlobal.h"
31 #include "SerializationIncludes.h"
32 #include <vector>
33 #include <utility>
34 #include <sstream>
35 #include <iterator>
36 #include <type_traits>
37 #include <algorithm>
38 #include <cereal/types/vector.hpp>
39 #include <boost/throw_exception.hpp>
40 
42 namespace core_lib
43 {
45 namespace serialize
46 {
47 
49 using char_vector_t = std::vector<char>;
50 
52 struct CORE_LIBRARY_DLL_SHARED_API raw_iarchive
53 {
54 };
55 
57 struct CORE_LIBRARY_DLL_SHARED_API raw_oarchive
58 {
59 };
60 
62 struct CORE_LIBRARY_DLL_SHARED_API protobuf_iarchive
63 {
64 };
65 
67 struct CORE_LIBRARY_DLL_SHARED_API protobuf_oarchive
68 {
69 };
70 
72 namespace archives
73 {
74 
76 using out_port_bin_t = cereal::PortableBinaryOutputArchive;
78 using out_bin_t = cereal::BinaryOutputArchive;
80 using out_xml_t = cereal::XMLOutputArchive;
82 using out_json_t = cereal::JSONOutputArchive;
84 using out_raw_t = raw_oarchive;
86 using out_protobuf_t = protobuf_oarchive;
88 using in_port_bin_t = cereal::PortableBinaryInputArchive;
90 using in_bin_t = cereal::BinaryInputArchive;
92 using in_xml_t = cereal::XMLInputArchive;
94 using in_json_t = cereal::JSONInputArchive;
96 using in_raw_t = raw_iarchive;
98 using in_protobuf_t = protobuf_iarchive;
99 
100 } // namespace archives
101 
103 namespace impl
104 {
105 
113 template <typename T, typename A> struct ToCharVectorImpl
114 {
122  char_vector_t operator()(const T& object) const
123  {
124  std::stringstream os;
125  // Reduce scope of archive to make sure it has
126  // flushed its contents to the stream before
127  // we try and do anything with it.
128  {
129  A oa(os);
130  // CEREAL_NVP is required to fully support xml archives.
131  oa(CEREAL_NVP(object));
132  }
133 
134  char_vector_t charVector;
135  charVector.assign(std::istreambuf_iterator<char>(os), std::istreambuf_iterator<char>());
136  return charVector;
137  }
138 
146  void operator()(const T& object, char_vector_t& result) const
147  {
148  std::stringstream os;
149  // Reduce scope of archive to make sure it has
150  // flushed its contents to the stream before
151  // we try and do anything with it.
152  {
153  A oa(os);
154  // CEREAL_NVP is required to fully support xml archives.
155  oa(CEREAL_NVP(object));
156  }
157 
158  result.assign(std::istreambuf_iterator<char>(os), std::istreambuf_iterator<char>());
159  }
160 };
161 
163 template <typename T> struct ToCharVectorImpl<T, archives::out_raw_t>
164 {
172  char_vector_t operator()(const T& object) const
173  {
174  if (!std::is_pod<T>::value)
175  {
176  BOOST_THROW_EXCEPTION(std::invalid_argument("object is not POD"));
177  }
178 
179  auto begin = reinterpret_cast<char const*>(&object);
180  auto end = std::next(begin, static_cast<int>(sizeof(T)));
181  char_vector_t charVector;
182  std::copy(begin, end, std::back_inserter(charVector));
183  return charVector;
184  }
185 
193  void operator()(const T& object, char_vector_t& result) const
194  {
195  if (!std::is_pod<T>::value)
196  {
197  BOOST_THROW_EXCEPTION(std::invalid_argument("object is not POD"));
198  }
199 
200  auto len = sizeof(T);
201  result.clear();
202  result.reserve(len);
203  auto begin = reinterpret_cast<char const*>(&object);
204  auto end = std::next(begin, static_cast<int>(len));
205  std::copy(begin, end, std::back_inserter(result));
206  }
207 };
208 
210 template <typename T> struct ToCharVectorImpl<T, archives::out_protobuf_t>
211 {
219  char_vector_t operator()(const T& object) const
220  {
221  std::stringstream os;
222 
223  if (!object.SerializeToOstream(&os))
224  {
225  BOOST_THROW_EXCEPTION(std::runtime_error("failed to serialize protocol buffer"));
226  }
227 
228  char_vector_t charVector;
229  charVector.assign(std::istreambuf_iterator<char>(os), std::istreambuf_iterator<char>());
230  return charVector;
231  }
232 
240  void operator()(const T& object, char_vector_t& result) const
241  {
242  std::stringstream os;
243 
244  if (!object.SerializeToOstream(&os))
245  {
246  BOOST_THROW_EXCEPTION(std::runtime_error("failed to serialize protocol buffer"));
247  }
248 
249  result.assign(std::istreambuf_iterator<char>(os), std::istreambuf_iterator<char>());
250  }
251 };
252 
260 template <typename T, typename A> struct ToObjectImpl
261 {
267  T operator()(const char_vector_t& charVector) const
268  {
269  std::stringstream is;
270  std::copy(charVector.begin(), charVector.end(), std::ostream_iterator<char>(is));
271  T object;
272  // Reduce scope of archive to make sure it has
273  // flushed its contents to the stream before
274  // we try and do anything with it.
275  {
276  A ia(is);
277  // CEREAL_NVP is required to fully support xml archives.
278  ia(CEREAL_NVP(object));
279  }
280 
281  return object;
282  }
283 };
284 
286 template <typename T> struct ToObjectImpl<T, archives::in_raw_t>
287 {
293  T operator()(const char_vector_t& charVector) const
294  {
295  if (!std::is_pod<T>::value)
296  {
297  BOOST_THROW_EXCEPTION(std::invalid_argument("object is not POD"));
298  }
299 
300  if (charVector.size() != sizeof(T))
301  {
302  BOOST_THROW_EXCEPTION(std::invalid_argument("buffer to object size mismatch"));
303  }
304 
305  T object{};
306  memcpy(&object, charVector.data(), charVector.size());
307  return object;
308  }
309 };
310 
312 template <typename T> struct ToObjectImpl<T, archives::in_protobuf_t>
313 {
319  T operator()(const char_vector_t& charVector) const
320  {
321  std::stringstream is;
322  std::copy(charVector.begin(), charVector.end(), std::ostream_iterator<char>(is));
323  T object;
324 
325  if (!object.ParseFromIstream(&is))
326  {
327  BOOST_THROW_EXCEPTION(std::runtime_error("failed to deserialize to protocol buffer"));
328  }
329 
330  return object;
331  }
332 };
333 
334 } // namespace impl
335 
346 template <typename T, typename OA = archives::out_port_bin_t>
347 char_vector_t ToCharVector(const T& object)
348 {
349  return impl::ToCharVectorImpl<T, OA>()(object);
350 }
351 
362 template <typename T, typename OA = archives::out_port_bin_t>
363 void ToCharVector(const T& object, char_vector_t& result)
364 {
365  impl::ToCharVectorImpl<T, OA>()(object, result);
366 }
367 
376 template <typename T, typename IA = archives::in_port_bin_t>
377 T ToObject(const char_vector_t& charVector)
378 {
379  return impl::ToObjectImpl<T, IA>()(charVector);
380 }
381 
382 } // namespace serialize
383 } // namespace core_lib
384 
385 #endif // #define SERIALIZETOVECTOR
char_vector_t operator()(const T &object) const
Function operator.
Definition: SerializeToVector.h:122
cereal::PortableBinaryInputArchive in_port_bin_t
Typedef to input portable binary archive.
Definition: SerializeToVector.h:88
cereal::BinaryInputArchive in_bin_t
Typedef to input binary archive.
Definition: SerializeToVector.h:90
cereal::JSONOutputArchive out_json_t
Typedef to output json archive.
Definition: SerializeToVector.h:82
Out archive placeholder struct for serializing POD objects.
Definition: SerializeToVector.h:57
raw_iarchive in_raw_t
Typedef to input raw archive.
Definition: SerializeToVector.h:96
protobuf_iarchive in_protobuf_t
Typedef to input using Google protocol buffers.
Definition: SerializeToVector.h:98
Serialization to char vector implementation.
Definition: SerializeToVector.h:113
std::vector< char > char_vector_t
Typedef for char vector.
Definition: SerializeToVector.h:49
The core_lib namespace.
Definition: AsioDefines.h:59
void operator()(const T &object, char_vector_t &result) const
Function operator.
Definition: SerializeToVector.h:193
Out archive placeholder struct for serializing Google protocol buffers.
Definition: SerializeToVector.h:67
T ToObject(const char_vector_t &charVector)
Deserialize a char vector into a corresponding object.
Definition: SerializeToVector.h:377
char_vector_t operator()(const T &object) const
Function operator.
Definition: SerializeToVector.h:172
void operator()(const T &object, char_vector_t &result) const
Function operator.
Definition: SerializeToVector.h:146
T operator()(const char_vector_t &charVector) const
Function operator.
Definition: SerializeToVector.h:267
T operator()(const char_vector_t &charVector) const
Function operator.
Definition: SerializeToVector.h:293
cereal::BinaryOutputArchive out_bin_t
Typedef to output binary archive.
Definition: SerializeToVector.h:78
File containing declaration of DLL import/export control defines.
void operator()(const T &object, char_vector_t &result) const
Function operator.
Definition: SerializeToVector.h:240
File containing includes for Cereal serialization.
In archive placeholder struct for serializing Google protocol buffers.
Definition: SerializeToVector.h:62
cereal::XMLInputArchive in_xml_t
Typedef to input xml archive.
Definition: SerializeToVector.h:92
Deserialization to object implementation.
Definition: SerializeToVector.h:260
cereal::XMLOutputArchive out_xml_t
Typedef to output xml archive.
Definition: SerializeToVector.h:80
cereal::PortableBinaryOutputArchive out_port_bin_t
Typedef to output portable binary archive.
Definition: SerializeToVector.h:76
protobuf_oarchive out_protobuf_t
Typedef to output using Google protocol buffers.
Definition: SerializeToVector.h:86
In archive placeholder struct for serializing POD objects.
Definition: SerializeToVector.h:52
char_vector_t ToCharVector(const T &object)
Serialize an object into a char vector.
Definition: SerializeToVector.h:347
cereal::JSONInputArchive in_json_t
Typedef to input json archive.
Definition: SerializeToVector.h:94
T operator()(const char_vector_t &charVector) const
Function operator.
Definition: SerializeToVector.h:319
char_vector_t operator()(const T &object) const
Function operator.
Definition: SerializeToVector.h:219
raw_oarchive out_raw_t
Typedef to output raw archive.
Definition: SerializeToVector.h:84