1 /*
2 Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef MYSQL_HARNESS_UTILITIES_INCLUDED
26 #define MYSQL_HARNESS_UTILITIES_INCLUDED
27
28 #include <memory>
29 #include <ostream>
30 #include <string>
31 #include <vector>
32
33 #include "my_compiler.h"
34
35 #include "harness_export.h"
36 #include "mysql/harness/utility/string.h"
37 #include "router_config.h"
38
39 namespace mysql_harness {
40
41 namespace utility {
42
43 /**
44 * Class to turn C array into range.
45 *
46 * @see make_range
47 */
48
49 template <class Type>
50 class Range {
51 public:
52 class iterator {
53 public:
iterator(Type * ptr)54 explicit iterator(Type *ptr) : ptr_(ptr) {}
55
56 iterator &operator++() {
57 ++ptr_;
58 return *this;
59 }
60
61 bool operator==(const iterator &rhs) { return ptr_ == rhs.ptr_; }
62
63 bool operator!=(const iterator &rhs) { return ptr_ != rhs.ptr_; }
64
65 Type &operator*() { return *ptr_; }
66
67 const Type &operator*() const { return *ptr_; }
68
69 private:
70 Type *ptr_;
71 };
72
Range(Type * ptr,size_t length)73 Range(Type *ptr, size_t length) : start_(ptr), finish_(ptr + length) {}
74
begin()75 iterator begin() { return iterator(start_); }
76
end()77 iterator end() { return iterator(finish_); }
78
79 private:
80 Type *start_;
81 Type *finish_;
82 };
83
84 /**
85 * Create a range from a plain C array.
86 *
87 * This function create a range from a plain array so that arrays can
88 * be used in range-based loops.
89 *
90 * @see Range
91 */
92
93 template <class Type>
make_range(Type * ptr,size_t length)94 Range<Type> make_range(Type *ptr, size_t length) {
95 return Range<Type>(ptr, length);
96 }
97
98 /**
99 * Class for creating a reverse range from another range.
100 */
101
102 template <typename Range>
103 class RangeReverse {
104 public:
RangeReverse(Range & range)105 explicit RangeReverse(Range &range) : range_(range) {}
106
begin()107 typename Range::reverse_iterator begin() { return range_.rbegin(); }
108
begin()109 typename Range::const_reverse_iterator begin() const {
110 return range_.rbegin();
111 }
112
end()113 typename Range::reverse_iterator end() { return range_.rend(); }
114
end()115 typename Range::const_reverse_iterator end() const { return range_.rend(); }
116
117 private:
118 Range &range_;
119 };
120
121 /**
122 * Iterate over a range in reverse.
123 *
124 * Function take a range, which can be any sequence container, and
125 * return a reverse range that iterate the sequence in reverse.
126 *
127 * Typical use-case is:
128 * @code
129 * for (auto item : reverse_iterate(my_list)) {
130 * ...
131 * }
132 * @endcode
133 */
134 template <typename Range>
reverse(Range & x)135 RangeReverse<Range> reverse(Range &x) { // NOLINT(runtime/references)
136 return RangeReverse<Range>(x);
137 }
138
139 template <class Map>
find_range_first(Map & assoc,const typename Map::key_type::first_type & first,typename Map::iterator start)140 std::pair<typename Map::iterator, typename Map::iterator> find_range_first(
141 Map &assoc, // NOLINT(runtime/references)
142 const typename Map::key_type::first_type &first,
143 typename Map::iterator start) {
144 typename Map::iterator finish = start;
145 while (finish != assoc.end() && finish->first.first == first) ++finish;
146 return make_pair(start, finish);
147 }
148
149 template <class Map>
find_range_first(Map & assoc,const typename Map::key_type::first_type & first)150 std::pair<typename Map::iterator, typename Map::iterator> find_range_first(
151 Map &assoc, // NOLINT(runtime/references)
152 const typename Map::key_type::first_type &first) {
153 typedef typename Map::key_type::second_type SType;
154 return find_range_first(assoc, first,
155 assoc.lower_bound(make_pair(first, SType())));
156 }
157
158 template <class Map>
159 std::pair<typename Map::const_iterator, typename Map::const_iterator>
find_range_first(const Map & assoc,const typename Map::key_type::first_type & first,typename Map::const_iterator start)160 find_range_first(const Map &assoc,
161 const typename Map::key_type::first_type &first,
162 typename Map::const_iterator start) {
163 typename Map::const_iterator finish = start;
164 while (finish != assoc.end() && finish->first.first == first) ++finish;
165 return make_pair(start, finish);
166 }
167
168 template <class Map>
169 std::pair<typename Map::const_iterator, typename Map::const_iterator>
find_range_first(const Map & assoc,const typename Map::key_type::first_type & first)170 find_range_first(const Map &assoc,
171 const typename Map::key_type::first_type &first) {
172 typedef typename Map::key_type::second_type SType;
173 return find_range_first(assoc, first,
174 assoc.lower_bound(make_pair(first, SType())));
175 }
176
177 std::string dirname(const std::string &path);
178 std::string basename(const std::string &path);
179
180 /**
181 * Remove starting and trailing delimiters from string.
182 */
183 void strip(std::string *str, const char *chars = " \t\n\r\f\v");
184 HARNESS_EXPORT
185 std::string strip_copy(std::string str, const char *chars = " \t\n\r\f\v");
186
187 HARNESS_EXPORT
188 MY_ATTRIBUTE((format(printf, 1, 2)))
189 std::string string_format(const char *format, ...);
190
191 bool matches_glob(const std::string &word, const std::string &pattern);
192
193 /*
194 * Checks wheter given string matches the pattern using extended posix regex.
195 */
196 bool regex_pattern_matches(const std::string &s, const std::string &pattern);
197
198 } // namespace utility
199
200 } // namespace mysql_harness
201 #endif /* MYSQL_HARNESS_UTILITIES_INCLUDED */
202