1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "perfetto/ext/base/string_utils.h"
18
19 #include "test/gtest_and_gmock.h"
20
21 #include "perfetto/ext/base/optional.h"
22
23 namespace perfetto {
24 namespace base {
25 namespace {
26
27 template <size_t N>
28 struct UninitializedBuf {
UninitializedBufperfetto::base::__anonb691bbd00111::UninitializedBuf29 UninitializedBuf() { memset(data, '?', sizeof(data)); }
operator char*perfetto::base::__anonb691bbd00111::UninitializedBuf30 operator char*() { return data; }
31 char data[N];
32 };
33
34 using testing::ElementsAre;
35
TEST(StringUtilsTest,Lowercase)36 TEST(StringUtilsTest, Lowercase) {
37 EXPECT_EQ(Lowercase('A'), 'a');
38 EXPECT_EQ(Lowercase('a'), 'a');
39 EXPECT_EQ(Lowercase('Z'), 'z');
40 EXPECT_EQ(Lowercase('z'), 'z');
41 EXPECT_EQ(Lowercase('!'), '!');
42 }
43
TEST(StringUtilsTest,Uppercase)44 TEST(StringUtilsTest, Uppercase) {
45 EXPECT_EQ(Uppercase('A'), 'A');
46 EXPECT_EQ(Uppercase('a'), 'A');
47 EXPECT_EQ(Uppercase('Z'), 'Z');
48 EXPECT_EQ(Uppercase('z'), 'Z');
49 EXPECT_EQ(Uppercase('!'), '!');
50 }
51
TEST(StringUtilsTest,CStringToUInt32)52 TEST(StringUtilsTest, CStringToUInt32) {
53 EXPECT_EQ(CStringToUInt32("0"), make_optional<uint32_t>(0U));
54 EXPECT_EQ(CStringToUInt32("1"), make_optional<uint32_t>(1U));
55 EXPECT_EQ(CStringToUInt32("42"), make_optional<uint32_t>(42U));
56 EXPECT_EQ(CStringToUInt32(""), nullopt);
57 EXPECT_EQ(CStringToUInt32("!?"), nullopt);
58 EXPECT_EQ(CStringToUInt32("abc"), nullopt);
59 EXPECT_EQ(CStringToUInt32("123 abc"), nullopt);
60 }
61
TEST(StringUtilsTest,CStringToInt32)62 TEST(StringUtilsTest, CStringToInt32) {
63 EXPECT_EQ(CStringToInt32("0"), make_optional<int32_t>(0));
64 EXPECT_EQ(CStringToInt32("1"), make_optional<int32_t>(1));
65 EXPECT_EQ(CStringToInt32("-42"), make_optional<int32_t>(-42));
66 EXPECT_EQ(CStringToInt32(""), nullopt);
67 EXPECT_EQ(CStringToInt32("!?"), nullopt);
68 EXPECT_EQ(CStringToInt32("abc"), nullopt);
69 EXPECT_EQ(CStringToInt32("123 abc"), nullopt);
70 }
71
TEST(StringUtilsTest,CStringToDouble)72 TEST(StringUtilsTest, CStringToDouble) {
73 EXPECT_DOUBLE_EQ(CStringToDouble("0").value(), 0l);
74 EXPECT_DOUBLE_EQ(CStringToDouble("1").value(), 1l);
75 EXPECT_DOUBLE_EQ(CStringToDouble("-42").value(), -42l);
76 EXPECT_DOUBLE_EQ(CStringToDouble("-42.5").value(), -42.5l);
77 EXPECT_EQ(CStringToDouble(""), nullopt);
78 EXPECT_EQ(CStringToDouble("!?"), nullopt);
79 EXPECT_EQ(CStringToDouble("abc"), nullopt);
80 EXPECT_EQ(CStringToDouble("123 abc"), nullopt);
81 }
82
TEST(StringUtilsTest,StringToUInt32)83 TEST(StringUtilsTest, StringToUInt32) {
84 EXPECT_EQ(StringToUInt32("0"), make_optional<uint32_t>(0U));
85 EXPECT_EQ(StringToUInt32("1"), make_optional<uint32_t>(1U));
86 EXPECT_EQ(StringToUInt32("42"), make_optional<uint32_t>(42U));
87 EXPECT_EQ(StringToUInt32("a", 16), make_optional<uint32_t>(10U));
88 EXPECT_EQ(StringToUInt32("fffffff0", 16),
89 make_optional<uint32_t>(0xfffffff0));
90 EXPECT_EQ(StringToUInt32(""), nullopt);
91 EXPECT_EQ(StringToUInt32("!?"), nullopt);
92 EXPECT_EQ(StringToUInt32("abc"), nullopt);
93 EXPECT_EQ(StringToUInt32("123 abc"), nullopt);
94 EXPECT_EQ(StringToUInt32("beefz", 16), nullopt);
95 }
96
TEST(StringUtilsTest,StringToInt32)97 TEST(StringUtilsTest, StringToInt32) {
98 EXPECT_EQ(StringToInt32("0"), make_optional<int32_t>(0));
99 EXPECT_EQ(StringToInt32("1"), make_optional<int32_t>(1));
100 EXPECT_EQ(StringToInt32("-42"), make_optional<int32_t>(-42));
101 EXPECT_EQ(StringToInt32("42", 16), make_optional<int32_t>(0x42));
102 EXPECT_EQ(StringToInt32("7ffffffe", 16), make_optional<int32_t>(0x7ffffffe));
103 EXPECT_EQ(StringToInt32(""), nullopt);
104 EXPECT_EQ(StringToInt32("!?"), nullopt);
105 EXPECT_EQ(StringToInt32("abc"), nullopt);
106 EXPECT_EQ(StringToInt32("123 abc"), nullopt);
107 EXPECT_EQ(StringToInt32("beefz", 16), nullopt);
108 }
109
TEST(StringUtilsTest,StringToUInt64)110 TEST(StringUtilsTest, StringToUInt64) {
111 EXPECT_EQ(StringToUInt64("0"), make_optional<uint64_t>(0u));
112 EXPECT_EQ(StringToUInt64("1"), make_optional<uint64_t>(1u));
113 EXPECT_EQ(StringToUInt64("5000000000"),
114 make_optional<uint64_t>(5000000000ULL));
115 EXPECT_EQ(StringToUInt64("7ffffffffffffffe", 16),
116 make_optional<uint64_t>(0x7ffffffffffffffeULL));
117 EXPECT_EQ(StringToUInt64("9ffffffffffffffe", 16),
118 make_optional<uint64_t>(0x9ffffffffffffffeULL));
119 EXPECT_EQ(StringToUInt64(""), nullopt);
120 EXPECT_EQ(StringToUInt64("abc"), nullopt);
121 EXPECT_EQ(StringToUInt64("beefz", 16), nullopt);
122 }
123
TEST(StringUtilsTest,StringToInt64)124 TEST(StringUtilsTest, StringToInt64) {
125 EXPECT_EQ(StringToInt64("0"), make_optional<int64_t>(0));
126 EXPECT_EQ(StringToInt64("1"), make_optional<int64_t>(1));
127 EXPECT_EQ(StringToInt64("-5000000000"),
128 make_optional<int64_t>(-5000000000LL));
129 EXPECT_EQ(StringToInt64("5000000000"), make_optional<int64_t>(5000000000LL));
130 EXPECT_EQ(StringToInt64("7ffffffffffffffe", 16),
131 make_optional<int64_t>(0x7ffffffffffffffeLL));
132 EXPECT_EQ(StringToInt64("9ffffffe", 16),
133 make_optional<int64_t>(0x9ffffffeLL));
134 EXPECT_EQ(StringToInt64(""), nullopt);
135 EXPECT_EQ(StringToInt64("abc"), nullopt);
136 EXPECT_EQ(StringToInt64("beefz", 16), nullopt);
137 }
138
TEST(StringUtilsTest,StringToDouble)139 TEST(StringUtilsTest, StringToDouble) {
140 EXPECT_DOUBLE_EQ(StringToDouble("0").value(), 0l);
141 EXPECT_DOUBLE_EQ(StringToDouble("1").value(), 1l);
142 EXPECT_DOUBLE_EQ(StringToDouble("-42").value(), -42l);
143 EXPECT_DOUBLE_EQ(StringToDouble("-42.5").value(), -42.5l);
144 EXPECT_DOUBLE_EQ(StringToDouble("0.5").value(), .5l);
145 EXPECT_DOUBLE_EQ(StringToDouble(".5").value(), .5l);
146 EXPECT_EQ(StringToDouble(""), nullopt);
147 EXPECT_EQ(StringToDouble("!?"), nullopt);
148 EXPECT_EQ(StringToDouble("abc"), nullopt);
149 EXPECT_EQ(StringToDouble("123 abc"), nullopt);
150 EXPECT_EQ(StringToDouble("124,456"), nullopt);
151 EXPECT_EQ(StringToDouble("4 2"), nullopt);
152 EXPECT_EQ(StringToDouble(" - 42"), nullopt);
153 }
154
TEST(StringUtilsTest,StartsWith)155 TEST(StringUtilsTest, StartsWith) {
156 EXPECT_TRUE(StartsWith("", ""));
157 EXPECT_TRUE(StartsWith("abc", ""));
158 EXPECT_TRUE(StartsWith("abc", "a"));
159 EXPECT_TRUE(StartsWith("abc", "ab"));
160 EXPECT_TRUE(StartsWith("abc", "abc"));
161 EXPECT_FALSE(StartsWith("abc", "abcd"));
162 EXPECT_FALSE(StartsWith("aa", "ab"));
163 EXPECT_FALSE(StartsWith("", "ab"));
164 }
165
TEST(StringUtilsTest,StartsWithAny)166 TEST(StringUtilsTest, StartsWithAny) {
167 EXPECT_FALSE(StartsWithAny("", {"a", "b"}));
168 EXPECT_FALSE(StartsWithAny("abcd", {}));
169 EXPECT_FALSE(StartsWithAny("", {}));
170 EXPECT_TRUE(StartsWithAny("abcd", {"ac", "ab"}));
171 EXPECT_FALSE(StartsWithAny("abcd", {"bc", "ac"}));
172 }
173
TEST(StringUtilsTest,EndsWith)174 TEST(StringUtilsTest, EndsWith) {
175 EXPECT_TRUE(EndsWith("", ""));
176 EXPECT_TRUE(EndsWith("abc", ""));
177 EXPECT_TRUE(EndsWith("abc", "c"));
178 EXPECT_TRUE(EndsWith("abc", "bc"));
179 EXPECT_TRUE(EndsWith("abc", "abc"));
180 EXPECT_FALSE(EndsWith("bcd", "abcd"));
181 EXPECT_FALSE(EndsWith("abc", "abd"));
182 EXPECT_FALSE(EndsWith("", "c"));
183 }
184
TEST(StringUtilsTest,ToHex)185 TEST(StringUtilsTest, ToHex) {
186 EXPECT_EQ(ToHex(""), "");
187 EXPECT_EQ(ToHex("abc123"), "616263313233");
188 }
189
TEST(StringUtilsTest,IntToHex)190 TEST(StringUtilsTest, IntToHex) {
191 EXPECT_EQ(IntToHexString(0), "0x00");
192 EXPECT_EQ(IntToHexString(1), "0x01");
193 EXPECT_EQ(IntToHexString(16), "0x10");
194 EXPECT_EQ(IntToHexString(4294967295), "0xffffffff");
195 }
196
TEST(StringUtilsTest,Uint64ToHex)197 TEST(StringUtilsTest, Uint64ToHex) {
198 EXPECT_EQ(Uint64ToHexString(0), "0x0");
199 EXPECT_EQ(Uint64ToHexString(1), "0x1");
200 EXPECT_EQ(Uint64ToHexString(16), "0x10");
201 EXPECT_EQ(Uint64ToHexString(18446744073709551615UL), "0xffffffffffffffff");
202 }
203
TEST(StringUtilsTest,Uint64ToHexNoPrefix)204 TEST(StringUtilsTest, Uint64ToHexNoPrefix) {
205 EXPECT_EQ(Uint64ToHexStringNoPrefix(0), "0");
206 EXPECT_EQ(Uint64ToHexStringNoPrefix(1), "1");
207 EXPECT_EQ(Uint64ToHexStringNoPrefix(16), "10");
208 EXPECT_EQ(Uint64ToHexStringNoPrefix(18446744073709551615UL),
209 "ffffffffffffffff");
210 }
211
TEST(StringUtilsTest,CaseInsensitiveEqual)212 TEST(StringUtilsTest, CaseInsensitiveEqual) {
213 EXPECT_TRUE(CaseInsensitiveEqual("", ""));
214 EXPECT_TRUE(CaseInsensitiveEqual("abc", "abc"));
215 EXPECT_TRUE(CaseInsensitiveEqual("ABC", "abc"));
216 EXPECT_TRUE(CaseInsensitiveEqual("abc", "ABC"));
217 EXPECT_FALSE(CaseInsensitiveEqual("abc", "AB"));
218 EXPECT_FALSE(CaseInsensitiveEqual("ab", "ABC"));
219 }
220
TEST(StringUtilsTest,SplitString)221 TEST(StringUtilsTest, SplitString) {
222 EXPECT_THAT(SplitString("", ":"), ElementsAre());
223 EXPECT_THAT(SplitString("a:b:c", ":"), ElementsAre("a", "b", "c"));
224 EXPECT_THAT(SplitString("a::b::c", "::"), ElementsAre("a", "b", "c"));
225 EXPECT_THAT(SplitString("::::a::b::::c::", "::"), ElementsAre("a", "b", "c"));
226 EXPECT_THAT(SplitString("abc", ":"), ElementsAre("abc"));
227 EXPECT_THAT(SplitString("abc", "::"), ElementsAre("abc"));
228 EXPECT_THAT(SplitString("abc", ":"), ElementsAre("abc"));
229 EXPECT_THAT(SplitString("abc", "::"), ElementsAre("abc"));
230 }
231
TEST(StringUtilsTest,Strip)232 TEST(StringUtilsTest, Strip) {
233 EXPECT_EQ(StripPrefix("abc", ""), "abc");
234 EXPECT_EQ(StripPrefix("abc", "a"), "bc");
235 EXPECT_EQ(StripPrefix("abc", "ab"), "c");
236 EXPECT_EQ(StripPrefix("abc", "abc"), "");
237 EXPECT_EQ(StripPrefix("abc", "abcd"), "abc");
238
239 EXPECT_EQ(StripSuffix("abc", ""), "abc");
240 EXPECT_EQ(StripSuffix("abc", "c"), "ab");
241 EXPECT_EQ(StripSuffix("abc", "bc"), "a");
242 EXPECT_EQ(StripSuffix("abc", "abc"), "");
243 EXPECT_EQ(StripSuffix("abc", "ebcd"), "abc");
244
245 EXPECT_EQ(StripChars("foobar", "", '_'), "foobar");
246 EXPECT_EQ(StripChars("foobar", "x", '_'), "foobar");
247 EXPECT_EQ(StripChars("foobar", "f", '_'), "_oobar");
248 EXPECT_EQ(StripChars("foobar", "o", '_'), "f__bar");
249 EXPECT_EQ(StripChars("foobar", "oa", '_'), "f__b_r");
250 EXPECT_EQ(StripChars("foobar", "fbr", '_'), "_oo_a_");
251 EXPECT_EQ(StripChars("foobar", "froab", '_'), "______");
252 }
253
TEST(StringUtilsTest,Contains)254 TEST(StringUtilsTest, Contains) {
255 EXPECT_TRUE(Contains("", ""));
256 EXPECT_TRUE(Contains("abc", ""));
257 EXPECT_TRUE(Contains("abc", "a"));
258 EXPECT_TRUE(Contains("abc", "b"));
259 EXPECT_TRUE(Contains("abc", "c"));
260 EXPECT_TRUE(Contains("abc", "ab"));
261 EXPECT_TRUE(Contains("abc", "bc"));
262 EXPECT_TRUE(Contains("abc", "abc"));
263 EXPECT_FALSE(Contains("abc", "d"));
264 EXPECT_FALSE(Contains("abc", "ac"));
265 EXPECT_FALSE(Contains("abc", "abcd"));
266 EXPECT_FALSE(Contains("", "a"));
267 EXPECT_FALSE(Contains("", "abc"));
268 }
269
TEST(StringUtilsTest,Find)270 TEST(StringUtilsTest, Find) {
271 EXPECT_EQ(Find("", ""), 0u);
272 EXPECT_EQ(Find("", "abc"), 0u);
273 EXPECT_EQ(Find("a", "abc"), 0u);
274 EXPECT_EQ(Find("b", "abc"), 1u);
275 EXPECT_EQ(Find("c", "abc"), 2u);
276 EXPECT_EQ(Find("ab", "abc"), 0u);
277 EXPECT_EQ(Find("bc", "abc"), 1u);
278 EXPECT_EQ(Find("abc", "abc"), 0u);
279 EXPECT_EQ(Find("d", "abc"), std::string::npos);
280 EXPECT_EQ(Find("ac", "abc"), std::string::npos);
281 EXPECT_EQ(Find("abcd", "abc"), std::string::npos);
282 EXPECT_EQ(Find("a", ""), std::string::npos);
283 EXPECT_EQ(Find("abc", ""), std::string::npos);
284 }
285
TEST(StringUtilsTest,ReplaceAll)286 TEST(StringUtilsTest, ReplaceAll) {
287 EXPECT_EQ(ReplaceAll("", "a", ""), "");
288 EXPECT_EQ(ReplaceAll("", "a", "b"), "");
289 EXPECT_EQ(ReplaceAll("a", "a", "b"), "b");
290 EXPECT_EQ(ReplaceAll("aaaa", "a", "b"), "bbbb");
291 EXPECT_EQ(ReplaceAll("aaaa", "aa", "b"), "bb");
292 EXPECT_EQ(ReplaceAll("aa", "aa", "bb"), "bb");
293 EXPECT_EQ(ReplaceAll("aa", "a", "bb"), "bbbb");
294 EXPECT_EQ(ReplaceAll("abc", "a", "b"), "bbc");
295 EXPECT_EQ(ReplaceAll("abc", "c", "b"), "abb");
296 EXPECT_EQ(ReplaceAll("abc", "c", "bbb"), "abbbb");
297 }
298
TEST(StringUtilsTest,StringCopy)299 TEST(StringUtilsTest, StringCopy) {
300 // Nothing should be written when |dst_size| = 0.
301 {
302 char dst[2] = {42, 43};
303 StringCopy(dst, "12345", 0);
304 EXPECT_EQ(42, dst[0]);
305 EXPECT_EQ(43, dst[1]);
306 }
307
308 // Nominal case, len(src) < sizeof(dst).
309 {
310 UninitializedBuf<10> dst;
311 StringCopy(dst, "1234567", sizeof(dst));
312 EXPECT_STREQ(dst, "1234567");
313 }
314
315 // Edge case where we perfectly fit including the \0.
316 {
317 UninitializedBuf<8> dst;
318 StringCopy(dst, "1234567", sizeof(dst));
319 EXPECT_STREQ(dst, "1234567");
320 }
321
322 // Edge case where |dst| is smaller by one char.
323 {
324 UninitializedBuf<8> dst;
325 StringCopy(dst, "12345678", sizeof(dst));
326 EXPECT_STREQ(dst, "1234567");
327 }
328
329 // Case when |dst| is smaller than |src|.
330 {
331 UninitializedBuf<3> dst;
332 StringCopy(dst, "12345678", sizeof(dst));
333 EXPECT_STREQ(dst, "12");
334 }
335 }
336
TEST(StringUtilsTest,SprintfTrunc)337 TEST(StringUtilsTest, SprintfTrunc) {
338 {
339 UninitializedBuf<3> dst;
340 ASSERT_EQ(0u, SprintfTrunc(dst, sizeof(dst), "%s", ""));
341 EXPECT_STREQ(dst, "");
342 }
343
344 {
345 char dst[3]{'O', 'K', '\0'};
346 ASSERT_EQ(0u, SprintfTrunc(dst, 0, "whatever"));
347 EXPECT_STREQ(dst, "OK"); // dst_size == 0 shouldn't touch the buffer.
348 }
349
350 {
351 UninitializedBuf<1> dst;
352 ASSERT_EQ(0u, SprintfTrunc(dst, sizeof(dst), "whatever"));
353 EXPECT_STREQ(dst, "");
354 }
355
356 {
357 UninitializedBuf<3> dst;
358 ASSERT_EQ(1u, SprintfTrunc(dst, sizeof(dst), "1"));
359 EXPECT_STREQ(dst, "1");
360 }
361
362 {
363 UninitializedBuf<3> dst;
364 ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "12"));
365 EXPECT_STREQ(dst, "12");
366 }
367
368 {
369 UninitializedBuf<3> dst;
370 ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "123"));
371 EXPECT_STREQ(dst, "12");
372 }
373
374 {
375 UninitializedBuf<3> dst;
376 ASSERT_EQ(2u, SprintfTrunc(dst, sizeof(dst), "1234"));
377 EXPECT_STREQ(dst, "12");
378 }
379
380 {
381 UninitializedBuf<11> dst;
382 ASSERT_EQ(10u, SprintfTrunc(dst, sizeof(dst), "a %d b %s", 42, "foo"));
383 EXPECT_STREQ(dst, "a 42 b foo");
384 }
385 }
386
TEST(StringUtilsTest,StackString)387 TEST(StringUtilsTest, StackString) {
388 {
389 StackString<1> s("123");
390 EXPECT_EQ(0u, s.len());
391 EXPECT_STREQ("", s.c_str());
392 }
393
394 {
395 StackString<4> s("123");
396 EXPECT_EQ(3u, s.len());
397 EXPECT_STREQ("123", s.c_str());
398 EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
399 EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
400 }
401
402 {
403 StackString<3> s("123");
404 EXPECT_EQ(2u, s.len());
405 EXPECT_STREQ("12", s.c_str());
406 EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
407 EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
408 }
409
410 {
411 StackString<11> s("foo %d %s", 42, "bar!!!OVERFLOW");
412 EXPECT_EQ(10u, s.len());
413 EXPECT_STREQ("foo 42 bar", s.c_str());
414 EXPECT_EQ(s.ToStdString(), std::string(s.c_str()));
415 EXPECT_EQ(s.string_view().ToStdString(), s.ToStdString());
416 }
417 }
418
419 } // namespace
420 } // namespace base
421 } // namespace perfetto
422