1 | // (C) Copyright Jonathan Turkanis 2003.
|
---|
2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
---|
3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
---|
4 |
|
---|
5 | // See http://www.boost.org/libs/iostreams for documentation.
|
---|
6 |
|
---|
7 | // Contains the definition of the template codecvt_helper, useful for
|
---|
8 | // defining specializations of std::codecvt where state_type != mbstate_t.
|
---|
9 | // Compensates for the fact that some standard library implementations
|
---|
10 | // do not derive the primiary codecvt template from locale::facet or
|
---|
11 | // provide the correct member types and functions.
|
---|
12 |
|
---|
13 | // Usage:
|
---|
14 | //
|
---|
15 | // // In global namespace:
|
---|
16 | // BOOST_IOSTREAMS_CODECVT_SPEC(mystate)
|
---|
17 | //
|
---|
18 | // // In user namespace:
|
---|
19 | // template<typename Intern, typename Extern>
|
---|
20 | // struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... };
|
---|
21 | //
|
---|
22 | // // Or:
|
---|
23 | // struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... };
|
---|
24 | //
|
---|
25 | // Etc.
|
---|
26 |
|
---|
27 | #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
|
---|
28 | #define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED
|
---|
29 |
|
---|
30 | #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
---|
31 | # pragma once
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #include <boost/config.hpp> // Put size_t in std, BOOST_MSVC, Dinkum.
|
---|
35 | #include <boost/detail/workaround.hpp>
|
---|
36 | #include <algorithm> // min.
|
---|
37 | #include <cstddef> // size_t.
|
---|
38 | #include <locale> // locale, codecvt_base, codecvt.
|
---|
39 | #include <boost/iostreams/detail/config/codecvt.hpp>
|
---|
40 |
|
---|
41 | //------------------Definition of traits--------------------------------------//
|
---|
42 |
|
---|
43 | namespace boost { namespace iostreams { namespace detail {
|
---|
44 |
|
---|
45 | #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------//
|
---|
46 |
|
---|
47 | template<typename T>
|
---|
48 | struct codecvt_intern { typedef typename T::intern_type type; };
|
---|
49 |
|
---|
50 | template<typename T>
|
---|
51 | struct codecvt_extern { typedef typename T::extern_type type; };
|
---|
52 |
|
---|
53 | #else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------//
|
---|
54 |
|
---|
55 | template<typename T>
|
---|
56 | struct codecvt_intern { typedef typename T::from_type type; };
|
---|
57 |
|
---|
58 | template<typename T>
|
---|
59 | struct codecvt_extern { typedef typename T::to_type type; };
|
---|
60 |
|
---|
61 | #endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------//
|
---|
62 |
|
---|
63 | template<typename T>
|
---|
64 | struct codecvt_state { typedef typename T::state_type type; };
|
---|
65 |
|
---|
66 | } } } // End namespaces detail, iostreams, boost.
|
---|
67 |
|
---|
68 | //------------------Definition of codecvt_impl--------------------------------//
|
---|
69 |
|
---|
70 | #if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \
|
---|
71 | defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \
|
---|
72 | defined(BOOST_IOSTREAMS_NO_LOCALE) \
|
---|
73 | /**/
|
---|
74 |
|
---|
75 | namespace boost { namespace iostreams { namespace detail {
|
---|
76 |
|
---|
77 | template<typename Intern, typename Extern, typename State>
|
---|
78 | struct codecvt_impl : std::locale::facet, std::codecvt_base {
|
---|
79 | public:
|
---|
80 | typedef Intern intern_type;
|
---|
81 | typedef Extern extern_type;
|
---|
82 | typedef State state_type;
|
---|
83 |
|
---|
84 | codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { }
|
---|
85 |
|
---|
86 | std::codecvt_base::result
|
---|
87 | in( State& state, const Extern* first1, const Extern* last1,
|
---|
88 | const Extern*& next1, Intern* first2, Intern* last2,
|
---|
89 | Intern*& next2 ) const
|
---|
90 | {
|
---|
91 | return do_in(state, first1, last1, next1, first2, last2, next2);
|
---|
92 | }
|
---|
93 |
|
---|
94 | std::codecvt_base::result
|
---|
95 | out( State& state, const Intern* first1, const Intern* last1,
|
---|
96 | const Intern*& next1, Extern* first2, Extern* last2,
|
---|
97 | Extern*& next2 ) const
|
---|
98 | {
|
---|
99 | return do_out(state, first1, last1, next1, first2, last2, next2);
|
---|
100 | }
|
---|
101 |
|
---|
102 | std::codecvt_base::result
|
---|
103 | unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const
|
---|
104 | {
|
---|
105 | return do_unshift(state, first2, last2, next2);
|
---|
106 | }
|
---|
107 |
|
---|
108 | bool always_noconv() const throw() { return do_always_noconv(); }
|
---|
109 |
|
---|
110 | int max_length() const throw() { return do_max_length(); }
|
---|
111 |
|
---|
112 | int encoding() const throw() { return do_encoding(); }
|
---|
113 |
|
---|
114 | int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state,
|
---|
115 | const Extern* first1, const Extern* last1,
|
---|
116 | std::size_t len2 ) const throw()
|
---|
117 | {
|
---|
118 | return do_length(state, first1, last1, len2);
|
---|
119 | }
|
---|
120 | protected:
|
---|
121 | std::codecvt_base::result
|
---|
122 | virtual do_in( State&, const Extern*, const Extern*, const Extern*&,
|
---|
123 | Intern*, Intern*, Intern*& ) const
|
---|
124 | {
|
---|
125 | return std::codecvt_base::noconv;
|
---|
126 | }
|
---|
127 |
|
---|
128 | std::codecvt_base::result
|
---|
129 | virtual do_out( State&, const Intern*, const Intern*, const Intern*&,
|
---|
130 | Extern*, Extern*, Extern*& ) const
|
---|
131 | {
|
---|
132 | return std::codecvt_base::noconv;
|
---|
133 | }
|
---|
134 |
|
---|
135 | std::codecvt_base::result
|
---|
136 | virtual do_unshift( State& state, Extern* first2, Extern* last2,
|
---|
137 | Extern*& next2 ) const
|
---|
138 | {
|
---|
139 | return std::codecvt_base::ok;
|
---|
140 | }
|
---|
141 |
|
---|
142 | virtual bool do_always_noconv() const throw() { return true; }
|
---|
143 |
|
---|
144 | virtual int do_max_length() const throw() { return 1; }
|
---|
145 |
|
---|
146 | virtual int do_encoding() const throw() { return 1; }
|
---|
147 |
|
---|
148 | virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& 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;
|
---|
221 | 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
|
---|
229 | int max_length() const throw() { return do_max_length(); }
|
---|
230 | protected:
|
---|
231 | 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
|
---|