00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <drizzled/definitions.h>
00023 #include <drizzled/internal/m_string.h>
00024 #include <drizzled/charset.h>
00025
00026 #include <algorithm>
00027
00028 using namespace std;
00029
00030 namespace drizzled {
00031
00032 void my_hash_sort_bin(const charset_info_st * const,
00033 const unsigned char *key, size_t len,
00034 uint32_t *nr1, uint32_t *nr2);
00035
00036
00037 static unsigned char ctype_bin[]=
00038 {
00039 0,
00040 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32,
00041 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
00042 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00043 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16,
00044 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00045 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16,
00046 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00047 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32,
00048 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00049 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00050 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00056 };
00057
00058
00059
00060
00061 static unsigned char bin_char_array[] =
00062 {
00063 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
00064 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
00065 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
00066 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
00067 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
00068 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
00069 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
00070 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
00071 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
00072 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
00073 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
00074 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
00075 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
00076 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
00077 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
00078 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
00079 };
00080
00081
00082 int my_strnncoll_binary(const charset_info_st * const,
00083 const unsigned char *s, size_t slen,
00084 const unsigned char *t, size_t tlen,
00085 bool t_is_prefix)
00086 {
00087 size_t len= min(slen,tlen);
00088 int cmp= memcmp(s,t,len);
00089 return cmp ? cmp : static_cast<int>((t_is_prefix ? len : slen) - tlen);
00090 }
00091
00092
00093 size_t my_lengthsp_binary(const charset_info_st * const,
00094 const char *, size_t length)
00095 {
00096 return length;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int my_strnncollsp_binary(const charset_info_st * const cs,
00123 const unsigned char *s, size_t slen,
00124 const unsigned char *t, size_t tlen,
00125 bool)
00126 {
00127 return my_strnncoll_binary(cs,s,slen,t,tlen,0);
00128 }
00129
00130
00131 int my_strnncoll_8bit_bin(const charset_info_st * const,
00132 const unsigned char *s, size_t slen,
00133 const unsigned char *t, size_t tlen,
00134 bool t_is_prefix)
00135 {
00136 size_t len= min(slen,tlen);
00137 int cmp= memcmp(s,t,len);
00138 return cmp ? cmp : static_cast<int>((t_is_prefix ? len : slen) - tlen);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 int my_strnncollsp_8bit_bin(const charset_info_st * const,
00168 const unsigned char *a, size_t a_length,
00169 const unsigned char *b, size_t b_length,
00170 bool diff_if_only_endspace_difference)
00171 {
00172 const unsigned char *end;
00173 size_t length;
00174 int res;
00175
00176 #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
00177 diff_if_only_endspace_difference= 0;
00178 #endif
00179
00180 end= a + (length= min(a_length, b_length));
00181 while (a < end)
00182 {
00183 if (*a++ != *b++)
00184 return a[-1] - b[-1];
00185 }
00186 res= 0;
00187 if (a_length != b_length)
00188 {
00189 int swap= 1;
00190
00191
00192
00193
00194 if (diff_if_only_endspace_difference)
00195 res= 1;
00196 if (a_length < b_length)
00197 {
00198
00199 a_length= b_length;
00200 a= b;
00201 swap= -1;
00202 res= -res;
00203 }
00204 for (end= a + a_length-length; a < end ; a++)
00205 {
00206 if (*a != ' ')
00207 return (*a < ' ') ? -swap : swap;
00208 }
00209 }
00210 return res;
00211 }
00212
00213
00214
00215
00216 size_t my_case_str_bin(const charset_info_st * const, char *)
00217 {
00218 return 0;
00219 }
00220
00221
00222 size_t my_case_bin(const charset_info_st * const, char *,
00223 size_t srclen, char *, size_t)
00224 {
00225 return srclen;
00226 }
00227
00228
00229 int my_strcasecmp_bin(const charset_info_st * const,
00230 const char *s, const char *t)
00231 {
00232 return strcmp(s,t);
00233 }
00234
00235
00236 uint32_t my_mbcharlen_8bit(const charset_info_st * const, uint32_t)
00237 {
00238 return 1;
00239 }
00240
00241
00242 int my_mb_wc_bin(const charset_info_st * const,
00243 my_wc_t *wc, const unsigned char *str,
00244 const unsigned char *end)
00245 {
00246 if (str >= end)
00247 return MY_CS_TOOSMALL;
00248
00249 *wc=str[0];
00250 return 1;
00251 }
00252
00253
00254 int my_wc_mb_bin(const charset_info_st * const, my_wc_t wc,
00255 unsigned char *str, unsigned char *end)
00256 {
00257 if (str >= end)
00258 return MY_CS_TOOSMALL;
00259
00260 if (wc < 256)
00261 {
00262 str[0]= wc;
00263 return 1;
00264 }
00265 return MY_CS_ILUNI;
00266 }
00267
00268
00269 void my_hash_sort_8bit_bin(const charset_info_st * const,
00270 const unsigned char *key, size_t len,
00271 uint32_t *nr1, uint32_t *nr2)
00272 {
00273 const unsigned char *pos = key;
00274
00275
00276
00277
00278
00279 key= internal::skip_trailing_space(key, len);
00280
00281 for (; pos < key ; pos++)
00282 {
00283 nr1[0]^= (((nr1[0] & 63) + nr2[0]) * *pos) + (nr1[0] << 8);
00284 nr2[0]+=3;
00285 }
00286 }
00287
00288
00289 void my_hash_sort_bin(const charset_info_st * const,
00290 const unsigned char *key, size_t len,
00291 uint32_t *nr1, uint32_t *nr2)
00292 {
00293 const unsigned char *pos = key;
00294
00295 key+= len;
00296
00297 for (; pos < key ; pos++)
00298 {
00299 nr1[0]^= (((nr1[0] & 63) + nr2[0]) * *pos) + (nr1[0] << 8);
00300 nr2[0]+=3;
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 #define likeconv(s,A) (A)
00311 #define INC_PTR(cs,A,B) (A)++
00312
00313
00314 int my_wildcmp_bin(const charset_info_st * const cs,
00315 const char *str,const char *str_end,
00316 const char *wildstr,const char *wildend,
00317 int escape, int w_one, int w_many)
00318 {
00319 int result= -1;
00320
00321 while (wildstr != wildend)
00322 {
00323 while (*wildstr != w_many && *wildstr != w_one)
00324 {
00325 if (*wildstr == escape && wildstr+1 != wildend)
00326 wildstr++;
00327 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
00328 return 1;
00329 if (wildstr == wildend)
00330 return(str != str_end);
00331 result=1;
00332 }
00333 if (*wildstr == w_one)
00334 {
00335 do
00336 {
00337 if (str == str_end)
00338 return(result);
00339 INC_PTR(cs,str,str_end);
00340 } while (++wildstr < wildend && *wildstr == w_one);
00341 if (wildstr == wildend)
00342 break;
00343 }
00344 if (*wildstr == w_many)
00345 {
00346 unsigned char cmp;
00347 wildstr++;
00348
00349 for (; wildstr != wildend ; wildstr++)
00350 {
00351 if (*wildstr == w_many)
00352 continue;
00353 if (*wildstr == w_one)
00354 {
00355 if (str == str_end)
00356 return(-1);
00357 INC_PTR(cs,str,str_end);
00358 continue;
00359 }
00360 break;
00361 }
00362 if (wildstr == wildend)
00363 return 0;
00364 if (str == str_end)
00365 return(-1);
00366
00367 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
00368 cmp= *++wildstr;
00369
00370 INC_PTR(cs,wildstr,wildend);
00371 cmp=likeconv(cs,cmp);
00372 do
00373 {
00374 while (str != str_end && (unsigned char) likeconv(cs,*str) != cmp)
00375 str++;
00376 if (str++ == str_end)
00377 return(-1);
00378 {
00379 int tmp=my_wildcmp_bin(cs,str,str_end,wildstr,wildend,escape,w_one,
00380 w_many);
00381 if (tmp <= 0)
00382 return(tmp);
00383 }
00384 } while (str != str_end && wildstr[0] != w_many);
00385 return(-1);
00386 }
00387 }
00388 return(str != str_end ? 1 : 0);
00389 }
00390
00391
00392 size_t
00393 my_strnxfrm_8bit_bin(const charset_info_st * const cs,
00394 unsigned char * dst, size_t dstlen, uint32_t nweights,
00395 const unsigned char *src, size_t srclen, uint32_t flags)
00396 {
00397 set_if_smaller(srclen, dstlen);
00398 set_if_smaller(srclen, (size_t) nweights);
00399 if (dst != src)
00400 memcpy(dst, src, srclen);
00401 return my_strxfrm_pad_desc_and_reverse(cs, dst, dst + srclen, dst + dstlen,
00402 nweights - srclen, flags, 0);
00403 }
00404
00405
00406 uint32_t my_instr_bin(const charset_info_st * const,
00407 const char *b, size_t b_length,
00408 const char *s, size_t s_length,
00409 my_match_t *match, uint32_t nmatch)
00410 {
00411 const unsigned char *str, *search, *end, *search_end;
00412
00413 if (s_length <= b_length)
00414 {
00415 if (!s_length)
00416 {
00417 if (nmatch)
00418 {
00419 match->beg= 0;
00420 match->end= 0;
00421 match->mb_len= 0;
00422 }
00423 return 1;
00424 }
00425
00426 str= (const unsigned char*) b;
00427 search= (const unsigned char*) s;
00428 end= (const unsigned char*) b+b_length-s_length+1;
00429 search_end= (const unsigned char*) s + s_length;
00430
00431 skip:
00432 while (str != end)
00433 {
00434 if ( (*str++) == (*search))
00435 {
00436 const unsigned char *i,*j;
00437
00438 i= str;
00439 j= search+1;
00440
00441 while (j != search_end)
00442 if ((*i++) != (*j++))
00443 goto skip;
00444
00445 if (nmatch > 0)
00446 {
00447 match[0].beg= 0;
00448 match[0].end= (size_t) (str- (const unsigned char*)b-1);
00449 match[0].mb_len= match[0].end;
00450
00451 if (nmatch > 1)
00452 {
00453 match[1].beg= match[0].end;
00454 match[1].end= match[0].end+s_length;
00455 match[1].mb_len= match[1].end-match[1].beg;
00456 }
00457 }
00458 return 2;
00459 }
00460 }
00461 }
00462 return 0;
00463 }
00464
00465
00466 static MY_COLLATION_HANDLER my_collation_binary_handler =
00467 {
00468 NULL,
00469 my_strnncoll_binary,
00470 my_strnncollsp_binary,
00471 my_strnxfrm_8bit_bin,
00472 my_strnxfrmlen_simple,
00473 my_like_range_simple,
00474 my_wildcmp_bin,
00475 my_strcasecmp_bin,
00476 my_instr_bin,
00477 my_hash_sort_bin,
00478 my_propagate_simple
00479 };
00480
00481
00482 static MY_CHARSET_HANDLER my_charset_handler=
00483 {
00484 NULL,
00485 my_mbcharlen_8bit,
00486 my_numchars_8bit,
00487 my_charpos_8bit,
00488 my_well_formed_len_8bit,
00489 my_lengthsp_binary,
00490 my_numcells_8bit,
00491 my_mb_wc_bin,
00492 my_wc_mb_bin,
00493 my_mb_ctype_8bit,
00494 my_case_str_bin,
00495 my_case_str_bin,
00496 my_case_bin,
00497 my_case_bin,
00498 my_snprintf_8bit,
00499 my_long10_to_str_8bit,
00500 my_int64_t10_to_str_8bit,
00501 my_fill_8bit,
00502 my_strntol_8bit,
00503 my_strntoul_8bit,
00504 my_strntoll_8bit,
00505 my_strntoull_8bit,
00506 my_strntod_8bit,
00507 my_strtoll10_8bit,
00508 my_strntoull10rnd_8bit,
00509 my_scan_8bit
00510 };
00511
00512
00513 DRIZZLED_API charset_info_st my_charset_bin =
00514 {
00515 63,0,0,
00516 MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_PRIMARY,
00517 "binary",
00518 "binary",
00519 "",
00520 NULL,
00521 ctype_bin,
00522 bin_char_array,
00523 bin_char_array,
00524 NULL,
00525 NULL,
00526 NULL,
00527 NULL,
00528 NULL,
00529 my_unicase_default,
00530 NULL,
00531 NULL,
00532 1,
00533 1,
00534 1,
00535 1,
00536 1,
00537 0,
00538 255,
00539 0,
00540 1,
00541 1,
00542 &my_charset_handler,
00543 &my_collation_binary_handler
00544 };
00545
00546 }