~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/m_string.h

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

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