Files
serialization/example/portable_binary_oarchive.hpp
2007-07-16 16:44:29 +00:00

154 lines
4.7 KiB
C++

#ifndef PORTABLE_BINARY_OARCHIVE_HPP
#define PORTABLE_BINARY_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.hpp
// (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 <ostream>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/detail/endian.hpp>
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" output binary archive. This is a variation of the native binary
// archive. it addresses integer size and endienness so that binary archives can
// be passed across systems. Note:floating point types not addressed here
class portable_binary_oarchive :
// don't derive from binary_oarchive !!!
public boost::archive::binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>
{
typedef boost::archive::binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> archive_base_t;
typedef boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override save below
friend class boost::archive::basic_binary_oarchive<portable_binary_oarchive>;
friend class boost::archive::save_access;
#endif
void save_impl(const long l){
long ll = l;
char size = 0;
if(l < 0){
// make sure that enough of data is output
// to include a high order bit indicating the sign
char x;
do{
x = ll;
ll >>= 8;
++size;
}while(ll != -1 && x < 0);
}
else{
do{
ll >>= 8;
++size;
}while(ll != 0);
}
this->archive_base_t::save(size);
// we choose to use litle endian
#ifdef BOOST_BIG_ENDIAN
char * first = static_cast<char *>(static_cast<void *>(& l));
char * last = first + sizeof(l) - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
#endif
save_binary(& l, size);
}
// add base class to the places considered when matching
// save function to a specific set of arguments. Note, this didn't
// work on my MSVC 7.0 system so we use the sure-fire method below
// using archive_base_t::save;
// default fall through for any types not specified here
template<class T>
void save(const T & t){
this->primitive_base_t::save(t);
}
void save(const short t){
save_impl(t);
}
void save(const unsigned short t){
save_impl(t);
}
void save(const unsigned int t){
save_impl(t);
}
void save(const int t){
save_impl(t);
}
void save(const unsigned long t){
save_impl(t);
}
void save(const long t){
save_impl(t);
}
public:
portable_binary_oarchive(std::ostream & os, unsigned flags = 0) :
archive_base_t(
os,
flags | boost::archive::no_header // skip default header checking
)
{
// use our own header checking
if(0 != (flags & boost::archive::no_header)){
this->archive_base_t::init(flags);
// skip the following for "portable" binary archives
// boost::archive::basic_binary_iprimitive<derived_t, std::ostream>::init();
}
}
};
#include <boost/archive/impl/basic_binary_oarchive.ipp>
#include <boost/archive/impl/archive_pointer_oserializer.ipp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost {
namespace archive {
// explicitly instantiate for this type of binary stream
template class binary_oarchive_impl<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>;
template class detail::archive_pointer_oserializer<portable_binary_oarchive> ;
} // namespace archive
} // namespace boost
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive
#endif // PORTABLE_BINARY_OARCHIVE_HPP