~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

Viewing changes to strings/ctype-bin.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp.
 
2
   
 
3
   This library is free software; you can redistribute it and/or
 
4
   modify it under the terms of the GNU Library General Public
 
5
   License as published by the Free Software Foundation; version 2
 
6
   of the License.
 
7
   
 
8
   This library is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
   Library General Public License for more details.
 
12
   
 
13
   You should have received a copy of the GNU Library General Public
 
14
   License along with this library; if not, write to the Free
 
15
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
16
   MA 02111-1307, USA */
 
17
 
 
18
/* This file is for binary pseudo charset, created by bar@mysql.com */
 
19
 
 
20
 
 
21
#include <my_global.h>
 
22
#include "m_string.h"
 
23
#include "m_ctype.h"
 
24
 
 
25
static uchar ctype_bin[]=
 
26
{
 
27
  0,
 
28
  32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
 
29
  32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
 
30
  72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
 
31
  132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
 
32
  16,129,129,129,129,129,129,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 
33
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 16, 16, 16, 16, 16,
 
34
  16,130,130,130,130,130,130,  2,  2,  2,  2,  2,  2,  2,  2,  2,
 
35
  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 16, 16, 16, 16, 32,
 
36
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
37
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
38
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
39
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
40
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
41
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
42
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
43
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 
44
};
 
45
 
 
46
 
 
47
/* Dummy array for toupper / tolower / sortorder */
 
48
 
 
49
static uchar bin_char_array[] =
 
50
{
 
51
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
 
52
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
 
53
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 
54
   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 
55
   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
 
56
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
 
57
   96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 
58
  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 
59
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
 
60
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
 
61
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
 
62
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
 
63
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
 
64
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
 
65
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
 
66
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
 
67
};
 
68
 
 
69
 
 
70
static my_bool 
 
71
my_coll_init_8bit_bin(CHARSET_INFO *cs,
 
72
                      void *(*alloc)(size_t) __attribute__((unused)))
 
73
{
 
74
  cs->max_sort_char=255; 
 
75
  return FALSE;
 
76
}
 
77
 
 
78
static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
 
79
                               const uchar *s, size_t slen,
 
80
                               const uchar *t, size_t tlen,
 
81
                               my_bool t_is_prefix)
 
82
{
 
83
  size_t len=min(slen,tlen);
 
84
  int cmp= memcmp(s,t,len);
 
85
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
 
86
}
 
87
 
 
88
 
 
89
size_t my_lengthsp_binary(CHARSET_INFO *cs __attribute__((unused)),
 
90
                          const char *ptr __attribute__((unused)),
 
91
                          size_t length)
 
92
{
 
93
  return length;
 
94
}
 
95
 
 
96
 
 
97
/*
 
98
  Compare two strings. Result is sign(first_argument - second_argument)
 
99
 
 
100
  SYNOPSIS
 
101
    my_strnncollsp_binary()
 
102
    cs                  Chararacter set
 
103
    s                   String to compare
 
104
    slen                Length of 's'
 
105
    t                   String to compare
 
106
    tlen                Length of 't'
 
107
 
 
108
  NOTE
 
109
   This function is used for real binary strings, i.e. for
 
110
   BLOB, BINARY(N) and VARBINARY(N).
 
111
   It compares trailing spaces as spaces.
 
112
 
 
113
  RETURN
 
114
  < 0   s < t
 
115
  0     s == t
 
116
  > 0   s > t
 
117
*/
 
118
 
 
119
static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)),
 
120
                                 const uchar *s, size_t slen,
 
121
                                 const uchar *t, size_t tlen,
 
122
                                 my_bool diff_if_only_endspace_difference
 
123
                                 __attribute__((unused)))
 
124
{
 
125
  return my_strnncoll_binary(cs,s,slen,t,tlen,0);
 
126
}
 
127
 
 
128
 
 
129
static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
 
130
                                 const uchar *s, size_t slen,
 
131
                                 const uchar *t, size_t tlen,
 
