GCC Code Coverage Report


Directory: ./
File: include/pinocchio/serialization/archive.hpp
Date: 2024-08-27 18:20:05
Exec Total Coverage
Lines: 0 77 0.0%
Branches: 0 146 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2017-2022 CNRS INRIA
3 //
4
5 #ifndef __pinocchio_serialization_archive_hpp__
6 #define __pinocchio_serialization_archive_hpp__
7
8 #include "pinocchio/serialization/fwd.hpp"
9 #include "pinocchio/serialization/static-buffer.hpp"
10
11 #include <fstream>
12 #include <string>
13 #include <sstream>
14 #include <stdexcept>
15 #include <boost/archive/text_oarchive.hpp>
16 #include <boost/archive/text_iarchive.hpp>
17 #include <boost/archive/xml_iarchive.hpp>
18 #include <boost/archive/xml_oarchive.hpp>
19 #include <boost/archive/binary_iarchive.hpp>
20 #include <boost/archive/binary_oarchive.hpp>
21
22 #if BOOST_VERSION / 100 % 1000 == 78 && __APPLE__
23 // See https://github.com/qcscine/utilities/issues/5#issuecomment-1246897049 for further details
24
25 #ifndef BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
26 #define DEFINE_BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
27 #define BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
28 #endif
29
30 #include <boost/asio/streambuf.hpp>
31
32 #ifdef DEFINE_BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
33 #undef BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC
34 #endif
35
36 #else
37 #include <boost/asio/streambuf.hpp>
38 #endif
39
40 #include <boost/iostreams/device/array.hpp>
41 #include <boost/iostreams/stream.hpp>
42 #include <boost/iostreams/stream_buffer.hpp>
43
44 // Handle NAN inside TXT or XML archives
45 #include <boost/math/special_functions/nonfinite_num_facets.hpp>
46
47 namespace pinocchio
48 {
49 namespace serialization
50 {
51
52 ///
53 /// \brief Loads an object from a TXT file.
54 ///
55 /// \tparam T Type of the object to deserialize.
56 ///
57 /// \param[out] object Object in which the loaded data are copied.
58 /// \param[in] filename Name of the file containing the serialized data.
59 ///
60 template<typename T>
61 inline void loadFromText(T & object, const std::string & filename)
62 {
63 std::ifstream ifs(filename.c_str());
64 if (ifs)
65 {
66 std::locale const new_loc(ifs.getloc(), new boost::math::nonfinite_num_get<char>);
67 ifs.imbue(new_loc);
68 boost::archive::text_iarchive ia(ifs, boost::archive::no_codecvt);
69 ia >> object;
70 }
71 else
72 {
73 const std::string exception_message(filename + " does not seem to be a valid file.");
74 throw std::invalid_argument(exception_message);
75 }
76 }
77
78 ///
79 /// \brief Saves an object inside a TXT file.
80 ///
81 /// \tparam T Type of the object to deserialize.
82 ///
83 /// \param[in] object Object in which the loaded data are copied.
84 /// \param[in] filename Name of the file containing the serialized data.
85 ///
86 template<typename T>
87 inline void saveToText(const T & object, const std::string & filename)
88 {
89 std::ofstream ofs(filename.c_str());
90 if (ofs)
91 {
92 boost::archive::text_oarchive oa(ofs);
93 oa & object;
94 }
95 else
96 {
97 const std::string exception_message(filename + " does not seem to be a valid file.");
98 throw std::invalid_argument(exception_message);
99 }
100 }
101
102 ///
103 /// \brief Loads an object from a std::stringstream.
104 ///
105 /// \tparam T Type of the object to deserialize.
106 ///
107 /// \param[out] object Object in which the loaded data are copied.
108 /// \param[in] is string stream constaining the serialized content of the object.
109 ///
110 template<typename T>
111 inline void loadFromStringStream(T & object, std::istringstream & is)
112 {
113 boost::archive::text_iarchive ia(is, boost::archive::no_codecvt);
114 ia >> object;
115 }
116
117 ///
118 /// \brief Saves an object inside a std::stringstream.
119 ///
120 /// \tparam T Type of the object to deserialize.
121 ///
122 /// \param[in] object Object in which the loaded data are copied.
123 /// \param[out] ss String stream constaining the serialized content of the object.
124 ///
125 template<typename T>
126 inline void saveToStringStream(const T & object, std::stringstream & ss)
127 {
128 boost::archive::text_oarchive oa(ss);
129 oa & object;
130 }
131
132 ///
133 /// \brief Loads an object from a std::string
134 ///
135 /// \tparam T Type of the object to deserialize.
136 ///
137 /// \param[out] object Object in which the loaded data are copied.
138 /// \param[in] str string constaining the serialized content of the object.
139 ///
140 template<typename T>
141 inline void loadFromString(T & object, const std::string & str)
142 {
143 std::istringstream is(str);
144 loadFromStringStream(object, is);
145 }
146
147 ///
148 /// \brief Saves an object inside a std::string
149 ///
150 /// \tparam T Type of the object to deserialize.
151 ///
152 /// \param[in] object Object in which the loaded data are copied.
153 ///
154 /// \returns a string constaining the serialized content of the object.
155 ///
156 template<typename T>
157 inline std::string saveToString(const T & object)
158 {
159 std::stringstream ss;
160 saveToStringStream(object, ss);
161 return ss.str();
162 }
163
164 ///
165 /// \brief Loads an object from a XML file.
166 ///
167 /// \tparam T Type of the object to deserialize.
168 ///
169 /// \param[out] object Object in which the loaded data are copied.
170 /// \param[in] filename Name of the file containing the serialized data.
171 /// \param[in] tag_name XML Tag for the given object.
172 ///
173 template<typename T>
174 inline void loadFromXML(T & object, const std::string & filename, const std::string & tag_name)
175 {
176 PINOCCHIO_CHECK_INPUT_ARGUMENT(!tag_name.empty());
177
178 std::ifstream ifs(filename.c_str());
179 if (ifs)
180 {
181 std::locale const new_loc(ifs.getloc(), new boost::math::nonfinite_num_get<char>);
182 ifs.imbue(new_loc);
183 boost::archive::xml_iarchive ia(ifs, boost::archive::no_codecvt);
184 ia >> boost::serialization::make_nvp(tag_name.c_str(), object);
185 }
186 else
187 {
188 const std::string exception_message(filename + " does not seem to be a valid file.");
189 throw std::invalid_argument(exception_message);
190 }
191 }
192
193 ///
194 /// \brief Saves an object inside a XML file.
195 ///
196 /// \tparam T Type of the object to deserialize.
197 ///
198 /// \param[in] object Object in which the loaded data are copied.
199 /// \param[in] filename Name of the file containing the serialized data.
200 /// \param[in] tag_name XML Tag for the given object.
201 ///
202 template<typename T>
203 inline void
204 saveToXML(const T & object, const std::string & filename, const std::string & tag_name)
205 {
206 PINOCCHIO_CHECK_INPUT_ARGUMENT(!tag_name.empty());
207
208 std::ofstream ofs(filename.c_str());
209 if (ofs)
210 {
211 boost::archive::xml_oarchive oa(ofs);
212 oa & boost::serialization::make_nvp(tag_name.c_str(), object);
213 }
214 else
215 {
216 const std::string exception_message(filename + " does not seem to be a valid file.");
217 throw std::invalid_argument(exception_message);
218 }
219 }
220
221 ///
222 /// \brief Loads an object from a binary file.
223 ///
224 /// \tparam T Type of the object to deserialize.
225 ///
226 /// \param[out] object Object in which the loaded data are copied.
227 /// \param[in] filename Name of the file containing the serialized data.
228 ///
229 template<typename T>
230 inline void loadFromBinary(T & object, const std::string & filename)
231 {
232 std::ifstream ifs(filename.c_str(), std::ios::binary);
233 if (ifs)
234 {
235 boost::archive::binary_iarchive ia(ifs);
236 ia >> object;
237 }
238 else
239 {
240 const std::string exception_message(filename + " does not seem to be a valid file.");
241 throw std::invalid_argument(exception_message);
242 }
243 }
244
245 ///
246 /// \brief Saves an object inside a binary file.
247 ///
248 /// \tparam T Type of the object to deserialize.
249 ///
250 /// \param[in] object Object in which the loaded data are copied.
251 /// \param[in] filename Name of the file containing the serialized data.
252 ///
253 template<typename T>
254 void saveToBinary(const T & object, const std::string & filename)
255 {
256 std::ofstream ofs(filename.c_str(), std::ios::binary);
257 if (ofs)
258 {
259 boost::archive::binary_oarchive oa(ofs);
260 oa & object;
261 }
262 else
263 {
264 const std::string exception_message(filename + " does not seem to be a valid file.");
265 throw std::invalid_argument(exception_message);
266 }
267 }
268
269 ///
270 /// \brief Loads an object from a binary buffer.
271 ///
272 /// \tparam T Type of the object to deserialize.
273 ///
274 /// \param[out] object Object in which the loaded data are copied.
275 /// \param[in] buffer Input buffer containing the serialized data.
276 ///
277 template<typename T>
278 inline void loadFromBinary(T & object, boost::asio::streambuf & buffer)
279 {
280 boost::archive::binary_iarchive ia(buffer);
281 ia >> object;
282 }
283
284 ///
285 /// \brief Saves an object to a binary buffer.
286 ///
287 /// \tparam T Type of the object to serialize.
288 ///
289 /// \param[in] object Object in which the loaded data are copied.
290 /// \param[out] buffer Output buffer containing the serialized data.
291 ///
292 template<typename T>
293 void saveToBinary(const T & object, boost::asio::streambuf & buffer)
294 {
295 boost::archive::binary_oarchive oa(buffer);
296 oa & object;
297 }
298
299 ///
300 /// \brief Loads an object from a static binary buffer.
301 /// The buffer should be of a sufficient size.
302 ///
303 /// \tparam T Type of the object to deserialize.
304 ///
305 /// \param[out] object Object in which the loaded data are copied.
306 /// \param[in] buffer Input buffer containing the serialized data.
307 ///
308 template<typename T>
309 inline void loadFromBinary(T & object, StaticBuffer & buffer)
310 {
311 boost::iostreams::stream_buffer<boost::iostreams::basic_array<char>> stream(
312 buffer.data(), buffer.size());
313
314 boost::archive::binary_iarchive ia(stream);
315 ia >> object;
316 }
317
318 ///
319 /// \brief Saves an object to a static binary buffer.
320 /// The buffer should be of a sufficient size.
321 ///
322 /// \tparam T Type of the object to deserialize.
323 ///
324 /// \param[in] object Object in which the loaded data are copied.
325 /// \param[out] buffer Output buffer containing the serialized data.
326 ///
327 template<typename T>
328 inline void saveToBinary(const T & object, StaticBuffer & buffer)
329 {
330 boost::iostreams::stream_buffer<boost::iostreams::basic_array<char>> stream(
331 buffer.data(), buffer.size());
332
333 boost::archive::binary_oarchive oa(stream);
334 oa & object;
335 }
336
337 } // namespace serialization
338 } // namespace pinocchio
339
340 #endif // ifndef __pinocchio_serialization_archive_hpp__
341