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