basic_binary_iarchive.hpp 7.4 KB

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