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) 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 # define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ 166 namespace std { \ 167 template<typename Intern, typename Extern> \ 168 class codecvt<Intern, Extern, state> \ 169 : public ::boost::iostreams::detail::codecvt_impl< \ 170 Intern, Extern, state \ 171 > \ 172 { \ 173 public: \ 174 codecvt(std::size_t refs = 0) \ 175 : ::boost::iostreams::detail::codecvt_impl< \ 176 Intern, Extern, state \ 177 >(refs) \ 178 { } \ 179 static std::locale::id id; \ 180 }; \ 181 template<typename Intern, typename Extern> \ 182 std::locale::id codecvt<Intern, Extern, state>::id; \ 183 } \ 184 /**/ 185 #else 186 # define BOOST_IOSTREAMS_CODECVT_SPEC(state) 187 #endif // no primary codecvt definition, or empty definition. 188 189 namespace boost { namespace iostreams { namespace detail { 190 191 //------------------Definition of codecvt_helper------------------------------// 192 193 template<typename Intern, typename Extern, typename State> 194 struct codecvt_helper : std::codecvt<Intern, Extern, State> { 195 typedef Intern intern_type; 196 typedef Extern extern_type; 197 typedef State state_type; codecvt_helperboost::iostreams::detail::codecvt_helper198 codecvt_helper(std::size_t refs = 0) 199 #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T) 200 : std::codecvt<Intern, Extern, State>(refs) 201 #else 202 : std::codecvt<Intern, Extern, State>() 203 #endif 204 { } 205 #ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH max_lengthboost::iostreams::detail::codecvt_helper206 int max_length() const throw() { return do_max_length(); } 207 protected: do_max_lengthboost::iostreams::detail::codecvt_helper208 virtual int do_max_length() const throw() { return 1; } 209 #endif 210 }; 211 212 } } } // End namespaces detail, iostreams, boost. 213 214 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED 215