Electroneum
portable_binary_iarchive.hpp
Go to the documentation of this file.
1 #ifndef PORTABLE_BINARY_IARCHIVE_HPP
2 #define PORTABLE_BINARY_IARCHIVE_HPP
3 
4 // MS compatible compilers support #pragma once
5 #if defined(_MSC_VER)
6 # pragma once
7 #endif
8 
9 #if defined(_MSC_VER)
10 #pragma warning( push )
11 #pragma warning( disable : 4244 )
12 #endif
13 
15 // portable_binary_iarchive.hpp
16 
17 // (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
18 // Use, modification and distribution is subject to the Boost Software
19 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
20 // http://www.boost.org/LICENSE_1_0.txt)
21 
22 // See http://www.boost.org for updates, documentation, and revision history.
23 
24 #include <istream>
25 #include <boost/version.hpp>
26 #include <boost/serialization/string.hpp>
27 #include <boost/serialization/item_version_type.hpp>
28 #include <boost/archive/archive_exception.hpp>
29 #include <boost/archive/basic_binary_iprimitive.hpp>
30 #include <boost/archive/detail/common_iarchive.hpp>
31 #include <boost/archive/detail/register_archive.hpp>
32 
34 #include <boost/archive/impl/basic_binary_iprimitive.ipp>
35 
36 namespace boost { namespace archive {
37 
39 // exception to be thrown if integer read from archive doesn't fit
40 // variable being loaded
42  public boost::archive::archive_exception
43 {
44 public:
49  boost::archive::archive_exception(boost::archive::archive_exception::other_exception),
51  {}
52  virtual const char *what( ) const throw( )
53  {
54  const char *msg = "programmer error";
55  switch(m_exception_code){
57  msg = "integer cannot be represented";
58  break;
59  default:
60  msg = boost::archive::archive_exception::what();
61  assert(false);
62  break;
63  }
64  return msg;
65  }
66 };
67 
69 // "Portable" input binary archive. It addresses integer size and endienness so
70 // that binary archives can be passed across systems. Note:floating point types
71 // not addressed here
73  public boost::archive::basic_binary_iprimitive<
74  portable_binary_iarchive,
75  std::istream::char_type,
76  std::istream::traits_type
77  >,
78  public boost::archive::detail::common_iarchive<
79  portable_binary_iarchive
80  >
81  {
82  typedef boost::archive::basic_binary_iprimitive<
84  std::istream::char_type,
85  std::istream::traits_type
86  > primitive_base_t;
87  typedef boost::archive::detail::common_iarchive<
89  > archive_base_t;
90 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
91 public:
92 #else
93  friend archive_base_t;
94  friend primitive_base_t; // since with override load below
95  friend class boost::archive::detail::interface_iarchive<
97  >;
98  friend class boost::archive::load_access;
99 protected:
100 #endif
101  unsigned int m_flags;
102  void load_impl(boost::intmax_t & l, char maxsize);
103 
104  // default fall through for any types not specified here
105  template<class T>
106  void load(T & t){
107  boost::intmax_t l;
108  load_impl(l, sizeof(T));
109  // use cast to avoid compile time warning
110  //t = static_cast< T >(l);
111  t = T(l);
112  }
113  void load(boost::serialization::item_version_type & t){
114  boost::intmax_t l;
115  load_impl(l, sizeof(boost::serialization::item_version_type));
116  // use cast to avoid compile time warning
117  t = boost::serialization::item_version_type(l);
118  }
119  void load(boost::archive::version_type & t){
120  boost::intmax_t l;
121  load_impl(l, sizeof(boost::archive::version_type));
122  // use cast to avoid compile time warning
123  t = boost::archive::version_type(l);
124  }
125  void load(boost::archive::class_id_type & t){
126  boost::intmax_t l;
127  load_impl(l, sizeof(boost::archive::class_id_type));
128  // use cast to avoid compile time warning
129  t = boost::archive::class_id_type(static_cast<int>(l));
130  }
131  void load(std::string & t){
132  this->primitive_base_t::load(t);
133  }
134  #ifndef BOOST_NO_STD_WSTRING
135  void load(std::wstring & t){
136  this->primitive_base_t::load(t);
137  }
138  #endif
139  void load(float & t){
140  this->primitive_base_t::load(t);
141  // floats not supported
142  //BOOST_STATIC_ASSERT(false);
143  }
144  void load(double & t){
145  this->primitive_base_t::load(t);
146  // doubles not supported
147  //BOOST_STATIC_ASSERT(false);
148  }
149  void load(char & t){
150  this->primitive_base_t::load(t);
151  }
152  void load(unsigned char & t){
153  this->primitive_base_t::load(t);
154  }
155  typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
157 #if BOOST_VERSION > 105800
158  template<class T>
159  void load_override(T & t){
160  this->detail_common_iarchive::load_override(t);
161  }
162  void load_override(boost::archive::class_name_type & t);
163  // binary files don't include the optional information
164  void load_override(boost::archive::class_id_optional_type &){}
165 #else
166  template<class T>
167  void load_override(T & t, int){
168  this->detail_common_iarchive::load_override(t, 0);
169  }
170  void load_override(boost::archive::class_name_type & t, int);
171  // binary files don't include the optional information
172  void load_override(boost::archive::class_id_optional_type &, int){}
173 #endif
174 
175  void init(unsigned int flags);
176 public:
177  portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
178  primitive_base_t(
179  * is.rdbuf(),
180  0 != (flags & boost::archive::no_codecvt)
181  ),
182  archive_base_t(flags),
183  m_flags(0)
184  {
185  init(flags);
186  }
187 
189  std::basic_streambuf<
190  std::istream::char_type,
191  std::istream::traits_type
192  > & bsb,
193  unsigned int flags
194  ) :
195  primitive_base_t(
196  bsb,
197  0 != (flags & boost::archive::no_codecvt)
198  ),
199  archive_base_t(flags),
200  m_flags(0)
201  {
202  init(flags);
203  }
204 };
205 
206 } }
207 
208 // required by export in boost version > 1.34
209 #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
210  BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
211 #endif
212 
213 // required by export in boost <= 1.34
214 #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
215 
217 // portable_binary_iarchive.cpp
218 
219 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
220 // Use, modification and distribution is subject to the Boost Software
221 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
222 // http://www.boost.org/LICENSE_1_0.txt)
223 
224 // See http://www.boost.org for updates, documentation, and revision history.
225 
226 #include <istream>
227 #include <string>
228 
229 #include <boost/predef/other/endian.h>
230 #include <boost/serialization/throw_exception.hpp>
231 #include <boost/archive/archive_exception.hpp>
232 
233 namespace boost { namespace archive {
234 
235 inline void
237  signed char size;
238  l = 0;
239  this->primitive_base_t::load(size);
240 
241  if(0 == size){
242  return;
243  }
244 
245  bool negative = (size < 0);
246  if(negative)
247  size = -size;
248 
249  if(size > maxsize)
250  boost::serialization::throw_exception(
252  );
253 
254  char * cptr = reinterpret_cast<char *>(& l);
255 #if BOOST_ENDIAN_BIG_BYTE
256  cptr += (sizeof(boost::intmax_t) - size);
257 #endif
258  this->primitive_base_t::load_binary(cptr, size);
259 
260 #if BOOST_ENDIAN_BIG_BYTE
261  if((m_flags & endian_little) || (!(m_flags & endian_big)))
262 #else
263  if(m_flags & endian_big)
264 #endif
265  reverse_bytes(size, cptr);
266 
267  if(negative)
268  l = -l;
269 }
270 
271 #if BOOST_VERSION > 105800
272 inline void
274  boost::archive::class_name_type & t
275 ){
276  std::string cn;
277  cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
278  load_override(cn);
279  if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
280  boost::serialization::throw_exception(
281  boost::archive::archive_exception(
282  boost::archive::archive_exception::invalid_class_name)
283  );
284  std::memcpy(t, cn.data(), cn.size());
285  // borland tweak
286  t.t[cn.size()] = '\0';
287 }
288 #else
289 inline void
291  boost::archive::class_name_type & t, int
292 ){
293  std::string cn;
294  cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
295  load_override(cn, 0);
296  if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
297  boost::serialization::throw_exception(
298  boost::archive::archive_exception(
299  boost::archive::archive_exception::invalid_class_name)
300  );
301  std::memcpy(t, cn.data(), cn.size());
302  // borland tweak
303  t.t[cn.size()] = '\0';
304 }
305 #endif
306 
307 inline void
308 portable_binary_iarchive::init(unsigned int flags){
309  if(0 == (flags & boost::archive::no_header)){
310  // read signature in an archive version independent manner
311  std::string file_signature;
312  * this >> file_signature;
313  if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
314  boost::serialization::throw_exception(
315  boost::archive::archive_exception(
316  boost::archive::archive_exception::invalid_signature
317  )
318  );
319  // make sure the version of the reading archive library can
320  // support the format of the archive being read
321  boost::archive::library_version_type input_library_version;
322  * this >> input_library_version;
323 
324  // ignore archive version checking
325  /*
326  // extra little .t is to get around borland quirk
327  if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
328  boost::serialization::throw_exception(
329  boost::archive::archive_exception(
330  boost::archive::archive_exception::unsupported_version
331  )
332  );
333  */
334 
335  #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
336  this->set_library_version(input_library_version);
337  //#else
338  //#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
339  //detail::
340  //#endif
341  boost::archive::detail::basic_iarchive::set_library_version(
342  input_library_version
343  );
344 #endif
345  }
346  if (!(m_flags & (endian_little | endian_big)))
348  unsigned char x;
349  load(x);
350  m_flags = x << CHAR_BIT;
351 }
352 
353 } }
354 
355 namespace boost {
356 namespace archive {
357 
358 namespace detail {
359  template class archive_serializer_map<portable_binary_iarchive>;
360 }
361 
362 // template class basic_binary_iprimitive<
363 // portable_binary_iarchive,
364 // std::istream::char_type,
365 // std::istream::traits_type
366 //> ;
367 
368 } // namespace archive
369 } // namespace boost
370 
371 #if defined(_MSC_VER)
372 #pragma warning( pop )
373 #endif
374 
375 #endif // PORTABLE_BINARY_IARCHIVE_HPP
const uint32_t T[512]
void load(boost::serialization::item_version_type &t)
int64_t intmax_t
Definition: stdint.h:169
::std::string string
Definition: gtest-port.h:1097
portable_binary_iarchive_exception(exception_code c=incompatible_integer_size)
void load_override(boost::archive::class_id_optional_type &, int)
boost::archive::detail::common_iarchive< portable_binary_iarchive > detail_common_iarchive
void reverse_bytes(signed char size, char *address)
void load(boost::archive::class_id_type &t)
declaration and default definition for the functions used the API
Definition: expect.cpp:33
::std::wstring wstring
Definition: gtest-port.h:1103
void load(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
void load_impl(boost::intmax_t &l, char maxsize)
portable_binary_iarchive(std::istream &is, unsigned flags=0)
void load(boost::archive::version_type &t)
void * memcpy(void *a, const void *b, size_t c)
portable_binary_iarchive(std::basic_streambuf< std::istream::char_type, std::istream::traits_type > &bsb, unsigned int flags)
enum boost::archive::portable_binary_iarchive_exception::exception_code m_exception_code