00001 /* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp. 00002 00003 This library is free software; you can redistribute it and/or 00004 modify it under the terms of the GNU Library General Public 00005 License as published by the Free Software Foundation; either 00006 version 2 of the License, or (at your option) any later version. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public 00014 License along with this library; if not, write to the Free 00015 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 00016 MA 02111-1307, USA */ 00017 00018 /* This file is for binary pseudo charset, created by bar@mysql.com */ 00019 00020 00021 #include <my_global.h> 00022 #include "m_string.h" 00023 #include "m_ctype.h" 00024 00025 static uchar ctype_bin[]= 00026 { 00027 0, 00028 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, 00029 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 00030 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 00031 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16, 00032 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1, 00033 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 00034 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2, 00035 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32, 00036 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00037 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00038 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00039 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00040 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00041 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00042 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00043 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00044 }; 00045 00046 00047 /* Dummy array for toupper / tolower / sortorder */ 00048 00049 static uchar bin_char_array[] = 00050 { 00051 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 00052 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 00053 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 00054 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 00055 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 00056 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 00057 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, 00058 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 00059 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 00060 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 00061 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 00062 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 00063 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 00064 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 00065 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 00066 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 00067 }; 00068 00069 00070 static my_bool 00071 my_coll_init_8bit_bin(CHARSET_INFO *cs, 00072 void *(*alloc)(uint) __attribute__((unused))) 00073 { 00074 cs->max_sort_char=255; 00075 return FALSE; 00076 } 00077 00078 static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), 00079 const uchar *s, uint slen, 00080 const uchar *t, uint tlen, 00081 my_bool t_is_prefix) 00082 { 00083 uint len=min(slen,tlen); 00084 int cmp= memcmp(s,t,len); 00085 return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen); 00086 } 00087 00088 00089 uint my_lengthsp_binary(CHARSET_INFO *cs __attribute__((unused)), 00090 const char *ptr __attribute__((unused)), 00091 uint length) 00092 { 00093 return length; 00094 } 00095 00096 00097 /* 00098 Compare two strings. Result is sign(first_argument - second_argument) 00099 00100 SYNOPSIS 00101 my_strnncollsp_binary() 00102 cs Chararacter set 00103 s String to compare 00104 slen Length of 's' 00105 t String to compare 00106 tlen Length of 't' 00107 00108 NOTE 00109 This function is used for real binary strings, i.e. for 00110 BLOB, BINARY(N) and VARBINARY(N). 00111 It compares trailing spaces as spaces. 00112 00113 RETURN 00114 < 0 s < t 00115 0 s == t 00116 > 0 s > t 00117 */ 00118 00119 static int my_strnncollsp_binary(CHARSET_INFO * cs __attribute__((unused)), 00120 const uchar *s, uint slen, 00121 const uchar *t, uint tlen, 00122 my_bool diff_if_only_endspace_difference 00123 __attribute__((unused))) 00124 { 00125 return my_strnncoll_binary(cs,s,slen,t,tlen,0); 00126 } 00127 00128 00129 static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), 00130 const uchar *s, uint slen, 00131 const uchar *t, uint tlen, 00132 my_bool t_is_prefix) 00133 { 00134 uint len=min(slen,tlen); 00135 int cmp= memcmp(s,t,len); 00136 return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen); 00137 } 00138 00139 00140 /* 00141 Compare two strings. Result is sign(first_argument - second_argument) 00142 00143 SYNOPSIS 00144 my_strnncollsp_8bit_bin() 00145 cs Chararacter set 00146 s String to compare 00147 slen Length of 's' 00148 t String to compare 00149 tlen Length of 't' 00150 diff_if_only_endspace_difference 00151 Set to 1 if the strings should be regarded as different 00152 if they only difference in end space 00153 00154 NOTE 00155 This function is used for character strings with binary collations. 00156 The shorter string is extended with end space to be as long as the longer 00157 one. 00158 00159 RETURN 00160 < 0 s < t 00161 0 s == t 00162 > 0 s > t 00163 */ 00164 00165 static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), 00166 const uchar *a, uint a_length, 00167 const uchar *b, uint b_length, 00168 my_bool diff_if_only_endspace_difference) 00169 { 00170 const uchar *end; 00171 uint length; 00172 int res; 00173 00174 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE 00175 diff_if_only_endspace_difference= 0; 00176 #endif 00177 00178 end= a + (length= min(a_length, b_length)); 00179 while (a < end) 00180 { 00181 if (*a++ != *b++) 00182 return ((int) a[-1] - (int) b[-1]); 00183 } 00184 res= 0; 00185 if (a_length != b_length) 00186 { 00187 int swap= 1; 00188 /* 00189 Check the next not space character of the longer key. If it's < ' ', 00190 then it's smaller than the other key. 00191 */ 00192 if (diff_if_only_endspace_difference) 00193 res= 1; /* Assume 'a' is bigger */ 00194 if (a_length < b_length) 00195 { 00196 /* put shorter key in s */ 00197 a_length= b_length; 00198 a= b; 00199 swap= -1; /* swap sign of result */ 00200 res= -res; 00201 } 00202 for (end= a + a_length-length; a < end ; a++) 00203 { 00204 if (*a != ' ') 00205 return (*a < ' ') ? -swap : swap; 00206 } 00207 } 00208 return res; 00209 } 00210 00211 00212 /* This function is used for all conversion functions */ 00213 00214 static void my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)), 00215 char *str __attribute__((unused))) 00216 { 00217 } 00218 00219 static uint my_case_bin(CHARSET_INFO *cs __attribute__((unused)), 00220 char *src __attribute__((unused)), 00221 uint srclen, 00222 char *dst __attribute__((unused)), 00223 uint dstlen __attribute__((unused))) 00224 { 00225 return srclen; 00226 } 00227 00228 00229 static int my_strcasecmp_bin(CHARSET_INFO * cs __attribute__((unused)), 00230 const char *s, const char *t) 00231 { 00232 return strcmp(s,t); 00233 } 00234 00235 00236 int my_mbcharlen_8bit(CHARSET_INFO *cs __attribute__((unused)), 00237 uint c __attribute__((unused))) 00238 { 00239 return 1; 00240 } 00241 00242 00243 static int my_mb_wc_bin(CHARSET_INFO *cs __attribute__((unused)), 00244 my_wc_t *wc, 00245 const unsigned char *str, 00246 const unsigned char *end __attribute__((unused))) 00247 { 00248 if (str >= end) 00249 return MY_CS_TOOSMALL; 00250 00251 *wc=str[0]; 00252 return 1; 00253 } 00254 00255 00256 static int my_wc_mb_bin(CHARSET_INFO *cs __attribute__((unused)), 00257 my_wc_t wc, 00258 unsigned char *s, 00259 unsigned char *e __attribute__((unused))) 00260 { 00261 if (s >= e) 00262 return MY_CS_TOOSMALL; 00263 00264 if (wc < 256) 00265 { 00266 s[0]= (char) wc; 00267 return 1; 00268 } 00269 return MY_CS_ILUNI; 00270 } 00271 00272 00273 void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)), 00274 const uchar *key, uint len,ulong *nr1, ulong *nr2) 00275 { 00276 const uchar *pos = key; 00277 00278 key+= len; 00279 00280 for (; pos < (uchar*) key ; pos++) 00281 { 00282 nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * 00283 ((uint)*pos)) + (nr1[0] << 8); 00284 nr2[0]+=3; 00285 } 00286 } 00287 00288 00289 /* 00290 The following defines is here to keep the following code identical to 00291 the one in ctype-simple.c 00292 */ 00293 00294 #define likeconv(s,A) (A) 00295 #define INC_PTR(cs,A,B) (A)++ 00296 00297 00298 int my_wildcmp_bin(CHARSET_INFO *cs, 00299 const char *str,const char *str_end, 00300 const char *wildstr,const char *wildend, 00301 int escape, int w_one, int w_many) 00302 { 00303 int result= -1; /* Not found, using wildcards */ 00304 00305 while (wildstr != wildend) 00306 { 00307 while (*wildstr != w_many && *wildstr != w_one) 00308 { 00309 if (*wildstr == escape && wildstr+1 != wildend) 00310 wildstr++; 00311 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++)) 00312 return(1); /* No match */ 00313 if (wildstr == wildend) 00314 return(str != str_end); /* Match if both are at end */ 00315 result=1; /* Found an anchor char */ 00316 } 00317 if (*wildstr == w_one) 00318 { 00319 do 00320 { 00321 if (str == str_end) /* Skip one char if possible */ 00322 return(result); 00323 INC_PTR(cs,str,str_end); 00324 } while (++wildstr < wildend && *wildstr == w_one); 00325 if (wildstr == wildend) 00326 break; 00327 } 00328 if (*wildstr == w_many) 00329 { /* Found w_many */ 00330 uchar cmp; 00331 wildstr++; 00332 /* Remove any '%' and '_' from the wild search string */ 00333 for (; wildstr != wildend ; wildstr++) 00334 { 00335 if (*wildstr == w_many) 00336 continue; 00337 if (*wildstr == w_one) 00338 { 00339 if (str == str_end) 00340 return(-1); 00341 INC_PTR(cs,str,str_end); 00342 continue; 00343 } 00344 break; /* Not a wild character */ 00345 } 00346 if (wildstr == wildend) 00347 return(0); /* match if w_many is last */ 00348 if (str == str_end) 00349 return(-1); 00350 00351 if ((cmp= *wildstr) == escape && wildstr+1 != wildend) 00352 cmp= *++wildstr; 00353 00354 INC_PTR(cs,wildstr,wildend); /* This is compared through cmp */ 00355 cmp=likeconv(cs,cmp); 00356 do 00357 { 00358 while (str != str_end && (uchar) likeconv(cs,*str) != cmp) 00359 str++; 00360 if (str++ == str_end) 00361 return(-1); 00362 { 00363 int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one, 00364 w_many); 00365 if (tmp <= 0) 00366 return(tmp); 00367 } 00368 } while (str != str_end && wildstr[0] != w_many); 00369 return(-1); 00370 } 00371 } 00372 return(str != str_end ? 1 : 0); 00373 } 00374 00375 00376 static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), 00377 uchar * dest, uint dstlen, 00378 const uchar *src, uint srclen) 00379 { 00380 if (dest != src) 00381 memcpy(dest, src, min(dstlen,srclen)); 00382 if (dstlen > srclen) 00383 bfill(dest + srclen, dstlen - srclen, 0); 00384 return dstlen; 00385 } 00386 00387 00388 static 00389 int my_strnxfrm_8bit_bin(CHARSET_INFO *cs __attribute__((unused)), 00390 uchar * dest, uint dstlen, 00391 const uchar *src, uint srclen) 00392 { 00393 if (dest != src) 00394 memcpy(dest, src, min(dstlen,srclen)); 00395 if (dstlen > srclen) 00396 bfill(dest + srclen, dstlen - srclen, ' '); 00397 return dstlen; 00398 } 00399 00400 00401 static 00402 uint my_instr_bin(CHARSET_INFO *cs __attribute__((unused)), 00403 const char *b, uint b_length, 00404 const char *s, uint s_length, 00405 my_match_t *match, uint nmatch) 00406 { 00407 register const uchar *str, *search, *end, *search_end; 00408 00409 if (s_length <= b_length) 00410 { 00411 if (!s_length) 00412 { 00413 if (nmatch) 00414 { 00415 match->beg= 0; 00416 match->end= 0; 00417 match->mblen= 0; 00418 } 00419 return 1; /* Empty string is always found */ 00420 } 00421 00422 str= (const uchar*) b; 00423 search= (const uchar*) s; 00424 end= (const uchar*) b+b_length-s_length+1; 00425 search_end= (const uchar*) s + s_length; 00426 00427 skip: 00428 while (str != end) 00429 { 00430 if ( (*str++) == (*search)) 00431 { 00432 register const uchar *i,*j; 00433 00434 i= str; 00435 j= search+1; 00436 00437 while (j != search_end) 00438 if ((*i++) != (*j++)) 00439 goto skip; 00440 00441 if (nmatch > 0) 00442 { 00443 match[0].beg= 0; 00444 match[0].end= (uint) (str- (const uchar*)b-1); 00445 match[0].mblen= match[0].end; 00446 00447 if (nmatch > 1) 00448 { 00449 match[1].beg= match[0].end; 00450 match[1].end= match[0].end+s_length; 00451 match[1].mblen= match[1].end-match[1].beg; 00452 } 00453 } 00454 return 2; 00455 } 00456 } 00457 } 00458 return 0; 00459 } 00460 00461 00462 MY_COLLATION_HANDLER my_collation_8bit_bin_handler = 00463 { 00464 my_coll_init_8bit_bin, 00465 my_strnncoll_8bit_bin, 00466 my_strnncollsp_8bit_bin, 00467 my_strnxfrm_8bit_bin, 00468 my_strnxfrmlen_simple, 00469 my_like_range_simple, 00470 my_wildcmp_bin, 00471 my_strcasecmp_bin, 00472 my_instr_bin, 00473 my_hash_sort_bin, 00474 my_propagate_simple 00475 }; 00476 00477 00478 static MY_COLLATION_HANDLER my_collation_binary_handler = 00479 { 00480 NULL, /* init */ 00481 my_strnncoll_binary, 00482 my_strnncollsp_binary, 00483 my_strnxfrm_bin, 00484 my_strnxfrmlen_simple, 00485 my_like_range_simple, 00486 my_wildcmp_bin, 00487 my_strcasecmp_bin, 00488 my_instr_bin, 00489 my_hash_sort_bin, 00490 my_propagate_simple 00491 }; 00492 00493 00494 static MY_CHARSET_HANDLER my_charset_handler= 00495 { 00496 NULL, /* init */ 00497 NULL, /* ismbchar */ 00498 my_mbcharlen_8bit, /* mbcharlen */ 00499 my_numchars_8bit, 00500 my_charpos_8bit, 00501 my_well_formed_len_8bit, 00502 my_lengthsp_binary, 00503 my_numcells_8bit, 00504 my_mb_wc_bin, 00505 my_wc_mb_bin, 00506 my_mb_ctype_8bit, 00507 my_case_str_bin, 00508 my_case_str_bin, 00509 my_case_bin, 00510 my_case_bin, 00511 my_snprintf_8bit, 00512 my_long10_to_str_8bit, 00513 my_longlong10_to_str_8bit, 00514 my_fill_8bit, 00515 my_strntol_8bit, 00516 my_strntoul_8bit, 00517 my_strntoll_8bit, 00518 my_strntoull_8bit, 00519 my_strntod_8bit, 00520 my_strtoll10_8bit, 00521 my_scan_8bit 00522 }; 00523 00524 00525 CHARSET_INFO my_charset_bin = 00526 { 00527 63,0,0, /* number */ 00528 MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,/* state */ 00529 "binary", /* cs name */ 00530 "binary", /* name */ 00531 "", /* comment */ 00532 NULL, /* tailoring */ 00533 ctype_bin, /* ctype */ 00534 bin_char_array, /* to_lower */ 00535 bin_char_array, /* to_upper */ 00536 NULL, /* sort_order */ 00537 NULL, /* contractions */ 00538 NULL, /* sort_order_big*/ 00539 NULL, /* tab_to_uni */ 00540 NULL, /* tab_from_uni */ 00541 my_unicase_default, /* caseinfo */ 00542 NULL, /* state_map */ 00543 NULL, /* ident_map */ 00544 1, /* strxfrm_multiply */ 00545 1, /* caseup_multiply */ 00546 1, /* casedn_multiply */ 00547 1, /* mbminlen */ 00548 1, /* mbmaxlen */ 00549 0, /* min_sort_char */ 00550 255, /* max_sort_char */ 00551 0, /* pad char */ 00552 0, /* escape_with_backslash_is_dangerous */ 00553 &my_charset_handler, 00554 &my_collation_binary_handler 00555 };
1.4.7