132
                                 my_bool t_is_prefix)
 
133
{
 
134
  size_t len=min(slen,tlen);
 
135
  int cmp= memcmp(s,t,len);
 
136
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
 
137
}
 
138
 
 
139
 
 
140
/*
 
141
  Compare two strings. Result is sign(first_argument - second_argument)
 
142
 
 
143
  SYNOPSIS
 
144
    my_strnncollsp_8bit_bin()
 
145
    cs                  Chararacter set
 
146
    s                   String to compare
 
147
    slen                Length of 's'
 
148
    t                   String to compare
 
149
    tlen                Length of 't'
 
150
    diff_if_only_endspace_difference
 
151
                        Set to 1 if the strings should be regarded as different
 
152
                        if they only difference in end space
 
153
 
 
154
  NOTE
 
155
   This function is used for character strings with binary collations.
 
156
   The shorter string is extended with end space to be as long as the longer
 
157
   one.
 
158
 
 
159
  RETURN
 
160
  < 0   s < t
 
161
  0     s == t
 
162
  > 0   s > t
 
163
*/
 
164
 
 
165
static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
 
166
                                   const uchar *a, size_t a_length, 
 
167
                                   const uchar *b, size_t b_length,
 
168
                                   my_bool diff_if_only_endspace_difference)
 
169
{
 
170
  const uchar *end;
 
171
  size_t length;
 
172
  int res;
 
173
 
 
174
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
 
175
  diff_if_only_endspace_difference= 0;
 
176
#endif
 
177
 
 
178
  end= a + (length= min(a_length, b_length));
 
179
  while (a < end)
 
180
  {
 
181
    if (*a++ != *b++)
 
182
      return ((int) a[-1] - (int) b[-1]);
 
183
  }
 
184
  res= 0;
 
185
  if (a_length != b_length)
 
186
  {
 
187
    int swap= 1;
 
188
    /*
 
189
      Check the next not space character of the longer key. If it's < ' ',
 
190
      then it's smaller than the other key.
 
191
    */
 
192
    if (diff_if_only_endspace_difference)
 
193
      res= 1;                                   /* Assume 'a' is bigger */
 
194
    if (a_length < b_length)
 
195
    {
 
196
      /* put shorter key in s */
 
197
      a_length= b_length;
 
198
      a= b;
 
199
      swap= -1;                                 /* swap sign of result */
 
200
      res= -res;
 
201
    }
 
202
    for (end= a + a_length-length; a < end ; a++)
 
203
    {
 
204
      if (*a != ' ')
 
205
        return (*a < ' ') ? -swap : swap;
 
206
    }
 
207
  }
 
208
  return res;
 
209
}
 
210
 
 
211
 
 
212
/* This function is used for all conversion functions */
 
213
 
 
214
static size_t my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)),
 
215
                              char *str __attribute__((unused)))
 
216
{
 
217
  return 0;
 
218
}
 
219
 
 
220
 
 
221
static size_t my_case_bin(CHARSET_INFO *cs __attribute__((unused)),
 
222
                          char *src __attribute__((unused)),
 
223
                          size_t srclen,
 
224
                          char *dst __attribute__((unused)),
 
225
                          size_t dstlen __attribute__((unused)))
 
226
{
 
227
  return srclen;
 
228
}
 
229
 
 
230
 
 
231
static int my_strcasecmp_bin(CHARSET_INFO * cs __attribute__((unused)),
 
232
                             const char *s, const char *t)
 
233
{
 
234
  return strcmp(s,t);
 
235
}
 
236
 
 
237
 
 
238
uint my_mbcharlen_8bit(CHARSET_INFO *cs __attribute__((unused)),
 
239
                      uint c __attribute__((unused)))
 
240
{
 
241
  return 1;
 
242
}
 
243
 
 
244
 
 
245
static int my_mb_wc_bin(CHARSET_INFO *cs __attribute__((unused)),
 
246
                        my_wc_t *wc,
 
247
                        const uchar *str,
 
248
                        const uchar *end __attribute__((unused)))
 
