Coverage Report

Created: 2024-11-21 14:46

/root/doris/be/src/util/string_util.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <strings.h>
21
22
#include <algorithm>
23
#include <boost/token_functions.hpp>
24
#include <boost/tokenizer.hpp>
25
#include <cctype>
26
#include <cstddef>
27
#include <map>
28
#include <set>
29
#include <sstream>
30
#include <string>
31
#include <unordered_map>
32
#include <unordered_set>
33
#include <vector>
34
35
namespace doris {
36
37
3.97k
inline std::string to_lower(const std::string& input) {
38
3.97k
    std::string output;
39
3.97k
    output.resize(input.size());
40
3.97k
    std::transform(input.begin(), input.end(), output.begin(),
41
17.6k
                   [](unsigned char c) { return std::tolower(c); });
42
3.97k
    return output;
43
3.97k
}
44
45
29
inline std::string to_upper(const std::string& input) {
46
29
    std::string output;
47
29
    output.resize(input.size());
48
29
    std::transform(input.begin(), input.end(), output.begin(),
49
137
                   [](unsigned char c) { return std::toupper(c); });
50
29
    return output;
51
29
}
52
53
49
inline bool iequal(const std::string& lhs, const std::string& rhs) {
54
49
    if (lhs.size() != rhs.size()) {
55
22
        return false;
56
22
    }
57
27
    return to_lower(lhs) == to_lower(rhs);
58
49
}
59
60
9
inline bool starts_with(const std::string& value, const std::string& beginning) {
61
9
    return value.find(beginning) == 0;
62
9
}
63
64
8
inline bool ends_with(std::string const& value, std::string const& ending) {
65
8
    if (ending.size() > value.size()) {
66
1
        return false;
67
1
    }
68
7
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
69
8
}
70
71
7
inline std::vector<std::string> split(const std::string& s, const std::string& delim) {
72
7
    std::vector<std::string> out;
73
7
    size_t pos {};
74
75
20
    for (size_t find = 0; (find = s.find(delim, pos)) != std::string::npos;
76
13
         pos = find + delim.size()) {
77
13
        out.emplace_back(s.data() + pos, s.data() + find);
78
13
    }
79
80
7
    out.emplace_back(s.data() + pos, s.data() + s.size());
81
7
    return out;
82
7
}
83
84
template <typename T>
85
3
std::string join(const std::vector<T>& elems, const std::string& delim) {
86
3
    std::stringstream ss;
87
13
    for (size_t i = 0; i < elems.size(); ++i) {
88
10
        if (i != 0) {
89
8
            ss << delim.c_str();
90
8
        }
91
10
        ss << elems[i];
92
10
    }
93
3
    return ss.str();
94
3
}
95
96
struct StringCaseHasher {
97
public:
98
252
    std::size_t operator()(const std::string& value) const {
99
252
        std::string lower_value = to_lower(value);
100
252
        return std::hash<std::string>()(lower_value);
101
252
    }
102
};
103
104
struct StringCaseEqual {
105
public:
106
106
    bool operator()(const std::string& lhs, const std::string& rhs) const {
107
106
        if (lhs.size() != rhs.size()) {
108
0
            return false;
109
0
        }
110
106
        return strncasecmp(lhs.c_str(), rhs.c_str(), lhs.size()) == 0;
111
106
    }
112
};
113
114
struct StringCaseLess {
115
public:
116
38
    bool operator()(const std::string& lhs, const std::string& rhs) const {
117
38
        size_t common_size = std::min(lhs.size(), rhs.size());
118
38
        auto cmp = strncasecmp(lhs.c_str(), rhs.c_str(), common_size);
119
38
        if (cmp == 0) {
120
30
            return lhs.size() < rhs.size();
121
30
        }
122
8
        return cmp < 0;
123
38
    }
124
};
125
126
size_t hash_of_path(const std::string& identifier, const std::string& path);
127
128
using StringCaseSet = std::set<std::string, StringCaseLess>;
129
using StringCaseUnorderedSet = std::unordered_set<std::string, StringCaseHasher, StringCaseEqual>;
130
template <class T>
131
using StringCaseMap = std::map<std::string, T, StringCaseLess>;
132
template <class T>
133
using StringCaseUnorderedMap =
134
        std::unordered_map<std::string, T, StringCaseHasher, StringCaseEqual>;
135
136
template <typename T>
137
14
auto get_json_token(T& path_string) {
138
14
    return boost::tokenizer<boost::escaped_list_separator<char>>(
139
14
            path_string, boost::escaped_list_separator<char>("\\", ".", "\""));
140
14
}
141
142
#ifdef USE_LIBCPP
143
template <>
144
auto get_json_token(std::string_view& path_string) = delete;
145
#endif
146
147
} // namespace doris