#ifndef MQUEUE_TINY_ARCHIVE_HPP_ #define MQUEUE_TINY_ARCHIVE_HPP_ #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace archive { class mqueue_tiny_iarchive { std::streambuf& m_sb; public: // we provide an optimized load for all fundamental types // typedef serialization::is_bitwise_serializable // use_array_optimization; struct use_array_optimization { template #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) struct apply { typedef BOOST_DEDUCED_TYPENAME boost::serialization::is_bitwise_serializable::type type; }; #else struct apply : public boost::serialization::is_bitwise_serializable {}; #endif }; mqueue_tiny_iarchive(std::streambuf& bsb) : m_sb(bsb) { } mqueue_tiny_iarchive(std::istream& is) : m_sb(*is.rdbuf()) { } unsigned int get_library_version() { return 0; } void reset_object_address(const void * new_address, const void * old_address) {} template mqueue_tiny_iarchive &operator>>(T &t){ return load_a_type(t, boost::mpl::bool_::value == serialization::primitive_type>(), 0 ); } template mqueue_tiny_iarchive &load_a_type(T &t,boost::mpl::true_, const unsigned BOOST_PFTO int version){ load_binary(&t, sizeof(T)); return *this; } template mqueue_tiny_iarchive &load_a_type(T &t,boost::mpl::false_, const unsigned BOOST_PFTO int version){ boost::serialization::load(*this, t, version); return *this; } // ADL does not work: template mqueue_tiny_iarchive &load_a_type(boost::serialization::nvp &t,boost::mpl::false_, const unsigned int version ){ t.load(*this, version); return *this; } template mqueue_tiny_iarchive &operator&(T &t){ return this->operator>>(t); } // the optimized load_array dispatches to load_binary template void load_array(boost::serialization::array& a, unsigned int) { load_binary(a.address(), a.count() * sizeof(ValueType)); } ////////////////////////////////////////////////////////// // public interface used by programs that use the // serialization library // archives are expected to support this function typedef char Elem; void load_binary(void *address, std::size_t count) { // note: an optimizer should eliminate the following for char files std::streamsize s = count / sizeof(Elem); std::streamsize scount = m_sb.sgetn( static_cast (address), s); if (scount != static_cast (s)) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::stream_error)); // note: an optimizer should eliminate the following for char files s = count % sizeof(Elem); if (0 < s) { // if(is.fail()) // boost::serialization::throw_exception( // archive_exception(archive_exception::stream_error) // ); Elem t; scount = m_sb.sgetn(&t, 1); if (scount != 1) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::stream_error)); std::memcpy(static_cast (address) + (count - s), &t, s); } } }; class mqueue_tiny_oarchive { std::streambuf & m_sb; public: // we provide an optimized load for all fundamental types // typedef serialization::is_bitwise_serializable // use_array_optimization; struct use_array_optimization { template #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) struct apply { typedef BOOST_DEDUCED_TYPENAME boost::serialization::is_bitwise_serializable::type type; }; #else struct apply : public boost::serialization::is_bitwise_serializable {}; #endif }; mqueue_tiny_oarchive(std::ostream& os) : m_sb(*os.rdbuf()) { } mqueue_tiny_oarchive(std::streambuf& sb) : m_sb(sb) { } unsigned int get_library_version() { return 0; } // the optimized save_array dispatches to save_binary template void save_array(boost::serialization::array const& a, unsigned int) { save_binary(a.address(), a.count() * sizeof(ValueType)); } template mqueue_tiny_oarchive &operator<<(T const &t){ return save_a_type(t,boost::mpl::bool_< serialization::implementation_level::value == serialization::primitive_type>() ); } template mqueue_tiny_oarchive &operator<<(boost::serialization::nvp const &t){ t.save(*this, 0); return *this; } template mqueue_tiny_oarchive &save_a_type(T const &t,boost::mpl::true_){ save_binary(&t, sizeof(T)); return *this; } template mqueue_tiny_oarchive &save_a_type(T const &t,boost::mpl::false_){ boost::serialization::save(*this, t, 0); return *this; } template mqueue_tiny_oarchive &operator&(T const &t){ return this->operator<<(t); } ////////////////////////////////////////////////////////// // public interface used by programs that use the // serialization library // archives are expected to support this function typedef char Elem; inline void save_binary(const void *address, std::size_t count) { //assert( // static_cast((std::numeric_limits::max)()) >= count //); // note: if the following assertions fail // a likely cause is that the output stream is set to "text" // mode where by cr characters recieve special treatment. // be sure that the output stream is opened with ios::binary //if(os.fail()) // boost::serialization::throw_exception( // archive_exception(archive_exception::stream_error) // ); // figure number of elements to output - round up count = (count + sizeof(Elem) - 1) / sizeof(Elem); std::streamsize scount = m_sb.sputn( static_cast (address), count); if (count != static_cast (scount)) boost::serialization::throw_exception( boost::archive::archive_exception( boost::archive::archive_exception::stream_error)); //os.write( // static_cast(address), // count //); //assert(os.good()); } }; } } #endif /* MQUEUE_TINY_ARCHIVE_HPP_ */