mb_from_wchar.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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)
  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 <boost/assert.hpp>
  15. #include <cstddef> // size_t
  16. #include <cstring> // memcpy
  17. #ifndef BOOST_NO_CWCHAR
  18. #include <cwchar> // mbstate_t
  19. #endif
  20. #include <boost/config.hpp>
  21. #if defined(BOOST_NO_STDC_NAMESPACE)
  22. namespace std{
  23. using ::mbstate_t;
  24. using ::memcpy;
  25. } // namespace std
  26. #endif
  27. #include <boost/archive/detail/utf8_codecvt_facet.hpp>
  28. #include <boost/iterator/iterator_adaptor.hpp>
  29. namespace boost {
  30. namespace archive {
  31. namespace iterators {
  32. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  33. // class used by text archives to translate wide strings and to char
  34. // strings of the currently selected locale
  35. template<class Base> // the input iterator
  36. class mb_from_wchar
  37. : public boost::iterator_adaptor<
  38. mb_from_wchar<Base>,
  39. Base,
  40. wchar_t,
  41. single_pass_traversal_tag,
  42. char
  43. >
  44. {
  45. friend class boost::iterator_core_access;
  46. typedef typename boost::iterator_adaptor<
  47. mb_from_wchar<Base>,
  48. Base,
  49. wchar_t,
  50. single_pass_traversal_tag,
  51. char
  52. > super_t;
  53. typedef mb_from_wchar<Base> this_t;
  54. char dereference_impl() {
  55. if(! m_full){
  56. fill();
  57. m_full = true;
  58. }
  59. return m_buffer[m_bnext];
  60. }
  61. char dereference() const {
  62. return (const_cast<this_t *>(this))->dereference_impl();
  63. }
  64. // test for iterator equality
  65. bool equal(const mb_from_wchar<Base> & rhs) const {
  66. // once the value is filled, the base_reference has been incremented
  67. // so don't permit comparison anymore.
  68. return
  69. 0 == m_bend
  70. && 0 == m_bnext
  71. && this->base_reference() == rhs.base_reference()
  72. ;
  73. }
  74. void fill(){
  75. wchar_t value = * this->base_reference();
  76. const wchar_t *wend;
  77. char *bend;
  78. BOOST_VERIFY(
  79. m_codecvt_facet.out(
  80. m_mbs,
  81. & value, & value + 1, wend,
  82. m_buffer, m_buffer + sizeof(m_buffer), bend
  83. )
  84. ==
  85. std::codecvt_base::ok
  86. );
  87. m_bnext = 0;
  88. m_bend = bend - m_buffer;
  89. }
  90. void increment(){
  91. if(++m_bnext < m_bend)
  92. return;
  93. m_bend =
  94. m_bnext = 0;
  95. ++(this->base_reference());
  96. m_full = false;
  97. }
  98. boost::archive::detail::utf8_codecvt_facet m_codecvt_facet;
  99. std::mbstate_t m_mbs;
  100. // buffer to handle pending characters
  101. char m_buffer[9 /* MB_CUR_MAX */];
  102. std::size_t m_bend;
  103. std::size_t m_bnext;
  104. bool m_full;
  105. public:
  106. // make composable by using templated constructor
  107. template<class T>
  108. mb_from_wchar(T start) :
  109. super_t(Base(static_cast< T >(start))),
  110. m_mbs(std::mbstate_t()),
  111. m_bend(0),
  112. m_bnext(0),
  113. m_full(false)
  114. {}
  115. // intel 7.1 doesn't like default copy constructor
  116. mb_from_wchar(const mb_from_wchar & rhs) :
  117. super_t(rhs.base_reference()),
  118. m_mbs(rhs.m_mbs),
  119. m_bend(rhs.m_bend),
  120. m_bnext(rhs.m_bnext),
  121. m_full(rhs.m_full)
  122. {
  123. std::memcpy(m_buffer, rhs.m_buffer, sizeof(m_buffer));
  124. }
  125. };
  126. } // namespace iterators
  127. } // namespace archive
  128. } // namespace boost
  129. #endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP