1 // Copyright (C) 2017-2025 Free Software Foundation, Inc.
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)
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.
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/>.
18 // { dg-do run { target c++11 } }
22 #include <testsuite_hooks.h>
24 using std::codecvt_base
;
25 using std::codecvt_mode
;
26 using std::codecvt_utf16
;
27 using std::wstring_convert
;
30 constexpr codecvt_mode
31 operator|(codecvt_mode m1
, codecvt_mode m2
)
33 using underlying
= std::underlying_type
<codecvt_mode
>::type
;
34 return static_cast<codecvt_mode
>(static_cast<underlying
>(m1
) | m2
);
37 // Read/write UTF-16 code units from data not correctly aligned for char16_t
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;
48 int len
= conv
.length(st
, src
+ 1, src_end
, 1);
50 len
= conv
.length(st
, src
+ 1, src_end
, 2);
54 char16_t
* const dst_end
= dst
+ 2;
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
);
64 char out
[sizeof(src
)] = { src
[0] };
65 char* const out_end
= out
+ 7;
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] );
79 codecvt_utf16
<char16_t
, 0x10FFFF, m
|std::little_endian
> conv_le
;
81 len
= conv_le
.length(st
, src
+ 1, src_end
, 1);
83 len
= conv_le
.length(st
, src
+ 1, src_end
, 2);
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
);
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] );
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;
114 int len
= conv
.length(st
, src
+ 1, src_end
, 1);
116 len
= conv
.length(st
, src
+ 1, src_end
, 2);
118 len
= conv
.length(st
, src
+ 1, src_end
, -1ul);
122 char32_t
* const dst_end
= dst
+ 3;
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
);
133 char out
[sizeof(src
)] = { src
[0] };
134 char* const out_end
= out
+ 11;
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] );
152 codecvt_utf16
<char32_t
, 0x10FFFF, m
|std::little_endian
> conv_le
;
154 len
= conv_le
.length(st
, src
+ 1, src_end
, 1);
156 len
= conv_le
.length(st
, src
+ 1, src_end
, 2);
158 len
= conv
.length(st
, src
+ 1, src_end
, -1ul);
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
);
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] );
188 #ifdef _GLIBCXX_USE_WCHAR_T
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
;
197 int len
= conv
.length(st
, src
+ 1, src_end
, 1);
199 len
= conv
.length(st
, src
+ 1, src_end
, 2);
201 if (sizeof(wchar_t) == 4)
203 len
= conv
.length(st
, src
+ 1, src_end
, -1ul);
207 wchar_t dst
[out_len
];
208 wchar_t* const dst_end
= dst
+ out_len
;
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
);
220 char out
[sizeof(src
)] = { src
[0] };
221 char* const out_end
= out
+ in_len
;
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)
236 VERIFY( out
[7] == src
[7] );
237 VERIFY( out
[8] == src
[8] );
238 VERIFY( out
[9] == src
[9] );
239 VERIFY( out
[10] == src
[10] );
242 codecvt_utf16
<wchar_t, 0x10FFFF, m
|std::little_endian
> conv_le
;
244 len
= conv_le
.length(st
, src
+ 1, src_end
, 1);
246 len
= conv_le
.length(st
, src
+ 1, src_end
, 2);
248 if (sizeof(wchar_t) == 4)
250 len
= conv
.length(st
, src
+ 1, src_end
, -1ul);
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
);
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)
275 VERIFY( out
[7] == src
[8] );
276 VERIFY( out
[8] == src
[7] );
277 VERIFY( out
[9] == src
[10] );
278 VERIFY( out
[10] == src
[9] );