• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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