Chris@16: #ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP Chris@16: #define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma warning( disable : 4800 ) Chris@16: #endif Chris@16: Chris@16: /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 Chris@16: // basic_binary_iprimitive.hpp Chris@16: // Chris@16: // archives stored as native binary - this should be the fastest way Chris@16: // to archive the state of a group of obects. It makes no attempt to Chris@16: // convert to any canonical form. Chris@16: Chris@16: // IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE Chris@16: // ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON Chris@16: Chris@16: // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // std::memcpy Chris@16: #include // std::size_t Chris@16: #include // basic_streambuf Chris@16: #include Chris@16: Chris@16: #include Chris@16: #if defined(BOOST_NO_STDC_NAMESPACE) Chris@16: namespace std{ Chris@16: using ::memcpy; Chris@16: using ::size_t; Chris@16: } // namespace std Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: Chris@101: #include Chris@101: #include Chris@16: #include Chris@16: #include // must be the last header Chris@16: Chris@16: namespace boost { Chris@16: namespace archive { Chris@16: Chris@101: template Chris@101: class codecvt_null; Chris@101: Chris@16: ///////////////////////////////////////////////////////////////////////////// Chris@16: // class binary_iarchive - read serialized objects from a input binary stream Chris@16: template Chris@16: class basic_binary_iprimitive Chris@16: { Chris@16: #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS Chris@16: friend class load_access; Chris@16: protected: Chris@16: #else Chris@16: public: Chris@16: #endif Chris@16: std::basic_streambuf & m_sb; Chris@16: // return a pointer to the most derived class Chris@16: Archive * This(){ Chris@16: return static_cast(this); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_STD_LOCALE Chris@101: boost::scoped_ptr > codecvt_facet; Chris@16: boost::scoped_ptr archive_locale; Chris@16: basic_streambuf_locale_saver locale_saver; Chris@16: #endif Chris@16: Chris@16: // main template for serilization of primitive types Chris@16: template Chris@16: void load(T & t){ Chris@16: load_binary(& t, sizeof(T)); Chris@16: } Chris@16: Chris@16: ///////////////////////////////////////////////////////// Chris@16: // fundamental types that need special treatment Chris@16: Chris@16: // trap usage of invalid uninitialized boolean Chris@16: void load(bool & t){ Chris@16: load_binary(& t, sizeof(t)); Chris@16: int i = t; Chris@16: BOOST_ASSERT(0 == i || 1 == i); Chris@16: (void)i; // warning suppression for release builds. Chris@16: } Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: load(std::string &s); Chris@16: #ifndef BOOST_NO_STD_WSTRING Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: load(std::wstring &ws); Chris@16: #endif Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: load(char * t); Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: load(wchar_t * t); Chris@16: Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(void) Chris@16: init(); Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: basic_binary_iprimitive( Chris@16: std::basic_streambuf & sb, Chris@16: bool no_codecvt Chris@16: ); Chris@16: BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY()) Chris@16: ~basic_binary_iprimitive(); Chris@16: public: Chris@16: // we provide an optimized load for all fundamental types Chris@16: // typedef serialization::is_bitwise_serializable Chris@16: // use_array_optimization; Chris@16: struct use_array_optimization { Chris@16: template Chris@16: #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) Chris@16: struct apply { Chris@101: typedef typename boost::serialization::is_bitwise_serializable< T >::type type; Chris@16: }; Chris@16: #else Chris@16: struct apply : public boost::serialization::is_bitwise_serializable< T > {}; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // the optimized load_array dispatches to load_binary Chris@16: template Chris@16: void load_array(serialization::array& a, unsigned int) Chris@16: { Chris@16: load_binary(a.address(),a.count()*sizeof(ValueType)); Chris@16: } Chris@16: Chris@16: void Chris@16: load_binary(void *address, std::size_t count); Chris@16: }; Chris@16: Chris@16: template Chris@16: inline void Chris@16: basic_binary_iprimitive::load_binary( Chris@16: void *address, Chris@16: std::size_t count Chris@16: ){ Chris@16: // note: an optimizer should eliminate the following for char files Chris@16: BOOST_ASSERT( Chris@16: static_cast(count / sizeof(Elem)) Chris@16: <= boost::integer_traits::const_max Chris@16: ); Chris@16: std::streamsize s = static_cast(count / sizeof(Elem)); Chris@16: std::streamsize scount = m_sb.sgetn( Chris@16: static_cast(address), Chris@16: s Chris@16: ); Chris@16: if(scount != s) Chris@16: boost::serialization::throw_exception( Chris@16: archive_exception(archive_exception::input_stream_error) Chris@16: ); Chris@16: // note: an optimizer should eliminate the following for char files Chris@16: BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits::const_max); Chris@16: s = static_cast(count % sizeof(Elem)); Chris@16: if(0 < s){ Chris@16: // if(is.fail()) Chris@16: // boost::serialization::throw_exception( Chris@16: // archive_exception(archive_exception::stream_error) Chris@16: // ); Chris@16: Elem t; Chris@16: scount = m_sb.sgetn(& t, 1); Chris@16: if(scount != 1) Chris@16: boost::serialization::throw_exception( Chris@16: archive_exception(archive_exception::input_stream_error) Chris@16: ); Chris@101: std::memcpy(static_cast(address) + (count - s), &t, static_cast(s)); Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace archive Chris@16: } // namespace boost Chris@16: Chris@16: #include // pop pragmas Chris@16: Chris@16: #endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP