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; portable_binary_oarchive_exception(exception_code c=invalid_flags)43 portable_binary_oarchive_exception(exception_code c = invalid_flags ) 44 {} what() const45 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> save(const T & t)101 void save(const T & t){ 102 save_impl(t, sizeof(T)); 103 } save(const std::string & t)104 void save(const std::string & t){ 105 this->primitive_base_t::save(t); 106 } 107 #ifndef BOOST_NO_STD_WSTRING save(const std::wstring & t)108 void save(const std::wstring & t){ 109 this->primitive_base_t::save(t); 110 } 111 #endif save(const float & t)112 void save(const float & t){ 113 this->primitive_base_t::save(t); 114 // floats not supported 115 //BOOST_STATIC_ASSERT(false); 116 } save(const double & t)117 void save(const double & t){ 118 this->primitive_base_t::save(t); 119 // doubles not supported 120 //BOOST_STATIC_ASSERT(false); 121 } save(const char & t)122 void save(const char & t){ 123 this->primitive_base_t::save(t); 124 } save(const unsigned char & t)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> save_override(T & 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 save_override(const boost::archive::class_name_type & t)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 save_override(const boost::archive::class_id_optional_type &)143 void save_override( 144 const boost::archive::class_id_optional_type & /* t */ 145 ){} 146 147 void init(unsigned int flags); 148 public: portable_binary_oarchive(std::ostream & os,unsigned flags=0)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 portable_binary_oarchive(std::basic_streambuf<std::ostream::char_type,std::ostream::traits_type> & bsb,unsigned int flags)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 192