Coverage Report

Created: 2026-01-07 02:43

/root/doris/be/src/gutil/strings/stringpiece.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2004 and onwards Google Inc.
2
//
3
//
4
5
#include "gutil/strings/stringpiece.h"
6
7
// IWYU pragma: no_include <pstl/glue_algorithm_defs.h>
8
9
#include "common/logging.h"
10
#include <string.h>
11
#include <algorithm>
12
#include <climits>
13
#include <string>
14
#include <deque>
15
#include <ostream>
16
17
#include "gutil/stl_util.h"
18
#include "gutil/strings/memutil.h"
19
#include "gutil/hash/legacy_hash.h"
20
21
using std::copy;
22
using std::max;
23
using std::min;
24
using std::reverse;
25
using std::sort;
26
using std::swap;
27
using std::string;
28
29
0
size_t std::hash<StringPiece>::operator()(StringPiece s) const {
30
0
    return HashTo32(s.data(), s.size());
31
0
}
32
33
0
std::ostream& operator<<(std::ostream& o, StringPiece piece) {
34
0
    o.write(piece.data(), piece.size());
35
0
    return o;
36
0
}
37
38
0
StringPiece::StringPiece(StringPiece x, int pos) : ptr_(x.ptr_ + pos), length_(x.length_ - pos) {
39
0
    DCHECK_LE(0, pos);
40
0
    DCHECK_LE(pos, x.length_);
41
0
}
42
43
StringPiece::StringPiece(StringPiece x, int pos, int len)
44
0
        : ptr_(x.ptr_ + pos), length_(min(len, x.length_ - pos)) {
45
0
    DCHECK_LE(0, pos);
46
0
    DCHECK_LE(pos, x.length_);
47
0
    DCHECK_GE(len, 0);
48
0
}
49
50
0
void StringPiece::CopyToString(string* target) const {
51
0
    STLAssignToString(target, ptr_, length_);
52
0
}
53
54
0
void StringPiece::AppendToString(string* target) const {
55
0
    STLAppendToString(target, ptr_, length_);
56
0
}
57
58
0
int StringPiece::copy(char* buf, size_type n, size_type pos) const {
59
0
    int ret = min(length_ - pos, n);
60
0
    memcpy(buf, ptr_ + pos, ret);
61
0
    return ret;
62
0
}
63
64
0
bool StringPiece::contains(StringPiece s) const {
65
0
    return find(s, 0) != npos;
66
0
}
67
68
3.66k
int StringPiece::find(StringPiece s, size_type pos) const {
69
3.66k
    if (length_ <= 0 || pos > static_cast<size_type>(length_)) {
70
46
        if (length_ == 0 && pos == 0 && s.length_ == 0) return 0;
71
46
        return npos;
72
46
    }
73
3.61k
    const char* result = memmatch(ptr_ + pos, length_ - pos, s.ptr_, s.length_);
74
3.61k
    return result ? result - ptr_ : npos;
75
3.66k
}
76
77
0
int StringPiece::find(char c, size_type pos) const {
78
0
    if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
79
0
        return npos;
80
0
    }
81
0
    const char* result = static_cast<const char*>(memchr(ptr_ + pos, c, length_ - pos));
82
0
    return result != nullptr ? result - ptr_ : npos;
