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