1 #ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP 2 #define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP 3 4 // MS compatible compilers support #pragma once 5 #if defined(_MSC_VER) 6 # pragma once 7 #endif 8 9 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 10 // basic_binary_iarchive.hpp 11 // 12 // archives stored as native binary - this should be the fastest way 13 // to archive the state of a group of obects. It makes no attempt to 14 // convert to any canonical form. 15 16 // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE 17 // ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON 18 19 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 20 // Use, modification and distribution is subject to the Boost Software 21 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 22 // http://www.boost.org/LICENSE_1_0.txt) 23 24 // See http://www.boost.org for updates, documentation, and revision history. 25 26 #include <boost/config.hpp> 27 #include <boost/detail/workaround.hpp> 28 29 #include <boost/archive/basic_archive.hpp> 30 #include <boost/archive/detail/common_iarchive.hpp> 31 #include <boost/serialization/collection_size_type.hpp> 32 #include <boost/serialization/string.hpp> 33 #include <boost/serialization/library_version_type.hpp> 34 #include <boost/serialization/item_version_type.hpp> 35 #include <boost/integer_traits.hpp> 36 37 #ifdef BOOST_MSVC 38 # pragma warning(push) 39 # pragma warning(disable : 4511 4512) 40 #endif 41 42 #include <boost/archive/detail/abi_prefix.hpp> // must be the last header 43 44 namespace boost { 45 namespace archive { 46 47 namespace detail { 48 template<class Archive> class interface_iarchive; 49 } // namespace detail 50 51 ///////////////////////////////////////////////////////////////////////// 52 // class basic_binary_iarchive - read serialized objects from a input binary stream 53 template<class Archive> 54 class BOOST_SYMBOL_VISIBLE basic_binary_iarchive : 55 public detail::common_iarchive<Archive> 56 { 57 #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS 58 public: 59 #else 60 protected: 61 #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) 62 // for some inexplicable reason insertion of "class" generates compile erro 63 // on msvc 7.1 64 friend detail::interface_iarchive<Archive>; 65 #else 66 friend class detail::interface_iarchive<Archive>; 67 #endif 68 #endif 69 // intermediate level to support override of operators 70 // fot templates in the absence of partial function 71 // template ordering. If we get here pass to base class 72 // note extra nonsense to sneak it pass the borland compiers 73 typedef detail::common_iarchive<Archive> detail_common_iarchive; 74 template<class T> load_override(T & t)75 void load_override(T & t){ 76 this->detail_common_iarchive::load_override(t); 77 } 78 79 // include these to trap a change in binary format which 80 // isn't specifically handled 81 // upto 32K classes 82 BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); 83 BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); 84 // upto 2G objects 85 BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); 86 BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); 87 88 // binary files don't include the optional information load_override(class_id_optional_type &)89 void load_override(class_id_optional_type & /* t */){} 90 load_override(tracking_type & t,int)91 void load_override(tracking_type & t, int /*version*/){ 92 boost::serialization::library_version_type lv = this->get_library_version(); 93 if(boost::serialization::library_version_type(6) < lv){ 94 int_least8_t x=0; 95 * this->This() >> x; 96 t = boost::archive::tracking_type(x); 97 } 98 else{ 99 bool x=0; 100 * this->This() >> x; 101 t = boost::archive::tracking_type(x); 102 } 103 } load_override(class_id_type & t)104 void load_override(class_id_type & t){ 105 boost::serialization::library_version_type lv = this->get_library_version(); 106 /* 107 * library versions: 108 * boost 1.39 -> 5 109 * boost 1.43 -> 7 110 * boost 1.47 -> 9 111 * 112 * 113 * 1) in boost 1.43 and inferior, class_id_type is always a 16bit value, with no check on the library version 114 * --> this means all archives with version v <= 7 are written with a 16bit class_id_type 115 * 2) in boost 1.44 this load_override has disappeared (and thus boost 1.44 is not backward compatible at all !!) 116 * 3) recent boosts reintroduced load_override with a test on the version : 117 * - v > 7 : this->detail_common_iarchive::load_override(t, version) 118 * - v > 6 : 16bit 119 * - other : 32bit 120 * --> which is obviously incorrect, see point 1 121 * 122 * the fix here decodes class_id_type on 16bit for all v <= 7, which seems to be the correct behaviour ... 123 */ 124 if(boost::serialization::library_version_type (7) < lv){ 125 this->detail_common_iarchive::load_override(t); 126 } 127 else{ 128 int_least16_t x=0; 129 * this->This() >> x; 130 t = boost::archive::class_id_type(x); 131 } 132 } load_override(class_id_reference_type & t)133 void load_override(class_id_reference_type & t){ 134 load_override(static_cast<class_id_type &>(t)); 135 } 136 load_override(version_type & t)137 void load_override(version_type & t){ 138 boost::serialization::library_version_type lv = this->get_library_version(); 139 if(boost::serialization::library_version_type(7) < lv){ 140 this->detail_common_iarchive::load_override(t); 141 } 142 else 143 if(boost::serialization::library_version_type(6) < lv){ 144 uint_least8_t x=0; 145 * this->This() >> x; 146 t = boost::archive::version_type(x); 147 } 148 else 149 if(boost::serialization::library_version_type(5) < lv){ 150 uint_least16_t x=0; 151 * this->This() >> x; 152 t = boost::archive::version_type(x); 153 } 154 else 155 if(boost::serialization::library_version_type(2) < lv){ 156 // upto 255 versions 157 unsigned char x=0; 158 * this->This() >> x; 159 t = version_type(x); 160 } 161 else{ 162 unsigned int x=0; 163 * this->This() >> x; 164 t = boost::archive::version_type(x); 165 } 166 } 167 load_override(boost::serialization::item_version_type & t)168 void load_override(boost::serialization::item_version_type & t){ 169 boost::serialization::library_version_type lv = this->get_library_version(); 170 // if(boost::serialization::library_version_type(7) < lvt){ 171 if(boost::serialization::library_version_type(6) < lv){ 172 this->detail_common_iarchive::load_override(t); 173 } 174 else 175 if(boost::serialization::library_version_type(6) < lv){ 176 uint_least16_t x=0; 177 * this->This() >> x; 178 t = boost::serialization::item_version_type(x); 179 } 180 else{ 181 unsigned int x=0; 182 * this->This() >> x; 183 t = boost::serialization::item_version_type(x); 184 } 185 } 186 load_override(serialization::collection_size_type & t)187 void load_override(serialization::collection_size_type & t){ 188 if(boost::serialization::library_version_type(5) < this->get_library_version()){ 189 this->detail_common_iarchive::load_override(t); 190 } 191 else{ 192 unsigned int x=0; 193 * this->This() >> x; 194 t = serialization::collection_size_type(x); 195 } 196 } 197 198 BOOST_ARCHIVE_OR_WARCHIVE_DECL void 199 load_override(class_name_type & t); 200 BOOST_ARCHIVE_OR_WARCHIVE_DECL void 201 init(); 202 basic_binary_iarchive(unsigned int flags)203 basic_binary_iarchive(unsigned int flags) : 204 detail::common_iarchive<Archive>(flags) 205 {} 206 }; 207 208 } // namespace archive 209 } // namespace boost 210 211 #ifdef BOOST_MSVC 212 #pragma warning(pop) 213 #endif 214 215 #include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas 216 217 #endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP 218