PageRenderTime 21ms CodeModel.GetById 15ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/archive/impl/basic_binary_oprimitive.ipp

http://hadesmem.googlecode.com/
C++ Header | 160 lines | 116 code | 19 blank | 25 comment | 2 complexity | 4703f3cda004b620198267d8fa727108 MD5 | raw file
  1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2// basic_binary_oprimitive.ipp:
  3
  4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
  5// Use, modification and distribution is subject to the Boost Software
  6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7// http://www.boost.org/LICENSE_1_0.txt)
  8
  9//  See http://www.boost.org for updates, documentation, and revision history.
 10
 11#include <ostream>
 12#include <cstddef> // NULL
 13#include <cstring>
 14
 15#include <boost/config.hpp>
 16
 17#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__)
 18namespace std{ 
 19    using ::strlen; 
 20} // namespace std
 21#endif
 22
 23#ifndef BOOST_NO_CWCHAR
 24#include <cwchar>
 25#ifdef BOOST_NO_STDC_NAMESPACE
 26namespace std{ using ::wcslen; }
 27#endif
 28#endif
 29
 30#include <boost/detail/workaround.hpp>
 31
 32#include <boost/archive/add_facet.hpp>
 33#include <boost/archive/codecvt_null.hpp>
 34
 35namespace boost {
 36namespace archive {
 37
 38//////////////////////////////////////////////////////////////////////
 39// implementation of basic_binary_oprimitive
 40
 41template<class Archive, class Elem, class Tr>
 42BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
 43basic_binary_oprimitive<Archive, Elem, Tr>::init()
 44{
 45    // record native sizes of fundamental types
 46    // this is to permit detection of attempts to pass
 47    // native binary archives accross incompatible machines.
 48    // This is not foolproof but its better than nothing.
 49    this->This()->save(static_cast<unsigned char>(sizeof(int)));
 50    this->This()->save(static_cast<unsigned char>(sizeof(long)));
 51    this->This()->save(static_cast<unsigned char>(sizeof(float)));
 52    this->This()->save(static_cast<unsigned char>(sizeof(double)));
 53    // for checking endianness
 54    this->This()->save(int(1));
 55}
 56
 57template<class Archive, class Elem, class Tr>
 58BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
 59basic_binary_oprimitive<Archive, Elem, Tr>::save(const char * s)
 60{
 61    std::size_t l = std::strlen(s);
 62    this->This()->save(l);
 63    save_binary(s, l);
 64}
 65
 66template<class Archive, class Elem, class Tr>
 67BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
 68basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
 69{
 70    std::size_t l = static_cast<std::size_t>(s.size());
 71    this->This()->save(l);
 72    save_binary(s.data(), l);
 73}
 74
 75#ifndef BOOST_NO_CWCHAR
 76template<class Archive, class Elem, class Tr>
 77BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
 78basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
 79{
 80    std::size_t l = std::wcslen(ws);
 81    this->This()->save(l);
 82    save_binary(ws, l * sizeof(wchar_t) / sizeof(char));
 83}
 84#endif
 85
 86#ifndef BOOST_NO_STD_WSTRING
 87template<class Archive, class Elem, class Tr>
 88BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
 89basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
 90{
 91    std::size_t l = ws.size();
 92    this->This()->save(l);
 93    save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char));
 94}
 95#endif
 96
 97template<class Archive, class Elem, class Tr>
 98BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
 99basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
100    std::basic_streambuf<Elem, Tr> & sb, 
101    bool no_codecvt
102) : 
103#ifndef BOOST_NO_STD_LOCALE
104    m_sb(sb),
105    archive_locale(NULL),
106    locale_saver(m_sb)
107{
108    if(! no_codecvt){
109        archive_locale.reset(
110            add_facet(
111                std::locale::classic(), 
112                new codecvt_null<Elem>
113            )
114        );
115        m_sb.pubimbue(* archive_locale);
116    }
117}
118#else
119    m_sb(sb)
120{}
121#endif
122
123// some libraries including stl and libcomo fail if the
124// buffer isn't flushed before the code_cvt facet is changed.
125// I think this is a bug.  We explicity invoke sync to when
126// we're done with the streambuf to work around this problem.
127// Note that sync is a protected member of stream buff so we
128// have to invoke it through a contrived derived class.
129namespace detail {
130// note: use "using" to get past msvc bug
131using namespace std;
132template<class Elem, class Tr>
133class output_streambuf_access : public std::basic_streambuf<Elem, Tr> {
134    public:
135        virtual int sync(){
136#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
137            return this->basic_streambuf::sync();
138#else
139            return this->basic_streambuf<Elem, Tr>::sync();
140#endif
141        }
142};
143} // detail
144
145// scoped_ptr requires that g be a complete type at time of
146// destruction so define destructor here rather than in the header
147template<class Archive, class Elem, class Tr>
148BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
149basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){
150    // flush buffer
151    //destructor can't throw
152    try{
153        static_cast<detail::output_streambuf_access<Elem, Tr> &>(m_sb).sync();
154    }
155    catch(...){
156    }
157}
158
159} // namespace archive
160} // namespace boost