Coverage Report

Created: 2026-01-13 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/perfetto/buildtools/android-libbase/strings.cpp
Line
Count
Source
1
/*
2
 * Copyright (C) 2015 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 "android-base/strings.h"
18
19
#include <stdlib.h>
20
#include <string.h>
21
22
#include <string>
23
#include <vector>
24
25
namespace android {
26
namespace base {
27
28
#define CHECK_NE(a, b) \
29
0
  if ((a) == (b)) abort();
30
31
std::vector<std::string> Split(const std::string& s,
32
0
                               const std::string& delimiters) {
33
0
  CHECK_NE(delimiters.size(), 0U);
34
35
0
  std::vector<std::string> result;
36
37
0
  size_t base = 0;
38
0
  size_t found;
39
0
  while (true) {
40
0
    found = s.find_first_of(delimiters, base);
41
0
    result.push_back(s.substr(base, found - base));
42
0
    if (found == s.npos) break;
43
0
    base = found + 1;
44
0
  }
45
46
0
  return result;
47
0
}
48
49
0
std::string Trim(const std::string& s) {
50
0
  std::string result;
51
52
0
  if (s.size() == 0) {
53
0
    return result;
54
0
  }
55
56
0
  size_t start_index = 0;
57
0
  size_t end_index = s.size() - 1;
58
59
  // Skip initial whitespace.
60
0
  while (start_index < s.size()) {
61
0
    if (!isspace(s[start_index])) {
62
0
      break;
63
0
    }
64
0
    start_index++;
65
0
  }
66
67
  // Skip terminating whitespace.
68
0
  while (end_index >= start_index) {
69
0
    if (!isspace(s[end_index])) {
70
0
      break;
71
0
    }
72
0
    end_index--;
73
0
  }
74
75
  // All spaces, no beef.
76
0
  if (end_index < start_index) {
77
0
    return "";
78
0
  }
79
  // Start_index is the first non-space, end_index is the last one.
80
0
  return s.substr(start_index, end_index - start_index + 1);
81
0
}
82
83
// These cases are probably the norm, so we mark them extern in the header to
84
// aid compile time and binary size.
85
template std::string Join(const std::vector<std::string>&, char);
86
template std::string Join(const std::vector<const char*>&, char);
87
template std::string Join(const std::vector<std::string>&, const std::string&);
88
template std::string Join(const std::vector<const char*>&, const std::string&);
89
90
0
bool StartsWith(std::string_view s, std::string_view prefix) {
91
0
  return s.substr(0, prefix.size()) == prefix;
92
0
}
93
94
0
bool StartsWith(std::string_view s, char prefix) {
95
0
  return !s.empty() && s.front() == prefix;
96
0
}
97
98
0
bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix) {
99
0
  return s.size() >= prefix.size() && strncasecmp(s.data(), prefix.data(), prefix.size()) == 0;
100
0
}
101
102
0
bool EndsWith(std::string_view s, std::string_view suffix) {
103
0
  return s.size() >= suffix.size() && s.substr(s.size() - suffix.size(), suffix.size()) == suffix;
104
0
}
105
106
0
bool EndsWith(std::string_view s, char suffix) {
107
0
  return !s.empty() && s.back() == suffix;
108
0
}
109
110
0
bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix) {
111
0
  return s.size() >= suffix.size() &&
112
0
         strncasecmp(s.data() + (s.size() - suffix.size()), suffix.data(), suffix.size()) == 0;
113
0
}
114
115
0
bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs) {
116
0
  return lhs.size() == rhs.size() && strncasecmp(lhs.data(), rhs.data(), lhs.size()) == 0;
117
0
}
118
119
std::string StringReplace(std::string_view s, std::string_view from, std::string_view to,
120
0
                          bool all) {
121
0
  if (from.empty()) return std::string(s);
122
123
0
  std::string result;
124
0
  std::string_view::size_type start_pos = 0;
125
0
  do {
126
0
    std::string_view::size_type pos = s.find(from, start_pos);
127
0
    if (pos == std::string_view::npos) break;
128
129
0
    result.append(s.data() + start_pos, pos - start_pos);
130
0
    result.append(to.data(), to.size());
131
132
0
    start_pos = pos + from.size();
133
0
  } while (all);
134
0
  result.append(s.data() + start_pos, s.size() - start_pos);
135
0
  return result;
136
0
}
137
138
}  // namespace base
139
}  // namespace android