1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
#ifndef PORTABLE_BINARY_IARCHIVE_HPP
#define PORTABLE_BINARY_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/detail/endian.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_archive_exception :
public virtual boost::archive::archive_exception
{
public:
typedef enum {
incompatible_integer_size
} exception_code;
portable_binary_archive_exception(exception_code c = incompatible_integer_size )
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
switch(code){
case incompatible_integer_size:
msg = "integer cannot be represented";
default:
boost::archive::archive_exception::what();
}
return msg;
}
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" input binary archive. This is a variation of the native binary
// archive. it addresses integer size and endienness so that binary archives can
// be passed across systems. Note:floating point types not addressed here
class portable_binary_iarchive :
// don't derive from binary_iarchive !!!
public boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>,
public boost::archive::detail::shared_ptr_helper
{
typedef boost::archive::binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> archive_base_t;
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override load below
friend class boost::archive::basic_binary_iarchive<portable_binary_iarchive>;
friend class boost::archive::load_access;
#endif
void load_impl(long & l, char maxsize){
char size;
this->archive_base_t::load(size);
if(size > maxsize)
throw portable_binary_archive_exception() ;
l = 0;
load_binary(& l, size);
// we choose to use litle endian
#ifdef BOOST_BIG_ENDIAN
char * first = static_cast<char *>(static_cast<void *>(& l));
char * last = first + sizeof(l) - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
#endif
// extend sign if necessary
if((l >> (size - 1) * 8) & 0x80){
l |= (-1 << (size * 8));
}
}
// default fall through for any types not specified here
template<class T>
void load(T & t){
this->primitive_base_t::load(t);
}
void load(unsigned short & t){
long l;
load_impl(l, sizeof(unsigned short));
t = l;
}
void load(short & t){
long l;
load_impl(l, sizeof(short));
t = l;
}
void load(unsigned int & t){
long l;
load_impl(l, sizeof(unsigned int));
t = l;
}
void load(int & t){
long l;
load_impl(l, sizeof(int));
t = l;
}
void load(unsigned long & t){
long l;
load_impl(l, sizeof(unsigned long));
t = l;
}
void load(long & t){
long l;
load_impl(l, sizeof(long));
t = l;
}
public:
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
archive_base_t(
is,
flags | boost::archive::no_header // skip default header checking
)
{
// use our own header checking
if(0 != (flags & boost::archive::no_header)){
this->archive_base_t::init(flags);
// skip the following for "portable" binary archives
// boost::archive::basic_binary_oprimitive<derived_t, std::ostream>::init();
}
}
};
// explicitly instantiate for this type of text stream
#include <boost/archive/impl/basic_binary_iarchive.ipp>
#include <boost/archive/impl/archive_pointer_iserializer.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost {
namespace archive {
template class binary_iarchive_impl<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>;
template class detail::archive_pointer_iserializer<portable_binary_iarchive> ;
} // namespace archive
} // namespace boost
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
#endif // PORTABLE_BINARY_IARCHIVE_HPP
|