~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/m_string.h

  • Committer: Eric Day
  • Date: 2009-08-27 07:26:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1131.
  • Revision ID: eday@oddments.org-20090827072622-72te13ua0wdlc2ky
Reworked listen interface to not require binding of TCP ports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
#include <stdlib.h>
38
38
#include <stddef.h>
39
 
#include <stdbool.h>
40
39
#include <assert.h>
41
40
#include <limits.h>
 
41
#include <ctype.h>
42
42
 
43
43
/*  This is needed for the definitions of memcpy... on solaris */
44
44
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
49
49
extern "C" {
50
50
#endif
51
51
 
52
 
/*
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.
55
 
 */
56
 
extern void *(*my_str_malloc)(size_t);
57
 
extern void (*my_str_free)(void *);
58
 
 
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);
61
 
 
62
52
#define strmov_overlapp(A,B) my_stpcpy(A,B)
63
53
#define strmake_overlapp(A,B,C) strmake(A,B,C)
64
54
 
80
70
extern  char *strxmov(char *dst,const char *src, ...);
81
71
extern  char *strxcpy(char *dst,const char *src, ...);
82
72
extern  char *strxncat(char *dst,size_t len, const char *src, ...);
83
 
extern  char *strxnmov(char *dst,size_t len, const char *src, ...);
84
73
extern  char *strxncpy(char *dst,size_t len, const char *src, ...);
85
74
 
86
75
/* Prototypes of normal stringfunctions (with may ours) */
92
81
extern char *strcpy(char *, const char *);
93
82
#endif
94
83
 
95
 
#if !defined(__cplusplus)
96
 
#ifndef HAVE_STRPBRK
97
 
extern char *strpbrk(const char *, const char *);
98
 
#endif
99
 
#endif
100
84
extern int is_prefix(const char *, const char *);
101
85
 
102
86
/* Conversion routines */
111
95
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
112
96
               bool *error);
113
97
 
114
 
#define NOT_FIXED_DEC 31
 
98
#define NOT_FIXED_DEC (uint8_t)31
115
99
 
116
100
/*
117
101
  The longest string my_fcvt can return is 311 + "precision" bytes.
136
120
  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
137
121
*/
138
122
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
139
 
  
 
123
 
140
124
 
141
125
extern char *llstr(int64_t value,char *buff);
142
126
extern char *ullstr(int64_t value,char *buff);
143
127
 
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,
147
 
                         long *val);
 
128
extern char *int2str(int32_t val, char *dst, int radix, int upcase);
 
129
extern char *int10_to_str(int32_t val,char *dst,int radix);
148
130
int64_t my_strtoll10(const char *nptr, char **endptr, int *error);
149
 
#if SIZEOF_LONG == SIZEOF_LONG_LONG
150
 
#define int64_t2str(A,B,C) int2str((A),(B),(C),1)
151
 
#define int64_t10_to_str(A,B,C) int10_to_str((A),(B),(C))
152
 
#else
153
131
extern char *int64_t2str(int64_t val,char *dst,int radix);
154
132
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
155
 
#endif
156
133
 
157
134
 
158
135
#if defined(__cplusplus)
159
136
}
160
137
#endif
161
138
 
162
 
/*
163
 
  LEX_STRING -- a pair of a C-string and its length.
164
 
*/
165
 
 
166
 
#ifndef _my_plugin_h
167
 
/* This definition must match the one given in mysql/plugin.h */
168
 
struct st_mysql_lex_string
169
 
{
170
 
  char *str;
171
 
  size_t length;
172
 
};
173
 
#endif
174
 
typedef struct st_mysql_lex_string LEX_STRING;
175
 
 
176
 
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
177
 
#define USTRING_WITH_LEN(X) ((unsigned char*) X), ((size_t) (sizeof(X) - 1))
178
 
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
179
 
 
180
 
/* SPACE_INT is a word that contains only spaces */
181
 
#if SIZEOF_INT == 4
182
 
#define SPACE_INT 0x20202020
183
 
#elif SIZEOF_INT == 8
184
 
#define SPACE_INT 0x2020202020202020
185
 
#else
186
 
#error define the appropriate constant for a word full of spaces
187
 
#endif
188
139
 
189
140
/**
190
141
  Skip trailing space.
191
142
 
192
 
  On most systems reading memory in larger chunks (ideally equal to the size of
193
 
  the chinks that the machine physically reads from memory) causes fewer memory
194
 
  access loops and hence increased performance.
195
 
  This is why the 'int' type is used : it's closest to that (according to how
196
 
  it's defined in C).
197
 
  So when we determine the amount of whitespace at the end of a string we do
198
 
  the following :
199
 
    1. We divide the string into 3 zones :
200
 
      a) from the start of the string (__start) to the first multiple
201
 
        of sizeof(int)  (__start_words)
202
 
      b) from the end of the string (__end) to the last multiple of sizeof(int)
203
 
        (__end_words)
204
 
      c) a zone that is aligned to sizeof(int) and can be safely accessed
205
 
        through an int *
206
 
    2. We start comparing backwards from (c) char-by-char. If all we find is
207
 
       space then we continue
208
 
    3. If there are elements in zone (b) we compare them as unsigned ints to a
209
 
       int mask (SPACE_INT) consisting of all spaces
210
 
    4. Finally we compare the remaining part (a) of the string char by char.
211
 
       This covers for the last non-space unsigned int from 3. (if any)
212
 
 
213
 
   This algorithm works well for relatively larger strings, but it will slow
214
 
   the things down for smaller strings (because of the additional calculations
215
 
   and checks compared to the naive method). Thus the barrier of length 20
216
 
   is added.
217
 
 
218
143
   @param     ptr   pointer to the input string
219
144
   @param     len   the length of the string
220
145
   @return          the last non-space character
221
146
*/
222
147
 
223
 
static inline const unsigned char *skip_trailing_space(const unsigned char *ptr,size_t len)
 
148
static inline const unsigned char *
 
149
skip_trailing_space(const unsigned char *ptr, size_t len)
224
150
{
225
151
  const unsigned char *end= ptr + len;
226
152
 
227
 
  if (len > 20)
228
 
  {
229
 
    const unsigned char *end_words= (const unsigned char *)(intptr_t)
230
 
      (((uint64_t)(intptr_t)end) / SIZEOF_INT * SIZEOF_INT);
231
 
    const unsigned char *start_words= (const unsigned char *)(intptr_t)
232
 
       ((((uint64_t)(intptr_t)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
233
 
 
234
 
    assert(((uint64_t)(intptr_t)ptr) >= SIZEOF_INT);
235
 
    if (end_words > ptr)
236
 
    {
237
 
      while (end > end_words && end[-1] == 0x20)
238
 
        end--;
239
 
      if (end[-1] == 0x20 && start_words < end_words)
240
 
        while (end > start_words && ((const unsigned *)end)[-1] == SPACE_INT)
241
 
          end -= SIZEOF_INT;
242
 
    }
243
 
  }
244
 
  while (end > ptr && end[-1] == 0x20)
245
 
    end--;
246
 
  return (end);
 
153
  while (end > ptr && isspace(*--end))
 
154
    continue;
 
155
  return end+1;
247
156
}
248
157
 
249
158
#endif