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
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 
32 template <class CharT>
33 struct TestHelper<CharT, 2> {
34   static void test();
35 };
36 
37 template <class CharT>
38 struct TestHelper<CharT, 4> {
39   static void test();
40 };
41 
42 template <class CharT>
43 void TestHelper<CharT, 2>::test() {
44   {
45     typedef std::codecvt_utf8<CharT> C;
46     C c;
47     CharT w = 0x1005;
48     char n[4] = {0};
49     const CharT* wp = nullptr;
50     std::mbstate_t m;
51     char* np = nullptr;
52     std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
53     assert(r == std::codecvt_base::ok);
54     assert(wp == &w + 1);
55     assert(np == n + 3);
56     assert(n[0] == char(0xE1));
57     assert(n[1] == char(0x80));
58     assert(n[2] == char(0x85));
59     assert(n[3] == char(0));
60 
61     w = 0x453;
62     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
63     assert(r == std::codecvt_base::ok);
64     assert(wp == &w + 1);
65     assert(np == n + 2);
66     assert(n[0] == char(0xD1));
67     assert(n[1] == char(0x93));
68     assert(n[2] == char(0x85));
69     assert(n[3] == char(0));
70 
71     w = 0x56;
72     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
73     assert(r == std::codecvt_base::ok);
74     assert(wp == &w + 1);
75     assert(np == n + 1);
76     assert(n[0] == char(0x56));
77     assert(n[1] == char(0x93));
78     assert(n[2] == char(0x85));
79     assert(n[3] == char(0));
80   }
81   {
82     typedef std::codecvt_utf8<CharT, 0x1000> C;
83     C c;
84     CharT w = 0x1005;
85     char n[4] = {0};
86     const CharT* wp = nullptr;
87     std::mbstate_t m;
88     char* np = nullptr;
89     std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
90     assert(r == std::codecvt_base::error);
91     assert(wp == &w);
92     assert(np == n);
93     assert(n[0] == char(0));
94     assert(n[1] == char(0));
95     assert(n[2] == char(0));
96     assert(n[3] == char(0));
97 
98     w = 0x453;
99     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
100     assert(r == std::codecvt_base::ok);
101     assert(wp == &w + 1);
102     assert(np == n + 2);
103     assert(n[0] == char(0xD1));
104     assert(n[1] == char(0x93));
105     assert(n[2] == char(0));
106     assert(n[3] == char(0));
107 
108     w = 0x56;
109     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
110     assert(r == std::codecvt_base::ok);
111     assert(wp == &w + 1);
112     assert(np == n + 1);
113     assert(n[0] == char(0x56));
114     assert(n[1] == char(0x93));
115     assert(n[2] == char(0));
116     assert(n[3] == char(0));
117   }
118   {
119     typedef std::codecvt_utf8<CharT, 0xFFFFFFFF, std::generate_header> C;
120     C c;
121     CharT w = 0x1005;
122     char n[7] = {0};
123     const CharT* wp = nullptr;
124     std::mbstate_t m;
125     char* np = nullptr;
126     std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
127     assert(r == std::codecvt_base::ok);
128     assert(wp == &w + 1);
129     assert(np == n + 6);
130     assert(n[0] == char(0xEF));
131     assert(n[1] == char(0xBB));
132     assert(n[2] == char(0xBF));
133     assert(n[3] == char(0xE1));
134     assert(n[4] == char(0x80));
135     assert(n[5] == char(0x85));
136     assert(n[6] == char(0));
137 
138     w = 0x453;
139     r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
140     assert(r == std::codecvt_base::ok);
141     assert(wp == &w + 1);
142     assert(np == n + 5);
143     assert(n[0] == char(0xEF));
144     assert(n[1] == char(0xBB));
145     assert(n[2] == char(0xBF));
146     assert(n[3] == char(0xD1));
147     assert(n[4] == char(0x93));
148     assert(n[5] == char(0x85));
149     assert(n[6] == char(0));
150 
151     w = 0x56;
152     r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
153     assert(r == std::codecvt_base::ok);
154     assert(wp == &w + 1);
155     assert(np == n + 4);
156     assert(n[0] == char(0xEF));
157     assert(n[1] == char(0xBB));
158     assert(n[2] == char(0xBF));
159     assert(n[3] == char(0x56));
160     assert(n[4] == char(0x93));
161     assert(n[5] == char(0x85));
162     assert(n[6] == char(0));
163   }
164 }
165 
166 template <class CharT>
167 void TestHelper<CharT, 4>::test() {
168   {
169     typedef std::codecvt_utf8<CharT> C;
170     C c;
171     CharT w = 0x40003;
172     char n[4] = {0};
173     const CharT* wp = nullptr;
174     std::mbstate_t m;
175     char* np = nullptr;
176     std::codecvt_base::result r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
177     assert(r == std::codecvt_base::ok);
178     assert(wp == &w + 1);
179     assert(np == n + 4);
180     assert(n[0] == char(0xF1));
181     assert(n[1] == char(0x80));
182     assert(n[2] == char(0x80));
183     assert(n[3] == char(0x83));
184 
185     w = 0x1005;
186     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
187     assert(r == std::codecvt_base::ok);
188     assert(wp == &w + 1);
189     assert(np == n + 3);
190     assert(n[0] == char(0xE1));
191     assert(n[1] == char(0x80));
192     assert(n[2] == char(0x85));
193     assert(n[3] == char(0x83));
194 
195     w = 0x453;
196     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
197     assert(r == std::codecvt_base::ok);
198     assert(wp == &w + 1);
199     assert(np == n + 2);
200     assert(n[0] == char(0xD1));
201     assert(n[1] == char(0x93));
202     assert(n[2] == char(0x85));
203     assert(n[3] == char(0x83));
204 
205     w = 0x56;
206     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
207     assert(r == std::codecvt_base::ok);
208     assert(wp == &w + 1);
209     assert(np == n + 1);
210     assert(n[0] == char(0x56));
211     assert(n[1] == char(0x93));
212     assert(n[2] == char(0x85));
213     assert(n[3] == char(0x83));
214   }
215   {
216     typedef std::codecvt_utf8<CharT, 0x1000> C;
217     C c;
218     CharT w = 0x40003;
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 + 1, wp, n, n + 4, np);
224     assert(r == std::codecvt_base::error);
225     assert(wp == &w);
226     assert(np == n);
227     assert(n[0] == char(0));
228     assert(n[1] == char(0));
229     assert(n[2] == char(0));
230     assert(n[3] == char(0));
231 
232     w = 0x1005;
233     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
234     assert(r == std::codecvt_base::error);
235     assert(wp == &w);
236     assert(np == n);
237     assert(n[0] == char(0));
238     assert(n[1] == char(0));
239     assert(n[2] == char(0));
240     assert(n[3] == char(0));
241 
242     w = 0x453;
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 + 2);
247     assert(n[0] == char(0xD1));
248     assert(n[1] == char(0x93));
249     assert(n[2] == char(0));
250     assert(n[3] == char(0));
251 
252     w = 0x56;
253     r = c.out(m, &w, &w + 1, wp, n, n + 4, np);
254     assert(r == std::codecvt_base::ok);
255     assert(wp == &w + 1);
256     assert(np == n + 1);
257     assert(n[0] == char(0x56));
258     assert(n[1] == char(0x93));
259     assert(n[2] == char(0));
260     assert(n[3] == char(0));
261   }
262   {
263     typedef std::codecvt_utf8<CharT, 0xFFFFFFFF, std::generate_header> C;
264     C c;
265     CharT w = 0x40003;
266     char n[7] = {0};
267     const CharT* wp = nullptr;
268     std::mbstate_t m;
269     char* np = nullptr;
270     std::codecvt_base::result 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 + 7);
274     assert(n[0] == char(0xEF));
275     assert(n[1] == char(0xBB));
276     assert(n[2] == char(0xBF));
277     assert(n[3] == char(0xF1));
278     assert(n[4] == char(0x80));
279     assert(n[5] == char(0x80));
280     assert(n[6] == char(0x83));
281 
282     w = 0x1005;
283     r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
284     assert(r == std::codecvt_base::ok);
285     assert(wp == &w + 1);
286     assert(np == n + 6);
287     assert(n[0] == char(0xEF));
288     assert(n[1] == char(0xBB));
289     assert(n[2] == char(0xBF));
290     assert(n[3] == char(0xE1));
291     assert(n[4] == char(0x80));
292     assert(n[5] == char(0x85));
293     assert(n[6] == char(0x83));
294 
295     w = 0x453;
296     r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
297     assert(r == std::codecvt_base::ok);
298     assert(wp == &w + 1);
299     assert(np == n + 5);
300     assert(n[0] == char(0xEF));
301     assert(n[1] == char(0xBB));
302     assert(n[2] == char(0xBF));
303     assert(n[3] == char(0xD1));
304     assert(n[4] == char(0x93));
305     assert(n[5] == char(0x85));
306     assert(n[6] == char(0x83));
307 
308     w = 0x56;
309     r = c.out(m, &w, &w + 1, wp, n, n + 7, np);
310     assert(r == std::codecvt_base::ok);
311     assert(wp == &w + 1);
312     assert(np == n + 4);
313     assert(n[0] == char(0xEF));
314     assert(n[1] == char(0xBB));
315     assert(n[2] == char(0xBF));
316     assert(n[3] == char(0x56));
317     assert(n[4] == char(0x93));
318     assert(n[5] == char(0x85));
319     assert(n[6] == char(0x83));
320   }
321 }
322 
323 int main(int, char**) {
324 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
325   TestHelper<wchar_t>::test();
326 #endif
327   TestHelper<char32_t>::test();
328   TestHelper<char16_t>::test();
329 
330   return 0;
331 }
332