249
{
 
250
  if (str >= end)
 
251
    return MY_CS_TOOSMALL;
 
252
  
 
253
  *wc=str[0];
 
254
  return 1;
 
255
}
 
256
 
 
257
 
 
258
static int my_wc_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
 
259
                        my_wc_t wc,
 
260
                        uchar *s,
 
261
                        uchar *e __attribute__((unused)))
 
262
{
 
263
  if (s >= e)
 
264
    return MY_CS_TOOSMALL;
 
265
 
 
266
  if (wc < 256)
 
267
  {
 
268
    s[0]= (char) wc;
 
269
    return 1;
 
270
  }
 
271
  return MY_CS_ILUNI;
 
272
}
 
273
 
 
274
 
 
275
void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
 
276
                           const uchar *key, size_t len,
 
277
                           ulong *nr1, ulong *nr2)
 
278
{
 
279
  const uchar *pos = key;
 
280
  
 
281
  /*
 
282
     Remove trailing spaces. We have to do this to be able to compare
 
283
    'A ' and 'A' as identical
 
284
  */
 
285
  key= skip_trailing_space(key, len);
 
286
 
 
287
  for (; pos < (uchar*) key ; pos++)
 
288
  {
 
289
    nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * 
 
290
             ((uint)*pos)) + (nr1[0] << 8);
 
291
    nr2[0]+=3;
 
292
  }
 
293
}
 
294
 
 
295
 
 
296
void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
 
297
                      const uchar *key, size_t len,ulong *nr1, ulong *nr2)
 
298
{
 
299
  const uchar *pos = key;
 
300
  
 
301
  key+= len;
 
302
  
 
303
  for (; pos < (uchar*) key ; pos++)
 
304
  {
 
305
    nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * 
 
306
             ((uint)*pos)) + (nr1[0] << 8);
 
307
    nr2[0]+=3;
 
308
  }
 
309
}
 
310
 
 
311
 
 
312
/*
 
313
  The following defines is here to keep the following code identical to
 
314
  the one in ctype-simple.c
 
315
*/
 
316
 
 
317
#define likeconv(s,A) (A)
 
318
#define INC_PTR(cs,A,B) (A)++
 
319
 
 
320
 
 
321
int my_wildcmp_bin(CHARSET_INFO *cs,
 
322
                   const char *str,const char *str_end,
 
323
                   const char *wildstr,const char *wildend,
 
324
                   int escape, int w_one, int w_many)
 
325
{
 
326
  int result= -1;                       /* Not found, using wildcards */
 
327
  
 
328
  while (wildstr != wildend)
 
329
  {
 
330
    while (*wildstr != w_many && *wildstr != w_one)
 
331
    {
 
332
      if (*wildstr == escape && wildstr+1 != wildend)
 
333
        wildstr++;
 
334
      if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
 
335
        return(1);                      /* No match */
 
336
      if (wildstr == wildend)
 
337
        return(str != str_end);         /* Match if both are at end */
 
338
      result=1;                         /* Found an anchor char */
 
339
    }
 
340
    if (*wildstr == w_one)
 
341
    {
 
342
      do
 
343
      {
 
344
        if (str == str_end)             /* Skip one char if possible */
 
345
          return(result);
 
346
        INC_PTR(cs,str,str_end);
 
347
      } while (++wildstr < wildend && *wildstr == w_one);
 
348
      if (wildstr == wildend)
 
349
        break;
 
350
    }
 
351
    if (*wildstr == w_many)
 
352
    {                                   /* Found w_many */
 
353
      uchar cmp;
 
354
      wildstr++;
 
355
      /* Remove any '%' and '_' from the wild search string */
 
356
      for (; wildstr != wildend ; wildstr++)
 
357
      {
 
358
        if (*wildstr == w_many)
 
359
          continue;
 
360
        if (*wildstr == w_one)
 
361
        {
 
362
          if (str == str_end)
 
363
            return(-1);
 
364
          INC_PTR(cs,str,str_end);
 
365
          continue;
 
366
        }
 
367
        break;                          /* Not a wild character */
 
368
      }
 
369
      if (wildstr == wildend)
 
370
        return(0);                      /* match if w_many is last */
 
371
      if (str == str_end)
 
372
        return(-1);
 
373
      
 
374
      if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
 
375
        cmp= *++wildstr;
 
376
 
 
377
      INC_PTR(cs,wildstr,wildend);      /* This is compared through cmp */
 
378
      cmp=likeconv(cs,cmp);
 
379
      do
 
380
      {
 
381
        while (str != str_end && (uchar) likeconv(cs,*str) != cmp)
 
382
          str++;
 
383
        if (str++ == str_end)
 
384
          return(-1);
 
385
        {
 
386
          int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one,
 
387
                                 w_many);
 
388
          if (tmp <= 0)
 
389
            return(tmp);
 
390
        }
 
391
      } while (str != str_end && wildstr[0] != w_many);
 
392
      return(-1);
 
393
    }
 
394
  }
 
