mb_from_wchar.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
  2. #define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  8. // mb_from_wchar.hpp
  9. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  10. // Use, modification and distribution is subject to the Boost Software
  11. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. // See http://www.boost.org for updates, documentation, and revision history.
  14. #include <cassert>
  15. #include <cstddef> // size_t
  16. #include <cstdlib> // for wctomb()
  17. #include <boost/config.hpp> // for BOOST_DEDUCED_TYPENAME
  18. #if defined(BOOST_NO_STDC_NAMESPACE)
  19. namespace std{
  20. using ::size_t;
  21. using ::wctomb;
  22. } // namespace std
  23. #endif
  24. #include <boost/serialization/pfto.hpp>
  25. #include <boost/iterator/iterator_adaptor.hpp>
  26. namespace boost {
  27. namespace archive {
  28. namespace iterators {
  29. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  30. // class used by text archives to translate wide strings and to char
  31. // strings of the currently selected locale
  32. template<class Base> // the input iterator
  33. class mb_from_wchar
  34. : public boost::iterator_adaptor<
  35. mb_from_wchar<Base>,
  36. Base,
  37. wchar_t,
  38. single_pass_traversal_tag,
  39. char
  40. >
  41. {
  42. friend class boost::iterator_core_access;
  43. typedef BOOST_DEDUCED_TYPENAME boost::iterator_adaptor<
  44. mb_from_wchar<Base>,
  45. Base,
  46. wchar_t,
  47. single_pass_traversal_tag,
  48. char
  49. > super_t;
  50. typedef mb_from_wchar<Base> this_t;
  51. char dereference_impl() {
  52. if(! m_full){
  53. fill();
  54. m_full = true;
  55. }
  56. return m_buffer[m_bnext];
  57. }
  58. char dereference() const {
  59. return (const_cast<this_t *>(this))->dereference_impl();
  60. }
  61. // test for iterator equality
  62. bool equal(const mb_from_wchar<Base> & rhs) const {
  63. // once the value is filled, the base_reference has been incremented
  64. // so don't permit comparison anymore.
  65. return
  66. 0 == m_bend
  67. && 0 == m_bnext
  68. && this->base_reference() == rhs.base_reference()
  69. ;
  70. }
  71. void fill(){
  72. wchar_t value = * this->base_reference();
  73. #if (defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 3) \
  74. || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION >= 8))))
  75. m_bend = std::wcrtomb(m_buffer, value, 0);
  76. #else
  77. m_bend = std::wctomb(m_buffer, value);
  78. #endif
  79. assert(-1 != m_bend);
  80. assert((std::size_t)m_bend <= sizeof(m_buffer));
  81. assert(m_bend > 0);
  82. m_bnext = 0;
  83. }
  84. void increment(){
  85. if(++m_bnext < m_bend)
  86. return;
  87. m_bend =
  88. m_bnext = 0;
  89. ++(this->base_reference());
  90. m_full = false;
  91. }
  92. // buffer to handle pending characters
  93. int m_bend;
  94. int m_bnext;
  95. char m_buffer[9];
  96. bool m_full;
  97. public:
  98. // make composible buy using templated constructor
  99. template<class T>
  100. mb_from_wchar(BOOST_PFTO_WRAPPER(T) start) :
  101. super_t(Base(BOOST_MAKE_PFTO_WRAPPER(static_cast<T>(start)))),
  102. m_bend(0),
  103. m_bnext(0),
  104. m_full(false)
  105. {}
  106. // intel 7.1 doesn't like default copy constructor
  107. mb_from_wchar(const mb_from_wchar & rhs) :
  108. super_t(rhs.base_reference()),
  109. m_bend(rhs.m_bend),
  110. m_bnext(rhs.m_bnext),
  111. m_full(rhs.m_full)
  112. {}
  113. };
  114. } // namespace iterators
  115. } // namespace archive
  116. } // namespace boost
  117. #endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP