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