395
  return(str != str_end ? 1 : 0);
 
396
}
 
397
 
 
398
 
 
399
static size_t
 
400
my_strnxfrm_8bit_bin(CHARSET_INFO *cs,
 
401
                     uchar * dst, size_t dstlen, uint nweights,
 
402
                     const uchar *src, size_t srclen, uint flags)
 
403
{
 
404
  set_if_smaller(srclen, dstlen);
 
405
  set_if_smaller(srclen, nweights);
 
406
  if (dst != src)
 
407
    memcpy(dst, src, srclen);
 
408
  return my_strxfrm_pad_desc_and_reverse(cs, dst, dst + srclen, dst + dstlen,
 
409
                                         nweights - srclen, flags, 0);
 
410
}
 
411
 
 
412
 
 
413
static
 
414
uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)),
 
415
                  const char *b, size_t b_length,
 
416
                  const char *s, size_t s_length,
 
417
                  my_match_t *match, uint nmatch)
 
418
{
 
419
  register const uchar *str, *search, *end, *search_end;
 
420
 
 
421
  if (s_length <= b_length)
 
422
  {
 
423
    if (!s_length)
 
424
    {
 
425
      if (nmatch)
 
426
      {
 
427
        match->beg= 0;
 
428
        match->end= 0;
 
429
        match->mb_len= 0;
 
430
      }
 
431
      return 1;         /* Empty string is always found */
 
432
    }
 
433
 
 
434
    str= (const uchar*) b;
 
435
    search= (const uchar*) s;
 
436
    end= (const uchar*) b+b_length-s_length+1;
 
437
    search_end= (const uchar*) s + s_length;
 
438
 
 
439
skip:
 
440
    while (str != end)
 
441
    {
 
442
      if ( (*str++) == (*search))
 
443
      {
 
444
        register const uchar *i,*j;
 
445
 
 
446
        i= str;
 
447
        j= search+1;
 
448
 
 
449
        while (j != search_end)
 
450
          if ((*i++) != (*j++))
 
451
            goto skip;
 
452
 
 
453
        if (nmatch > 0)
 
454
        {
 
455
          match[0].beg= 0;
 
456
          match[0].end= (size_t) (str- (const uchar*)b-1);
 
457
          match[0].mb_len= match[0].end;
 
458
 
 
459
          if (nmatch > 1)
 
460
          {
 
461
            match[1].beg= match[0].end;
 
462
            match[1].end= match[0].end+s_length;
 
463
            match[1].mb_len= match[1].end-match[1].beg;
 
464
          }
 
465
        }
 
466
        return 2;
 
467
      }
 
468
    }
 
469
  }
 
470
  return 0;
 
471
}
 
472
 
 
473
 
 
474
MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
 
