1 // Copyright (C) 2017-2018 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 // { dg-do run { target c++11 } }
19 
20 #include <locale>
21 #include <codecvt>
22 #include <testsuite_hooks.h>
23 
24 using std::codecvt_base;
25 using std::codecvt_mode;
26 using std::codecvt_utf16;
27 using std::wstring_convert;
28 using std::mbstate_t;
29 
30 constexpr codecvt_mode
operator |(codecvt_mode m1,codecvt_mode m2)31 operator|(codecvt_mode m1, codecvt_mode m2)
32 {
33   using underlying = std::underlying_type<codecvt_mode>::type;
34   return static_cast<codecvt_mode>(static_cast<underlying>(m1) | m2);
35 }
36 
37 // Read/write UTF-16 code units from data not correctly aligned for char16_t
38 
39 void
test01()40 test01()
41 {
42   mbstate_t st;
43   constexpr codecvt_mode m = std::consume_header|std::generate_header;
44   codecvt_utf16<char16_t, 0x10FFFF, m> conv;
45   const char src[] = "-\xFE\xFF\0\x61\xAB\xCD";
46   const char* const src_end = src + 7;
47 
48   int len = conv.length(st, src + 1, src_end, 1);
49   VERIFY( len == 4 );
50   len = conv.length(st, src + 1, src_end, 2);
51   VERIFY( len == 6 );
52 
53   char16_t dst[2];
54   char16_t* const dst_end = dst + 2;
55   char16_t* dst_next;
56   const char* src_cnext;
57   auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
58   VERIFY( res == codecvt_base::ok );
59   VERIFY( dst[0] == 0x0061 );
60   VERIFY( dst[1] == 0xabcd );
61   VERIFY( src_cnext == src_end );
62   VERIFY( dst_next == dst_end );
63 
64   char out[sizeof(src)] = { src[0] };
65   char* const out_end = out + 7;
66   char* out_next;
67   const char16_t* dst_cnext;
68   res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
69   VERIFY( res == codecvt_base::ok );
70   VERIFY( out_next == out_end );
71   VERIFY( dst_cnext == dst_end );
72   VERIFY( out[1] == src[1] );
73   VERIFY( out[2] == src[2] );
74   VERIFY( out[3] == src[3] );
75   VERIFY( out[4] == src[4] );
76   VERIFY( out[5] == src[5] );
77   VERIFY( out[6] == src[6] );
78 
79   codecvt_utf16<char16_t, 0x10FFFF, m|std::little_endian> conv_le;
80 
81   len = conv_le.length(st, src + 1, src_end, 1);
82   VERIFY( len == 4 );
83   len = conv_le.length(st, src + 1, src_end, 2);
84   VERIFY( len == 6 );
85 
86   res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
87   VERIFY( res == codecvt_base::ok );
88   VERIFY( dst[0] == 0x0061 );
89   VERIFY( dst[1] == 0xabcd );
90   VERIFY( src_cnext == src_end );
91   VERIFY( dst_next == dst_end );
92 
93   res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
94   VERIFY( res == codecvt_base::ok );
95   VERIFY( out_next == out_end );
96   VERIFY( dst_cnext == dst_end );
97   VERIFY( out[1] == src[2] );
98   VERIFY( out[2] == src[1] );
99   VERIFY( out[3] == src[4] );
100   VERIFY( out[4] == src[3] );
101   VERIFY( out[5] == src[6] );
102   VERIFY( out[6] == src[5] );
103 }
104 
105 void
test02()106 test02()
107 {
108   mbstate_t st;
109   constexpr codecvt_mode m = std::consume_header|std::generate_header;
110   codecvt_utf16<char32_t, 0x10FFFF, m> conv;
111   const char src[] = "-\xFE\xFF\0\x61\xAB\xCD\xD8\x08\xDF\x45";
112   const char* const src_end = src + 11;
113 
114   int len = conv.length(st, src + 1, src_end, 1);
115   VERIFY( len == 4 );
116   len = conv.length(st, src + 1, src_end, 2);
117   VERIFY( len == 6 );
118   len = conv.length(st, src + 1, src_end, -1ul);
119   VERIFY( len == 10 );
120 
121   char32_t dst[3];
122   char32_t* const dst_end = dst + 3;
123   char32_t* dst_next;
124   const char* src_cnext;
125   auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
126   VERIFY( res == codecvt_base::ok );
127   VERIFY( dst[0] == 0x0061 );
128   VERIFY( dst[1] == 0xabcd );
129   VERIFY( dst[2] == 0x012345 );
130   VERIFY( src_cnext == src_end );
131   VERIFY( dst_next == dst_end );
132 
133   char out[sizeof(src)] = { src[0] };
134   char* const out_end = out + 11;
135   char* out_next;
136   const char32_t* dst_cnext;
137   res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
138   VERIFY( res == codecvt_base::ok );
139   VERIFY( out_next == out_end );
140   VERIFY( dst_cnext == dst_end );
141   VERIFY( out[1] == src[1] );
142   VERIFY( out[2] == src[2] );
143   VERIFY( out[3] == src[3] );
144   VERIFY( out[4] == src[4] );
145   VERIFY( out[5] == src[5] );
146   VERIFY( out[6] == src[6] );
147   VERIFY( out[7] == src[7] );
148   VERIFY( out[8] == src[8] );
149   VERIFY( out[9] == src[9] );
150   VERIFY( out[10] == src[10] );
151 
152   codecvt_utf16<char32_t, 0x10FFFF, m|std::little_endian> conv_le;
153 
154   len = conv_le.length(st, src + 1, src_end, 1);
155   VERIFY( len == 4 );
156   len = conv_le.length(st, src + 1, src_end, 2);
157   VERIFY( len == 6 );
158   len = conv.length(st, src + 1, src_end, -1ul);
159   VERIFY( len == 10 );
160 
161   res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
162   VERIFY( res == codecvt_base::ok );
163   VERIFY( dst[0] == 0x0061 );
164   VERIFY( dst[1] == 0xabcd );
165   VERIFY( dst[2] == 0x012345 );
166   VERIFY( src_cnext == src_end );
167   VERIFY( dst_next == dst_end );
168 
169   res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
170   VERIFY( res == codecvt_base::ok );
171   VERIFY( out_next == out_end );
172   VERIFY( dst_cnext == dst_end );
173   VERIFY( out[1] == src[2] );
174   VERIFY( out[2] == src[1] );
175   VERIFY( out[3] == src[4] );
176   VERIFY( out[4] == src[3] );
177   VERIFY( out[5] == src[6] );
178   VERIFY( out[6] == src[5] );
179   VERIFY( out[7] == src[8] );
180   VERIFY( out[8] == src[7] );
181   VERIFY( out[9] == src[10] );
182   VERIFY( out[10] == src[9] );
183 }
184 
185 void
test03()186 test03()
187 {
188 #ifdef _GLIBCXX_USE_WCHAR_T
189   mbstate_t st;
190   constexpr codecvt_mode m = std::consume_header|std::generate_header;
191   codecvt_utf16<wchar_t, 0x10FFFF, m> conv;
192   const char src[] = "-\xFE\xFF\0\x61\xAB\xCD\xD8\x08\xDF\x45";
193   const size_t in_len = sizeof(wchar_t) == 4 ? 11 : 7;
194   const size_t out_len = sizeof(wchar_t) == 4 ? 3 : 2;
195   const char* const src_end = src + in_len;
196 
197   int len = conv.length(st, src + 1, src_end, 1);
198   VERIFY( len == 4 );
199   len = conv.length(st, src + 1, src_end, 2);
200   VERIFY( len == 6 );
201   if (sizeof(wchar_t) == 4)
202   {
203     len = conv.length(st, src + 1, src_end, -1ul);
204     VERIFY( len == 10 );
205   }
206 
207   wchar_t dst[out_len];
208   wchar_t* const dst_end = dst + out_len;
209   wchar_t* dst_next;
210   const char* src_cnext;
211   auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
212   VERIFY( res == codecvt_base::ok );
213   VERIFY( dst[0] == 0x0061 );
214   VERIFY( dst[1] == 0xabcd );
215   if (sizeof(wchar_t) == 4)
216     VERIFY( dst[2] == 0x012345 );
217   VERIFY( src_cnext == src_end );
218   VERIFY( dst_next == dst_end );
219 
220   char out[sizeof(src)] = { src[0] };
221   char* const out_end = out + in_len;
222   char* out_next;
223   const wchar_t* dst_cnext;
224   res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
225   VERIFY( res == codecvt_base::ok );
226   VERIFY( out_next == out_end );
227   VERIFY( dst_cnext == dst_end );
228   VERIFY( out[1] == src[1] );
229   VERIFY( out[2] == src[2] );
230   VERIFY( out[3] == src[3] );
231   VERIFY( out[4] == src[4] );
232   VERIFY( out[5] == src[5] );
233   VERIFY( out[6] == src[6] );
234   if (sizeof(wchar_t) == 4)
235   {
236     VERIFY( out[7] == src[7] );
237     VERIFY( out[8] == src[8] );
238     VERIFY( out[9] == src[9] );
239     VERIFY( out[10] == src[10] );
240   }
241 
242   codecvt_utf16<wchar_t, 0x10FFFF, m|std::little_endian> conv_le;
243 
244   len = conv_le.length(st, src + 1, src_end, 1);
245   VERIFY( len == 4 );
246   len = conv_le.length(st, src + 1, src_end, 2);
247   VERIFY( len == 6 );
248   if (sizeof(wchar_t) == 4)
249   {
250     len = conv.length(st, src + 1, src_end, -1ul);
251     VERIFY( len == 10 );
252   }
253 
254   res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
255   VERIFY( res == codecvt_base::ok );
256   VERIFY( dst[0] == 0x0061 );
257   VERIFY( dst[1] == 0xabcd );
258   if (sizeof(wchar_t) == 4)
259     VERIFY( dst[2] == 0x012345 );
260   VERIFY( src_cnext == src_end );
261   VERIFY( dst_next == dst_end );
262 
263   res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
264   VERIFY( res == codecvt_base::ok );
265   VERIFY( out_next == out_end );
266   VERIFY( dst_cnext == dst_end );
267   VERIFY( out[1] == src[2] );
268   VERIFY( out[2] == src[1] );
269   VERIFY( out[3] == src[4] );
270   VERIFY( out[4] == src[3] );
271   VERIFY( out[5] == src[6] );
272   VERIFY( out[6] == src[5] );
273   if (sizeof(wchar_t) == 4)
274   {
275     VERIFY( out[7] == src[8] );
276     VERIFY( out[8] == src[7] );
277     VERIFY( out[9] == src[10] );
278     VERIFY( out[10] == src[9] );
279   }
280 #endif
281 }
282 
283 int
main()284 main()
285 {
286   test01();
287   test02();
288   test03();
289 }
290