cereal
A C++11 library for serialization
 All Classes Files Functions Variables Typedefs Enumerations Groups
binary.hpp
Go to the documentation of this file.
1 
3 /*
4  Copyright (c) 2013, Randolph Voorhies, Shane Grant
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in the
13  documentation and/or other materials provided with the distribution.
14  * Neither the name of cereal nor the
15  names of its contributors may be used to endorse or promote products
16  derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #ifndef CEREAL_ARCHIVES_BINARY_HPP_
30 #define CEREAL_ARCHIVES_BINARY_HPP_
31 
32 #include <cereal/cereal.hpp>
33 #include <sstream>
34 
35 namespace cereal
36 {
37  // ######################################################################
39 
43  class BinaryOutputArchive : public OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>
44  {
45  public:
47 
49  BinaryOutputArchive(std::ostream & stream) :
50  OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>(this),
51  itsStream(stream)
52  { }
53 
55  void saveBinary( const void * data, size_t size )
56  {
57  size_t const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
58 
59  if(writtenSize != size)
60  throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
61  }
62 
63  private:
64  std::ostream & itsStream;
65  };
66 
67  // ######################################################################
69 
70  class BinaryInputArchive : public InputArchive<BinaryInputArchive, AllowEmptyClassElision>
71  {
72  public:
74  BinaryInputArchive(std::istream & stream) :
75  InputArchive<BinaryInputArchive, AllowEmptyClassElision>(this),
76  itsStream(stream)
77  { }
78 
80  void loadBinary( void * const data, size_t size )
81  {
82  size_t const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
83 
84  if(readSize != size)
85  throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));
86  }
87 
88  private:
89  std::istream & itsStream;
90  };
91 
92  // ######################################################################
93  // Common BinaryArchive serialization functions
94 
96  template<class T> inline
97  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
98  save(BinaryOutputArchive & ar, T const & t)
99  {
100  ar.saveBinary(std::addressof(t), sizeof(t));
101  }
102 
104  template<class T> inline
105  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
106  load(BinaryInputArchive & ar, T & t)
107  {
108  ar.loadBinary(std::addressof(t), sizeof(t));
109  }
110 
112  template <class Archive, class T> inline
113  CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
114  serialize( Archive & ar, NameValuePair<T> & t )
115  {
116  ar( t.value );
117  }
118 
120  template <class Archive, class T> inline
121  CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
122  serialize( Archive & ar, SizeTag<T> & t )
123  {
124  ar( t.size );
125  }
126 
128  template <class T> inline
129  typename std::enable_if<std::is_array<T>::value, void>::type
130  save(BinaryOutputArchive & ar, T const & array)
131  {
132  ar.saveBinary(array, traits::sizeof_array<T>() * sizeof(typename std::remove_all_extents<T>::type));
133  }
134 
136  template <class T> inline
137  typename std::enable_if<std::is_array<T>::value, void>::type
138  load(BinaryInputArchive & ar, T & array)
139  {
140  ar.loadBinary(array, traits::sizeof_array<T>() * sizeof(typename std::remove_all_extents<T>::type));
141  }
142 
144  template <class T> inline
145  void save(BinaryOutputArchive & ar, BinaryData<T> const & bd)
146  {
147  ar.saveBinary(bd.data, bd.size);
148  }
149 
151  template <class T> inline
152  void load(BinaryInputArchive & ar, BinaryData<T> & bd)
153  {
154  ar.loadBinary(bd.data, bd.size);
155  }
156 } // namespace cereal
157 
158 // register archives for polymorphic support
159 CEREAL_REGISTER_ARCHIVE(cereal::BinaryOutputArchive);
160 CEREAL_REGISTER_ARCHIVE(cereal::BinaryInputArchive);
161 
162 #endif // CEREAL_ARCHIVES_BINARY_HPP_