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