~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/m_string.h

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

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>
39
40
#include <assert.h>
40
41
#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
 
52
62
#define strmov_overlapp(A,B) my_stpcpy(A,B)
53
63
#define strmake_overlapp(A,B,C) strmake(A,B,C)
54
64
 
70
80
extern  char *strxmov(char *dst,const char *src, ...);
71
81
extern  char *strxcpy(char *dst,const char *src, ...);
72
82
extern  char *strxncat(char *dst,size_t len, const char *src, ...);
 
83
extern  char *strxnmov(char *dst,size_t len, const char *src, ...);
73
84
extern  char *strxncpy(char *dst,size_t len, const char *src, ...);
74
85
 
75
86
/* Prototypes of normal stringfunctions (with may ours) */
100
111
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
101
112
               bool *error);
102
113
 
103
 
#define NOT_FIXED_DEC (uint8_t)31
 
114
#define NOT_FIXED_DEC 31
104
115
 
105
116
/*
106
117
  The longest string my_fcvt can return is 311 + "precision" bytes.
125
136
  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
126
137
*/
127
138
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + cmax(5, MAX_DECPT_FOR_F_FORMAT))
128
 
 
 
139
  
129
140
 
130
141
extern char *llstr(int64_t value,char *buff);
131
142
extern char *ullstr(int64_t value,char *buff);
132
143
 
133
 
extern char *int2str(int32_t val, char *dst, int radix, int upcase);
134
 
extern char *int10_to_str(int32_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);
135
146
extern char *str2int(const char *src,int radix,long lower,long upper,
136
 
                     long *val);
 
147
                         long *val);
137
148
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
138
153
extern char *int64_t2str(int64_t val,char *dst,int radix);
139
154
extern char *int64_t10_to_str(int64_t val,char *dst,int radix);
 
155
#endif
140
156
 
141
157
 
142
158
#if defined(__cplusplus)
143
159
}
144
160
#endif
145
161
 
 
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
146
188
 
147
189
/**
148
190
  Skip trailing space.
149
191
 
 
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
 
150
218
   @param     ptr   pointer to the input string
151
219
   @param     len   the length of the string
152
220
   @return          the last non-space character
153
221
*/
154
222
 
155
 
static inline const unsigned char *
156
 
skip_trailing_space(const unsigned char *ptr, size_t len)
 
223
static inline const unsigned char *skip_trailing_space(const unsigned char *ptr,size_t len)
157
224
{
158
225
  const unsigned char *end= ptr + len;
159
226
 
160
 
  while (end > ptr && isspace(*--end))
161
 
    continue;
162
 
  return end+1;
 
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);
163
247
}
164
248
 
165
249
#endif