83
0
}
84
85
0
int StringPiece::rfind(StringPiece s, size_type pos) const {
86
0
    if (length_ < s.length_) return npos;
87
0
    const size_t ulen = length_;
88
0
    if (s.length_ == 0) return min(ulen, pos);
89
90
0
    const char* last = ptr_ + min(ulen - s.length_, pos) + s.length_;
91
0
    const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
92
0
    return result != last ? result - ptr_ : npos;
93
0
}
94
95
// Search range is [0..pos] inclusive.  If pos == npos, search everything.
96
0
int StringPiece::rfind(char c, size_type pos) const {
97
    // Note: memrchr() is not available on Windows.
98
0
    if (length_ <= 0) return npos;
99
0
    for (int i = min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
100
0
        if (ptr_[i] == c) {
101
0
            return i;
102
0
        }
103
0
    }
104
0
    return npos;
105
0
}
106
107
// For each character in characters_wanted, sets the index corresponding
108
// to the ASCII code of that character to 1 in table.  This is used by
109
// the find_.*_of methods below to tell whether or not a character is in
110
// the lookup table in constant time.
111
// The argument `table' must be an array that is large enough to hold all
112
// the possible values of an unsigned char.  Thus it should be be declared
113
// as follows:
114
//   bool table[UCHAR_MAX + 1]
115
0
static inline void BuildLookupTable(StringPiece characters_wanted, bool* table) {
116
0
    const int length = characters_wanted.length();
117
0
    const char* const data = characters_wanted.data();
118
0
    for (int i = 0; i < length; ++i) {
119
0
        table[static_cast<unsigned char>(data[i])] = true;
120
0
    }
121
0
}
122
123
0
int StringPiece::find_first_of(StringPiece s, size_type pos) const {
124
0
    if (length_ <= 0 || s.length_ <= 0) {
125
0
        return npos;
126
0
    }
127
    // Avoid the cost of BuildLookupTable() for a single-character search.
128
0
    if (s.length_ == 1) return find_first_of(s.ptr_[0], pos);
129
130
0
    bool lookup[UCHAR_MAX + 1] = {false};
131
0
    BuildLookupTable(s, lookup);
132
0
    for (int i = pos; i < length_; ++i) {
133
0
        if (lookup[static_cast<unsigned char>(ptr_[i])]) {
134
0
            return i;
135
0
        }
136
0
    }
137
0
    return npos;
138
0
}
139
140
0
int StringPiece::find_first_not_of(StringPiece s, size_type pos) const {
141
0
    if (length_ <= 0) return npos;
142
0
    if (s.length_ <= 0) return 0;
143
    // Avoid the cost of BuildLookupTable() for a single-character search.
144
0
    if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
145
146
0
    bool lookup[UCHAR_MAX + 1] = {false};
147
0
    BuildLookupTable(s, lookup);
148
0
    for (int i = pos; i < length_; ++i) {
149
0
        if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
150
0
            return i;
151
0
        }
152
0
    }
153
0
    return npos;
154
0
}
155
156
0
int StringPiece::find_first_not_of(char c, size_type pos) const {
157
0
    if (length_ <= 0) return npos;
158
159
0
    for (; pos < static_cast<size_type>(length_); ++pos) {
160
0
        if (ptr_[pos] != c) {
161
0
            return pos;
162
0
        }
163
0
    }
164
0
    return npos;
165
0
}
166
167
0
int StringPiece::find_last_of(StringPiece s, size_type pos) const {
168
0
    if (length_ <= 0 || s.length_ <= 0) return npos;
169
    // Avoid the cost of BuildLookupTable() for a single-character search.
170
0
    if (s.length_ == 1) return find_last_of(s.ptr_[0], pos);
171
172
0
    bool lookup[UCHAR_MAX + 1] = {false};
173
0
    BuildLookupTable(s, lookup);
174
0
    for (int i = min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
175
0
        if (lookup[static_cast<unsigned char>(ptr_[i])]) {
176
0
            return i;
177
0
        }
178
0
    }
179
0
    return npos;
180
0
}
181
182
0
int StringPiece::find_last_not_of(StringPiece s, size_type pos) const {
183
0
    if (length_ <= 0) return npos;
184
185
0
    int i = min(pos, static_cast<size_type>(length_ - 1));
186
0
    if (s.length_ <= 0) return i;
187
188
    // Avoid the cost of BuildLookupTable() for a single-character search.
189
0
    if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos);
190
191
0
    bool lookup[UCHAR_MAX + 1] = {false};
192
0
    BuildLookupTable(s, lookup);
193
0
    for (; i >= 0; --i) {
194
0
        if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
195
0
            return i;
196
0
        }
197
0
    }
198
0
    return npos;
199
0
}
200
201
0
int StringPiece::find_last_not_of(char c, size_type pos) const {
202
0
    if (length_ <= 0) return npos;
203
204
0
    for (int i = min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
205
0
        if (ptr_[i] != c) {
206
0
            return i;
207
0
        }
208
0
    }
209
0
    return npos;
210
0
}
211
212
0
StringPiece StringPiece::substr(size_type pos, size_type n) const {
213
0
    if (pos > length_) pos = length_;
214
0
    if (n > length_ - pos) n = length_ - pos;
215
0
    return StringPiece(ptr_ + pos, n);
216
0
}
217
218
const StringPiece::size_type StringPiece::npos = size_type(-1);