MySQL 9.1.0
Source Code Documentation
m_string.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2000, 2024, 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,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 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
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
24
25#ifndef M_STRING_INCLUDED
26#define M_STRING_INCLUDED
27
28/**
29 @file include/m_string.h
30*/
31
32/*
33 This file is for trivial constant definitions and in-line wrappers only.
34
35 Please don't add new stuff to this file unnecessarily.
36*/
37
38#include <float.h>
39#include <limits.h>
40#include <stdbool.h> // IWYU pragma: keep
41#include <stdint.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45
46#include <algorithm>
47#include <cstdint>
48
49#include "lex_string.h"
50#include "my_config.h"
51
52/*
53 bchange(dst, old_length, src, new_length, tot_length)
54 replaces old_length characters at dst to new_length characters from
55 src in a buffer with tot_length bytes.
56*/
57static inline void bchange(uint8_t *dst, size_t old_length, const uint8_t *src,
58 size_t new_length, size_t tot_length) {
59 memmove(dst + new_length, dst + old_length, tot_length - old_length);
60 memcpy(dst, src, new_length);
61}
62
63/*
64 strend(s) returns a character pointer to the NUL which ends s. That
65 is, strend(s)-s == strlen(s). This is useful for adding things at
66 the end of strings. It is redundant, because strchr(s,'\0') could
67 be used instead, but this is clearer and faster.
68*/
69static inline const char *strend(const char *s) {
70 while (*s++) {
71 }
72 return s - 1;
73}
74
75static inline char *strend(char *s) {
76 while (*s++) {
77 }
78 return s - 1;
79}
80
81/*
82 strcend(s, c) returns a pointer to the first place in s where c
83 occurs, or a pointer to the end-null of s if c does not occur in s.
84*/
85static inline const char *strcend(const char *s, char c) {
86 for (;;) {
87 if (*s == c) return s;
88 if (!*s++) return s - 1;
89 }
90}
91
92/*
93 strfill(dest, len, fill) makes a string of fill-characters. The result
94 string is of length == len. The des+len character is always set to NULL.
95 strfill() returns pointer to dest+len;
96*/
97static inline char *strfill(char *s, size_t len, char fill) {
98 while (len--) *s++ = fill;
99 *(s) = '\0';
100 return (s);
101}
102
103/*
104 my_stpmov(dst, src) moves all the characters of src (including the
105 closing NUL) to dst, and returns a pointer to the new closing NUL in
106 dst. The similar UNIX routine strcpy returns the old value of dst,
107 which I have never found useful. my_stpmov(my_stpmov(dst,a),b) moves a//b
108 into dst, which seems useful.
109*/
110static inline char *my_stpmov(char *dst, const char *src) {
111 while ((*dst++ = *src++)) {
112 }
113 return dst - 1;
114}
115
116/*
117 my_stpnmov(dst,src,length) moves length characters, or until end, of src to
118 dst and appends a closing NUL to dst if src is shorter than length.
119 The result is a pointer to the first NUL in dst, or is dst+n if dst was
120 truncated.
121*/
122static inline char *my_stpnmov(char *dst, const char *src, size_t n) {
123 while (n-- != 0) {
124 if (!(*dst++ = *src++)) return (char *)dst - 1;
125 }
126 return dst;
127}
128
129/**
130 Copy a string from src to dst until (and including) terminating null byte.
131
132 @param dst Destination
133 @param src Source
134
135 @note src and dst cannot overlap.
136 Use my_stpmov() if src and dst overlaps.
137
138 @note Unsafe, consider using my_stpnpy() instead.
139
140 @return pointer to terminating null byte.
141*/
142static inline char *my_stpcpy(char *dst, const char *src) {
143#if defined(HAVE_BUILTIN_STPCPY)
144 /*
145 If __builtin_stpcpy() is available, use it instead of stpcpy(), since GCC in
146 some situations is able to transform __builtin_stpcpy() into more efficient
147 strcpy() or memcpy() calls. It does not perform these transformations for a
148 plain call to stpcpy() when the compiler runs in strict mode. See GCC bug
149 82429.
150 */
151 return __builtin_stpcpy(dst, src);
152#elif defined(HAVE_STPCPY)
153 return stpcpy(dst, src);
154#else
155 /* Fallback to implementation supporting overlap. */
156 return my_stpmov(dst, src);
157#endif
158}
159
160/**
161 Copy fixed-size string from src to dst.
162
163 @param dst Destination
164 @param src Source
165 @param n Maximum number of characters to copy.
166
167 @note src and dst cannot overlap
168 Use my_stpnmov() if src and dst overlaps.
169
170 @return pointer to terminating null byte.
171*/
172static inline char *my_stpncpy(char *dst, const char *src, size_t n) {
173#if defined(HAVE_STPNCPY)
174 return stpncpy(dst, src, n);
175#else
176 /* Fallback to implementation supporting overlap. */
177 return my_stpnmov(dst, src, n);
178#endif
179}
180
181static inline long long my_strtoll(const char *nptr, char **endptr, int base) {
182#if defined _WIN32
183 return _strtoi64(nptr, endptr, base);
184#else
185 return strtoll(nptr, endptr, base);
186#endif
187}
188
189static inline unsigned long long my_strtoull(const char *nptr, char **endptr,
190 int base) {
191#if defined _WIN32
192 return _strtoui64(nptr, endptr, base);
193#else
194 return strtoull(nptr, endptr, base);
195#endif
196}
197
198static inline char *my_strtok_r(char *str, const char *delim, char **saveptr) {
199#if defined _WIN32
200 return strtok_s(str, delim, saveptr);
201#else
202 return strtok_r(str, delim, saveptr);
203#endif
204}
205
206/* native_ rather than my_ since my_strcasecmp already exists */
207static inline int native_strcasecmp(const char *s1, const char *s2) {
208#if defined _WIN32
209 return _stricmp(s1, s2);
210#else
211 return strcasecmp(s1, s2);
212#endif
213}
214
215/* native_ rather than my_ for consistency with native_strcasecmp */
216static inline int native_strncasecmp(const char *s1, const char *s2, size_t n) {
217#if defined _WIN32
218 return _strnicmp(s1, s2, n);
219#else
220 return strncasecmp(s1, s2, n);
221#endif
222}
223
224/*
225 is_prefix(s, t) returns 1 if s starts with t.
226 A empty t is always a prefix.
227*/
228static inline int is_prefix(const char *s, const char *t) {
229 while (*t)
230 if (*s++ != *t++) return 0;
231 return 1; /* WRONG */
232}
233
234/**
235 Skip trailing space (ASCII spaces only).
236
237 @return New end of the string.
238*/
239static inline const uint8_t *skip_trailing_space(const uint8_t *ptr,
240 size_t len) {
241 const uint8_t *end = ptr + len;
242 while (end - ptr >= 8) {
243 uint64_t chunk;
244 memcpy(&chunk, end - 8, sizeof(chunk));
245 if (chunk != 0x2020202020202020ULL) break;
246 end -= 8;
247 }
248 while (end > ptr && end[-1] == 0x20) end--;
249 return (end);
250}
251
252/*
253 Format a double (representing number of bytes) into a human-readable string.
254
255 @param buf Buffer used for printing
256 @param buf_len Length of buffer
257 @param dbl_val Value to be formatted
258
259 @note
260 Sample output format: 42 1K 234M 2G
261 If we exceed ULLONG_MAX YiB we give up, and convert to "+INF".
262
263 @todo Consider writing KiB GiB etc, since we use 1024 rather than 1000
264 */
265static inline void human_readable_num_bytes(char *buf, int buf_len,
266 double dbl_val) {
267 const char size[] = {'\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
268 unsigned int i;
269 for (i = 0; dbl_val > 1024 && i < sizeof(size) - 1; i++) dbl_val /= 1024;
270 const char mult = size[i];
271 // 18446744073709551615 Yottabytes should be enough for most ...
272 // ULLONG_MAX is not exactly representable as a double. This is the largest
273 // double that is still below ULLONG_MAX.
274 if (dbl_val > 18446744073709549568.0)
275 snprintf(buf, buf_len, "+INF");
276 else
277 snprintf(buf, buf_len, "%llu%c", (unsigned long long)dbl_val, mult);
278}
279
280static inline void lex_string_set(LEX_STRING *lex_str, char *c_str) {
281 lex_str->str = c_str;
282 lex_str->length = strlen(c_str);
283}
284
285static inline void lex_cstring_set(LEX_CSTRING *lex_str, const char *c_str) {
286 lex_str->str = c_str;
287 lex_str->length = strlen(c_str);
288}
289
290#endif // M_STRING_INCLUDED
static Bigint * mult(Bigint *a, Bigint *b, Stack_alloc *alloc)
Definition: dtoa.cc:922
static const char * strcend(const char *s, char c)
Definition: m_string.h:85
static int is_prefix(const char *s, const char *t)
Definition: m_string.h:228
static int native_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: m_string.h:216
static void bchange(uint8_t *dst, size_t old_length, const uint8_t *src, size_t new_length, size_t tot_length)
Definition: m_string.h:57
static void lex_string_set(LEX_STRING *lex_str, char *c_str)
Definition: m_string.h:280
static const char * strend(const char *s)
Definition: m_string.h:69
static char * my_stpmov(char *dst, const char *src)
Definition: m_string.h:110
static char * my_stpcpy(char *dst, const char *src)
Copy a string from src to dst until (and including) terminating null byte.
Definition: m_string.h:142
static char * my_stpncpy(char *dst, const char *src, size_t n)
Copy fixed-size string from src to dst.
Definition: m_string.h:172
static char * strfill(char *s, size_t len, char fill)
Definition: m_string.h:97
static int native_strcasecmp(const char *s1, const char *s2)
Definition: m_string.h:207
static char * my_stpnmov(char *dst, const char *src, size_t n)
Definition: m_string.h:122
static char * my_strtok_r(char *str, const char *delim, char **saveptr)
Definition: m_string.h:198
static void human_readable_num_bytes(char *buf, int buf_len, double dbl_val)
Definition: m_string.h:265
static unsigned long long my_strtoull(const char *nptr, char **endptr, int base)
Definition: m_string.h:189
static const uint8_t * skip_trailing_space(const uint8_t *ptr, size_t len)
Skip trailing space (ASCII spaces only).
Definition: m_string.h:239
static void lex_cstring_set(LEX_CSTRING *lex_str, const char *c_str)
Definition: m_string.h:285
static long long my_strtoll(const char *nptr, char **endptr, int base)
Definition: m_string.h:181
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1105
Definition: buf0block_hint.cc:30
size_t size(const char *const c)
Definition: base64.h:46
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
Definition: mysql_lex_string.h:40
const char * str
Definition: mysql_lex_string.h:41
size_t length
Definition: mysql_lex_string.h:42
Definition: mysql_lex_string.h:35
char * str
Definition: mysql_lex_string.h:36
size_t length
Definition: mysql_lex_string.h:37
int n
Definition: xcom_base.cc:509