1 | // (C) Copyright Jonathan Turkanis 2004 |
---|
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 | #include <boost/iostreams/detail/config/wide_streams.hpp> |
---|
8 | #ifdef BOOST_IOSTREAMS_NO_WIDE_STREAMS |
---|
9 | # error wide streams not supported on this platform |
---|
10 | #endif |
---|
11 | |
---|
12 | #include <algorithm> // equal. |
---|
13 | #include <locale> |
---|
14 | #include <string> |
---|
15 | #include <boost/config.hpp> // BOOST_DEDUCED_TYPENAME. |
---|
16 | #include <boost/iostreams/code_converter.hpp> |
---|
17 | #include <boost/iostreams/copy.hpp> |
---|
18 | #include <boost/iostreams/detail/add_facet.hpp> |
---|
19 | #include <boost/iostreams/device/back_inserter.hpp> |
---|
20 | #include <boost/iostreams/detail/config/windows_posix.hpp> |
---|
21 | #include <boost/iostreams/device/file.hpp> |
---|
22 | #if !defined(__COMO__) || !defined(BOOST_COMO_STRICT) |
---|
23 | # if defined(BOOST_IOSTREAMS_NO_LIB) || defined(BOOST_ALL_NO_LIB) |
---|
24 | # include "../src/file_descriptor.cpp" |
---|
25 | # else |
---|
26 | # include <boost/iostreams/device/file_descriptor.hpp> |
---|
27 | # endif |
---|
28 | #endif |
---|
29 | #include <boost/iostreams/stream.hpp> |
---|
30 | #include <boost/test/test_tools.hpp> |
---|
31 | #include <boost/test/unit_test.hpp> |
---|
32 | #include "detail/temp_file.hpp" |
---|
33 | |
---|
34 | // Include codevct facets |
---|
35 | |
---|
36 | #include "detail/null_padded_codecvt.hpp" |
---|
37 | #include "detail/utf8_codecvt_facet.hpp" |
---|
38 | #ifdef BOOST_IOSTREAMS_USE_DINKUM_COREX |
---|
39 | # include <codecvt/8859_1> |
---|
40 | # include <codecvt/8859_10> |
---|
41 | # include <codecvt/8859_13> |
---|
42 | # include <codecvt/8859_14> |
---|
43 | # include <codecvt/8859_15> |
---|
44 | # include <codecvt/8859_16> |
---|
45 | # include <codecvt/8859_2> |
---|
46 | # include <codecvt/8859_3> |
---|
47 | # include <codecvt/8859_4> |
---|
48 | # include <codecvt/8859_5> |
---|
49 | # include <codecvt/8859_6> |
---|
50 | # include <codecvt/8859_7> |
---|
51 | # include <codecvt/8859_8> |
---|
52 | # include <codecvt/8859_9> |
---|
53 | # include <codecvt/baltic> |
---|
54 | # include <codecvt/big5> |
---|
55 | # include <codecvt/cp037> |
---|
56 | # include <codecvt/cp1006> |
---|
57 | # include <codecvt/cp1026> |
---|
58 | # include <codecvt/cp1250> |
---|
59 | # include <codecvt/cp1251> |
---|
60 | # include <codecvt/cp1252> |
---|
61 | # include <codecvt/cp1253> |
---|
62 | # include <codecvt/cp1254> |
---|
63 | # include <codecvt/cp1255> |
---|
64 | # include <codecvt/cp1256> |
---|
65 | # include <codecvt/cp1257> |
---|
66 | # include <codecvt/cp1258> |
---|
67 | # include <codecvt/cp424> |
---|
68 | # include <codecvt/cp437> |
---|
69 | # include <codecvt/cp500> |
---|
70 | # include <codecvt/cp737> |
---|
71 | # include <codecvt/cp775> |
---|
72 | # include <codecvt/cp850> |
---|
73 | # include <codecvt/cp852> |
---|
74 | # include <codecvt/cp855> |
---|
75 | # include <codecvt/cp856> |
---|
76 | # include <codecvt/cp857> |
---|
77 | # include <codecvt/cp860> |
---|
78 | # include <codecvt/cp861> |
---|
79 | # include <codecvt/cp862> |
---|
80 | # include <codecvt/cp863> |
---|
81 | # include <codecvt/cp864> |
---|
82 | # include <codecvt/cp865> |
---|
83 | # include <codecvt/cp866> |
---|
84 | # include <codecvt/cp869> |
---|
85 | # include <codecvt/cp874> |
---|
86 | # include <codecvt/cp875> |
---|
87 | # include <codecvt/cp932> |
---|
88 | # include <codecvt/cp936> |
---|
89 | # include <codecvt/cp949> |
---|
90 | # include <codecvt/cp950> |
---|
91 | # include <codecvt/cyrillic> |
---|
92 | # include <codecvt/ebcdic> |
---|
93 | # include <codecvt/euc> |
---|
94 | # include <codecvt/euc_0208> |
---|
95 | # include <codecvt/gb12345> |
---|
96 | # include <codecvt/gb2312> |
---|
97 | # include <codecvt/greek> |
---|
98 | # include <codecvt/iceland> |
---|
99 | # include <codecvt/jis> |
---|
100 | # include <codecvt/jis_0208> |
---|
101 | # include <codecvt/jis0201> |
---|
102 | # include <codecvt/ksc5601> |
---|
103 | # include <codecvt/latin2> |
---|
104 | # include <codecvt/one_one> |
---|
105 | # include <codecvt/roman> |
---|
106 | # include <codecvt/sjis> |
---|
107 | # include <codecvt/sjis_0208> |
---|
108 | # include <codecvt/turkish> |
---|
109 | # include <codecvt/utf16> |
---|
110 | # include <codecvt/utf8> |
---|
111 | # include <codecvt/utf8_utf16> |
---|
112 | # include <codecvt/xjis> |
---|
113 | #endif // #ifdef BOOST_IOSTREAMS_USE_DINKUM_COREX] |
---|
114 | |
---|
115 | #include <iostream> |
---|
116 | |
---|
117 | using namespace std; |
---|
118 | using namespace boost::iostreams; |
---|
119 | using namespace boost::iostreams::detail; |
---|
120 | using namespace boost::iostreams::test; |
---|
121 | using boost::unit_test::test_suite; |
---|
122 | namespace io = boost::iostreams; |
---|
123 | |
---|
124 | const int max_length = 30; |
---|
125 | const unsigned int pattern_length = 100; |
---|
126 | const unsigned int pattern_reps = 100; |
---|
127 | |
---|
128 | template<typename Codecvt> |
---|
129 | bool valid_char(typename codecvt_intern<Codecvt>::type c) |
---|
130 | { |
---|
131 | typedef typename codecvt_state<Codecvt>::type state_type; |
---|
132 | typedef typename codecvt_intern<Codecvt>::type intern_type; |
---|
133 | Codecvt cvt; |
---|
134 | state_type state = state_type(); |
---|
135 | const intern_type* nint; |
---|
136 | char* next; |
---|
137 | char buf[max_length]; |
---|
138 | |
---|
139 | return cvt.out( state, &c, &c + 1, nint, |
---|
140 | buf, buf + max_length, next ) |
---|
141 | == |
---|
142 | codecvt_base::ok; |
---|
143 | } |
---|
144 | |
---|
145 | template<typename Codecvt> |
---|
146 | basic_string< |
---|
147 | BOOST_DEDUCED_TYPENAME |
---|
148 | codecvt_intern<Codecvt>::type |
---|
149 | > |
---|
150 | test_string() |
---|
151 | { |
---|
152 | typedef typename codecvt_intern<Codecvt>::type intern_type; |
---|
153 | std::basic_string<intern_type> pattern, result; |
---|
154 | for (intern_type c = 255; pattern.size() < pattern_length; --c) |
---|
155 | if (valid_char<Codecvt>(c)) |
---|
156 | pattern += c; |
---|
157 | result.reserve(pattern.size() * pattern_reps); |
---|
158 | for (int w = 0; w < pattern_reps; ++w) |
---|
159 | result += pattern; |
---|
160 | return result; |
---|
161 | } |
---|
162 | |
---|
163 | // Como can't compile file_descriptor.cpp in strict mode; this failure |
---|
164 | // is detected by file_descriptor_test.cpp. |
---|
165 | #if !defined(__COMO__) || !defined(BOOST_COMO_STRICT) |
---|
166 | typedef io::file_descriptor_source classic_file_source; |
---|
167 | typedef io::file_descriptor_sink classic_file_sink; |
---|
168 | #else |
---|
169 | struct classic_file_source : io::source { |
---|
170 | classic_file_source(const std::string& path) |
---|
171 | : file_(new filebuf) |
---|
172 | { |
---|
173 | file_->pubimbue(locale::classic()); |
---|
174 | file_->open(path.c_str(), BOOST_IOS::in | BOOST_IOS::binary); |
---|
175 | } |
---|
176 | streamsize read(char* s, streamsize n) { return file_->sgetn(s, n); } |
---|
177 | boost::shared_ptr<filebuf> file_; |
---|
178 | }; |
---|
179 | |
---|
180 | struct classic_file_sink : io::sink { |
---|
181 | classic_file_sink(const std::string& path) |
---|
182 | : file_(new filebuf) |
---|
183 | { |
---|
184 | file_->pubimbue(locale::classic()); |
---|
185 | file_->open(path.c_str(), BOOST_IOS::out | BOOST_IOS::binary); |
---|
186 | } |
---|
187 | streamsize write(const char* s, streamsize n) { return file_->sputn(s, n); } |
---|
188 | boost::shared_ptr<filebuf> file_; |
---|
189 | }; |
---|
190 | #endif |
---|
191 | |
---|
192 | template<typename Codecvt> |
---|
193 | bool codecvt_test1() |
---|
194 | { |
---|
195 | typedef basic_string< |
---|
196 | BOOST_DEDUCED_TYPENAME |
---|
197 | codecvt_intern<Codecvt>::type |
---|
198 | > string_type; |
---|
199 | typedef code_converter<classic_file_source, Codecvt> wide_file_source; |
---|
200 | typedef code_converter<classic_file_sink, Codecvt> wide_file_sink; |
---|
201 | |
---|
202 | BOOST_CHECK(Codecvt().max_length() <= max_length); |
---|
203 | temp_file temp; |
---|
204 | string_type test = test_string<Codecvt>(); |
---|
205 | stream<wide_file_sink> out(temp.name()); |
---|
206 | out.write(test.data(), static_cast<streamsize>(test.size())); |
---|
207 | out.close(); |
---|
208 | |
---|
209 | stream<wide_file_source> in(temp.name()); |
---|
210 | string_type test2; |
---|
211 | io::copy(in, io::back_inserter(test2)); |
---|
212 | |
---|
213 | return test == test2; |
---|
214 | } |
---|
215 | |
---|
216 | template<typename Codecvt> |
---|
217 | bool codecvt_test2() |
---|
218 | { |
---|
219 | typedef basic_string< |
---|
220 | BOOST_DEDUCED_TYPENAME |
---|
221 | codecvt_intern<Codecvt>::type |
---|
222 | > string_type; |
---|
223 | typedef code_converter<classic_file_source> wide_file_source; |
---|
224 | typedef code_converter<classic_file_sink> wide_file_sink; |
---|
225 | |
---|
226 | // Set global locale. |
---|
227 | locale loc = add_facet(locale(), new Codecvt); |
---|
228 | locale::global(loc); |
---|
229 | |
---|
230 | temp_file temp; |
---|
231 | string_type test = test_string<Codecvt>(); |
---|
232 | stream<wide_file_sink> out(temp.name()); |
---|
233 | out.write(test.data(), static_cast<streamsize>(test.size())); |
---|
234 | out.close(); |
---|
235 | |
---|
236 | stream<wide_file_source> in(temp.name()); |
---|
237 | string_type test2; |
---|
238 | io::copy(in, io::back_inserter(test2)); |
---|
239 | |
---|
240 | return test == test2; |
---|
241 | } |
---|
242 | |
---|
243 | template<typename Codecvt> |
---|
244 | bool codecvt_test() |
---|
245 | { |
---|
246 | return codecvt_test1<Codecvt>() && codecvt_test2<Codecvt>(); |
---|
247 | } |
---|
248 | |
---|
249 | void code_converter_test() |
---|
250 | { |
---|
251 | BOOST_CHECK((codecvt_test<utf8_codecvt_facet<wchar_t, char> >())); |
---|
252 | BOOST_CHECK(codecvt_test<null_padded_codecvt>()); |
---|
253 | BOOST_CHECK(codecvt_test<stateless_null_padded_codecvt>()); |
---|
254 | #ifdef BOOST_IOSTREAMS_USE_DINKUM_COREX |
---|
255 | using namespace Dinkum::conversions; |
---|
256 | BOOST_CHECK(codecvt_test< codecvt_8859_1<wchar_t> >()); |
---|
257 | BOOST_CHECK(codecvt_test< codecvt_8859_10<wchar_t> >()); |
---|
258 | BOOST_CHECK(codecvt_test< codecvt_8859_13<wchar_t> >()); |
---|
259 | BOOST_CHECK(codecvt_test< codecvt_8859_14<wchar_t> >()); |
---|
260 | BOOST_CHECK(codecvt_test< codecvt_8859_15<wchar_t> >()); |
---|
261 | BOOST_CHECK(codecvt_test< codecvt_8859_16<wchar_t> >()); |
---|
262 | BOOST_CHECK(codecvt_test< codecvt_8859_2<wchar_t> >()); |
---|
263 | BOOST_CHECK(codecvt_test< codecvt_8859_3<wchar_t> >()); |
---|
264 | BOOST_CHECK(codecvt_test< codecvt_8859_4<wchar_t> >()); |
---|
265 | BOOST_CHECK(codecvt_test< codecvt_8859_5<wchar_t> >()); |
---|
266 | BOOST_CHECK(codecvt_test< codecvt_8859_6<wchar_t> >()); |
---|
267 | BOOST_CHECK(codecvt_test< codecvt_8859_7<wchar_t> >()); |
---|
268 | BOOST_CHECK(codecvt_test< codecvt_8859_8<wchar_t> >()); |
---|
269 | BOOST_CHECK(codecvt_test< codecvt_8859_9<wchar_t> >()); |
---|
270 | BOOST_CHECK(codecvt_test< codecvt_baltic<wchar_t> >()); |
---|
271 | BOOST_CHECK(codecvt_test< codecvt_big5<wchar_t> >()); |
---|
272 | BOOST_CHECK(codecvt_test< codecvt_cp037<wchar_t> >()); |
---|
273 | BOOST_CHECK(codecvt_test< codecvt_cp1006<wchar_t> >()); |
---|
274 | BOOST_CHECK(codecvt_test< codecvt_cp1026<wchar_t> >()); |
---|
275 | BOOST_CHECK(codecvt_test< codecvt_cp1250<wchar_t> >()); |
---|
276 | BOOST_CHECK(codecvt_test< codecvt_cp1251<wchar_t> >()); |
---|
277 | BOOST_CHECK(codecvt_test< codecvt_cp1252<wchar_t> >()); |
---|
278 | BOOST_CHECK(codecvt_test< codecvt_cp1253<wchar_t> >()); |
---|
279 | BOOST_CHECK(codecvt_test< codecvt_cp1254<wchar_t> >()); |
---|
280 | BOOST_CHECK(codecvt_test< codecvt_cp1255<wchar_t> >()); |
---|
281 | BOOST_CHECK(codecvt_test< codecvt_cp1256<wchar_t> >()); |
---|
282 | BOOST_CHECK(codecvt_test< codecvt_cp1257<wchar_t> >()); |
---|
283 | BOOST_CHECK(codecvt_test< codecvt_cp1258<wchar_t> >()); |
---|
284 | BOOST_CHECK(codecvt_test< codecvt_cp424<wchar_t> >()); |
---|
285 | BOOST_CHECK(codecvt_test< codecvt_cp437<wchar_t> >()); |
---|
286 | BOOST_CHECK(codecvt_test< codecvt_cp500<wchar_t> >()); |
---|
287 | BOOST_CHECK(codecvt_test< codecvt_cp737<wchar_t> >()); |
---|
288 | BOOST_CHECK(codecvt_test< codecvt_cp775<wchar_t> >()); |
---|
289 | BOOST_CHECK(codecvt_test< codecvt_cp850<wchar_t> >()); |
---|
290 | BOOST_CHECK(codecvt_test< codecvt_cp852<wchar_t> >()); |
---|
291 | BOOST_CHECK(codecvt_test< codecvt_cp855<wchar_t> >()); |
---|
292 | BOOST_CHECK(codecvt_test< codecvt_cp856<wchar_t> >()); |
---|
293 | BOOST_CHECK(codecvt_test< codecvt_cp857<wchar_t> >()); |
---|
294 | BOOST_CHECK(codecvt_test< codecvt_cp860<wchar_t> >()); |
---|
295 | BOOST_CHECK(codecvt_test< codecvt_cp861<wchar_t> >()); |
---|
296 | BOOST_CHECK(codecvt_test< codecvt_cp862<wchar_t> >()); |
---|
297 | BOOST_CHECK(codecvt_test< codecvt_cp863<wchar_t> >()); |
---|
298 | BOOST_CHECK(codecvt_test< codecvt_cp864<wchar_t> >()); |
---|
299 | BOOST_CHECK(codecvt_test< codecvt_cp865<wchar_t> >()); |
---|
300 | BOOST_CHECK(codecvt_test< codecvt_cp866<wchar_t> >()); |
---|
301 | BOOST_CHECK(codecvt_test< codecvt_cp869<wchar_t> >()); |
---|
302 | BOOST_CHECK(codecvt_test< codecvt_cp874<wchar_t> >()); |
---|
303 | BOOST_CHECK(codecvt_test< codecvt_cp875<wchar_t> >()); |
---|
304 | BOOST_CHECK(codecvt_test< codecvt_cp932<wchar_t> >()); |
---|
305 | BOOST_CHECK(codecvt_test< codecvt_cp936<wchar_t> >()); |
---|
306 | BOOST_CHECK(codecvt_test< codecvt_cp949<wchar_t> >()); |
---|
307 | BOOST_CHECK(codecvt_test< codecvt_cp950<wchar_t> >()); |
---|
308 | BOOST_CHECK(codecvt_test< codecvt_cyrillic<wchar_t> >()); |
---|
309 | BOOST_CHECK(codecvt_test< codecvt_ebcdic<wchar_t> >()); |
---|
310 | BOOST_CHECK(codecvt_test< codecvt_euc<wchar_t> >()); |
---|
311 | BOOST_CHECK(codecvt_test< codecvt_euc_0208<wchar_t> >()); |
---|
312 | BOOST_CHECK(codecvt_test< codecvt_gb12345<wchar_t> >()); |
---|
313 | BOOST_CHECK(codecvt_test< codecvt_gb2312<wchar_t> >()); |
---|
314 | BOOST_CHECK(codecvt_test< codecvt_greek<wchar_t> >()); |
---|
315 | BOOST_CHECK(codecvt_test< codecvt_iceland<wchar_t> >()); |
---|
316 | BOOST_CHECK(codecvt_test< codecvt_jis<wchar_t> >()); |
---|
317 | BOOST_CHECK(codecvt_test< codecvt_jis_0208<wchar_t> >()); |
---|
318 | BOOST_CHECK(codecvt_test< codecvt_jis0201<wchar_t> >()); |
---|
319 | BOOST_CHECK(codecvt_test< codecvt_ksc5601<wchar_t> >()); |
---|
320 | BOOST_CHECK(codecvt_test< codecvt_latin2<wchar_t> >()); |
---|
321 | BOOST_CHECK(codecvt_test< codecvt_one_one<wchar_t> >()); |
---|
322 | BOOST_CHECK(codecvt_test< codecvt_roman<wchar_t> >()); |
---|
323 | BOOST_CHECK(codecvt_test< codecvt_sjis<wchar_t> >()); |
---|
324 | BOOST_CHECK(codecvt_test< codecvt_sjis_0208<wchar_t> >()); |
---|
325 | BOOST_CHECK(codecvt_test< codecvt_turkish<wchar_t> >()); |
---|
326 | BOOST_CHECK(codecvt_test< codecvt_utf16<wchar_t> >()); |
---|
327 | BOOST_CHECK(codecvt_test< codecvt_utf8<wchar_t> >()); |
---|
328 | BOOST_CHECK(codecvt_test< codecvt_utf8_utf16<wchar_t> >()); |
---|
329 | #endif |
---|
330 | } |
---|
331 | |
---|
332 | test_suite* init_unit_test_suite(int, char* []) |
---|
333 | { |
---|
334 | test_suite* test = BOOST_TEST_SUITE("code_converter test"); |
---|
335 | test->add(BOOST_TEST_CASE(&code_converter_test)); |
---|
336 | return test; |
---|
337 | } |
---|