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 14 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 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/serialization/string.hpp> 26 #include <boost/serialization/item_version_type.hpp> 27 #include <boost/archive/archive_exception.hpp> 28 #include <boost/archive/basic_binary_iprimitive.hpp> 29 #include <boost/archive/detail/common_iarchive.hpp> 30 #include <boost/archive/detail/register_archive.hpp> 31 32 #include "portable_binary_archive.hpp" 33 34 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 35 // exception to be thrown if integer read from archive doesn't fit 36 // variable being loaded 37 class portable_binary_iarchive_exception : 38 public boost::archive::archive_exception 39 { 40 public: 41 enum exception_code { 42 incompatible_integer_size 43 } m_exception_code ; portable_binary_iarchive_exception(exception_code c=incompatible_integer_size)44 portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) : 45 boost::archive::archive_exception(boost::archive::archive_exception::other_exception), 46 m_exception_code(c) 47 {} what() const48 virtual const char *what( ) const throw( ) 49 { 50 const char *msg = "programmer error"; 51 switch(m_exception_code){ 52 case incompatible_integer_size: 53 msg = "integer cannot be represented"; 54 break; 55 default: 56 msg = boost::archive::archive_exception::what(); 57 assert(false); 58 break; 59 } 60 return msg; 61 } 62 }; 63 64 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 65 // "Portable" input binary archive. It addresses integer size and endienness so 66 // that binary archives can be passed across systems. Note:floating point types 67 // not addressed here 68 class portable_binary_iarchive : 69 public boost::archive::basic_binary_iprimitive< 70 portable_binary_iarchive, 71 std::istream::char_type, 72 std::istream::traits_type 73 >, 74 public boost::archive::detail::common_iarchive< 75 portable_binary_iarchive 76 > 77 { 78 typedef boost::archive::basic_binary_iprimitive< 79 portable_binary_iarchive, 80 std::istream::char_type, 81 std::istream::traits_type 82 > primitive_base_t; 83 typedef boost::archive::detail::common_iarchive< 84 portable_binary_iarchive 85 > archive_base_t; 86 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 87 public: 88 #else 89 friend archive_base_t; 90 friend primitive_base_t; // since with override load below 91 friend class boost::archive::detail::interface_iarchive< 92 portable_binary_iarchive 93 >; 94 friend class boost::archive::load_access; 95 protected: 96 #endif 97 unsigned int m_flags; 98 void load_impl(boost::intmax_t & l, char maxsize); 99 100 // default fall through for any types not specified here 101 template<class T> load(T & t)102 void load(T & t){ 103 boost::intmax_t l; 104 load_impl(l, sizeof(T)); 105 // use cast to avoid compile time warning 106 //t = static_cast< T >(l); 107 t = T(l); 108 } load(boost::serialization::item_version_type & t)109 void load(boost::serialization::item_version_type & t){ 110 boost::intmax_t l; 111 load_impl(l, sizeof(boost::serialization::item_version_type)); 112 // use cast to avoid compile time warning 113 t = boost::serialization::item_version_type(l); 114 } load(boost::archive::version_type & t)115 void load(boost::archive::version_type & t){ 116 boost::intmax_t l; 117 load_impl(l, sizeof(boost::archive::version_type)); 118 // use cast to avoid compile time warning 119 t = boost::archive::version_type(l); 120 } load(boost::archive::class_id_type & t)121 void load(boost::archive::class_id_type & t){ 122 boost::intmax_t l; 123 load_impl(l, sizeof(boost::archive::class_id_type)); 124 // use cast to avoid compile time warning 125 t = boost::archive::class_id_type(static_cast<int>(l)); 126 } load(std::string & t)127 void load(std::string & t){ 128 this->primitive_base_t::load(t); 129 } 130 #ifndef BOOST_NO_STD_WSTRING load(std::wstring & t)131 void load(std::wstring & t){ 132 this->primitive_base_t::load(t); 133 } 134 #endif load(float & t)135 void load(float & t){ 136 this->primitive_base_t::load(t); 137 // floats not supported 138 //BOOST_STATIC_ASSERT(false); 139 } load(double & t)140 void load(double & t){ 141 this->primitive_base_t::load(t); 142 // doubles not supported 143 //BOOST_STATIC_ASSERT(false); 144 } load(char & t)145 void load(char & t){ 146 this->primitive_base_t::load(t); 147 } load(unsigned char & t)148 void load(unsigned char & t){ 149 this->primitive_base_t::load(t); 150 } 151 typedef boost::archive::detail::common_iarchive<portable_binary_iarchive> 152 detail_common_iarchive; 153 template<class T> load_override(T & t)154 void load_override(T & t){ 155 this->detail_common_iarchive::load_override(t); 156 } 157 void load_override(boost::archive::class_name_type & t); 158 // binary files don't include the optional information load_override(boost::archive::class_id_optional_type &)159 void load_override(boost::archive::class_id_optional_type &){} 160 161 void init(unsigned int flags); 162 public: portable_binary_iarchive(std::istream & is,unsigned flags=0)163 portable_binary_iarchive(std::istream & is, unsigned flags = 0) : 164 primitive_base_t( 165 * is.rdbuf(), 166 0 != (flags & boost::archive::no_codecvt) 167 ), 168 archive_base_t(flags), 169 m_flags(0) 170 { 171 init(flags); 172 } 173 portable_binary_iarchive(std::basic_streambuf<std::istream::char_type,std::istream::traits_type> & bsb,unsigned int flags)174 portable_binary_iarchive( 175 std::basic_streambuf< 176 std::istream::char_type, 177 std::istream::traits_type 178 > & bsb, 179 unsigned int flags 180 ) : 181 primitive_base_t( 182 bsb, 183 0 != (flags & boost::archive::no_codecvt) 184 ), 185 archive_base_t(flags), 186 m_flags(0) 187 { 188 init(flags); 189 } 190 }; 191 192 // required by export in boost version > 1.34 193 #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE 194 BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive) 195 #endif 196 197 // required by export in boost <= 1.34 198 #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive 199 200 #if defined(_MSC_VER) 201 #pragma warning( pop ) 202 #endif 203 204 #endif // PORTABLE_BINARY_IARCHIVE_HPP 205