]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 22_locale / codecvt / codecvt_utf16 / misaligned.cc
CommitLineData
a945c346 1// Copyright (C) 2017-2024 Free Software Foundation, Inc.
d951e75d
JW
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
24using std::codecvt_base;
25using std::codecvt_mode;
26using std::codecvt_utf16;
27using std::wstring_convert;
28using std::mbstate_t;
29
30constexpr codecvt_mode
31operator|(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
39void
40test01()
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
105void
106test02()
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
185void
186test03()
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
283int
284main()
285{
286 test01();
287 test02();
288 test03();
289}