~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
53.2.13 by Monty Taylor
Various static declares.
89
static size_t my_lengthsp_binary(CHARSET_INFO *cs __attribute__((unused)),
90
                                 const char *ptr __attribute__((unused)),
91
                                 size_t length)
1 by brian
clean slate
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
53.2.13 by Monty Taylor
Various static declares.
275
static void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
276
                                  const uchar *key, size_t len,
277
                                  ulong *nr1, ulong *nr2)
1 by brian
clean slate
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
53.2.13 by Monty Taylor
Various static declares.
296
static void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
297
                             const uchar *key, size_t len,
298
                             ulong *nr1, ulong *nr2)
1 by brian
clean slate
299
{
300
  const uchar *pos = key;
301
  
302
  key+= len;
303
  
304
  for (; pos < (uchar*) key ; pos++)
305
  {
306
    nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * 
307
	     ((uint)*pos)) + (nr1[0] << 8);
308
    nr2[0]+=3;
309
  }
310
}
311
312
313
/*
314
  The following defines is here to keep the following code identical to
315
  the one in ctype-simple.c
316
*/
317
318
#define likeconv(s,A) (A)
319
#define INC_PTR(cs,A,B) (A)++
320
321
322
int my_wildcmp_bin(CHARSET_INFO *cs,
323
                   const char *str,const char *str_end,
324
                   const char *wildstr,const char *wildend,
325
                   int escape, int w_one, int w_many)
326
{
327
  int result= -1;			/* Not found, using wildcards */
328
  
329
  while (wildstr != wildend)
330
  {
331
    while (*wildstr != w_many && *wildstr != w_one)
332
    {
333
      if (*wildstr == escape && wildstr+1 != wildend)
334
	wildstr++;
335
      if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
336
	return(1);			/* No match */
337
      if (wildstr == wildend)
338
	return(str != str_end);		/* Match if both are at end */
339
      result=1;				/* Found an anchor char */
340
    }
341
    if (*wildstr == w_one)
342
    {
343
      do
344
      {
345
	if (str == str_end)		/* Skip one char if possible */
346
	  return(result);
347
	INC_PTR(cs,str,str_end);
348
      } while (++wildstr < wildend && *wildstr == w_one);
349
      if (wildstr == wildend)
350
	break;
351
    }
352
    if (*wildstr == w_many)
353
    {					/* Found w_many */
354
      uchar cmp;
355
      wildstr++;
356
      /* Remove any '%' and '_' from the wild search string */
357
      for (; wildstr != wildend ; wildstr++)
358
      {
359
	if (*wildstr == w_many)
360
	  continue;
361
	if (*wildstr == w_one)
362
	{
363
	  if (str == str_end)
364
	    return(-1);
365
	  INC_PTR(cs,str,str_end);
366
	  continue;
367
	}
368
	break;				/* Not a wild character */
369
      }
370
      if (wildstr == wildend)
371
	return(0);			/* match if w_many is last */
372
      if (str == str_end)
373
	return(-1);
374
      
375
      if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
376
	cmp= *++wildstr;
377
378
      INC_PTR(cs,wildstr,wildend);	/* This is compared through cmp */
379
      cmp=likeconv(cs,cmp);
380
      do
381
      {
382
	while (str != str_end && (uchar) likeconv(cs,*str) != cmp)
383
	  str++;
384
	if (str++ == str_end)
385
	  return(-1);
386
	{
387
	  int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one,
388
				 w_many);
389
	  if (tmp <= 0)
390
	    return(tmp);
391
	}
392
      } while (str != str_end && wildstr[0] != w_many);
393
      return(-1);
394
    }
395
  }
396
  return(str != str_end ? 1 : 0);
397
}
398
399
400
static size_t
401
my_strnxfrm_8bit_bin(CHARSET_INFO *cs,
402
                     uchar * dst, size_t dstlen, uint nweights,
403
                     const uchar *src, size_t srclen, uint flags)
404
{
405
  set_if_smaller(srclen, dstlen);
406
  set_if_smaller(srclen, nweights);
407
  if (dst != src)
408
    memcpy(dst, src, srclen);
409
  return my_strxfrm_pad_desc_and_reverse(cs, dst, dst + srclen, dst + dstlen,
410
                                         nweights - srclen, flags, 0);
411
}
412
413
414
static
415
uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)),
416
		  const char *b, size_t b_length,
417
		  const char *s, size_t s_length,
418
		  my_match_t *match, uint nmatch)
