• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef PORTABLE_BINARY_IARCHIVE_HPP
2 #define PORTABLE_BINARY_IARCHIVE_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_iarchive.hpp
16 
17 // (C) Copyright 2002-7 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 <istream>
25 #include <boost/serialization/string.hpp>
26 #include <boost/serialization/item_version_type.hpp>
27 #include <boost/archive/archive_exception.hpp>
28 #include <boost/archive/basic_binary_iprimitive.hpp>
29 #include <boost/archive/detail/common_iarchive.hpp>
30 #include <boost/archive/detail/register_archive.hpp>
31 
32 #include "portable_binary_archive.hpp"
33 
34 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
35 // exception to be thrown if integer read from archive doesn't fit
36 // variable being loaded
37 class portable_binary_iarchive_exception :
38     public boost::archive::archive_exception
39 {
40 public:
41     enum exception_code {
42         incompatible_integer_size
43     } m_exception_code ;
portable_binary_iarchive_exception(exception_code c=incompatible_integer_size)44     portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) :
45         boost::archive::archive_exception(boost::archive::archive_exception::other_exception),
46         m_exception_code(c)
47     {}
what() const48     virtual const char *what( ) const throw( )
49     {
50         const char *msg = "programmer error";
51         switch(m_exception_code){
52         case incompatible_integer_size:
53             msg = "integer cannot be represented";
54             break;
55         default:
56             msg = boost::archive::archive_exception::what();
57             assert(false);
58             break;
59         }
60         return msg;
61     }
62 };
63 
64 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
65 // "Portable" input binary archive.  It addresses integer size and endienness so
66 // that binary archives can be passed across systems. Note:floating point types
67 // not addressed here
68 class portable_binary_iarchive :
69     public boost::archive::basic_binary_iprimitive<
70         portable_binary_iarchive,
71         std::istream::char_type,
72         std::istream::traits_type
73     >,
74     public boost::archive::detail::common_iarchive<
75         portable_binary_iarchive
76     >
77     {
78     typedef boost::archive::basic_binary_iprimitive<
79         portable_binary_iarchive,
80         std::istream::char_type,
81         std::istream::traits_type
82     > primitive_base_t;
83     typedef boost::archive::detail::common_iarchive<
84         portable_binary_iarchive
85     > archive_base_t;
86 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
87 public:
88 #else
89     friend archive_base_t;
90     friend primitive_base_t; // since with override load below
91     friend class boost::archive::detail::interface_iarchive<
92         portable_binary_iarchive
93     >;
94     friend class boost::archive::load_access;
95 protected:
96 #endif
97     unsigned int m_flags;
98     void load_impl(boost::intmax_t & l, char maxsize);
99 
100     // default fall through for any types not specified here
101     template<class T>
load(T & t)102     void load(T & t){
103         boost::intmax_t l;
104         load_impl(l, sizeof(T));
105         // use cast to avoid compile time warning
106         //t = static_cast< T >(l);
107         t = T(l);
108     }
load(boost::serialization::item_version_type & t)109     void load(boost::serialization::item_version_type & t){
110         boost::intmax_t l;
111         load_impl(l, sizeof(boost::serialization::item_version_type));
112         // use cast to avoid compile time warning
113         t = boost::serialization::item_version_type(l);
114     }
load(boost::archive::version_type & t)115     void load(boost::archive::version_type & t){
116         boost::intmax_t l;
117         load_impl(l, sizeof(boost::archive::version_type));
118         // use cast to avoid compile time warning
119         t = boost::archive::version_type(l);
120     }
load(boost::archive::class_id_type & t)121     void load(boost::archive::class_id_type & t){
122         boost::intmax_t l;
123         load_impl(l, sizeof(boost::archive::class_id_type));
124         // use cast to avoid compile time warning
125         t = boost::archive::class_id_type(static_cast<int>(l));
126     }
load(std::string & t)127     void load(std::string & t){
128         this->primitive_base_t::load(t);
129     }
130     #ifndef BOOST_NO_STD_WSTRING
load(std::wstring & t)131     void load(std::wstring & t){
132         this->primitive_base_t::load(t);
133     }
134     #endif
load(float & t)135     void load(float & t){
136         this->primitive_base_t::load(t);
137         // floats not supported
138         //BOOST_STATIC_ASSERT(false);
139     }
load(double & t)140     void load(double & t){
141         this->primitive_base_t::load(t);
142         // doubles not supported
143         //BOOST_STATIC_ASSERT(false);
144     }
load(char & t)145     void load(char & t){
146         this->primitive_base_t::load(t);
147     }
load(unsigned char & t)148     void load(unsigned char & t){
149         this->primitive_base_t::load(t);
150     }
151     typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
152         detail_common_iarchive;
153     template<class T>
load_override(T & t)154     void load_override(T & t){
155         this->detail_common_iarchive::load_override(t);
156     }
157     void load_override(boost::archive::class_name_type & t);
158     // binary files don't include the optional information
load_override(boost::archive::class_id_optional_type &)159     void load_override(boost::archive::class_id_optional_type &){}
160 
161     void init(unsigned int flags);
162 public:
portable_binary_iarchive(std::istream & is,unsigned flags=0)163     portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
164         primitive_base_t(
165             * is.rdbuf(),
166             0 != (flags & boost::archive::no_codecvt)
167         ),
168         archive_base_t(flags),
169         m_flags(0)
170     {
171         init(flags);
172     }
173 
portable_binary_iarchive(std::basic_streambuf<std::istream::char_type,std::istream::traits_type> & bsb,unsigned int flags)174     portable_binary_iarchive(
175         std::basic_streambuf<
176             std::istream::char_type,
177             std::istream::traits_type
178         > & bsb,
179         unsigned int flags
180     ) :
181         primitive_base_t(
182             bsb,
183             0 != (flags & boost::archive::no_codecvt)
184         ),
185         archive_base_t(flags),
186         m_flags(0)
187     {
188         init(flags);
189     }
190 };
191 
192 // required by export in boost version > 1.34
193 #ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
194     BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
195 #endif
196 
197 // required by export in boost <= 1.34
198 #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
199 
200 #if defined(_MSC_VER)
201 #pragma warning( pop )
202 #endif
203 
204 #endif // PORTABLE_BINARY_IARCHIVE_HPP
205