1 //
2 // Copyright (c) 2012 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOST_NOWIDE_TEST_SETS_HPP_INCLUDED
9 #define BOOST_NOWIDE_TEST_SETS_HPP_INCLUDED
10
11 #include <boost/nowide/config.hpp>
12 #include <iostream>
13 #include <string>
14
15 struct utf8_to_wide
16 {
17 const char* utf8;
18 const wchar_t* wide;
19 };
20
21 struct wide_to_utf8
22 {
23 const wchar_t* wide;
24 const char* utf8;
25 };
26
27 #if defined(BOOST_MSVC) && BOOST_MSVC < 1700
28 #pragma warning(disable : 4428) // universal-character-name encountered in source
29 #endif
30
31 const std::wstring wreplacement_str(1, wchar_t(BOOST_NOWIDE_REPLACEMENT_CHARACTER));
32
33 // clang-format off
34 const utf8_to_wide roundtrip_tests[] = {
35 {"", L""},
36 {"\xf0\x9d\x92\x9e-\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82.txt",
37 L"\U0001D49E-\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042.txt"},
38 {"\xd7\xa9-\xd0\xbc-\xce\xbd.txt",
39 L"\u05e9-\u043c-\u03bd.txt"},
40 {"\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d",
41 L"\u05e9\u05dc\u05d5\u05dd"},
42 };
43
44 const utf8_to_wide invalid_utf8_tests[] = {
45 {"\xFF\xFF", L"\ufffd\ufffd"},
46 {"\xd7\xa9\xFF", L"\u05e9\ufffd"},
47 {"\xd7", L"\ufffd"},
48 {"\xFF\xd7\xa9", L"\ufffd\u05e9"},
49 {"\xFF\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82", L"\uFFFD\u043F\u0440\u0438\u0432\u0435\u0442"},
50 {"\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82\xFF", L"\u043F\u0440\u0438\u0432\u0435\u0442\uFFFD"},
51 {"\xE3\x82\xFF\xE3\x81\x82", L"\ufffd\u3042"},
52 {"\xE3\xFF\x84\xE3\x81\x82", L"\ufffd\ufffd\u3042"},
53 };
54
55 const wide_to_utf8 invalid_wide_tests[] = {
56 {L"\xDC01\x05e9", "\xEF\xBF\xBD\xd7\xa9"},
57 {L"\x05e9\xD800", "\xd7\xa9\xEF\xBF\xBD"},
58 {L"\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
59 "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
60 {L"\u3084\u3042\xDC00\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
61 "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
62 };
63
64
65 const wide_to_utf8 invalid_utf16_tests[] = {
66 {L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
67 "\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
68 {L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
69 "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
70 };
71
72 const wide_to_utf8 invalid_utf32_tests[] = {
73 {L"\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
74 "\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
75 {L"\u3084\u3042\xD800\x20\u043F\u0440\u0438\u0432\u0435\u0442-\u3084\u3042",
76 "\xE3\x82\x84\xE3\x81\x82\xEF\xBF\xBD \xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82-\xE3\x82\x84\xE3\x81\x82"},
77 };
78
79 // clang-format on
80
81 #ifdef BOOST_MSVC
82 #pragma warning(push)
83 #pragma warning(disable : 4127) // Constant expression detected
84 #endif
85
86 template<typename T, size_t N>
array_size(const T (&)[N])87 size_t array_size(const T (&)[N])
88 {
89 return N;
90 }
91
run_all(std::wstring (* to_wide)(const std::string &),std::string (* to_narrow)(const std::wstring &))92 void run_all(std::wstring (*to_wide)(const std::string&), std::string (*to_narrow)(const std::wstring&))
93 {
94 for(size_t i = 0; i < array_size(roundtrip_tests); i++)
95 {
96 std::cout << " Roundtrip " << i << std::endl;
97 TEST(roundtrip_tests[i].utf8 == to_narrow(roundtrip_tests[i].wide));
98 TEST(to_wide(roundtrip_tests[i].utf8) == roundtrip_tests[i].wide);
99 }
100
101 for(size_t i = 0; i < array_size(invalid_utf8_tests); i++)
102 {
103 std::cout << " Invalid UTF8 " << i << std::endl;
104 TEST(to_wide(invalid_utf8_tests[i].utf8) == invalid_utf8_tests[i].wide);
105 }
106
107 for(size_t i = 0; i < array_size(invalid_wide_tests); i++)
108 {
109 std::cout << " Invalid Wide " << i << std::endl;
110 TEST(to_narrow(invalid_wide_tests[i].wide) == invalid_wide_tests[i].utf8);
111 }
112
113 size_t total = 0;
114 const wide_to_utf8* ptr = 0;
115 if(sizeof(wchar_t) == 2)
116 {
117 ptr = invalid_utf16_tests;
118 total = array_size(invalid_utf16_tests);
119 } else
120 {
121 ptr = invalid_utf32_tests;
122 total = array_size(invalid_utf32_tests);
123 }
124 for(size_t i = 0; i < total; i++)
125 {
126 std::cout << " Invalid UTF16/32 " << i << std::endl;
127 TEST(to_narrow(ptr[i].wide) == ptr[i].utf8);
128 }
129 }
130
131 #endif
132
133 #ifdef BOOST_MSVC
134 #pragma warning(pop)
135 #endif
136