summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/example/portable_binary_iarchive.cpp
blob: 08f3f20ec2abe677ccb64796d2f2e1a38d0393ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.cpp

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org for updates, documentation, and revision history.

#include <istream>
#include <string>

#include <boost/predef/other/endian.h>
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/archive_exception.hpp>

#include "portable_binary_iarchive.hpp"

void
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
    char size;
    l = 0;
    this->primitive_base_t::load(size);

    if(0 == size){
        return;
    }

    bool negative = (size < 0);
    if(negative)
        size = -size;

    if(size > maxsize)
        boost::serialization::throw_exception(
            portable_binary_iarchive_exception()
        );

    char * cptr = reinterpret_cast<char *>(& l);
    #if BOOST_ENDIAN_BIG_BYTE
        cptr += (sizeof(boost::intmax_t) - size);
    #endif
    this->primitive_base_t::load_binary(cptr, size);

    #if BOOST_ENDIAN_BIG_BYTE
        if(m_flags & endian_little)
    #else
        if(m_flags & endian_big)
    #endif
    reverse_bytes(size, cptr);

    if(negative)
        l = -l;
}

void
portable_binary_iarchive::load_override(
    boost::archive::class_name_type & t
){
    std::string cn;
    cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
    load_override(cn);
    if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
        boost::serialization::throw_exception(
            boost::archive::archive_exception(
                boost::archive::archive_exception::invalid_class_name)
            );
    std::memcpy(t, cn.data(), cn.size());
    // borland tweak
    t.t[cn.size()] = '\0';
}

void
portable_binary_iarchive::init(unsigned int flags){
    if(0 == (flags & boost::archive::no_header)){
        // read signature in an archive version independent manner
        std::string file_signature;
        * this >> file_signature;
        if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
            boost::serialization::throw_exception(
                boost::archive::archive_exception(
                    boost::archive::archive_exception::invalid_signature
                )
            );
        // make sure the version of the reading archive library can
        // support the format of the archive being read
        boost::archive::library_version_type input_library_version;
        * this >> input_library_version;

        // extra little .t is to get around borland quirk
        if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
            boost::serialization::throw_exception(
                boost::archive::archive_exception(
                    boost::archive::archive_exception::unsupported_version
                )
            );

        #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
        this->set_library_version(input_library_version);
        //#else
        //#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
        //detail::
        //#endif
        boost::archive::detail::basic_iarchive::set_library_version(
            input_library_version
        );
        #endif
    }
    unsigned char x;
    load(x);
    m_flags = x << CHAR_BIT;
}

#include <boost/archive/impl/archive_serializer_map.ipp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>

namespace boost {
namespace archive {

namespace detail {
    template class archive_serializer_map<portable_binary_iarchive>;
}

template class basic_binary_iprimitive<
    portable_binary_iarchive,
    std::istream::char_type,
    std::istream::traits_type
> ;

} // namespace archive
} // namespace boost