475
{
 
476
  my_coll_init_8bit_bin,
 
477
  my_strnncoll_8bit_bin,
 
478
  my_strnncollsp_8bit_bin,
 
479
  my_strnxfrm_8bit_bin,
 
480
  my_strnxfrmlen_simple,
 
481
  my_like_range_simple,
 
482
  my_wildcmp_bin,
 
483
  my_strcasecmp_bin,
 
484
  my_instr_bin,
 
485
  my_hash_sort_8bit_bin,
 
486
  my_propagate_simple
 
487
};
 
488
 
 
489
 
 
490
static MY_COLLATION_HANDLER my_collation_binary_handler =
 
491
{
 
492
  NULL,                 /* init */
 
493
  my_strnncoll_binary,
 
494
  my_strnncollsp_binary,
 
495
  my_strnxfrm_8bit_bin,
 
496
  my_strnxfrmlen_simple,
 
497
  my_like_range_simple,
 
498
  my_wildcmp_bin,
 
499
  my_strcasecmp_bin,
 
500
  my_instr_bin,
 
501
  my_hash_sort_bin,
 
502
  my_propagate_simple
 
503
};
 
504
 
 
505
 
 
506
static MY_CHARSET_HANDLER my_charset_handler=
 
507
{
 
508
  NULL,                 /* init */
 
509
  NULL,                 /* ismbchar      */
 
510
  my_mbcharlen_8bit,    /* mbcharlen     */
 
511
  my_numchars_8bit,
 
512
  my_charpos_8bit,
 
513
  my_well_formed_len_8bit,
 
514
  my_lengthsp_binary,
 
515
  my_numcells_8bit,
 
516
  my_mb_wc_bin,
 
517
  my_wc_mb_bin,
 
518
  my_mb_ctype_8bit,
 
519
  my_case_str_bin,
 
520
  my_case_str_bin,
 
521
  my_case_bin,
 
522
  my_case_bin,
 
523
  my_snprintf_8bit,
 
524
  my_long10_to_str_8bit,
 
525
  my_longlong10_to_str_8bit,
 
526
  my_fill_8bit,
 
527
  my_strntol_8bit,
 
528
  my_strntoul_8bit,
 
529
  my_strntoll_8bit,
 
530
  my_strntoull_8bit,
 
531
  my_strntod_8bit,
 
532
  my_strtoll10_8bit,
 
533
  my_strntoull10rnd_8bit,
 
534
  my_scan_8bit
 
535
};
 
536
 
 
537
 
 
538
CHARSET_INFO my_charset_bin =
 
539
{
 
540
    63,0,0,                     /* number        */
 
541
    MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */
 
542
    "binary",                   /* cs name    */
 
543
    "binary",                   /* name          */
 
544
    "",                         /* comment       */
 
545
    NULL,                       /* tailoring     */
 
546
    ctype_bin,                  /* ctype         */
 
547
    bin_char_array,             /* to_lower      */
 
548
    bin_char_array,             /* to_upper      */
 
549
    NULL,                       /* sort_order    */
 
550
    NULL,                       /* contractions */
 
551
    NULL,                       /* sort_order_big*/
 
552
    NULL,                       /* tab_to_uni    */
 
553
    NULL,                       /* tab_from_uni  */
 
554
    my_unicase_default,         /* caseinfo     */
 
555
    NULL,                       /* state_map    */
 
556
    NULL,                       /* ident_map    */
 
557
    1,                          /* strxfrm_multiply */
 
558
    1,                          /* caseup_multiply  */
 
559
    1,                          /* casedn_multiply  */
 
560
    1,                          /* mbminlen      */
 
561
    1,                          /* mbmaxlen      */
 
562
    0,                          /* min_sort_char */
 
563
    255,                        /* max_sort_char */
 
564
    0,                          /* pad char      */
 
565
    0,                          /* escape_with_backslash_is_dangerous */
 
566
    1,                          /* levels_for_compare */
 
567
    1,                          /* levels_for_order   */
 
568
    &my_charset_handler,
 
569
    &my_collation_binary_handler
 
570
};