Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/archive/impl/basic_binary_oprimitive.ipp @ 33

Last change on this file since 33 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.8 KB
Line 
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 <cstring>
13
14#include <boost/config.hpp>
15
16#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__)
17namespace std{
18    using ::strlen;
19} // namespace std
20#endif
21
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/throw_exception.hpp>
33#include <boost/scoped_ptr.hpp>
34#include <boost/archive/archive_exception.hpp>
35#include <boost/archive/add_facet.hpp>
36#include <boost/archive/codecvt_null.hpp>
37
38namespace boost {
39namespace archive {
40
41//////////////////////////////////////////////////////////////////////
42// implementation of basic_binary_oprimitive
43
44template<class Archive, class Elem, class Tr>
45BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
46basic_binary_oprimitive<Archive, Elem, Tr>::init()
47{
48    // record native sizes of fundamental types
49    // this is to permit detection of attempts to pass
50    // native binary archives accross incompatible machines.
51    // This is not foolproof but its better than nothing.
52    this->This()->save(static_cast<unsigned char>(sizeof(int)));
53    this->This()->save(static_cast<unsigned char>(sizeof(long)));
54    this->This()->save(static_cast<unsigned char>(sizeof(float)));
55    this->This()->save(static_cast<unsigned char>(sizeof(double)));
56    // for checking endianness
57    this->This()->save(int(1));
58}
59
60template<class Archive, class Elem, class Tr>
61BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
62basic_binary_oprimitive<Archive, Elem, Tr>::save(const char * s)
63{
64    std::size_t l = std::strlen(s);
65    this->This()->save(l);
66    save_binary(s, l);
67}
68
69template<class Archive, class Elem, class Tr>
70BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
71basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::string &s)
72{
73    std::size_t l = static_cast<unsigned int>(s.size());
74    this->This()->save(l);
75    save_binary(s.data(), l);
76}
77
78#ifndef BOOST_NO_CWCHAR
79template<class Archive, class Elem, class Tr>
80BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
81basic_binary_oprimitive<Archive, Elem, Tr>::save(const wchar_t * ws)
82{
83    std::size_t l = std::wcslen(ws);
84    this->This()->save(l);
85    save_binary(ws, l * sizeof(wchar_t) / sizeof(char));
86}
87
88#ifndef BOOST_NO_STD_WSTRING
89template<class Archive, class Elem, class Tr>
90BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
91basic_binary_oprimitive<Archive, Elem, Tr>::save(const std::wstring &ws)
92{
93    std::size_t l = ws.size();
94    this->This()->save(l);
95    save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char));
96}
97#endif
98#endif
99
100template<class Archive, class Elem, class Tr>
101BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
102basic_binary_oprimitive<Archive, Elem, Tr>::basic_binary_oprimitive(
103    std::basic_streambuf<Elem, Tr> & sb,
104    bool no_codecvt
105) :
106    m_sb(sb),
107    archive_locale(NULL),
108    locale_saver(m_sb)
109{
110    if(! no_codecvt){
111        archive_locale.reset(
112            add_facet(
113                std::locale::classic(),
114                new codecvt_null<Elem>
115            )
116        );
117        m_sb.pubimbue(* archive_locale);
118    }
119}
120
121// some libraries including stl and libcomo fail if the
122// buffer isn't flushed before the code_cvt facet is changed.
123// I think this is a bug.  We explicity invoke sync to when
124// we're done with the streambuf to work around this problem.
125// Note that sync is a protected member of stream buff so we
126// have to invoke it through a contrived derived class.
127namespace detail {
128// note: use "using" to get past msvc bug
129using namespace std;
130template<class Elem, class Tr>
131class output_streambuf_access : public std::basic_streambuf<Elem, Tr> {
132    public:
133        virtual int sync(){
134#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
135            return this->basic_streambuf::sync();
136#else
137            return this->basic_streambuf<Elem, Tr>::sync();
138#endif
139        }
140};
141} // detail
142
143// scoped_ptr requires that g be a complete type at time of
144// destruction so define destructor here rather than in the header
145template<class Archive, class Elem, class Tr>
146BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
147basic_binary_oprimitive<Archive, Elem, Tr>::~basic_binary_oprimitive(){
148    // flush buffer
149    int result = static_cast<detail::output_streambuf_access<Elem, Tr> &>(
150        m_sb
151    ).sync();
152    if(0 != result){
153        boost::throw_exception(
154            archive_exception(archive_exception::stream_error)
155        );
156    }
157}
158
159} // namespace archive
160} // namespace boost
Note: See TracBrowser for help on using the repository browser.