419
{
420
  register const uchar *str, *search, *end, *search_end;
421
422
  if (s_length <= b_length)
423
  {
424
    if (!s_length)
425
    {
426
      if (nmatch)
427
      {
428
        match->beg= 0;
429
        match->end= 0;
430
        match->mb_len= 0;
431
      }
432
      return 1;		/* Empty string is always found */
433
    }
434
435
    str= (const uchar*) b;
436
    search= (const uchar*) s;
437
    end= (const uchar*) b+b_length-s_length+1;
438
    search_end= (const uchar*) s + s_length;
439
440
skip:
441
    while (str != end)
442
    {
443
      if ( (*str++) == (*search))
444
      {
445
	register const uchar *i,*j;
446
447
	i= str;
448
	j= search+1;
449
450
	while (j != search_end)
451
	  if ((*i++) != (*j++))
452
            goto skip;
453
454
        if (nmatch > 0)
455
	{
456
	  match[0].beg= 0;
457
	  match[0].end= (size_t) (str- (const uchar*)b-1);
458
	  match[0].mb_len= match[0].end;
459
460
	  if (nmatch > 1)
461
	  {
462
	    match[1].beg= match[0].end;
463
	    match[1].end= match[0].end+s_length;
464
	    match[1].mb_len= match[1].end-match[1].beg;
465
	  }
466
	}
467
	return 2;
468
      }
469
    }
470
  }
471
  return 0;
472
}
473
474
475
MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
476
{
477
  my_coll_init_8bit_bin,
478
  my_strnncoll_8bit_bin,
479
  my_strnncollsp_8bit_bin,
480
  my_strnxfrm_8bit_bin,
481
  my_strnxfrmlen_simple,
482
  my_like_range_simple,
483
  my_wildcmp_bin,
484
  my_strcasecmp_bin,
485
  my_instr_bin,
486
  my_hash_sort_8bit_bin,
487
  my_propagate_simple
488
};
489
490
491
static MY_COLLATION_HANDLER my_collation_binary_handler =
492
{
493
  NULL,			/* init */
494
  my_strnncoll_binary,
495
  my_strnncollsp_binary,
496
  my_strnxfrm_8bit_bin,
497
  my_strnxfrmlen_simple,
498
  my_like_range_simple,
499
  my_wildcmp_bin,
500
  my_strcasecmp_bin,
501
  my_instr_bin,
502
  my_hash_sort_bin,
503
  my_propagate_simple
504
};
505
506
507
static MY_CHARSET_HANDLER my_charset_handler=
508
{
509
  NULL,			/* init */
510
  NULL,			/* ismbchar      */
511
  my_mbcharlen_8bit,	/* mbcharlen     */
512
  my_numchars_8bit,
513
  my_charpos_8bit,
514
  my_well_formed_len_8bit,
515
  my_lengthsp_binary,
516
  my_numcells_8bit,
517
  my_mb_wc_bin,
518
  my_wc_mb_bin,
519
  my_mb_ctype_8bit,
520
  my_case_str_bin,
521
  my_case_str_bin,
522
  my_case_bin,
523
  my_case_bin,
524
  my_snprintf_8bit,
525
  my_long10_to_str_8bit,
526
  my_longlong10_to_str_8bit,
527
  my_fill_8bit,
528
  my_strntol_8bit,
529
  my_strntoul_8bit,
530
  my_strntoll_8bit,
531
  my_strntoull_8bit,
532
  my_strntod_8bit,
533
  my_strtoll10_8bit,
534
  my_strntoull10rnd_8bit,
535
  my_scan_8bit
536
};
537
538
539
CHARSET_INFO my_charset_bin =
540
{
541
    63,0,0,			/* number        */
542
    MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */
543
    "binary",			/* cs name    */
544
    "binary",			/* name          */
545
    "",				/* comment       */
546
    NULL,			/* tailoring     */
547
    ctype_bin,			/* ctype         */
548
    bin_char_array,		/* to_lower      */
549
    bin_char_array,		/* to_upper      */
550
    NULL,			/* sort_order    */
551
    NULL,			/* contractions */
552
    NULL,			/* sort_order_big*/
553
    NULL,			/* tab_to_uni    */
554
    NULL,			/* tab_from_uni  */
555
    my_unicase_default,         /* caseinfo     */
556
    NULL,			/* state_map    */
557
    NULL,			/* ident_map    */
558
    1,				/* strxfrm_multiply */
559
    1,                          /* caseup_multiply  */
560
    1,                          /* casedn_multiply  */
561
    1,				/* mbminlen      */
562
    1,				/* mbmaxlen      */
563
    0,				/* min_sort_char */
564
    255,			/* max_sort_char */
565
    0,                          /* pad char      */
566
    0,                          /* escape_with_backslash_is_dangerous */
567
    1,                          /* levels_for_compare */
568
    1,                          /* levels_for_order   */
569
    &my_charset_handler,
570
    &my_collation_binary_handler
571
};