• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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