• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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