]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_string.h
update sources to v12.1.3
[ceph.git] / ceph / src / rgw / rgw_string.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#ifndef CEPH_RGW_STRING_H
5#define CEPH_RGW_STRING_H
6
31f18b77 7#include <errno.h>
7c673cae
FG
8#include <stdlib.h>
9#include <limits.h>
10
31f18b77
FG
11#include <boost/container/small_vector.hpp>
12#include <boost/utility/string_view.hpp>
13
7c673cae
FG
14struct ltstr_nocase
15{
31f18b77 16 bool operator()(const std::string& s1, const std::string& s2) const
7c673cae
FG
17 {
18 return strcasecmp(s1.c_str(), s2.c_str()) < 0;
19 }
20};
21
31f18b77 22static inline int stringcasecmp(const std::string& s1, const std::string& s2)
7c673cae
FG
23{
24 return strcasecmp(s1.c_str(), s2.c_str());
25}
26
31f18b77 27static inline int stringcasecmp(const std::string& s1, const char *s2)
7c673cae
FG
28{
29 return strcasecmp(s1.c_str(), s2);
30}
31
31f18b77 32static inline int stringcasecmp(const std::string& s1, int ofs, int size, const std::string& s2)
7c673cae
FG
33{
34 return strncasecmp(s1.c_str() + ofs, s2.c_str(), size);
35}
36
31f18b77 37static inline int stringtoll(const std::string& s, int64_t *val)
7c673cae
FG
38{
39 char *end;
40
41 long long result = strtoll(s.c_str(), &end, 10);
42 if (result == LLONG_MAX)
43 return -EINVAL;
44
45 if (*end)
46 return -EINVAL;
47
48 *val = (int64_t)result;
49
50 return 0;
51}
52
31f18b77 53static inline int stringtoull(const std::string& s, uint64_t *val)
7c673cae
FG
54{
55 char *end;
56
57 unsigned long long result = strtoull(s.c_str(), &end, 10);
58 if (result == ULLONG_MAX)
59 return -EINVAL;
60
61 if (*end)
62 return -EINVAL;
63
64 *val = (uint64_t)result;
65
66 return 0;
67}
68
31f18b77 69static inline int stringtol(const std::string& s, int32_t *val)
7c673cae
FG
70{
71 char *end;
72
73 long result = strtol(s.c_str(), &end, 10);
74 if (result == LONG_MAX)
75 return -EINVAL;
76
77 if (*end)
78 return -EINVAL;
79
80 *val = (int32_t)result;
81
82 return 0;
83}
84
31f18b77 85static inline int stringtoul(const std::string& s, uint32_t *val)
7c673cae
FG
86{
87 char *end;
88
89 unsigned long result = strtoul(s.c_str(), &end, 10);
90 if (result == ULONG_MAX)
91 return -EINVAL;
92
93 if (*end)
94 return -EINVAL;
95
96 *val = (uint32_t)result;
97
98 return 0;
99}
100
31f18b77
FG
101/* A converter between boost::string_view and null-terminated C-strings.
102 * It copies memory while trying to utilize the local memory instead of
103 * issuing dynamic allocations. */
104template<std::size_t N = 128>
105static inline boost::container::small_vector<char, N>
106sview2cstr(const boost::string_view& sv)
107{
108 boost::container::small_vector<char, N> cstr;
109 cstr.reserve(sv.size() + sizeof('\0'));
110
111 cstr.assign(std::begin(sv), std::end(sv));
112 cstr.push_back('\0');
113
114 return cstr;
115}
116
117/* std::strlen() isn't guaranteed to be computable at compile-time. Although
118 * newer GCCs actually do that, Clang doesn't. Please be aware this function
119 * IS NOT A DROP-IN REPLACEMENT FOR STRLEN -- it returns a different result
120 * for strings having \0 in the middle. */
121template<size_t N>
122static inline constexpr size_t sarrlen(const char (&arr)[N]) {
123 return N - 1;
124}
125
126namespace detail {
127
128// variadic sum() to add up string lengths for reserve()
129static inline constexpr size_t sum() { return 0; }
130template <typename... Args>
131constexpr size_t sum(size_t v, Args... args) { return v + sum(args...); }
132
133// traits for string_size()
134template <typename T>
135struct string_traits {
136 static constexpr size_t size(const T& s) { return s.size(); }
137};
138// specializations for char*/const char* use strlen()
139template <>
140struct string_traits<const char*> {
141 static size_t size(const char* s) { return std::strlen(s); }
142};
143template <>
144struct string_traits<char*> : string_traits<const char*> {};
145// constexpr specializations for char[]/const char[]
146template <std::size_t N>
147struct string_traits<const char[N]> {
148 static constexpr size_t size_(const char* s, size_t i) {
149 return i < N ? (*(s + i) == '\0' ? i : size_(s, i + 1))
150 : throw std::invalid_argument("Unterminated string constant.");
151 }
152 static constexpr size_t size(const char(&s)[N]) { return size_(s, 0); }
153};
154template <std::size_t N>
155struct string_traits<char[N]> : string_traits<const char[N]> {};
156
157// helpers for string_cat_reserve()
158static inline void append_to(std::string& s) {}
159template <typename... Args>
160void append_to(std::string& s, const boost::string_view& v, const Args&... args)
161{
162 s.append(v.begin(), v.end());
163 append_to(s, args...);
164}
165
166// helpers for string_join_reserve()
167static inline void join_next(std::string& s, const boost::string_view& d) {}
168template <typename... Args>
169void join_next(std::string& s, const boost::string_view& d,
170 const boost::string_view& v, const Args&... args)
171{
172 s.append(d.begin(), d.end());
173 s.append(v.begin(), v.end());
174 join_next(s, d, args...);
175}
176
177static inline void join(std::string& s, const boost::string_view& d) {}
178template <typename... Args>
179void join(std::string& s, const boost::string_view& d,
180 const boost::string_view& v, const Args&... args)
181{
182 s.append(v.begin(), v.end());
183 join_next(s, d, args...);
184}
185
186} // namespace detail
187
188/// return the length of a c string, string literal, or string type
189template <typename T>
190constexpr size_t string_size(const T& s)
191{
192 return detail::string_traits<T>::size(s);
193}
194
195/// concatenates the given string arguments, returning as a std::string that
196/// gets preallocated with reserve()
197template <typename... Args>
198std::string string_cat_reserve(const Args&... args)
199{
200 size_t total_size = detail::sum(string_size(args)...);
201 std::string result;
202 result.reserve(total_size);
203 detail::append_to(result, args...);
204 return result;
205}
206
207/// joins the given string arguments with a delimiter, returning as a
208/// std::string that gets preallocated with reserve()
209template <typename... Args>
210std::string string_join_reserve(const boost::string_view& delim,
211 const Args&... args)
212{
213 size_t delim_size = delim.size() * std::max<ssize_t>(0, sizeof...(args) - 1);
214 size_t total_size = detail::sum(string_size(args)...) + delim_size;
215 std::string result;
216 result.reserve(total_size);
217 detail::join(result, delim, args...);
218 return result;
219}
220template <typename... Args>
221std::string string_join_reserve(char delim, const Args&... args)
222{
223 return string_join_reserve(boost::string_view{&delim, 1}, args...);
224}
225
d2e6a577
FG
226
227/// use case-insensitive comparison in match_wildcards()
228static constexpr uint32_t MATCH_CASE_INSENSITIVE = 0x01;
229
230/// attempt to match the given input string with the pattern, which may contain
231/// the wildcard characters * and ?
232extern bool match_wildcards(boost::string_view pattern,
233 boost::string_view input,
234 uint32_t flags = 0);
235
7c673cae 236#endif