Brian Silverman | 8867871 | 2018-08-04 23:56:48 -0700 | [diff] [blame^] | 1 | #ifndef PORTABLE_BINARY_OARCHIVE_HPP |
| 2 | #define PORTABLE_BINARY_OARCHIVE_HPP |
| 3 | |
| 4 | // MS compatible compilers support #pragma once |
| 5 | #if defined(_MSC_VER) |
| 6 | # pragma once |
| 7 | #endif |
| 8 | |
| 9 | #if defined(_MSC_VER) |
| 10 | #pragma warning( push ) |
| 11 | #pragma warning( disable : 4244 ) |
| 12 | #endif |
| 13 | |
| 14 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
| 15 | // portable_binary_oarchive.hpp |
| 16 | |
| 17 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . |
| 18 | // Use, modification and distribution is subject to the Boost Software |
| 19 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| 20 | // http://www.boost.org/LICENSE_1_0.txt) |
| 21 | |
| 22 | // See http://www.boost.org for updates, documentation, and revision history. |
| 23 | |
| 24 | #include <ostream> |
| 25 | #include <boost/serialization/string.hpp> |
| 26 | #include <boost/archive/archive_exception.hpp> |
| 27 | #include <boost/archive/basic_binary_oprimitive.hpp> |
| 28 | #include <boost/archive/detail/common_oarchive.hpp> |
| 29 | #include <boost/archive/detail/register_archive.hpp> |
| 30 | |
| 31 | #include "portable_binary_archive.hpp" |
| 32 | |
| 33 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
| 34 | // exception to be thrown if integer read from archive doesn't fit |
| 35 | // variable being loaded |
| 36 | class portable_binary_oarchive_exception : |
| 37 | public boost::archive::archive_exception |
| 38 | { |
| 39 | public: |
| 40 | typedef enum { |
| 41 | invalid_flags |
| 42 | } exception_code; |
| 43 | portable_binary_oarchive_exception(exception_code c = invalid_flags ) |
| 44 | {} |
| 45 | virtual const char *what( ) const throw( ) |
| 46 | { |
| 47 | const char *msg = "programmer error"; |
| 48 | switch(code){ |
| 49 | case invalid_flags: |
| 50 | msg = "cannot be both big and little endian"; |
| 51 | default: |
| 52 | boost::archive::archive_exception::what(); |
| 53 | } |
| 54 | return msg; |
| 55 | } |
| 56 | }; |
| 57 | |
| 58 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
| 59 | // "Portable" output binary archive. This is a variation of the native binary |
| 60 | // archive. it addresses integer size and endienness so that binary archives can |
| 61 | // be passed across systems. Note:floating point types not addressed here |
| 62 | |
| 63 | class portable_binary_oarchive : |
| 64 | public boost::archive::basic_binary_oprimitive< |
| 65 | portable_binary_oarchive, |
| 66 | std::ostream::char_type, |
| 67 | std::ostream::traits_type |
| 68 | >, |
| 69 | public boost::archive::detail::common_oarchive< |
| 70 | portable_binary_oarchive |
| 71 | > |
| 72 | { |
| 73 | typedef boost::archive::basic_binary_oprimitive< |
| 74 | portable_binary_oarchive, |
| 75 | std::ostream::char_type, |
| 76 | std::ostream::traits_type |
| 77 | > primitive_base_t; |
| 78 | typedef boost::archive::detail::common_oarchive< |
| 79 | portable_binary_oarchive |
| 80 | > archive_base_t; |
| 81 | #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS |
| 82 | public: |
| 83 | #else |
| 84 | friend archive_base_t; |
| 85 | friend primitive_base_t; // since with override save below |
| 86 | friend class boost::archive::detail::interface_oarchive< |
| 87 | portable_binary_oarchive |
| 88 | >; |
| 89 | friend class boost::archive::save_access; |
| 90 | protected: |
| 91 | #endif |
| 92 | unsigned int m_flags; |
| 93 | void save_impl(const boost::intmax_t l, const char maxsize); |
| 94 | // add base class to the places considered when matching |
| 95 | // save function to a specific set of arguments. Note, this didn't |
| 96 | // work on my MSVC 7.0 system so we use the sure-fire method below |
| 97 | // using archive_base_t::save; |
| 98 | |
| 99 | // default fall through for any types not specified here |
| 100 | template<class T> |
| 101 | void save(const T & t){ |
| 102 | save_impl(t, sizeof(T)); |
| 103 | } |
| 104 | void save(const std::string & t){ |
| 105 | this->primitive_base_t::save(t); |
| 106 | } |
| 107 | #ifndef BOOST_NO_STD_WSTRING |
| 108 | void save(const std::wstring & t){ |
| 109 | this->primitive_base_t::save(t); |
| 110 | } |
| 111 | #endif |
| 112 | void save(const float & t){ |
| 113 | this->primitive_base_t::save(t); |
| 114 | // floats not supported |
| 115 | //BOOST_STATIC_ASSERT(false); |
| 116 | } |
| 117 | void save(const double & t){ |
| 118 | this->primitive_base_t::save(t); |
| 119 | // doubles not supported |
| 120 | //BOOST_STATIC_ASSERT(false); |
| 121 | } |
| 122 | void save(const char & t){ |
| 123 | this->primitive_base_t::save(t); |
| 124 | } |
| 125 | void save(const unsigned char & t){ |
| 126 | this->primitive_base_t::save(t); |
| 127 | } |
| 128 | |
| 129 | // default processing - kick back to base class. Note the |
| 130 | // extra stuff to get it passed borland compilers |
| 131 | typedef boost::archive::detail::common_oarchive<portable_binary_oarchive> |
| 132 | detail_common_oarchive; |
| 133 | template<class T> |
| 134 | void save_override(T & t){ |
| 135 | this->detail_common_oarchive::save_override(t); |
| 136 | } |
| 137 | // explicitly convert to char * to avoid compile ambiguities |
| 138 | void save_override(const boost::archive::class_name_type & t){ |
| 139 | const std::string s(t); |
| 140 | * this << s; |
| 141 | } |
| 142 | // binary files don't include the optional information |
| 143 | void save_override( |
| 144 | const boost::archive::class_id_optional_type & /* t */ |
| 145 | ){} |
| 146 | |
| 147 | void init(unsigned int flags); |
| 148 | public: |
| 149 | portable_binary_oarchive(std::ostream & os, unsigned flags = 0) : |
| 150 | primitive_base_t( |
| 151 | * os.rdbuf(), |
| 152 | 0 != (flags & boost::archive::no_codecvt) |
| 153 | ), |
| 154 | archive_base_t(flags), |
| 155 | m_flags(flags & (endian_big | endian_little)) |
| 156 | { |
| 157 | init(flags); |
| 158 | } |
| 159 | |
| 160 | portable_binary_oarchive( |
| 161 | std::basic_streambuf< |
| 162 | std::ostream::char_type, |
| 163 | std::ostream::traits_type |
| 164 | > & bsb, |
| 165 | unsigned int flags |
| 166 | ) : |
| 167 | primitive_base_t( |
| 168 | bsb, |
| 169 | 0 != (flags & boost::archive::no_codecvt) |
| 170 | ), |
| 171 | archive_base_t(flags), |
| 172 | m_flags(0) |
| 173 | { |
| 174 | init(flags); |
| 175 | } |
| 176 | }; |
| 177 | |
| 178 | |
| 179 | // required by export in boost version > 1.34 |
| 180 | #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE |
| 181 | BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive) |
| 182 | #endif |
| 183 | |
| 184 | // required by export in boost <= 1.34 |
| 185 | #define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive |
| 186 | |
| 187 | #if defined(_MSC_VER) |
| 188 | #pragma warning( pop ) |
| 189 | #endif |
| 190 | |
| 191 | #endif // PORTABLE_BINARY_OARCHIVE_HPP |