mb_from_wchar.hpp 3.7 KB

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