]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP |
2 | #define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP | |
3 | ||
4 | // MS compatible compilers support #pragma once | |
5 | #if defined(_MSC_VER) | |
6 | # pragma once | |
7 | #endif | |
8 | ||
9 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 | |
10 | // basic_binary_oprimitive.hpp | |
11 | ||
12 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . | |
13 | // Use, modification and distribution is subject to the Boost Software | |
14 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
15 | // http://www.boost.org/LICENSE_1_0.txt) | |
16 | ||
17 | // See http://www.boost.org for updates, documentation, and revision history. | |
18 | ||
19 | // archives stored as native binary - this should be the fastest way | |
20 | // to archive the state of a group of obects. It makes no attempt to | |
21 | // convert to any canonical form. | |
22 | ||
23 | // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE | |
24 | // ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON | |
25 | ||
26 | #include <iosfwd> | |
27 | #include <boost/assert.hpp> | |
28 | #include <locale> | |
29 | #include <streambuf> // basic_streambuf | |
30 | #include <string> | |
31 | #include <cstddef> // size_t | |
32 | ||
33 | #include <boost/config.hpp> | |
34 | #if defined(BOOST_NO_STDC_NAMESPACE) | |
35 | namespace std{ | |
36 | using ::size_t; | |
37 | } // namespace std | |
38 | #endif | |
39 | ||
40 | #include <boost/cstdint.hpp> | |
41 | #include <boost/integer.hpp> | |
42 | #include <boost/integer_traits.hpp> | |
43 | #include <boost/scoped_ptr.hpp> | |
44 | #include <boost/serialization/throw_exception.hpp> | |
45 | ||
46 | //#include <boost/mpl/placeholders.hpp> | |
47 | #include <boost/serialization/is_bitwise_serializable.hpp> | |
b32b8144 | 48 | #include <boost/serialization/array_wrapper.hpp> |
7c673cae FG |
49 | |
50 | #include <boost/archive/basic_streambuf_locale_saver.hpp> | |
51 | #include <boost/archive/codecvt_null.hpp> | |
52 | #include <boost/archive/archive_exception.hpp> | |
53 | #include <boost/archive/detail/auto_link_archive.hpp> | |
54 | #include <boost/archive/detail/abi_prefix.hpp> // must be the last header | |
55 | ||
56 | namespace boost { | |
57 | namespace archive { | |
58 | ||
59 | ///////////////////////////////////////////////////////////////////////// | |
60 | // class basic_binary_oprimitive - binary output of prmitives | |
61 | ||
62 | template<class Archive, class Elem, class Tr> | |
63 | class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive { | |
64 | #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS | |
65 | friend class save_access; | |
66 | protected: | |
67 | #else | |
68 | public: | |
69 | #endif | |
70 | std::basic_streambuf<Elem, Tr> & m_sb; | |
71 | // return a pointer to the most derived class | |
72 | Archive * This(){ | |
73 | return static_cast<Archive *>(this); | |
74 | } | |
75 | #ifndef BOOST_NO_STD_LOCALE | |
76 | // note order! - if you change this, libstd++ will fail! | |
77 | // a) create new locale with new codecvt facet | |
78 | // b) save current locale | |
79 | // c) change locale to new one | |
80 | // d) use stream buffer | |
81 | // e) change locale back to original | |
82 | // f) destroy new codecvt facet | |
83 | boost::archive::codecvt_null<Elem> codecvt_null_facet; | |
84 | basic_streambuf_locale_saver<Elem, Tr> locale_saver; | |
85 | std::locale archive_locale; | |
86 | #endif | |
87 | // default saving of primitives. | |
88 | template<class T> | |
89 | void save(const T & t) | |
90 | { | |
91 | save_binary(& t, sizeof(T)); | |
92 | } | |
93 | ||
94 | ///////////////////////////////////////////////////////// | |
95 | // fundamental types that need special treatment | |
96 | ||
97 | // trap usage of invalid uninitialized boolean which would | |
98 | // otherwise crash on load. | |
99 | void save(const bool t){ | |
100 | BOOST_ASSERT(0 == static_cast<int>(t) || 1 == static_cast<int>(t)); | |
101 | save_binary(& t, sizeof(t)); | |
102 | } | |
103 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
104 | save(const std::string &s); | |
105 | #ifndef BOOST_NO_STD_WSTRING | |
106 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
107 | save(const std::wstring &ws); | |
108 | #endif | |
109 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
110 | save(const char * t); | |
111 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
112 | save(const wchar_t * t); | |
113 | ||
114 | BOOST_ARCHIVE_OR_WARCHIVE_DECL void | |
115 | init(); | |
116 | ||
117 | BOOST_ARCHIVE_OR_WARCHIVE_DECL | |
118 | basic_binary_oprimitive( | |
119 | std::basic_streambuf<Elem, Tr> & sb, | |
120 | bool no_codecvt | |
121 | ); | |
122 | BOOST_ARCHIVE_OR_WARCHIVE_DECL | |
123 | ~basic_binary_oprimitive(); | |
124 | public: | |
125 | ||
126 | // we provide an optimized save for all fundamental types | |
127 | // typedef serialization::is_bitwise_serializable<mpl::_1> | |
128 | // use_array_optimization; | |
129 | // workaround without using mpl lambdas | |
130 | struct use_array_optimization { | |
131 | template <class T> | |
132 | #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) | |
133 | struct apply { | |
134 | typedef typename boost::serialization::is_bitwise_serializable< T >::type type; | |
135 | }; | |
136 | #else | |
137 | struct apply : public boost::serialization::is_bitwise_serializable< T > {}; | |
138 | #endif | |
139 | }; | |
140 | ||
141 | // the optimized save_array dispatches to save_binary | |
142 | template <class ValueType> | |
143 | void save_array(boost::serialization::array_wrapper<ValueType> const& a, unsigned int) | |
144 | { | |
145 | save_binary(a.address(),a.count()*sizeof(ValueType)); | |
146 | } | |
147 | ||
148 | void save_binary(const void *address, std::size_t count); | |
149 | }; | |
150 | ||
151 | template<class Archive, class Elem, class Tr> | |
152 | inline void | |
153 | basic_binary_oprimitive<Archive, Elem, Tr>::save_binary( | |
154 | const void *address, | |
155 | std::size_t count | |
156 | ){ | |
157 | // BOOST_ASSERT(count <= std::size_t(boost::integer_traits<std::streamsize>::const_max)); | |
158 | // note: if the following assertions fail | |
159 | // a likely cause is that the output stream is set to "text" | |
160 | // mode where by cr characters recieve special treatment. | |
161 | // be sure that the output stream is opened with ios::binary | |
162 | //if(os.fail()) | |
163 | // boost::serialization::throw_exception( | |
164 | // archive_exception(archive_exception::output_stream_error) | |
165 | // ); | |
166 | // figure number of elements to output - round up | |
167 | count = ( count + sizeof(Elem) - 1) / sizeof(Elem); | |
168 | std::streamsize scount = m_sb.sputn( | |
169 | static_cast<const Elem *>(address), | |
170 | static_cast<std::streamsize>(count) | |
171 | ); | |
172 | if(count != static_cast<std::size_t>(scount)) | |
173 | boost::serialization::throw_exception( | |
174 | archive_exception(archive_exception::output_stream_error) | |
175 | ); | |
176 | //os.write( | |
177 | // static_cast<const typename OStream::char_type *>(address), | |
178 | // count | |
179 | //); | |
180 | //BOOST_ASSERT(os.good()); | |
181 | } | |
182 | ||
183 | } //namespace boost | |
184 | } //namespace archive | |
185 | ||
186 | #include <boost/archive/detail/abi_suffix.hpp> // pop pragmas | |
187 | ||
188 | #endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP |