/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_binary_oprimitive.ipp:

// (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 <cstddef> // NULL
#include <cstring>

#include <boost/config.hpp>

#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__)
namespace std{ 
    using ::strlen; 
} // namespace std
#endif

#ifndef BOOST_NO_CWCHAR
#include <cwchar>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::wcslen; }
#endif
#endif

#include <boost/detail/workaround.hpp>

#include <boost/archive/add_facet.hpp>
#include <boost/archive/codecvt_null.hpp>

namespace boost {
namespace archive {

//////////////////////////////////////////////////////////////////////
// implementation of basic_binary_oprimitive

template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_binary_oprimitive<Archive, Elem, Tr>::init()
{
    // record native sizes of fundamental types
    // this is to permit detection of attempts to pass
    // native binary archives accross incompatible machines.
    // This is not foolproof but its better than nothing.
    this->This()->save(static_cast<unsigned char>(sizeof(int)));
    this->This()->save(static_cast<unsigned char>(sizeof(long)));
    this->This()->save(static_cast<unsigned char>(sizeof(float)));
    this->This()->save(static_cast<unsigned char>(sizeof(double)));
    // for checking endianness
    this->This()->save(int(1));
}

template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_binary_oprimitive<Archive, Elem, Tr>::save(const char * s)
{
    std::size_t l = std::strlen(s);
    this->This()->save(l);
    save_binary(s, l);
}

template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
{
    std::size_t l = static_cast<std::size_t>(s.size());
    this->This()->save(l);
    save_binary(s.data(), l);
}

#ifndef BOOST_NO_CWCHAR
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
{
    std::size_t l = std::wcslen(ws);
    this->This()->save(l);
    save_binary(ws, l * sizeof(wchar_t) / sizeof(char));
}
#endif

#ifndef BOOST_NO_STD_WSTRING
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
{
    std::size_t l = ws.size();
    this->This()->save(l);
    save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char));
}
#endif

template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
    std::basic_streambuf<Elem, Tr> & sb, 
    bool no_codecvt
) : 
#ifndef BOOST_NO_STD_LOCALE
    m_sb(sb),
    archive_locale(NULL),
    locale_saver(m_sb)
{
    if(! no_codecvt){
        archive_locale.reset(
            add_facet(
                std::locale::classic(), 
                new codecvt_null<Elem>
            )
        );
        m_sb.pubimbue(* archive_locale);
    }
}
#else
    m_sb(sb)
{}
#endif

// some libraries including stl and libcomo fail if the
// buffer isn't flushed before the code_cvt facet is changed.
// I think this is a bug.  We explicity invoke sync to when
// we're done with the streambuf to work around this problem.
// Note that sync is a protected member of stream buff so we
// have to invoke it through a contrived derived class.
namespace detail {
// note: use "using" to get past msvc bug
using namespace std;
template<class Elem, class Tr>
class output_streambuf_access : public std::basic_streambuf<Elem, Tr> {
    public:
        virtual int sync(){
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
            return this->basic_streambuf::sync();
#else
            return this->basic_streambuf<Elem, Tr>::sync();
#endif
        }
};
} // detail

// scoped_ptr requires that g be a complete type at time of
// destruction so define destructor here rather than in the header
template<class Archive, class Elem, class Tr>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){
    // flush buffer
    //destructor can't throw
    try{
        static_cast<detail::output_streambuf_access<Elem, Tr> &>(m_sb).sync();
    }
    catch(...){
    }
}

} // namespace archive
} // namespace boost
