1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) 2 // (C) Copyright 2003-2007 Jonathan Turkanis 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) 5 6 // See http://www.boost.org/libs/iostreams for documentation. 7 8 // Contains the definition of the template codecvt_helper, useful for 9 // defining specializations of std::codecvt where state_type != mbstate_t. 10 // Compensates for the fact that some standard library implementations 11 // do not derive the primiary codecvt template from locale::facet or 12 // provide the correct member types and functions. 13 14 // Usage: 15 // 16 // // In global namespace: 17 // BOOST_IOSTREAMS_CODECVT_SPEC(mystate) 18 // 19 // // In user namespace: 20 // template<typename Intern, typename Extern> 21 // struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... }; 22 // 23 // // Or: 24 // struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... }; 25 // 26 // Etc. 27 28 #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED 29 #define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED 30 31 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 32 # pragma once 33 #endif 34 35 #include <boost/config.hpp> // Put size_t in std, BOOST_MSVC, Dinkum. 36 #include <boost/detail/workaround.hpp> 37 #include <algorithm> // min. 38 #include <cstddef> // size_t. 39 #include <locale> // locale, codecvt_base, codecvt. 40 #include <boost/iostreams/detail/config/codecvt.hpp> 41 42 //------------------Definition of traits--------------------------------------// 43 44 namespace boost { namespace iostreams { namespace detail { 45 46 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------// 47 48 template<typename T> 49 struct codecvt_intern { typedef typename T::intern_type type; }; 50 51 template<typename T> 52 struct codecvt_extern { typedef typename T::extern_type type; }; 53 54 #else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------// 55 56 template<typename T> 57 struct codecvt_intern { typedef typename T::from_type type; }; 58 59 template<typename T> 60 struct codecvt_extern { typedef typename T::to_type type; }; 61 62 #endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------// 63 64 template<typename T> 65 struct codecvt_state { typedef typename T::state_type type; }; 66 67 } } } // End namespaces detail, iostreams, boost. 68 69 //------------------Definition of codecvt_impl--------------------------------// 70 71 #if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ 72 defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \ 73 defined(BOOST_IOSTREAMS_NO_LOCALE) \ 74 /**/ 75 76 namespace boost { namespace iostreams { namespace detail { 77 78 template<typename Intern, typename Extern, typename State> 79 struct codecvt_impl : std::locale::facet, std::codecvt_base { 80 public: 81 typedef Intern intern_type; 82 typedef Extern extern_type; 83 typedef State state_type; 84 codecvt_implboost::iostreams::detail::codecvt_impl85 codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { } 86 87 std::codecvt_base::result inboost::iostreams::detail::codecvt_impl88 in( State& state, const Extern* first1, const Extern* last1, 89 const Extern*& next1, Intern* first2, Intern* last2, 90 Intern*& next2 ) const 91 { 92 return do_in(state, first1, last1, next1, first2, last2, next2); 93 } 94 95 std::codecvt_base::result outboost::iostreams::detail::codecvt_impl96 out( State& state, const Intern* first1, const Intern* last1, 97 const Intern*& next1, Extern* first2, Extern* last2, 98 Extern*& next2 ) const 99 { 100 return do_out(state, first1, last1, next1, first2, last2, next2); 101 } 102 103 std::codecvt_base::result unshiftboost::iostreams::detail::codecvt_impl104 unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const 105 { 106 return do_unshift(state, first2, last2, next2); 107 } 108 always_noconvboost::iostreams::detail::codecvt_impl109 bool always_noconv() const throw() { return do_always_noconv(); } 110 max_lengthboost::iostreams::detail::codecvt_impl111 int max_length() const throw() { return do_max_length(); } 112 encodingboost::iostreams::detail::codecvt_impl113 int encoding() const throw() { return do_encoding(); } 114 lengthboost::iostreams::detail::codecvt_impl115 int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state, 116 const Extern* first1, const Extern* last1, 117 std::size_t len2 ) const throw() 118 { 119 return do_length(state, first1, last1, len2); 120 } 121 protected: 122 std::codecvt_base::result do_inboost::iostreams::detail::codecvt_impl123 virtual do_in( State&, const Extern*, const Extern*, const Extern*&, 124 Intern*, Intern*, Intern*& ) const 125 { 126 return std::codecvt_base::noconv; 127 } 128 129 std::codecvt_base::result do_outboost::iostreams::detail::codecvt_impl130 virtual do_out( State&, const Intern*, const Intern*, const Intern*&, 131 Extern*, Extern*, Extern*& ) const 132 { 133 return std::codecvt_base::noconv; 134 } 135 136 std::codecvt_base::result do_unshiftboost::iostreams::detail::codecvt_impl137 virtual do_unshift(State&, Extern*, Extern*, Extern*&) const 138 { 139 return std::codecvt_base::ok; 140 } 141 do_always_noconvboost::iostreams::detail::codecvt_impl142 virtual bool do_always_noconv() const throw() { return true; } 143 do_max_lengthboost::iostreams::detail::codecvt_impl144 virtual int do_max_length() const throw() { return 1; } 145 do_encodingboost::iostreams::detail::codecvt_impl146 virtual int do_encoding() const throw() { return 1; } 147 do_lengthboost::iostreams::detail::codecvt_impl148 virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&, 149 const Extern* first1, const Extern* last1, 150 std::size_t len2 ) const throw() 151 { 152 return (std::min)(static_cast<std::size_t>(last1 - first1), len2); 153 } 154 }; 155 156 } } } // End namespaces detail, iostreams, boost. 157 158 #endif // no primary codecvt definition, empty definition. 159 160 //------------------Definition of BOOST_IOSTREAMS_CODECVT_SPEC----------------// 161 162 #if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ 163 defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \ 164 /**/ 165 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 166 # define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ 167 namespace std { \ 168 template<typename Intern, typename Extern> \ 169 class codecvt<Intern, Extern, state> \ 170 : public ::boost::iostreams::detail::codecvt_impl< \ 171 Intern, Extern, state \ 172 > \ 173 { \ 174 public: \ 175 codecvt(std::size_t refs = 0) \ 176 : ::boost::iostreams::detail::codecvt_impl< \ 177 Intern, Extern, state \ 178 >(refs) \ 179 { } \ 180 static std::locale::id id; \ 181 }; \ 182 template<typename Intern, typename Extern> \ 183 std::locale::id codecvt<Intern, Extern, state>::id; \ 184 } \ 185 /**/ 186 # else 187 # define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ 188 namespace std { \ 189 template<> \ 190 class codecvt<wchar_t, char, state> \ 191 : public ::boost::iostreams::detail::codecvt_impl< \ 192 wchar_t, char, state \ 193 > \ 194 { \ 195 public: \ 196 codecvt(std::size_t refs = 0) \ 197 : ::boost::iostreams::detail::codecvt_impl< \ 198 wchar_t, char, state \ 199 >(refs) \ 200 { } \ 201 static std::locale::id id; \ 202 }; \ 203 template<> \ 204 std::locale::id codecvt<wchar_t, char, state>::id; \ 205 } \ 206 /**/ 207 # endif 208 #else 209 # define BOOST_IOSTREAMS_CODECVT_SPEC(state) 210 #endif // no primary codecvt definition, or empty definition. 211 212 namespace boost { namespace iostreams { namespace detail { 213 214 //------------------Definition of codecvt_helper------------------------------// 215 216 template<typename Intern, typename Extern, typename State> 217 struct codecvt_helper : std::codecvt<Intern, Extern, State> { 218 typedef Intern intern_type; 219 typedef Extern extern_type; 220 typedef State state_type; codecvt_helperboost::iostreams::detail::codecvt_helper221 codecvt_helper(std::size_t refs = 0) 222 #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T) 223 : std::codecvt<Intern, Extern, State>(refs) 224 #else 225 : std::codecvt<Intern, Extern, State>() 226 #endif 227 { } 228 #ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH max_lengthboost::iostreams::detail::codecvt_helper229 int max_length() const throw() { return do_max_length(); } 230 protected: do_max_lengthboost::iostreams::detail::codecvt_helper231 virtual int do_max_length() const throw() { return 1; } 232 #endif 233 }; 234 235 } } } // End namespaces detail, iostreams, boost. 236 237 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED 238