1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <codecvt>
10 
11 // template <class Elem, unsigned long Maxcode = 0x10ffff,
12 //           codecvt_mode Mode = (codecvt_mode)0>
13 // class codecvt_utf8_utf16
14 //     : public codecvt<Elem, char, mbstate_t>
15 // {
16 //     // unspecified
17 // };
18 
19 // result
20 // out(stateT& state,
21 //     const internT* from, const internT* from_end, const internT*& from_next,
22 //     externT* to, externT* to_end, externT*& to_next) const;
23 
24 #include <codecvt>
25 #include <cassert>
26 
27 #include "test_macros.h"
28 
29 template <class CharT, size_t = sizeof(CharT)>
30 struct TestHelper;
31 template <class CharT>
32 struct TestHelper<CharT, 2> {
33   static void test();
34 };
35 template <class CharT>
36 struct TestHelper<CharT, 4> {
37   static void test();
38 };
39 
40 template <class CharT>
41 void TestHelper<CharT, 2>::test() {
42   {
43     typedef std::codecvt_utf8_utf16<CharT> C;
44     C c;
45     CharT w[2] = {0xD8C0, 0xDC03};
46     char n[4] = {0};
47     const CharT* wp = nullptr;
48     std::mbstate_t m;
49     char* np = nullptr;
50     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
51     assert(r == std::codecvt_base::ok);
52     assert(wp == w + 2);
53     assert(np == n + 4);
54     assert(n[0] == char(0xF1));
55     assert(n[1] == char(0x80));
56     assert(n[2] == char(0x80));
57     assert(n[3] == char(0x83));
58 
59     w[0] = 0x1005;
60     r = c.out(m, w, w + 1, wp, n, n + 4, np);
61     assert(r == std::codecvt_base::ok);
62     assert(wp == w + 1);
63     assert(np == n + 3);
64     assert(n[0] == char(0xE1));
65     assert(n[1] == char(0x80));
66     assert(n[2] == char(0x85));
67 
68     w[0] = 0x453;
69     r = c.out(m, w, w + 1, wp, n, n + 4, np);
70     assert(r == std::codecvt_base::ok);
71     assert(wp == w + 1);
72     assert(np == n + 2);
73     assert(n[0] == char(0xD1));
74     assert(n[1] == char(0x93));
75 
76     w[0] = 0x56;
77     r = c.out(m, w, w + 1, wp, n, n + 4, np);
78     assert(r == std::codecvt_base::ok);
79     assert(wp == w + 1);
80     assert(np == n + 1);
81     assert(n[0] == char(0x56));
82   }
83   {
84     typedef std::codecvt_utf8_utf16<CharT, 0x1000> C;
85     C c;
86     CharT w[2] = {0xD8C0, 0xDC03};
87     char n[4] = {0};
88     const CharT* wp = nullptr;
89     std::mbstate_t m;
90     char* np = nullptr;
91     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
92     assert(r == std::codecvt_base::error);
93     assert(wp == w);
94     assert(np == n);
95 
96     w[0] = 0x1005;
97     r = c.out(m, w, w + 1, wp, n, n + 4, np);
98     assert(r == std::codecvt_base::error);
99     assert(wp == w);
100     assert(np == n);
101 
102     w[0] = 0x453;
103     r = c.out(m, w, w + 1, wp, n, n + 4, np);
104     assert(r == std::codecvt_base::ok);
105     assert(wp == w + 1);
106     assert(np == n + 2);
107     assert(n[0] == char(0xD1));
108     assert(n[1] == char(0x93));
109 
110     w[0] = 0x56;
111     r = c.out(m, w, w + 1, wp, n, n + 4, np);
112     assert(r == std::codecvt_base::ok);
113     assert(wp == w + 1);
114     assert(np == n + 1);
115     assert(n[0] == char(0x56));
116   }
117   {
118     typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::generate_header> C;
119     C c;
120     CharT w[2] = {0xD8C0, 0xDC03};
121     char n[7] = {0};
122     const CharT* wp = nullptr;
123     std::mbstate_t m;
124     char* np = nullptr;
125     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 7, np);
126     assert(r == std::codecvt_base::ok);
127     assert(wp == w + 2);
128     assert(np == n + 7);
129     assert(n[0] == char(0xEF));
130     assert(n[1] == char(0xBB));
131     assert(n[2] == char(0xBF));
132     assert(n[3] == char(0xF1));
133     assert(n[4] == char(0x80));
134     assert(n[5] == char(0x80));
135     assert(n[6] == char(0x83));
136 
137     w[0] = 0x1005;
138     r = c.out(m, w, w + 1, wp, n, n + 7, np);
139     assert(r == std::codecvt_base::ok);
140     assert(wp == w + 1);
141     assert(np == n + 6);
142     assert(n[0] == char(0xEF));
143     assert(n[1] == char(0xBB));
144     assert(n[2] == char(0xBF));
145     assert(n[3] == char(0xE1));
146     assert(n[4] == char(0x80));
147     assert(n[5] == char(0x85));
148 
149     w[0] = 0x453;
150     r = c.out(m, w, w + 1, wp, n, n + 7, np);
151     assert(r == std::codecvt_base::ok);
152     assert(wp == w + 1);
153     assert(np == n + 5);
154     assert(n[0] == char(0xEF));
155     assert(n[1] == char(0xBB));
156     assert(n[2] == char(0xBF));
157     assert(n[3] == char(0xD1));
158     assert(n[4] == char(0x93));
159 
160     w[0] = 0x56;
161     r = c.out(m, w, w + 1, wp, n, n + 7, np);
162     assert(r == std::codecvt_base::ok);
163     assert(wp == w + 1);
164     assert(np == n + 4);
165     assert(n[0] == char(0xEF));
166     assert(n[1] == char(0xBB));
167     assert(n[2] == char(0xBF));
168     assert(n[3] == char(0x56));
169   }
170 }
171 
172 template <class CharT>
173 void TestHelper<CharT, 4>::test() {
174   {
175     typedef std::codecvt_utf8_utf16<CharT> C;
176     C c;
177     CharT w[2] = {0xD8C0, 0xDC03};
178     char n[4] = {0};
179     const CharT* wp = nullptr;
180     std::mbstate_t m;
181     char* np = nullptr;
182     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
183     assert(r == std::codecvt_base::ok);
184     assert(wp == w + 2);
185     assert(np == n + 4);
186     assert(n[0] == char(0xF1));
187     assert(n[1] == char(0x80));
188     assert(n[2] == char(0x80));
189     assert(n[3] == char(0x83));
190 
191     w[0] = 0x1005;
192     r = c.out(m, w, w + 1, wp, n, n + 4, np);
193     assert(r == std::codecvt_base::ok);
194     assert(wp == w + 1);
195     assert(np == n + 3);
196     assert(n[0] == char(0xE1));
197     assert(n[1] == char(0x80));
198     assert(n[2] == char(0x85));
199 
200     w[0] = 0x453;
201     r = c.out(m, w, w + 1, wp, n, n + 4, np);
202     assert(r == std::codecvt_base::ok);
203     assert(wp == w + 1);
204     assert(np == n + 2);
205     assert(n[0] == char(0xD1));
206     assert(n[1] == char(0x93));
207 
208     w[0] = 0x56;
209     r = c.out(m, w, w + 1, wp, n, n + 4, np);
210     assert(r == std::codecvt_base::ok);
211     assert(wp == w + 1);
212     assert(np == n + 1);
213     assert(n[0] == char(0x56));
214   }
215   {
216     typedef std::codecvt_utf8_utf16<CharT, 0x1000> C;
217     C c;
218     CharT w[2] = {0xD8C0, 0xDC03};
219     char n[4] = {0};
220     const CharT* wp = nullptr;
221     std::mbstate_t m;
222     char* np = nullptr;
223     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 4, np);
224     assert(r == std::codecvt_base::error);
225     assert(wp == w);
226     assert(np == n);
227 
228     w[0] = 0x1005;
229     r = c.out(m, w, w + 1, wp, n, n + 4, np);
230     assert(r == std::codecvt_base::error);
231     assert(wp == w);
232     assert(np == n);
233 
234     w[0] = 0x453;
235     r = c.out(m, w, w + 1, wp, n, n + 4, np);
236     assert(r == std::codecvt_base::ok);
237     assert(wp == w + 1);
238     assert(np == n + 2);
239     assert(n[0] == char(0xD1));
240     assert(n[1] == char(0x93));
241 
242     w[0] = 0x56;
243     r = c.out(m, w, w + 1, wp, n, n + 4, np);
244     assert(r == std::codecvt_base::ok);
245     assert(wp == w + 1);
246     assert(np == n + 1);
247     assert(n[0] == char(0x56));
248   }
249   {
250     typedef std::codecvt_utf8_utf16<CharT, 0x10ffff, std::generate_header> C;
251     C c;
252     CharT w[2] = {0xD8C0, 0xDC03};
253     char n[7] = {0};
254     const CharT* wp = nullptr;
255     std::mbstate_t m;
256     char* np = nullptr;
257     std::codecvt_base::result r = c.out(m, w, w + 2, wp, n, n + 7, np);
258     assert(r == std::codecvt_base::ok);
259     assert(wp == w + 2);
260     assert(np == n + 7);
261     assert(n[0] == char(0xEF));
262     assert(n[1] == char(0xBB));
263     assert(n[2] == char(0xBF));
264     assert(n[3] == char(0xF1));
265     assert(n[4] == char(0x80));
266     assert(n[5] == char(0x80));
267     assert(n[6] == char(0x83));
268 
269     w[0] = 0x1005;
270     r = c.out(m, w, w + 1, wp, n, n + 7, np);
271     assert(r == std::codecvt_base::ok);
272     assert(wp == w + 1);
273     assert(np == n + 6);
274     assert(n[0] == char(0xEF));
275     assert(n[1] == char(0xBB));
276     assert(n[2] == char(0xBF));
277     assert(n[3] == char(0xE1));
278     assert(n[4] == char(0x80));
279     assert(n[5] == char(0x85));
280 
281     w[0] = 0x453;
282     r = c.out(m, w, w + 1, wp, n, n + 7, np);
283     assert(r == std::codecvt_base::ok);
284     assert(wp == w + 1);
285     assert(np == n + 5);
286     assert(n[0] == char(0xEF));
287     assert(n[1] == char(0xBB));
288     assert(n[2] == char(0xBF));
289     assert(n[3] == char(0xD1));
290     assert(n[4] == char(0x93));
291 
292     w[0] = 0x56;
293     r = c.out(m, w, w + 1, wp, n, n + 7, np);
294     assert(r == std::codecvt_base::ok);
295     assert(wp == w + 1);
296     assert(np == n + 4);
297     assert(n[0] == char(0xEF));
298     assert(n[1] == char(0xBB));
299     assert(n[2] == char(0xBF));
300     assert(n[3] == char(0x56));
301   }
302 }
303 
304 int main(int, char**) {
305 #if !defined(_WIN32) && !defined(TEST_HAS_NO_WIDE_CHARACTERS)
306   TestHelper<wchar_t>::test();
307 #endif
308   TestHelper<char32_t>::test();
309   TestHelper<char16_t>::test();
310 
311   return 0;
312 }
313