MySQL 9.3.0
Source Code Documentation
utils_string.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
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 designed to work 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 either included with
14 * the program or referenced in the documentation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License, version 2.0, for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#ifndef MYSQLSHDK_LIBS_UTILS_UTILS_STRING_H_
27#define MYSQLSHDK_LIBS_UTILS_UTILS_STRING_H_
28
29#include <wctype.h>
30
31#include <algorithm>
32#include <cctype>
33#include <cstdint>
34#include <cstring>
35#include <cwchar>
36#include <string>
37#include <string_view>
38#include <unordered_map>
39#include <unordered_set>
40#include <utility>
41#include <vector>
42
43#include "mysqlrouter/jit_executor_plugin_export.h"
44
45namespace shcore {
46
47void clear_buffer(char *buffer, size_t size);
48void clear_buffer(std::string &buffer);
49
50namespace internal {
51
52template <typename Char, typename F>
53inline std::basic_string<Char> transform(std::basic_string_view<Char> s,
54 F fun) {
55 std::basic_string<Char> r(s);
56 std::transform(r.begin(), r.end(), r.begin(), fun);
57 return r;
58}
59
60} // namespace internal
61
62/** Convert a copy of an ASCII string to uppercase and return */
63inline std::string str_upper(std::string_view s) {
64 return internal::transform(s, ::toupper);
65}
66
67inline std::wstring str_upper(std::wstring_view s) {
68 return internal::transform(s, ::towupper);
69}
70
71/** Convert a copy of an ASCII string to lowercase and return */
72inline std::string str_lower(std::string_view s) {
73 return internal::transform(s, ::tolower);
74}
75
76inline std::wstring str_lower(std::wstring_view s) {
77 return internal::transform(s, ::towlower);
78}
79
80/** Compares 2 strings case insensitive (for ascii) */
81inline int str_casecmp(const char *a, const char *b) {
82#ifdef _WIN32
83 return ::_stricmp(a, b);
84#else
85 return ::strcasecmp(a, b);
86#endif
87}
88
89inline int str_casecmp(const wchar_t *a, const wchar_t *b) {
90#ifdef _WIN32
91 return ::_wcsicmp(a, b);
92#else
93 return ::wcscasecmp(a, b);
94#endif
95}
96
97inline int str_casecmp(const char *a, const char *b, size_t n) {
98#ifdef _WIN32
99 return ::_strnicmp(a, b, n);
100#else
101 return ::strncasecmp(a, b, n);
102#endif
103}
104
105inline int str_casecmp(const wchar_t *a, const wchar_t *b, size_t n) {
106#ifdef _WIN32
107 return ::_wcsnicmp(a, b, n);
108#else
109 return ::wcsncasecmp(a, b, n);
110#endif
111}
112
114 bool operator()(const std::string &a, const std::string &b) const {
115 return a.compare(b) < 0;
116 }
117
118 bool operator()(const std::wstring &a, const std::wstring &b) const {
119 return a.compare(b) < 0;
120 }
121};
122
124 bool operator()(const std::string &a, const std::string &b) const {
125 return str_casecmp(a.c_str(), b.c_str()) < 0;
126 }
127
128 bool operator()(const std::wstring &a, const std::wstring &b) const {
129 return str_casecmp(a.c_str(), b.c_str()) < 0;
130 }
131};
132
134 bool case_sensitive{true};
135 Case_comparator(bool p_case_sensitive) : case_sensitive{p_case_sensitive} {}
136
137 bool operator()(const std::string &a, const std::string &b) const {
140 }
141
142 bool operator()(const std::wstring &a, const std::wstring &b) const {
145 }
146};
147
149 bool operator()(const std::string &a, const std::string &b) const {
150 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
151 }
152
153 bool operator()(const std::wstring &a, const std::wstring &b) const {
154 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
155 }
156};
157
158namespace internal {
159
160template <typename Char>
161inline bool str_caseeq_pair(std::basic_string_view<Char> a,
162 std::basic_string_view<Char> b) {
163 if (a.length() != b.length()) return false;
164 return str_casecmp(a.data(), b.data(), a.length()) == 0;
165}
166
167template <typename Char, typename... T>
168inline bool str_caseeq(std::basic_string_view<Char> a, T &&...tokens) {
169 return (str_caseeq_pair<Char>(a, std::forward<T>(tokens)) || ...);
170}
171
172} // namespace internal
173
174template <typename... T>
175inline bool str_caseeq(std::string_view a, std::string_view token,
176 T &&...tokens) {
177 return internal::str_caseeq(a, token, std::forward<T>(tokens)...);
178}
179
180template <typename... T>
181inline bool str_caseeq(std::wstring_view a, std::wstring_view token,
182 T &&...tokens) {
183 return internal::str_caseeq(a, token, std::forward<T>(tokens)...);
184}
185
186/** Checks whether a string has another as a prefix */
187namespace internal {
188
189template <typename Char>
190inline bool str_beginswith_pair(std::basic_string_view<Char> s,
191 std::basic_string_view<Char> prefix) {
192 return s.compare(0, prefix.length(), prefix) == 0;
193}
194
195template <typename Char, typename... T>
196inline bool str_beginswith(std::basic_string_view<Char> s, T &&...prefixes) {
197 return (str_beginswith_pair<Char>(s, std::forward<T>(prefixes)) || ...);
198}
199
200} // namespace internal
201
202template <typename... T>
203inline bool str_beginswith(std::string_view s, std::string_view prefix,
204 T &&...prefixes) {
205 return internal::str_beginswith(s, prefix, std::forward<T>(prefixes)...);
206}
207
208template <typename... T>
209inline bool str_beginswith(std::wstring_view s, std::wstring_view prefix,
210 T &&...prefixes) {
211 return internal::str_beginswith(s, prefix, std::forward<T>(prefixes)...);
212}
213
214namespace internal {
215
216template <typename Char>
217inline bool str_ibeginswith_pair(std::basic_string_view<Char> s,
218 std::basic_string_view<Char> prefix) {
219 if (s.length() < prefix.length()) return false;
220 return str_casecmp(s.data(), prefix.data(), prefix.length()) == 0;
221}
222
223template <typename Char, typename... T>
224inline bool str_ibeginswith(std::basic_string_view<Char> s, T &&...prefixes) {
225 return (str_ibeginswith_pair<Char>(s, std::forward<T>(prefixes)) || ...);
226}
227
228} // namespace internal
229
230template <typename... T>
231inline bool str_ibeginswith(std::string_view s, std::string_view prefix,
232 T &&...prefixes) {
233 return internal::str_ibeginswith(s, prefix, std::forward<T>(prefixes)...);
234}
235
236template <typename... T>
237inline bool str_ibeginswith(std::wstring_view s, std::wstring_view prefix,
238 T &&...prefixes) {
239 return internal::str_ibeginswith(s, prefix, std::forward<T>(prefixes)...);
240}
241
242/** Checks whether a string has another as a suffix */
243namespace internal {
244
245template <typename Char>
246inline bool str_endswith_pair(std::basic_string_view<Char> s,
247 std::basic_string_view<Char> suffix) {
248 if (suffix.length() > s.length()) return false;
249 return s.compare(s.length() - suffix.length(), suffix.length(), suffix) == 0;
250}
251
252template <typename Char, typename... T>
253inline bool str_endswith(std::basic_string_view<Char> s, T &&...suffixes) {
254 return (str_endswith_pair<Char>(s, std::forward<T>(suffixes)) || ...);
255}
256
257} // namespace internal
258
259template <typename... T>
260inline bool str_endswith(std::string_view s, std::string_view suffix,
261 T &&...suffixes) {
262 return internal::str_endswith(s, suffix, std::forward<T>(suffixes)...);
263}
264
265template <typename... T>
266inline bool str_endswith(std::wstring_view s, std::wstring_view suffix,
267 T &&...suffixes) {
268 return internal::str_endswith(s, suffix, std::forward<T>(suffixes)...);
269}
270
271namespace internal {
272
273template <typename Char>
274inline bool str_iendswith_pair(std::basic_string_view<Char> s,
275 std::basic_string_view<Char> suffix) {
276 if (suffix.length() > s.length()) return false;
277 return str_casecmp(s.data() + s.length() - suffix.length(), suffix.data(),
278 suffix.length()) == 0;
279}
280
281template <typename Char, typename... T>
282inline bool str_iendswith(std::basic_string_view<Char> s, T &&...suffixes) {
283 return (str_iendswith_pair<Char>(s, std::forward<T>(suffixes)) || ...);
284}
285
286} // namespace internal
287
288template <typename... T>
289inline bool str_iendswith(std::string_view s, std::string_view suffix,
290 T &&...suffixes) {
291 return internal::str_iendswith(s, suffix, std::forward<T>(suffixes)...);
292}
293
294template <typename... T>
295inline bool str_iendswith(std::wstring_view s, std::wstring_view suffix,
296 T &&...suffixes) {
297 return internal::str_iendswith(s, suffix, std::forward<T>(suffixes)...);
298}
299
300const char *str_casestr(const char *haystack, const char *needle);
301
302/** Return position of the first difference in the strings or npos if they're
303 * the same */
304inline size_t str_span(const std::string &s1, const std::string &s2) {
305 size_t p = 0;
306 while (p < s1.size() && p < s2.size()) {
307 if (s1[p] != s2[p]) return p;
308 ++p;
309 }
310 if (p == s1.size() && p == s2.size()) return std::string::npos;
311 return p;
312}
313
314/** Partition a string in 2 at a separator, if present */
315template <class TOutput = std::string>
316inline std::pair<TOutput, TOutput> str_partition(std::string_view s,
317 std::string_view sep,
318 bool *found_sep = nullptr) {
319 static_assert(std::is_same_v<TOutput, std::string> ||
320 std::is_same_v<TOutput, std::string_view>,
321 "Type must either be std::string or std::string_view");
322
323 auto p = s.find(sep);
324
325 if (found_sep) {
326 *found_sep = p != std::string_view::npos;
327 }
328
329 if (p == std::string_view::npos)
330 return std::make_pair(TOutput{s}, TOutput{""});
331
332 return std::make_pair(TOutput{s.substr(0, p)},
333 TOutput{s.substr(p + sep.length())});
334}
335
336/** Partition a string in 2 after separator, in place, if present */
337template <class TOutput = std::string>
338inline std::pair<TOutput, TOutput> str_partition_after(std::string_view s,
339 std::string_view sep) {
340 static_assert(std::is_same_v<TOutput, std::string> ||
341 std::is_same_v<TOutput, std::string_view>,
342 "Type must either be std::string or std::string_view");
343
344 auto p = s.find(sep);
345 if (p == std::string_view::npos) {
346 return std::make_pair(TOutput{s}, TOutput{""});
347 }
348
349 p += sep.length();
350 return std::make_pair(TOutput{s.substr(0, p)}, TOutput{s.substr(p)});
351}
352
353/** Partition a string in 2 after separator, in place, if present */
354inline std::string str_partition_after_inpl(std::string *s,
355 const std::string &sep) {
356 auto p = s->find(sep);
357 if (p == std::string::npos) {
358 std::string tmp = *s;
359 s->clear();
360 return tmp;
361 } else {
362 std::string tmp = s->substr(0, p + sep.length());
363 s->erase(0, p + sep.length());
364 return tmp;
365 }
366}
367
368/**
369 * Splits string based on each of the individual characters of the separator
370 * string
371 *
372 * @param input The string to be split
373 * @param separator_chars String containing characters wherein the input string
374 * is split on any of the characters
375 * @param maxsplit max number of times to split or -1 for no limit
376 * @param compress Boolean value which when true ensures consecutive separators
377 * do not generate new elements in the split, but they're still counted towards
378 * maxsplit.
379 *
380 * @returns vector of splitted strings
381 */
382inline std::vector<std::string> str_split(
383 std::string_view input, std::string_view separator_chars = " \r\n\t",
384 int maxsplit = -1, bool compress = false) {
385 std::vector<std::string> ret_val;
386 size_t index = 0, new_find = 0;
387 const size_t end = input.size();
388
389 while (new_find < end) {
390 if (maxsplit--)
391 new_find = input.find_first_of(separator_chars, index);
392 else
393 new_find = std::string_view::npos;
394
395 if (new_find != std::string_view::npos) {
396 // When compress is enabled, consecutive separators
397 // do not generate new elements
398 if (new_find > index || !compress || new_find == 0)
399 ret_val.push_back(std::string{input.substr(index, new_find - index)});
400
401 index = new_find + 1;
402 } else {
403 ret_val.push_back(std::string{input.substr(index)});
404 }
405 }
406 return ret_val;
407}
408
409/**
410 * Split the given input string and call the functor for each token.
411 *
412 * @param input the string to be split
413 * @param f a functor called once for each split string. If its return value
414 * is false, the splitting is interrupted.
415 * @param separator_chars String containing characters wherein the input string
416 * is split on any of the characters
417 * @param maxsplit max number of times to split or -1 for no limit
418 * @param compress Boolean value which when true ensures consecutive separators
419 * do not generate new elements in the split, but they're still counted
420 * towards maxsplit.
421 *
422 * @returns false if f returns false, true otherwise
423 */
424template <class TCallback>
425inline bool str_itersplit(std::string_view input, TCallback &&f,
426 std::string_view separator_chars = " \r\n\t",
427 int maxsplit = -1, bool compress = false) {
428 static_assert(std::is_invocable_r_v<bool, TCallback, std::string_view>);
429
430 size_t index = 0, new_find = 0;
431 const auto end = input.size();
432
433 while (new_find < end) {
434 if (maxsplit--)
435 new_find = input.find_first_of(separator_chars, index);
436 else
437 new_find = std::string_view::npos;
438
439 if (new_find != std::string_view::npos) {
440 // When compress is enabled, consecutive separators
441 // do not generate new elements
442 if (new_find > index || !compress || new_find == 0)
443 if (!f(input.substr(index, new_find - index))) return false;
444
445 index = new_find + 1;
446 } else {
447 if (!f(input.substr(index))) return false;
448 }
449 }
450 return true;
451}
452
453/** Strip a string out of blank chars */
454std::string_view str_strip_view(std::string_view s,
455 std::string_view chars = " \r\n\t");
456std::string_view str_lstrip_view(std::string_view s,
457 std::string_view chars = " \r\n\t");
458std::string_view str_rstrip_view(std::string_view s,
459 std::string_view chars = " \r\n\t");
460
461std::string str_strip(std::string_view s, std::string_view chars = " \r\n\t");
462std::string str_lstrip(std::string_view s, std::string_view chars = " \r\n\t");
463std::string str_rstrip(std::string_view s, std::string_view chars = " \r\n\t");
464
465inline std::string str_ljust(const std::string &s, size_t width,
466 char pad = ' ') {
467 if (s.size() < width) return s + std::string(width - s.size(), pad);
468 return s;
469}
470
471inline std::string str_rjust(const std::string &s, size_t width,
472 char pad = ' ') {
473 if (s.size() < width) return std::string(width - s.size(), pad).append(s);
474 return s;
475}
476
477/** Return a formatted a string
478
479 Throws invalid_argument on encoding error
480*/
481#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))
482std::string str_format(const char *formats, ...)
483 __attribute__((__format__(__printf__, 1, 2)));
484#elif _MSC_VER
485std::string str_format(_In_z_ _Printf_format_string_ const char *format, ...);
486#else
487std::string str_format(const char *formats, ...);
488#endif
489
490template <typename Iter>
491inline std::string str_join(Iter begin, Iter end, std::string_view sep) {
492 if (begin == end) return {};
493
494 std::string s;
495
496 s.append(*begin);
497 while (++begin != end) {
498 s.append(sep);
499 s.append(*begin);
500 }
501
502 return s;
503}
504
505template <typename Iter, typename CTransform>
506inline std::string str_join(Iter begin, Iter end, std::string_view sep,
507 CTransform &&f) {
508 if (begin == end) return {};
509
510 std::string s;
511
512 s.append(f(*begin));
513 while (++begin != end) {
514 s.append(sep);
515 s.append(f(*begin));
516 }
517
518 return s;
519}
520
521template <typename C>
522inline std::string str_join(const C &container, std::string_view sep) {
523 return str_join(container.begin(), container.end(), sep);
524}
525
526template <typename C, typename CTransform>
527inline std::string str_join(const C &container, std::string_view sep,
528 CTransform &&f) {
529 return str_join(container.begin(), container.end(), sep,
530 std::forward<CTransform>(f));
531}
532
533std::string JIT_EXECUTOR_PLUGIN_EXPORT str_replace(std::string_view s,
534 std::string_view from,
535 std::string_view to);
536
537template <typename... Args>
538inline std::string JIT_EXECUTOR_PLUGIN_EXPORT str_replace(std::string_view s,
539 std::string_view from,
540 std::string_view to,
541 const Args &...rest) {
542 return str_replace(str_replace(s, from, to), rest...);
543}
544
545std::string bits_to_string(uint64_t bits, int nbits);
546std::pair<uint64_t, int> string_to_bits(std::string_view s);
547
548std::string bits_to_string_hex(uint64_t bits, int nbits);
549size_t bits_to_string_hex_size(int nbits);
550
551std::string string_to_hex(std::string_view s, bool prefix = true);
552
553/**
554 * Escape `quote` and `\` chars.
555 *
556 * @param s String to escape.
557 * @param quote `'` `"`
558 * @return Quote escaped string.
559 */
560std::string quote_string(const std::string &s, char quote);
561
562/**
563 * Inverse of quote_string().
564 *
565 * If the first and the last characters in the given strings match `quote`
566 * they are removed as well.
567 *
568 * @param s String to be processed.
569 * @param quote The quote character (`'`, `"`)
570 *
571 * @return Unquoted string.
572 */
573std::string unquote_string(std::string_view s, char quote);
574
575// Macro to turn a symbol into a string
576#define STRINGIFY(s) STRINGIFY_(s)
577#define STRINGIFY_(s) #s
578
579/** Breaks string into lines of specified width without breaking words.
580 *
581 * @param line long string to break.
582 * @param line_width maximum line width
583 * @return vector with split lines.
584 */
585std::vector<std::string> str_break_into_lines(const std::string &line,
586 std::size_t line_width);
587
588/**
589 * Auxiliary function to get the quotes span (i.e., start and end positions)
590 * for the given string.
591 *
592 * If not quote is found then std::string::npos is returned for both elements
593 * in the pair. If only one quote is found (no ending quote) then
594 * std::string::npos is returned for the second position of the pair.
595 *
596 * @param quote_char character with the quote to look for.
597 * @param str target string to get the start and end quote position.
598 * @return return a pair with the position of the starting quote and ending
599 * quote.
600 */
601std::pair<std::string::size_type, std::string::size_type> get_quote_span(
602 const char quote_char, const std::string &str);
603
604/**
605 * Convert UTF-8 string to UTF-16/UTF-32 (platform dependent) string.
606 *
607 * @param utf8 UTF-8 encoded string.
608 * @return std::wstring UTF-16/UTF-32 (platform dependent) string.
609 */
610std::wstring utf8_to_wide(const std::string &utf8);
611
612/**
613 * Convert UTF-8 string to UTF-16/UTF-32 (platform dependent) string.
614 *
615 * @param utf8 Pointer to UTF-8 encoded string.
616 * @param utf8_length Length of UTF-8 string in bytes.
617 * @return std::wstring UTF-16/UTF-32 (platform dependent) string.
618 */
619std::wstring utf8_to_wide(const char *utf8, const size_t utf8_length);
620
621/**
622 * Convert UTF-8 string to UTF-16/UTF-32 (platform dependent) string.
623 *
624 * @param utf8 Pointer to UTF-8 encoded string.
625 * @return std::wstring UTF-16/UTF-32 (platform dependent) string.
626 */
627std::wstring utf8_to_wide(const char *utf8);
628
629/**
630 * Convert UTF-16/UTF-32 (platform dependent) string to UTF-8 string.
631 *
632 * @param wide UTF-16/UTF-32 (platform dependent) encoded string.
633 * @return std::string UTF-8 encoded string.
634 */
635std::string wide_to_utf8(const std::wstring &wide);
636
637/**
638 * Convert UTF-16/UTF-32 (platform dependent) string to UTF-8 string.
639 *
640 * @param wide Pointer to UTF-16/UTF-32 (platform dependent) encoded string.
641 * @param wide_length Length of UTF-16/UTF-32 string in bytes.
642 * @return std::string UTF-8 encoded string.
643 */
644std::string wide_to_utf8(const wchar_t *wide, const size_t wide_length);
645
646/**
647 * Convert UTF-16/UTF-32 (platform dependent) string to UTF-8 string.
648 *
649 * @param wide Pointer to UTF-16/UTF-32 (platform dependent) encoded string.
650 * @return std::string UTF-8 encoded string.
651 */
652std::string wide_to_utf8(const wchar_t *wide);
653
654/**
655 * Truncates the given string to max_length code points.
656 *
657 * @param str UTF-8 string to be truncated.
658 * @param max_length Maximum number of code points.
659 *
660 * @return Input string truncated to max_length code points.
661 */
662std::string truncate(const std::string &str, const size_t max_length);
663
664/**
665 * Truncates the given string to max_length code points.
666 *
667 * @param str UTF-8 string to be truncated.
668 * @param length Length of string in bytes.
669 * @param max_length Maximum number of code points.
670 *
671 * @return Input string truncated to max_length code points.
672 */
673std::string truncate(const char *str, const size_t length,
674 const size_t max_length);
675
676/**
677 * Truncates the given string to max_length code points.
678 *
679 * @param str UTF-16/UTF-32 string to be truncated.
680 * @param max_length Maximum number of code points.
681 *
682 * @return Input string truncated to max_length code points.
683 */
684std::wstring truncate(const std::wstring &str, const size_t max_length);
685
686/**
687 * Truncates the given string to max_length code points.
688 *
689 * @param str UTF-16/UTF-32 string to be truncated.
690 * @param length Length of string in bytes.
691 * @param max_length Maximum number of code points.
692 *
693 * @return Input string truncated to max_length code points.
694 */
695std::wstring truncate(const wchar_t *str, const size_t length,
696 const size_t max_length);
697
698/**
699 * Checks if the given string contains only valid UTF-8 code points.
700 *
701 * @param s String to be checked.
702 *
703 * @returns true if the given string is a valid UTF-8 string
704 */
705bool is_valid_utf8(std::string_view s);
706
707/**
708 * Generates a percent encoded string based on RFC-3986, only unreserved
709 * characters are not encoded.
710 */
711std::string pctencode(std::string_view s);
712
713/**
714 * Decodes a string that is percent encoded based on RFC-3986.
715 */
716std::string pctdecode(std::string_view s);
717
718/**
719 * Returns a string of the given size created with random characters from the
720 * provided source.
721 */
722std::string get_random_string(size_t size, const char *source);
723
724/**
725 * Transparent hashing function, enables heterogeneous lookup in unordered
726 * containers.
727 */
729 using is_transparent = void;
730
731 [[nodiscard]] size_t operator()(const char *txt) const {
732 return std::hash<std::string_view>{}(txt);
733 }
734
735 [[nodiscard]] size_t operator()(std::string_view txt) const {
736 return std::hash<std::string_view>{}(txt);
737 }
738
739 [[nodiscard]] size_t operator()(const std::string &txt) const {
740 return std::hash<std::string>{}(txt);
741 }
742};
743
744template <typename Key, typename T>
746 std::unordered_map<Key, T, string_hash, std::equal_to<>>;
747
748template <typename Key>
749using heterogeneous_set = std::unordered_set<Key, string_hash, std::equal_to<>>;
750
751inline std::string utf8_upper(std::string_view s) {
752 return wide_to_utf8(str_upper(utf8_to_wide(s.data(), s.length())));
753}
754
755inline std::string utf8_lower(std::string_view s) {
756 return wide_to_utf8(str_lower(utf8_to_wide(s.data(), s.length())));
757}
758
759} // namespace shcore
760
761#endif // MYSQLSHDK_LIBS_UTILS_UTILS_STRING_H_
const char * p
Definition: ctype-mb.cc:1227
#define T
Definition: jit_executor_value.cc:373
#define F
Definition: jit_executor_value.cc:374
static int compress(PACK_MRG_INFO *file, char *join_name)
Definition: myisampack.cc:466
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1084
std::string format(const routing_guidelines::Session_info &session_info, bool extended_session_info)
Definition: dest_metadata_cache.cc:170
Definition: atomics_array.h:39
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:75
char tolower(const char &ch)
Definition: parsing_helpers.h:41
const char * begin(const char *const c)
Definition: base64.h:44
size_t size(const char *const c)
Definition: base64.h:46
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
bool str_ibeginswith(std::basic_string_view< Char > s, T &&...prefixes)
Definition: utils_string.h:224
bool str_beginswith(std::basic_string_view< Char > s, T &&...prefixes)
Definition: utils_string.h:196
bool str_beginswith_pair(std::basic_string_view< Char > s, std::basic_string_view< Char > prefix)
Definition: utils_string.h:190
bool str_ibeginswith_pair(std::basic_string_view< Char > s, std::basic_string_view< Char > prefix)
Definition: utils_string.h:217
bool str_endswith(std::basic_string_view< Char > s, T &&...suffixes)
Definition: utils_string.h:253
bool str_caseeq(std::basic_string_view< Char > a, T &&...tokens)
Definition: utils_string.h:168
bool str_endswith_pair(std::basic_string_view< Char > s, std::basic_string_view< Char > suffix)
Definition: utils_string.h:246
bool str_iendswith(std::basic_string_view< Char > s, T &&...suffixes)
Definition: utils_string.h:282
std::basic_string< Char > transform(std::basic_string_view< Char > s, F fun)
Definition: utils_string.h:53
bool str_iendswith_pair(std::basic_string_view< Char > s, std::basic_string_view< Char > suffix)
Definition: utils_string.h:274
bool str_caseeq_pair(std::basic_string_view< Char > a, std::basic_string_view< Char > b)
Definition: utils_string.h:161
Definition: file_system_exceptions.h:34
bool str_beginswith(std::string_view s, std::string_view prefix, T &&...prefixes)
Definition: utils_string.h:203
bool str_ibeginswith(std::string_view s, std::string_view prefix, T &&...prefixes)
Definition: utils_string.h:231
bool str_iendswith(std::string_view s, std::string_view suffix, T &&...suffixes)
Definition: utils_string.h:289
std::string str_partition_after_inpl(std::string *s, const std::string &sep)
Partition a string in 2 after separator, in place, if present.
Definition: utils_string.h:354
std::string pctdecode(std::string_view s)
Decodes a string that is percent encoded based on RFC-3986.
Definition: utils_string.cc:568
std::string wide_to_utf8(const std::wstring &wide)
Convert UTF-16/UTF-32 (platform dependent) string to UTF-8 string.
Definition: utils_string.cc:357
size_t bits_to_string_hex_size(int nbits)
Definition: utils_string.cc:191
std::string str_upper(std::string_view s)
Convert a copy of an ASCII string to uppercase and return.
Definition: utils_string.h:63
int str_casecmp(const char *a, const char *b)
Compares 2 strings case insensitive (for ascii)
Definition: utils_string.h:81
void clear_buffer(char *buffer, size_t size)
Definition: utils_string.cc:51
std::string utf8_lower(std::string_view s)
Definition: utils_string.h:755
std::string_view str_strip_view(std::string_view s, std::string_view chars)
Strip a string out of blank chars.
Definition: utils_string.cc:73
bool str_caseeq(std::string_view a, std::string_view token, T &&...tokens)
Definition: utils_string.h:175
std::string str_rjust(const std::string &s, size_t width, char pad=' ')
Definition: utils_string.h:471
std::vector< std::string > str_split(std::string_view input, std::string_view separator_chars=" \r\n\t", int maxsplit=-1, bool compress=false)
Splits string based on each of the individual characters of the separator string.
Definition: utils_string.h:382
std::string str_lower(std::string_view s)
Convert a copy of an ASCII string to lowercase and return.
Definition: utils_string.h:72
bool str_endswith(std::string_view s, std::string_view suffix, T &&...suffixes)
Definition: utils_string.h:260
std::string bits_to_string(uint64_t bits, int nbits)
Definition: utils_string.cc:169
std::string utf8_upper(std::string_view s)
Definition: utils_string.h:751
std::string string_to_hex(std::string_view s, bool prefix)
Definition: utils_string.cc:199
std::unordered_map< Key, T, string_hash, std::equal_to<> > heterogeneous_map
Definition: utils_string.h:746
std::vector< std::string > str_break_into_lines(const std::string &line, std::size_t line_width)
Breaks string into lines of specified width without breaking words.
Definition: utils_string.cc:239
std::wstring utf8_to_wide(const std::string &utf8)
Convert UTF-8 string to UTF-16/UTF-32 (platform dependent) string.
Definition: utils_string.cc:349
std::string str_strip(std::string_view s, std::string_view chars)
Definition: utils_string.cc:93
std::string str_format(const char *formats,...)
Return a formatted a string.
Definition: utils_string.cc:105
std::string get_random_string(size_t size, const char *source)
Returns a string of the given size created with random characters from the provided source.
Definition: utils_string.cc:588
bool is_valid_utf8(std::string_view s)
Checks if the given string contains only valid UTF-8 code points.
Definition: utils_string.cc:462
std::string truncate(const std::string &str, const size_t max_length)
Truncates the given string to max_length code points.
Definition: utils_string.cc:418
std::pair< std::string::size_type, std::string::size_type > get_quote_span(const char quote_char, const std::string &str)
Auxiliary function to get the quotes span (i.e., start and end positions) for the given string.
Definition: utils_string.cc:276
std::pair< TOutput, TOutput > str_partition(std::string_view s, std::string_view sep, bool *found_sep=nullptr)
Partition a string in 2 at a separator, if present.
Definition: utils_string.h:316
std::string pctencode(std::string_view s)
Generates a percent encoded string based on RFC-3986, only unreserved characters are not encoded.
Definition: utils_string.cc:546
std::string str_lstrip(std::string_view s, std::string_view chars)
Definition: utils_string.cc:97
const char * str_casestr(const char *haystack, const char *needle)
Definition: utils_string.cc:612
std::string str_replace(std::string_view s, std::string_view from, std::string_view to)
Definition: utils_string.cc:141
std::string str_rstrip(std::string_view s, std::string_view chars)
Definition: utils_string.cc:101
std::string quote_string(const std::string &s, char quote)
Escape quote and \ chars.
Definition: utils_string.cc:217
std::string str_ljust(const std::string &s, size_t width, char pad=' ')
Definition: utils_string.h:465
size_t str_span(const std::string &s1, const std::string &s2)
Return position of the first difference in the strings or npos if they're the same.
Definition: utils_string.h:304
std::pair< TOutput, TOutput > str_partition_after(std::string_view s, std::string_view sep)
Partition a string in 2 after separator, in place, if present.
Definition: utils_string.h:338
bool str_itersplit(std::string_view input, TCallback &&f, std::string_view separator_chars=" \r\n\t", int maxsplit=-1, bool compress=false)
Split the given input string and call the functor for each token.
Definition: utils_string.h:425
std::string str_join(Iter begin, Iter end, std::string_view sep)
Definition: utils_string.h:491
std::string bits_to_string_hex(uint64_t bits, int nbits)
Definition: utils_string.cc:183
std::string unquote_string(std::string_view s, char quote)
Inverse of quote_string().
Definition: utils_string.cc:224
std::string_view str_lstrip_view(std::string_view s, std::string_view chars)
Definition: utils_string.cc:81
std::unordered_set< Key, string_hash, std::equal_to<> > heterogeneous_set
Definition: utils_string.h:749
std::pair< uint64_t, int > string_to_bits(std::string_view s)
Definition: utils_string.cc:175
std::string_view str_rstrip_view(std::string_view s, std::string_view chars)
Definition: utils_string.cc:87
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:86
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
Definition: utils_string.h:133
bool operator()(const std::wstring &a, const std::wstring &b) const
Definition: utils_string.h:142
bool operator()(const std::string &a, const std::string &b) const
Definition: utils_string.h:137
bool case_sensitive
Definition: utils_string.h:134
Case_comparator(bool p_case_sensitive)
Definition: utils_string.h:135
Definition: utils_string.h:123
bool operator()(const std::wstring &a, const std::wstring &b) const
Definition: utils_string.h:128
bool operator()(const std::string &a, const std::string &b) const
Definition: utils_string.h:124
Definition: utils_string.h:113
bool operator()(const std::string &a, const std::string &b) const
Definition: utils_string.h:114
bool operator()(const std::wstring &a, const std::wstring &b) const
Definition: utils_string.h:118
Definition: utils_string.h:148
bool operator()(const std::string &a, const std::string &b) const
Definition: utils_string.h:149
bool operator()(const std::wstring &a, const std::wstring &b) const
Definition: utils_string.h:153
Transparent hashing function, enables heterogeneous lookup in unordered containers.
Definition: utils_string.h:728
size_t operator()(std::string_view txt) const
Definition: utils_string.h:735
size_t operator()(const char *txt) const
Definition: utils_string.h:731
size_t operator()(const std::string &txt) const
Definition: utils_string.h:739
void is_transparent
Definition: utils_string.h:729
int n
Definition: xcom_base.cc:509