Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef BINARY_DATA_ARCHIVE_HPP_
00042 #define BINARY_DATA_ARCHIVE_HPP_
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00068 #include <cassert>
00069 #include <istream>
00070 #include <ostream>
00071 #include <streambuf>
00072 #include <cstring>
00073 #include <boost/serialization/serialization.hpp>
00074 #include <boost/serialization/is_bitwise_serializable.hpp>
00075 #include <boost/archive/detail/iserializer.hpp>
00076 #include <boost/archive/detail/oserializer.hpp>
00077 #include <boost/archive/archive_exception.hpp>
00078 #include <boost/config.hpp>
00079 #include <boost/mpl/bool.hpp>
00080
00081
00082 #include <boost/version.hpp>
00083 #if BOOST_VERSION >= 104600
00084 #include <boost/serialization/item_version_type.hpp>
00085 #endif
00086
00087 namespace RTT
00088 {
00089 namespace mqueue
00090 {
00091
00098 class binary_data_iarchive
00099 {
00100 std::streambuf& m_sb;
00101 int data_read;
00102 public:
00103 typedef char Elem;
00104 typedef binary_data_iarchive Archive;
00105
00109 typedef boost::mpl::bool_<true> is_loading;
00113 typedef boost::mpl::bool_<false> is_saving;
00114
00119 binary_data_iarchive(std::streambuf& bsb) :
00120 m_sb(bsb), data_read(0)
00121 {
00122 }
00123
00128 binary_data_iarchive(std::istream& is) :
00129 m_sb(*is.rdbuf()), data_read(0)
00130 {
00131 }
00132
00137 unsigned int get_library_version() { return 0; }
00138
00144 void reset_object_address(const void * new_address, const void * old_address) {}
00145
00149 void delete_created_pointers() {}
00150
00156 template<class T>
00157 const boost::archive::detail::basic_pointer_iserializer *
00158 register_type(T * = NULL) {return 0;}
00159
00166 void load_object(
00167 void *t,
00168 const boost::archive::detail::basic_iserializer & bis
00169 ) {
00170 assert(false);
00171 }
00172
00177 template<class T>
00178 void load_override(T & t, BOOST_PFTO int){
00179 load_a_type(t, boost::mpl::bool_<boost::serialization::implementation_level<T>::value == boost::serialization::primitive_type>() );
00180
00181 }
00182
00188 #if 0
00189 void load_override(const boost::serialization::nvp<boost::serialization::collection_size_type> & t, int){
00190 size_t x=0;
00191 * this >> x;
00192 t.value() = boost::serialization::collection_size_type(x);
00193 }
00194 #endif
00195 template<class T>
00196 void load_override(const boost::serialization::nvp<T> & t, int){
00197 T& x(t.value());
00198 * this >> x;
00199 }
00200
00206 template<class T>
00207 void load_override(const boost::serialization::array<T> &t, int)
00208 {
00209 boost::serialization::array<T> tmp(t.address(), t.count());
00210 *this >> tmp;
00211 }
00212
00218 template<class T>
00219 binary_data_iarchive &operator>>(T &t){
00220 this->load_override(t, 0);
00221 return * this;
00222 }
00223
00229 template<class T>
00230 binary_data_iarchive &operator&(T &t){
00231 return this->operator>>(t);
00232 }
00233
00239 void load_binary(void *address, std::size_t count)
00240 {
00241
00242 std::streamsize s = count / sizeof(Elem);
00243 std::streamsize scount = m_sb.sgetn(
00244 static_cast<Elem *> (address), s);
00245 if (scount != static_cast<std::streamsize> (s))
00246 #if BOOST_VERSION >= 104400
00247 boost::serialization::throw_exception(
00248 boost::archive::archive_exception(
00249 boost::archive::archive_exception::input_stream_error));
00250 #else
00251 boost::serialization::throw_exception(
00252 boost::archive::archive_exception(
00253 boost::archive::archive_exception::stream_error));
00254 #endif
00255
00256 s = count % sizeof(Elem);
00257 if (0 < s)
00258 {
00259
00260
00261
00262
00263 Elem t;
00264 scount = m_sb.sgetn(&t, 1);
00265 if (scount != 1)
00266 #if BOOST_VERSION >= 104400
00267 boost::serialization::throw_exception(
00268 boost::archive::archive_exception(
00269 boost::archive::archive_exception::input_stream_error));
00270 #else
00271 boost::serialization::throw_exception(
00272 boost::archive::archive_exception(
00273 boost::archive::archive_exception::stream_error));
00274 #endif
00275 std::memcpy(static_cast<char*> (address) + (count - s), &t,
00276 s);
00277 }
00278 data_read += count;
00279 }
00280
00286 template<class T>
00287 binary_data_iarchive &load_a_type(T &t,boost::mpl::true_){
00288 load_binary(&t, sizeof(T));
00289 return *this;
00290 }
00291
00297 template<class T>
00298 binary_data_iarchive &load_a_type(T &t,boost::mpl::false_){
00299 #if BOOST_VERSION >= 104100
00300 boost::archive::detail::load_non_pointer_type<binary_data_iarchive>::load_only::invoke(*this,t);
00301 #else
00302 boost::archive::detail::load_non_pointer_type<binary_data_iarchive,T>::load_only::invoke(*this,t);
00303 #endif
00304 return *this;
00305 }
00306
00311 struct use_array_optimization {
00312 template <class T>
00313 #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS)
00314 struct apply {
00315 typedef BOOST_DEDUCED_TYPENAME boost::serialization::is_bitwise_serializable<T>::type type;
00316 };
00317 #else
00318 struct apply : public boost::serialization::is_bitwise_serializable<T> {};
00319 #endif
00320 };
00321
00325 template<class ValueType>
00326 void load_array(boost::serialization::array<ValueType>& a,
00327 unsigned int)
00328 {
00329 load_binary(a.address(), a.count()
00330 * sizeof(ValueType));
00331 }
00332
00336 int getArchiveSize() { return data_read; }
00337 };
00338
00344 class binary_data_oarchive
00345 {
00346 std::streambuf & m_sb;
00347 int data_written;
00348 bool mdo_save;
00349 public:
00350 typedef char Elem;
00354 typedef boost::mpl::bool_<false> is_loading;
00358 typedef boost::mpl::bool_<true> is_saving;
00359
00368 binary_data_oarchive(std::ostream& os,bool do_save = true) :
00369 m_sb(*os.rdbuf()), data_written(0), mdo_save(do_save)
00370 {
00371 }
00372
00381 binary_data_oarchive(std::streambuf& sb,bool do_save = true) :
00382 m_sb(sb), data_written(0), mdo_save(do_save)
00383 {
00384 }
00385
00390 unsigned int get_library_version() { return 0; }
00391
00397 template<class T>
00398 const boost::archive::detail::basic_pointer_iserializer *
00399 register_type(T * = NULL) {return 0;}
00400
00406 void save_object(
00407 const void *x,
00408 const boost::archive::detail::basic_oserializer & bos
00409 ) {
00410 assert(false);
00411
00412 }
00413
00419 template<class T>
00420 binary_data_oarchive &operator<<(T const &t){
00421 return save_a_type(t,boost::mpl::bool_< boost::serialization::implementation_level<T>::value == boost::serialization::primitive_type>() );
00422 }
00423
00429 template<class T>
00430 binary_data_oarchive &operator&(T const &t){
00431 return this->operator<<(t);
00432 }
00433
00439 inline void save_binary(const void *address, std::size_t count)
00440 {
00441
00442 count = (count + sizeof(Elem) - 1) / sizeof(Elem);
00443 if (mdo_save) {
00444 std::streamsize scount = m_sb.sputn(
00445 static_cast<const Elem *> (address), count);
00446 if (count != static_cast<std::size_t> (scount))
00447 #if BOOST_VERSION >= 104400
00448 boost::serialization::throw_exception(
00449 boost::archive::archive_exception(
00450 boost::archive::archive_exception::output_stream_error));
00451 #else
00452 boost::serialization::throw_exception(
00453 boost::archive::archive_exception(
00454 boost::archive::archive_exception::stream_error));
00455 #endif
00456 }
00457 data_written += count;
00458 }
00459
00465 template<class T>
00466 binary_data_oarchive &save_a_type(T const &t,boost::mpl::true_){
00467 save_binary(&t, sizeof(T));
00468 return *this;
00469 }
00470
00471 #if BOOST_VERSION >= 104600
00472 binary_data_oarchive &save_a_type(const boost::serialization::version_type & t,boost::mpl::true_){
00473
00474 return *this;
00475 }
00476 binary_data_oarchive &save_a_type(const boost::serialization::item_version_type & t,boost::mpl::true_){
00477
00478 return *this;
00479 }
00480 #endif
00481
00487 template<class T>
00488 binary_data_oarchive &save_a_type(T const &t,boost::mpl::false_){
00489 #if BOOST_VERSION >= 104100
00490 boost::archive::detail::save_non_pointer_type<binary_data_oarchive>::save_only::invoke(*this,t);
00491 #else
00492 boost::archive::detail::save_non_pointer_type<binary_data_oarchive,T>::save_only::invoke(*this,t);
00493 #endif
00494 return *this;
00495 }
00496
00501 struct use_array_optimization {
00502 template <class T>
00503 #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS)
00504 struct apply {
00505 typedef BOOST_DEDUCED_TYPENAME boost::serialization::is_bitwise_serializable<T>::type type;
00506 };
00507 #else
00508 struct apply : public boost::serialization::is_bitwise_serializable<T> {};
00509 #endif
00510 };
00511
00515 template<class ValueType>
00516 void save_array(boost::serialization::array<ValueType> const& a,
00517 unsigned int)
00518 {
00519 save_binary(a.address(), a.count()
00520 * sizeof(ValueType));
00521 }
00522
00526 int getArchiveSize() { return data_written; }
00527 };
00528 }
00529 }
00530
00531 BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(RTT::mqueue::binary_data_oarchive)
00532 BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(RTT::mqueue::binary_data_iarchive)
00533
00534 #endif