blob: 317aa1d7cbb67c74fc9390fdb62b171821818095 [file] [log] [blame]
Brian Silverman88678712018-08-04 23:56:48 -07001#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
36class portable_binary_oarchive_exception :
37 public boost::archive::archive_exception
38{
39public:
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
63class 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
82public:
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;
90protected:
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);
148public:
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