Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / archive / impl / basic_binary_iarchive.ipp
1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2 // basic_binary_iarchive.ipp:
3
4 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
5 // Use, modification and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 //  See http://www.boost.org for updates, documentation, and revision history.
10 #include <string>
11 #include <boost/assert.hpp>
12 #include <algorithm>
13 #include <cstring>
14
15 #include <boost/config.hpp>
16 #if defined(BOOST_NO_STDC_NAMESPACE)
17 namespace std{ 
18     using ::memcpy; 
19     using ::strlen;
20     using ::size_t;
21 }
22 #endif
23
24 #include <boost/detail/workaround.hpp>
25 #include <boost/predef/other/endian.h>
26
27 #include <boost/archive/basic_binary_iarchive.hpp>
28
29 namespace boost {
30 namespace archive {
31
32 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
33 // implementation of binary_binary_archive
34 template<class Archive>
35 BOOST_ARCHIVE_OR_WARCHIVE_DECL void
36 basic_binary_iarchive<Archive>::load_override(class_name_type & t){
37     std::string cn;
38     cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
39     load_override(cn);
40     if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
41         boost::serialization::throw_exception(
42             archive_exception(archive_exception::invalid_class_name)
43         );
44     std::memcpy(t, cn.data(), cn.size());
45     // borland tweak
46     t.t[cn.size()] = '\0';
47 }
48
49 template<class Archive>
50 BOOST_ARCHIVE_OR_WARCHIVE_DECL void
51 basic_binary_iarchive<Archive>::init(void){
52     // read signature in an archive version independent manner
53     std::string file_signature;
54     
55     #if 0 // commented out since it interfers with derivation
56     BOOST_TRY {
57         std::size_t l;
58         this->This()->load(l);
59         if(l == std::strlen(BOOST_ARCHIVE_SIGNATURE())) {
60             // borland de-allocator fixup
61             #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101))
62             if(NULL != file_signature.data())
63             #endif
64                 file_signature.resize(l);
65             // note breaking a rule here - could be a problem on some platform
66             if(0 < l)
67                 this->This()->load_binary(&(*file_signature.begin()), l);
68         }
69     }
70     BOOST_CATCH(archive_exception const &) {  // catch stream_error archive exceptions
71         // will cause invalid_signature archive exception to be thrown below
72         file_signature = "";   
73     }
74     BOOST_CATCH_END
75     #else
76     // https://svn.boost.org/trac/boost/ticket/7301
77     * this->This() >> file_signature;
78     #endif
79
80     if(file_signature != BOOST_ARCHIVE_SIGNATURE())
81         boost::serialization::throw_exception(
82             archive_exception(archive_exception::invalid_signature)
83         );
84
85     // make sure the version of the reading archive library can
86     // support the format of the archive being read
87     library_version_type input_library_version;
88     //* this->This() >> input_library_version;
89     {
90         int v = 0;
91         v = this->This()->m_sb.sbumpc();
92         #if BOOST_ENDIAN_LITTLE_BYTE
93         if(v < 6){
94             ;
95         }
96         else
97         if(v < 7){
98             // version 6 - next byte should be zero
99             this->This()->m_sb.sbumpc();
100         }
101         else
102         if(v < 8){
103             int x1;
104             // version 7 = might be followed by zero or some other byte
105             x1 = this->This()->m_sb.sgetc();
106             // it's =a zero, push it back
107             if(0 == x1)
108                 this->This()->m_sb.sbumpc();
109         }
110         else{
111             // version 8+ followed by a zero
112             this->This()->m_sb.sbumpc();
113         }
114         #elif BOOST_ENDIAN_BIG_BYTE
115         if(v == 0)
116             v = this->This()->m_sb.sbumpc();
117         #endif
118         input_library_version = static_cast<library_version_type>(v);
119     }
120     
121     #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
122     this->set_library_version(input_library_version);
123     #else
124     detail::basic_iarchive::set_library_version(input_library_version);
125     #endif
126     
127     if(BOOST_ARCHIVE_VERSION() < input_library_version)
128         boost::serialization::throw_exception(
129             archive_exception(archive_exception::unsupported_version)
130         );
131 }
132
133 } // namespace archive
134 } // namespace boost