12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* There may be prolems include all of theese. Try to test in
17
17
configure with ones are needed? */
21
#ifndef DRIZZLED_INTERNAL_M_STRING_H
22
#define DRIZZLED_INTERNAL_M_STRING_H
19
/* This is needed for the definitions of strchr... on solaris */
25
#include <drizzled/global.h>
28
#define __USE_GNU /* We want to use my_stpcpy */
24
30
#if defined(HAVE_STRINGS_H)
25
31
#include <strings.h>
31
37
#include <stdlib.h>
32
38
#include <stddef.h>
34
41
#include <limits.h>
37
43
/* This is needed for the definitions of memcpy... on solaris */
38
44
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
39
45
#include <memory.h>
43
#include "drizzled/visibility.h"
48
#if defined(__cplusplus)
53
my_str_malloc() and my_str_free() are assigned to implementations in
54
strings/alloc.c, but can be overridden in the calling program.
56
extern void *(*my_str_malloc)(size_t);
57
extern void (*my_str_free)(void *);
59
char *my_stpncpy(register char *dst, register const char *src, size_t n);
60
char *my_stpcpy(register char *dst, register const char *src);
62
#define strmov_overlapp(A,B) my_stpcpy(A,B)
63
#define strmake_overlapp(A,B,C) strmake(A,B,C)
50
65
extern void bmove_upp(unsigned char *dst,const unsigned char *src,size_t len);
56
71
extern char *strfill(char * s,size_t len,char fill);
57
72
extern char *strkey(char *dst,char *head,char *tail,char *flags);
58
73
extern char *strmake(char *dst,const char *src,size_t length);
74
#ifndef strmake_overlapp
75
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
60
78
extern char *strsuff(const char *src,const char *suffix);
61
79
extern char *strxcat(char *dst,const char *src, ...);
62
80
extern char *strxmov(char *dst,const char *src, ...);
63
81
extern char *strxcpy(char *dst,const char *src, ...);
64
82
extern char *strxncat(char *dst,size_t len, const char *src, ...);
83
extern char *strxnmov(char *dst,size_t len, const char *src, ...);
65
84
extern char *strxncpy(char *dst,size_t len, const char *src, ...);
86
/* Prototypes of normal stringfunctions (with may ours) */
88
#ifdef WANT_STRING_PROTOTYPES
89
extern char *strcat(char *, const char *);
90
extern char *strchr(const char *, char);
91
extern char *strrchr(const char *, char);
92
extern char *strcpy(char *, const char *);
95
#if !defined(__cplusplus)
97
extern char *strpbrk(const char *, const char *);
100
extern int is_prefix(const char *, const char *);
67
102
/* Conversion routines */
69
104
MY_GCVT_ARG_FLOAT,
70
105
MY_GCVT_ARG_DOUBLE
71
106
} my_gcvt_arg_type;
73
DRIZZLED_API double my_strtod(const char *str, char **end, int *error);
74
DRIZZLED_API double my_atof(const char *nptr);
75
DRIZZLED_API size_t my_fcvt(double x, int precision, char *to, bool *error);
76
DRIZZLED_API size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
108
double my_strtod(const char *str, char **end, int *error);
109
double my_atof(const char *nptr);
110
size_t my_fcvt(double x, int precision, char *to, bool *error);
111
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
79
#define NOT_FIXED_DEC (uint8_t)31
114
#define NOT_FIXED_DEC 31
82
117
The longest string my_fcvt can return is 311 + "precision" bytes.
101
136
MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
103
138
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
106
141
extern char *llstr(int64_t value,char *buff);
107
142
extern char *ullstr(int64_t value,char *buff);
109
extern char *int2str(int32_t val, char *dst, int radix, int upcase);
110
extern char *int10_to_str(int32_t val,char *dst,int radix);
111
DRIZZLED_API int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
112
DRIZZLED_API char *int64_t2str(int64_t val,char *dst,int radix);
113
DRIZZLED_API char *int64_t10_to_str(int64_t val,char *dst,int radix);
144
extern char *int2str(long val, char *dst, int radix, int upcase);
145
extern char *int10_to_str(long val,char *dst,int radix);
146
extern char *str2int(const char *src,int radix,long lower,long upper,
148
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
149
extern char *int64_t2str(int64_t val,char *dst,int radix);
150
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
153
#if defined(__cplusplus)
158
LEX_STRING -- a pair of a C-string and its length.
162
/* This definition must match the one given in mysql/plugin.h */
163
struct st_mysql_lex_string
169
typedef struct st_mysql_lex_string LEX_STRING;
171
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
172
#define USTRING_WITH_LEN(X) ((unsigned char*) X), ((size_t) (sizeof(X) - 1))
173
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
175
/* SPACE_INT is a word that contains only spaces */
177
#define SPACE_INT 0x20202020
178
#elif SIZEOF_INT == 8
179
#define SPACE_INT 0x2020202020202020
181
#error define the appropriate constant for a word full of spaces
117
185
Skip trailing space.
187
On most systems reading memory in larger chunks (ideally equal to the size of
188
the chinks that the machine physically reads from memory) causes fewer memory
189
access loops and hence increased performance.
190
This is why the 'int' type is used : it's closest to that (according to how
192
So when we determine the amount of whitespace at the end of a string we do
194
1. We divide the string into 3 zones :
195
a) from the start of the string (__start) to the first multiple
196
of sizeof(int) (__start_words)
197
b) from the end of the string (__end) to the last multiple of sizeof(int)
199
c) a zone that is aligned to sizeof(int) and can be safely accessed
201
2. We start comparing backwards from (c) char-by-char. If all we find is
202
space then we continue
203
3. If there are elements in zone (b) we compare them as unsigned ints to a
204
int mask (SPACE_INT) consisting of all spaces
205
4. Finally we compare the remaining part (a) of the string char by char.
206
This covers for the last non-space unsigned int from 3. (if any)
208
This algorithm works well for relatively larger strings, but it will slow
209
the things down for smaller strings (because of the additional calculations
210
and checks compared to the naive method). Thus the barrier of length 20
119
213
@param ptr pointer to the input string
120
214
@param len the length of the string
121
215
@return the last non-space character
124
static inline const unsigned char *
125
skip_trailing_space(const unsigned char *ptr, size_t len)
218
static inline const unsigned char *skip_trailing_space(const unsigned char *ptr,size_t len)
127
220
const unsigned char *end= ptr + len;
129
while (end > ptr && isspace(*--end))
224
const unsigned char *end_words= (const unsigned char *)(intptr_t)
225
(((uint64_t)(intptr_t)end) / SIZEOF_INT * SIZEOF_INT);
226
const unsigned char *start_words= (const unsigned char *)(intptr_t)
227
((((uint64_t)(intptr_t)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
229
assert(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
232
while (end > end_words && end[-1] == 0x20)
234
if (end[-1] == 0x20 && start_words < end_words)
235
while (end > start_words && ((const unsigned *)end)[-1] == SPACE_INT)
239
while (end > ptr && end[-1] == 0x20)
134
} /* namespace internal */
135
} /* namespace drizzled */
137
#endif /* DRIZZLED_INTERNAL_M_STRING_H */