]>
Commit | Line | Data |
---|---|---|
a5544970 | 1 | // Copyright (C) 2017-2019 Free Software Foundation, Inc. |
bcd682e1 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 | ||
24 | // PR libstdc++/79980 | |
25 | ||
26 | constexpr std::codecvt_mode mode(std::codecvt_mode m) | |
27 | { return static_cast<std::codecvt_mode>(m | std::consume_header); } | |
28 | ||
29 | template<typename WCh, unsigned long Max = 0x10FFFF, | |
30 | std::codecvt_mode Mode = std::consume_header> | |
31 | using Conv | |
32 | = std::wstring_convert<std::codecvt_utf16<WCh, Max, mode(Mode)>, WCh>; | |
33 | ||
34 | void | |
35 | test01() | |
36 | { | |
37 | const char src[] = "\xFE\xFF\xAB\xCD"; | |
38 | Conv<char16_t> conv; | |
39 | auto dst = conv.from_bytes(src, src+4); | |
40 | VERIFY( dst[0] == 0xabcd ); | |
41 | } | |
42 | ||
43 | void | |
44 | test02() | |
45 | { | |
46 | const char src[] = "\xFF\xFE\xAB\xCD"; | |
47 | Conv<char16_t> conv; | |
48 | auto dst = conv.from_bytes(src, src+4); | |
49 | VERIFY( dst[0] == 0xcdab ); | |
50 | } | |
51 | ||
52 | void | |
53 | test03() | |
54 | { | |
55 | const char src[] = "\xFE\xFF\xAB\xCD"; | |
56 | Conv<char16_t, 0x10FFFF, std::little_endian> conv; | |
57 | auto dst = conv.from_bytes(src, src+4); | |
58 | VERIFY( dst[0] == 0xabcd ); | |
59 | } | |
60 | ||
61 | void | |
62 | test04() | |
63 | { | |
64 | const char src[] = "\xFF\xFE\xAB\xCD"; | |
65 | Conv<char16_t, 0x10FFFF, std::little_endian> conv; | |
66 | auto dst = conv.from_bytes(src, src+4); | |
67 | VERIFY( dst[0] == 0xcdab ); | |
68 | } | |
69 | ||
70 | void | |
71 | test05() | |
72 | { | |
73 | const char src[] = "\0\x61\xAB\xCD"; // character greater than 0x00FF | |
74 | Conv<char16_t, 0xFF> conv("to_bytes failed", u"from_bytes failed"); | |
75 | std::u16string result = conv.from_bytes(src, src+4); | |
76 | VERIFY( result == u"from_bytes failed" ); | |
77 | VERIFY( conv.converted() == 2 ); | |
78 | } | |
79 | ||
80 | void | |
81 | test06() | |
82 | { | |
83 | const char src[] = "\0\x61\xAB\xCD"; | |
84 | Conv<char16_t> conv("to_bytes failed", u"from_bytes failed"); | |
85 | std::u16string result = conv.from_bytes(src, src+3); // incomplete character | |
86 | VERIFY( result == u"from_bytes failed" ); | |
87 | VERIFY( conv.converted() == 2 ); | |
88 | } | |
89 | ||
90 | void | |
91 | test07() | |
92 | { | |
93 | Conv<char16_t> conv("to_bytes failed", u"from_bytes failed"); | |
94 | // ucs2 to utf-16 conversion should fail on invalid ucs2 input: | |
95 | std::u16string utf16 = u"1234\U00001111\U0001ffff"; | |
96 | auto out = conv.to_bytes(utf16); | |
97 | VERIFY( out == "to_bytes failed" ); | |
98 | VERIFY( conv.converted() == 5 ); | |
99 | ||
100 | // And should also fail on incomplete surrogate pair (not return partial): | |
101 | out = conv.to_bytes(utf16.substr(0, utf16.size()-1)); | |
102 | VERIFY( out == "to_bytes failed" ); | |
103 | VERIFY( conv.converted() == 5 ); | |
104 | } | |
105 | ||
d951e75d JW |
106 | void |
107 | test08() | |
108 | { | |
109 | // Read/write UTF-16 code units from data not correctly aligned for char16_t | |
110 | Conv<char16_t, 0x10FFFF, std::generate_header> conv; | |
111 | const char src[] = "-\xFE\xFF\0\x61\xAB\xCD"; | |
112 | auto out = conv.from_bytes(src + 1, src + 7); | |
113 | VERIFY( out[0] == 0x0061 ); | |
114 | VERIFY( out[1] == 0xabcd ); | |
115 | auto bytes = conv.to_bytes(out); | |
116 | VERIFY( bytes == std::string(src + 1, 6) ); | |
117 | } | |
118 | ||
119 | void | |
120 | test09() | |
121 | { | |
122 | // Read/write UTF-16 code units from data not correctly aligned for char16_t | |
123 | Conv<char32_t, 0x10FFFF, std::generate_header> conv; | |
124 | const char src[] = "-\xFE\xFF\xD8\x08\xDF\x45"; | |
125 | auto out = conv.from_bytes(src + 1, src + 7); | |
126 | VERIFY( out == U"\U00012345" ); | |
127 | auto bytes = conv.to_bytes(out); | |
128 | VERIFY( bytes == std::string(src + 1, 6) ); | |
129 | } | |
130 | ||
bcd682e1 JW |
131 | int main() |
132 | { | |
133 | test01(); | |
134 | test02(); | |
135 | test03(); | |
136 | test04(); | |
137 | test05(); | |
138 | test06(); | |
139 | test07(); | |
d951e75d JW |
140 | test08(); |
141 | test09(); | |
bcd682e1 | 142 | } |