Chris@16
|
1 #ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP
|
Chris@16
|
2 #define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP
|
Chris@16
|
3
|
Chris@16
|
4 // MS compatible compilers support #pragma once
|
Chris@101
|
5 #if defined(_MSC_VER)
|
Chris@16
|
6 # pragma once
|
Chris@16
|
7 #endif
|
Chris@16
|
8
|
Chris@16
|
9 #if defined(_MSC_VER)
|
Chris@16
|
10 #pragma warning( disable : 4800 )
|
Chris@16
|
11 #endif
|
Chris@16
|
12
|
Chris@16
|
13 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
Chris@16
|
14 // basic_binary_iprimitive.hpp
|
Chris@16
|
15 //
|
Chris@16
|
16 // archives stored as native binary - this should be the fastest way
|
Chris@16
|
17 // to archive the state of a group of obects. It makes no attempt to
|
Chris@16
|
18 // convert to any canonical form.
|
Chris@16
|
19
|
Chris@16
|
20 // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE
|
Chris@16
|
21 // ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON
|
Chris@16
|
22
|
Chris@16
|
23 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
Chris@16
|
24 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
25 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
26 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
27
|
Chris@16
|
28 // See http://www.boost.org for updates, documentation, and revision history.
|
Chris@16
|
29
|
Chris@16
|
30 #include <iosfwd>
|
Chris@16
|
31 #include <boost/assert.hpp>
|
Chris@16
|
32 #include <locale>
|
Chris@16
|
33 #include <cstring> // std::memcpy
|
Chris@16
|
34 #include <cstddef> // std::size_t
|
Chris@16
|
35 #include <streambuf> // basic_streambuf
|
Chris@16
|
36 #include <string>
|
Chris@16
|
37
|
Chris@16
|
38 #include <boost/config.hpp>
|
Chris@16
|
39 #if defined(BOOST_NO_STDC_NAMESPACE)
|
Chris@16
|
40 namespace std{
|
Chris@16
|
41 using ::memcpy;
|
Chris@16
|
42 using ::size_t;
|
Chris@16
|
43 } // namespace std
|
Chris@16
|
44 #endif
|
Chris@16
|
45
|
Chris@16
|
46 #include <boost/cstdint.hpp>
|
Chris@16
|
47 #include <boost/scoped_ptr.hpp>
|
Chris@16
|
48 #include <boost/serialization/throw_exception.hpp>
|
Chris@16
|
49 #include <boost/integer.hpp>
|
Chris@16
|
50 #include <boost/integer_traits.hpp>
|
Chris@16
|
51
|
Chris@16
|
52 #include <boost/mpl/placeholders.hpp>
|
Chris@16
|
53 #include <boost/serialization/is_bitwise_serializable.hpp>
|
Chris@16
|
54 #include <boost/serialization/array.hpp>
|
Chris@101
|
55
|
Chris@101
|
56 #include <boost/archive/basic_streambuf_locale_saver.hpp>
|
Chris@101
|
57 #include <boost/archive/archive_exception.hpp>
|
Chris@16
|
58 #include <boost/archive/detail/auto_link_archive.hpp>
|
Chris@16
|
59 #include <boost/archive/detail/abi_prefix.hpp> // must be the last header
|
Chris@16
|
60
|
Chris@16
|
61 namespace boost {
|
Chris@16
|
62 namespace archive {
|
Chris@16
|
63
|
Chris@101
|
64 template<class Ch>
|
Chris@101
|
65 class codecvt_null;
|
Chris@101
|
66
|
Chris@16
|
67 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
68 // class binary_iarchive - read serialized objects from a input binary stream
|
Chris@16
|
69 template<class Archive, class Elem, class Tr>
|
Chris@16
|
70 class basic_binary_iprimitive
|
Chris@16
|
71 {
|
Chris@16
|
72 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
Chris@16
|
73 friend class load_access;
|
Chris@16
|
74 protected:
|
Chris@16
|
75 #else
|
Chris@16
|
76 public:
|
Chris@16
|
77 #endif
|
Chris@16
|
78 std::basic_streambuf<Elem, Tr> & m_sb;
|
Chris@16
|
79 // return a pointer to the most derived class
|
Chris@16
|
80 Archive * This(){
|
Chris@16
|
81 return static_cast<Archive *>(this);
|
Chris@16
|
82 }
|
Chris@16
|
83
|
Chris@16
|
84 #ifndef BOOST_NO_STD_LOCALE
|
Chris@101
|
85 boost::scoped_ptr<codecvt_null<Elem> > codecvt_facet;
|
Chris@16
|
86 boost::scoped_ptr<std::locale> archive_locale;
|
Chris@16
|
87 basic_streambuf_locale_saver<Elem, Tr> locale_saver;
|
Chris@16
|
88 #endif
|
Chris@16
|
89
|
Chris@16
|
90 // main template for serilization of primitive types
|
Chris@16
|
91 template<class T>
|
Chris@16
|
92 void load(T & t){
|
Chris@16
|
93 load_binary(& t, sizeof(T));
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 /////////////////////////////////////////////////////////
|
Chris@16
|
97 // fundamental types that need special treatment
|
Chris@16
|
98
|
Chris@16
|
99 // trap usage of invalid uninitialized boolean
|
Chris@16
|
100 void load(bool & t){
|
Chris@16
|
101 load_binary(& t, sizeof(t));
|
Chris@16
|
102 int i = t;
|
Chris@16
|
103 BOOST_ASSERT(0 == i || 1 == i);
|
Chris@16
|
104 (void)i; // warning suppression for release builds.
|
Chris@16
|
105 }
|
Chris@16
|
106 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
107 load(std::string &s);
|
Chris@16
|
108 #ifndef BOOST_NO_STD_WSTRING
|
Chris@16
|
109 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
110 load(std::wstring &ws);
|
Chris@16
|
111 #endif
|
Chris@16
|
112 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
113 load(char * t);
|
Chris@16
|
114 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
115 load(wchar_t * t);
|
Chris@16
|
116
|
Chris@16
|
117 BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
|
Chris@16
|
118 init();
|
Chris@16
|
119 BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
Chris@16
|
120 basic_binary_iprimitive(
|
Chris@16
|
121 std::basic_streambuf<Elem, Tr> & sb,
|
Chris@16
|
122 bool no_codecvt
|
Chris@16
|
123 );
|
Chris@16
|
124 BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
|
Chris@16
|
125 ~basic_binary_iprimitive();
|
Chris@16
|
126 public:
|
Chris@16
|
127 // we provide an optimized load for all fundamental types
|
Chris@16
|
128 // typedef serialization::is_bitwise_serializable<mpl::_1>
|
Chris@16
|
129 // use_array_optimization;
|
Chris@16
|
130 struct use_array_optimization {
|
Chris@16
|
131 template <class T>
|
Chris@16
|
132 #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS)
|
Chris@16
|
133 struct apply {
|
Chris@101
|
134 typedef typename boost::serialization::is_bitwise_serializable< T >::type type;
|
Chris@16
|
135 };
|
Chris@16
|
136 #else
|
Chris@16
|
137 struct apply : public boost::serialization::is_bitwise_serializable< T > {};
|
Chris@16
|
138 #endif
|
Chris@16
|
139 };
|
Chris@16
|
140
|
Chris@16
|
141 // the optimized load_array dispatches to load_binary
|
Chris@16
|
142 template <class ValueType>
|
Chris@16
|
143 void load_array(serialization::array<ValueType>& a, unsigned int)
|
Chris@16
|
144 {
|
Chris@16
|
145 load_binary(a.address(),a.count()*sizeof(ValueType));
|
Chris@16
|
146 }
|
Chris@16
|
147
|
Chris@16
|
148 void
|
Chris@16
|
149 load_binary(void *address, std::size_t count);
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 template<class Archive, class Elem, class Tr>
|
Chris@16
|
153 inline void
|
Chris@16
|
154 basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
|
Chris@16
|
155 void *address,
|
Chris@16
|
156 std::size_t count
|
Chris@16
|
157 ){
|
Chris@16
|
158 // note: an optimizer should eliminate the following for char files
|
Chris@16
|
159 BOOST_ASSERT(
|
Chris@16
|
160 static_cast<std::streamsize>(count / sizeof(Elem))
|
Chris@16
|
161 <= boost::integer_traits<std::streamsize>::const_max
|
Chris@16
|
162 );
|
Chris@16
|
163 std::streamsize s = static_cast<std::streamsize>(count / sizeof(Elem));
|
Chris@16
|
164 std::streamsize scount = m_sb.sgetn(
|
Chris@16
|
165 static_cast<Elem *>(address),
|
Chris@16
|
166 s
|
Chris@16
|
167 );
|
Chris@16
|
168 if(scount != s)
|
Chris@16
|
169 boost::serialization::throw_exception(
|
Chris@16
|
170 archive_exception(archive_exception::input_stream_error)
|
Chris@16
|
171 );
|
Chris@16
|
172 // note: an optimizer should eliminate the following for char files
|
Chris@16
|
173 BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits<std::streamsize>::const_max);
|
Chris@16
|
174 s = static_cast<std::streamsize>(count % sizeof(Elem));
|
Chris@16
|
175 if(0 < s){
|
Chris@16
|
176 // if(is.fail())
|
Chris@16
|
177 // boost::serialization::throw_exception(
|
Chris@16
|
178 // archive_exception(archive_exception::stream_error)
|
Chris@16
|
179 // );
|
Chris@16
|
180 Elem t;
|
Chris@16
|
181 scount = m_sb.sgetn(& t, 1);
|
Chris@16
|
182 if(scount != 1)
|
Chris@16
|
183 boost::serialization::throw_exception(
|
Chris@16
|
184 archive_exception(archive_exception::input_stream_error)
|
Chris@16
|
185 );
|
Chris@101
|
186 std::memcpy(static_cast<char*>(address) + (count - s), &t, static_cast<std::size_t>(s));
|
Chris@16
|
187 }
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 } // namespace archive
|
Chris@16
|
191 } // namespace boost
|
Chris@16
|
192
|
Chris@16
|
193 #include <boost/archive/detail/abi_suffix.hpp> // pop pragmas
|
Chris@16
|
194
|
Chris@16
|
195 #endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP
|