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)
17namespace 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
29namespace boost {
30namespace archive {
31
32/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
33// implementation of binary_binary_archive
34template<class Archive>
35BOOST_ARCHIVE_OR_WARCHIVE_DECL void
36basic_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
49template<class Archive>
50BOOST_ARCHIVE_OR_WARCHIVE_DECL void
51basic_binary_iarchive<Archive>::init() {
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    boost::serialization::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<boost::serialization::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
135