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