1 // Copyright (C) 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "aemu/base/system/Win32UnicodeString.h"
16 
17 #include <gtest/gtest.h>
18 
19 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
20 
21 namespace android {
22 namespace base {
23 
TEST(Win32UnicodeString,DefaultConstructor)24 TEST(Win32UnicodeString, DefaultConstructor) {
25     Win32UnicodeString str;
26     EXPECT_EQ(0u, str.size());
27     EXPECT_STREQ(L"", str.c_str());
28     EXPECT_TRUE(str.data());
29 }
30 
TEST(Win32UnicodeString,Constructors)31 TEST(Win32UnicodeString, Constructors) {
32     static const struct {
33         const char* utf8;
34         const wchar_t* utf16;
35     } kData[] = {
36             {"", L""},
37             {"Hello World!", L"Hello World!"},
38             {"T\xC3\xA9l\xC3\xA9vision", L"T\xE9l\xE9vision"},
39             {"foo\xE1\x80\x80 bar", L"foo\x1000 bar"},
40     };
41     const size_t kDataSize = ARRAY_SIZE(kData);
42 
43     for (size_t n = 0; n < kDataSize; ++n) {
44         Win32UnicodeString str1(kData[n].utf8);
45         EXPECT_EQ(wcslen(kData[n].utf16), str1.size());
46         EXPECT_STREQ(kData[n].utf16, str1.c_str());
47 
48         Win32UnicodeString str2(kData[n].utf8, strlen(kData[n].utf8));
49         EXPECT_EQ(wcslen(kData[n].utf16), str2.size());
50         EXPECT_STREQ(kData[n].utf16, str2.c_str());
51 
52         std::string baseStr(kData[n].utf8);
53         Win32UnicodeString str3(baseStr);
54         EXPECT_EQ(wcslen(kData[n].utf16), str3.size());
55         EXPECT_STREQ(kData[n].utf16, str3.c_str());
56 
57         size_t utf16Len = wcslen(kData[n].utf16);
58         Win32UnicodeString str4(kData[n].utf16);
59         EXPECT_EQ(utf16Len, str4.size());
60         EXPECT_STREQ(kData[n].utf16, str4.c_str());
61 
62         Win32UnicodeString str5 = str4;
63         EXPECT_EQ(utf16Len, str5.size());
64         EXPECT_STREQ(kData[n].utf16, str5.c_str());
65 
66         Win32UnicodeString str6("foo");
67         str6 = str5;
68         EXPECT_EQ(utf16Len, str6.size());
69         EXPECT_STREQ(kData[n].utf16, str6.c_str());
70     }
71 }
72 
TEST(Win32UnicodeString,convertToUtf8)73 TEST(Win32UnicodeString, convertToUtf8) {
74     static const struct {
75         const char* utf8;
76         const wchar_t* utf16;
77     } kData[] = {
78             {"", L""},
79             {"Hello World!", L"Hello World!"},
80             {"T\xC3\xA9l\xC3\xA9vision", L"T\xE9l\xE9vision"},
81             {"foo\xE1\x80\x80 bar", L"foo\x1000 bar"},
82     };
83     const size_t kDataSize = ARRAY_SIZE(kData);
84 
85     for (size_t n = 0; n < kDataSize; ++n) {
86         std::string str1 = Win32UnicodeString::convertToUtf8(kData[n].utf16);
87         EXPECT_EQ(strlen(kData[n].utf8), str1.size());
88         EXPECT_STREQ(kData[n].utf8, str1.c_str());
89 
90         std::string str2 = Win32UnicodeString::convertToUtf8(
91                 kData[n].utf16, wcslen(kData[n].utf16));
92         EXPECT_EQ(strlen(kData[n].utf8), str2.size());
93         EXPECT_STREQ(kData[n].utf8, str2.c_str());
94 
95         char out[256];
96         int len = Win32UnicodeString::convertToUtf8(out, sizeof(out),
97                                                     kData[n].utf16);
98         EXPECT_EQ(strlen(kData[n].utf8) + 1U, (size_t)len);
99         EXPECT_STREQ(kData[n].utf8, out);
100 
101         len = Win32UnicodeString::convertToUtf8(out, sizeof(out),
102                                                 kData[n].utf16,
103                                                 wcslen(kData[n].utf16));
104         EXPECT_EQ((int)strlen(kData[n].utf8), len);
105         out[len] = 0;
106         EXPECT_STREQ(kData[n].utf8, out);
107 
108         if (kData[n].utf8[0] != 0) {
109             len = Win32UnicodeString::convertToUtf8(out, 1,
110                                                     kData[n].utf16);
111             EXPECT_EQ(-1, len);
112         }
113 
114         len = Win32UnicodeString::convertToUtf8(nullptr, 0,
115                                                 kData[n].utf16);
116         EXPECT_EQ(-1, len);
117 
118         len = Win32UnicodeString::convertToUtf8(nullptr, 0,
119                                                 kData[n].utf16,
120                                                 wcslen(kData[n].utf16));
121         EXPECT_EQ(-1, len);
122 
123         len = Win32UnicodeString::calcUtf8BufferLength(kData[n].utf16);
124         EXPECT_EQ((int)strlen(kData[n].utf8) + 1, len);
125 
126         len = Win32UnicodeString::calcUtf8BufferLength(kData[n].utf16,
127                                                       wcslen(kData[n].utf16));
128         EXPECT_EQ((int)strlen(kData[n].utf8), len);
129     }
130 }
131 
TEST(Win32UnicodeString,convertFromUtf8)132 TEST(Win32UnicodeString, convertFromUtf8) {
133     static const struct {
134         const char* utf8;
135         const wchar_t* utf16;
136     } kData[] = {
137             {"", L""},
138             {"Hello World!", L"Hello World!"},
139             {"T\xC3\xA9l\xC3\xA9vision", L"T\xE9l\xE9vision"},
140             {"foo\xE1\x80\x80 bar", L"foo\x1000 bar"},
141     };
142     const size_t kDataSize = ARRAY_SIZE(kData);
143 
144     for (size_t n = 0; n < kDataSize; ++n) {
145         wchar_t out[256];
146         int len = Win32UnicodeString::convertFromUtf8(out, ARRAY_SIZE(out),
147                                                       kData[n].utf8);
148         EXPECT_EQ((int)wcslen(kData[n].utf16) + 1, len);
149         EXPECT_STREQ(kData[n].utf16, out);
150 
151         len = Win32UnicodeString::convertFromUtf8(out, ARRAY_SIZE(out),
152                                                   kData[n].utf8,
153                                                   strlen(kData[n].utf8));
154         EXPECT_EQ((int)wcslen(kData[n].utf16), len);
155         out[len] = 0;
156         EXPECT_STREQ(kData[n].utf16, out);
157 
158         if (kData[n].utf16[0] != 0) {
159             len = Win32UnicodeString::convertFromUtf8(out, 1, kData[n].utf8);
160             EXPECT_EQ(-1, len);
161         }
162 
163         len = Win32UnicodeString::convertFromUtf8(nullptr, 0, kData[n].utf8);
164         EXPECT_EQ(-1, len);
165 
166         len = Win32UnicodeString::convertFromUtf8(nullptr, 0,
167                                                   kData[n].utf8,
168                                                   strlen(kData[n].utf8));
169         EXPECT_EQ(-1, len);
170 
171         len = Win32UnicodeString::calcUtf16BufferLength(kData[n].utf8);
172         EXPECT_EQ((int)wcslen(kData[n].utf16) + 1, len);
173 
174         len = Win32UnicodeString::calcUtf16BufferLength(kData[n].utf8,
175                                                        strlen(kData[n].utf8));
176         EXPECT_EQ((int)wcslen(kData[n].utf16), len);
177     }
178 }
179 
TEST(Win32UnicodeString,appending)180 TEST(Win32UnicodeString, appending) {
181     static const struct {
182         const wchar_t* first;
183         const wchar_t* second;
184         const wchar_t* result;
185     } kData[] = {
186         {L"foo", L"bar", L"foobar"},
187         {L"", L"bar", L"bar"},
188         {L"foo", L"", L"foo"},
189         {L"foobar", L" with ice cream", L"foobar with ice cream"},
190     };
191 
192     for (const auto& data : kData) {
193         {
194             // Test appending Win32UnicodeString
195             Win32UnicodeString first(data.first);
196             Win32UnicodeString second(data.second);
197 
198             first.append(second);
199             EXPECT_EQ(wcslen(data.result), first.size());
200             EXPECT_STREQ(data.result, first.c_str());
201         }
202         {
203             // Test appending wchar_t*
204             Win32UnicodeString str(data.first);
205             str.append(data.second);
206             EXPECT_EQ(wcslen(data.result), str.size());
207             EXPECT_STREQ(data.result, str.c_str());
208         }
209         {
210             // Test appending wchar_t* with length
211             Win32UnicodeString str(data.first);
212             str.append(data.second, wcslen(data.second));
213             EXPECT_EQ(wcslen(data.result), str.size());
214             EXPECT_STREQ(data.result, str.c_str());
215         }
216         if (wcslen(data.second) > 0) {
217             // Test appending with fewer characters
218             Win32UnicodeString str(data.first);
219             str.append(data.second, wcslen(data.second) - 1);
220             EXPECT_EQ(wcslen(data.result) - 1, str.size());
221             std::wstring choppedResult(data.result, wcslen(data.result) - 1);
222             EXPECT_STREQ(choppedResult.c_str(), str.c_str());
223         }
224     }
225 }
226 
227 }  // namespace base
228 }  // namespace android
229