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