Line data Source code
1 :
2 : /* Copyright (c) 2012, Daniel Nachbaur <danielnachbaur@googlemail.com>
3 : * 2012, Stefan Eilemann <eile@eyescale.ch>
4 : *
5 : * This file is part of Collage <https://github.com/Eyescale/Collage>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : // Based on portable_iarchive.hpp
22 : // https://github.com/boost-vault/serialization/eos_portable_archive.zip
23 : // Copyright Christian Pfligersdorffer, 2007. All rights reserved.
24 : //
25 : // Distributed under the Boost Software License, Version 1.0. (See
26 : // accompanying file LICENSE_1_0.txt or copy at
27 : // http://www.boost.org/LICENSE_1_0.txt)
28 :
29 : #ifndef CO_DATAISTREAMARCHIVE_H
30 : #define CO_DATAISTREAMARCHIVE_H
31 :
32 : #include <co/api.h>
33 : #include <co/types.h>
34 :
35 : #include <boost/version.hpp>
36 : #pragma warning( push )
37 : #pragma warning( disable: 4800 )
38 : #include <boost/archive/basic_binary_iarchive.hpp>
39 : #pragma warning( pop )
40 : #include <boost/archive/detail/register_archive.hpp>
41 : #if BOOST_VERSION < 105600
42 : # include <boost/archive/shared_ptr_helper.hpp>
43 : #endif
44 : #include <boost/serialization/is_bitwise_serializable.hpp>
45 :
46 : #include <boost/spirit/home/support/detail/endian.hpp>
47 : #include <boost/spirit/home/support/detail/math/fpclassify.hpp>
48 :
49 : #include <boost/type_traits/is_integral.hpp>
50 : #include <boost/type_traits/is_unsigned.hpp>
51 : #include <boost/type_traits/is_floating_point.hpp>
52 :
53 : #include <boost/utility/enable_if.hpp>
54 :
55 : namespace co
56 : {
57 : /** A boost.serialization input archive reading from a co::DataIStream. */
58 6 : class DataIStreamArchive
59 : : public boost::archive::basic_binary_iarchive< DataIStreamArchive >
60 : #if BOOST_VERSION < 105600
61 : , public boost::archive::detail::shared_ptr_helper
62 : #endif
63 : {
64 : typedef boost::archive::basic_binary_iarchive< DataIStreamArchive > Super;
65 :
66 : public:
67 : /** Construct a new deserialization archive. @version 1.0 */
68 : CO_API explicit DataIStreamArchive( DataIStream& stream );
69 :
70 : /** @internal archives are expected to support this function */
71 : CO_API void load_binary( void* data, std::size_t size );
72 :
73 : /** @internal use optimized load for arrays. */
74 : template< typename T >
75 : void load_array( boost::serialization::array< T >& a, unsigned int );
76 :
77 : /** @internal enable serialization optimization for arrays. */
78 : struct use_array_optimization
79 : {
80 : template< class T >
81 : struct apply
82 : : public boost::serialization::is_bitwise_serializable< T > {};
83 : };
84 :
85 : private:
86 : friend class boost::archive::load_access;
87 :
88 : /**
89 : * Load boolean.
90 : *
91 : * Special case loading bool type, preserving compatibility to integer
92 : * types - this is somewhat redundant but simply treating bool as integer
93 : * type generates lots of warnings.
94 : */
95 : CO_API void load( bool& b );
96 :
97 : /** Load string types. */
98 : template< class C, class T, class A >
99 : void load( std::basic_string< C, T, A >& s );
100 :
101 : /**
102 : * Load integer types.
103 : *
104 : * First we load the size information ie. the number of bytes that
105 : * hold the actual data. Then we retrieve the data and transform it
106 : * to the original value by using load_little_endian.
107 : */
108 : template< typename T >
109 : typename boost::enable_if< boost::is_integral<T> >::type load( T& t );
110 :
111 : /**
112 : * Load floating point types.
113 : *
114 : * We simply rely on fp_traits to set the bit pattern from the (unsigned)
115 : * integral type that was stored in the stream. Francois Mauger provided
116 : * standardized behaviour for special values like inf and NaN, that need to
117 : * be serialized in his application.
118 : *
119 : * \note by Johan Rade (author of the floating point utilities library):
120 : * Be warned that the math::detail::fp_traits<T>::type::get_bits() function
121 : * is *not* guaranteed to give you all bits of the floating point number. It
122 : * will give you all bits if and only if there is an integer type that has
123 : * the same size as the floating point you are copying from. It will not
124 : * give you all bits for double if there is no uint64_t. It will not give
125 : * you all bits for long double if sizeof(long double) > 8 or there is no
126 : * uint64_t.
127 : *
128 : * The member fp_traits<T>::type::coverage will tell you whether all bits
129 : * are copied. This is a typedef for either math::detail::all_bits or
130 : * math::detail::not_all_bits.
131 : *
132 : * If the function does not copy all bits, then it will copy the most
133 : * significant bits. So if you serialize and deserialize the way you
134 : * describe, and fp_traits<T>::type::coverage is math::detail::not_all_bits,
135 : * then your floating point numbers will be truncated. This will introduce
136 : * small rounding off errors.
137 : */
138 : template< typename T >
139 : typename boost::enable_if< boost::is_floating_point<T> >::type load( T& t );
140 :
141 : #if BOOST_VERSION >= 104400
142 : // in boost 1.44 version_type was splitted into library_version_type and
143 : // item_version_type, plus a whole bunch of additional strong typedefs
144 : CO_API void load( boost::archive::library_version_type& version );
145 : CO_API void load( boost::archive::class_id_type& class_id );
146 : CO_API void load( boost::serialization::item_version_type& version );
147 : CO_API void load( boost::serialization::collection_size_type& version );
148 : CO_API void load( boost::archive::object_id_type& object_id );
149 : CO_API void load( boost::archive::version_type& version );
150 : #endif
151 :
152 : CO_API signed char _loadSignedChar();
153 :
154 : DataIStream& _stream;
155 : };
156 :
157 : }
158 :
159 : #include "dataIStreamArchive.ipp" // template implementation
160 :
161 : // contains load_override impl for class_name_type
162 : #include <boost/archive/impl/basic_binary_iarchive.ipp>
163 :
164 : BOOST_SERIALIZATION_REGISTER_ARCHIVE(co::DataIStreamArchive)
165 : BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(co::DataIStreamArchive)
166 :
167 : #endif //CO_DATAISTREAMARCHIVE_H
|