00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <config.h>
00017
00018 #include <drizzled/internal/m_string.h>
00019 #include <drizzled/charset.h>
00020 #include <cerrno>
00021 #include <cstdio>
00022 #include <cstdlib>
00023
00024 #include <stdarg.h>
00025
00026 #include <algorithm>
00027
00028 using namespace std;
00029
00030 namespace drizzled {
00031
00032
00033
00034
00035
00036 size_t my_strnxfrmlen_simple(const charset_info_st * const cs, size_t len)
00037 {
00038 return len * (cs->strxfrm_multiply ? cs->strxfrm_multiply : 1);
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 size_t my_snprintf_8bit(const charset_info_st * const,
00050 char* to, size_t n,
00051 const char* fmt, ...)
00052 {
00053 va_list args;
00054 int result;
00055 va_start(args,fmt);
00056 result= vsnprintf(to, n, fmt, args);
00057 va_end(args);
00058 return result;
00059 }
00060
00061
00062 long my_strntol_8bit(const charset_info_st * const cs,
00063 const char *nptr, size_t l, int base,
00064 char **endptr, int *err)
00065 {
00066 int negative;
00067 uint32_t cutoff;
00068 uint32_t cutlim;
00069 uint32_t i;
00070 const char *s;
00071 unsigned char c;
00072 const char *save, *e;
00073 int overflow;
00074
00075 *err= 0;
00076 #ifdef NOT_USED
00077 if (base < 0 || base == 1 || base > 36)
00078 base = 10;
00079 #endif
00080
00081 s = nptr;
00082 e = nptr+l;
00083
00084 for ( ; s<e && cs->isspace(*s) ; s++) {}
00085
00086 if (s == e)
00087 {
00088 goto noconv;
00089 }
00090
00091
00092 if (*s == '-')
00093 {
00094 negative = 1;
00095 ++s;
00096 }
00097 else if (*s == '+')
00098 {
00099 negative = 0;
00100 ++s;
00101 }
00102 else
00103 negative = 0;
00104
00105 #ifdef NOT_USED
00106 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
00107 s += 2;
00108 #endif
00109
00110 #ifdef NOT_USED
00111 if (base == 0)
00112 {
00113 if (*s == '0')
00114 {
00115 if (s[1]=='X' || s[1]=='x')
00116 {
00117 s += 2;
00118 base = 16;
00119 }
00120 else
00121 base = 8;
00122 }
00123 else
00124 base = 10;
00125 }
00126 #endif
00127
00128 save = s;
00129 cutoff = (UINT32_MAX) / (uint32_t) base;
00130 cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
00131
00132 overflow = 0;
00133 i = 0;
00134 for (c = *s; s != e; c = *++s)
00135 {
00136 if (c>='0' && c<='9')
00137 c -= '0';
00138 else if (c>='A' && c<='Z')
00139 c = c - 'A' + 10;
00140 else if (c>='a' && c<='z')
00141 c = c - 'a' + 10;
00142 else
00143 break;
00144 if (c >= base)
00145 break;
00146 if (i > cutoff || (i == cutoff && c > cutlim))
00147 overflow = 1;
00148 else
00149 {
00150 i *= (uint32_t) base;
00151 i += c;
00152 }
00153 }
00154
00155 if (s == save)
00156 goto noconv;
00157
00158 if (endptr != NULL)
00159 *endptr = (char *) s;
00160
00161 if (negative)
00162 {
00163 if (i > (uint32_t) INT32_MIN)
00164 overflow = 1;
00165 }
00166 else if (i > INT32_MAX)
00167 overflow = 1;
00168
00169 if (overflow)
00170 {
00171 err[0]= ERANGE;
00172 return negative ? INT32_MIN : INT32_MAX;
00173 }
00174
00175 return (negative ? -((long) i) : (long) i);
00176
00177 noconv:
00178 err[0]= EDOM;
00179 if (endptr != NULL)
00180 *endptr = (char *) nptr;
00181 return 0L;
00182 }
00183
00184
00185 ulong my_strntoul_8bit(const charset_info_st * const cs,
00186 const char *nptr, size_t l, int base,
00187 char **endptr, int *err)
00188 {
00189 int negative;
00190 uint32_t cutoff;
00191 uint32_t cutlim;
00192 uint32_t i;
00193 const char *s;
00194 unsigned char c;
00195 const char *save, *e;
00196 int overflow;
00197
00198 *err= 0;
00199 #ifdef NOT_USED
00200 if (base < 0 || base == 1 || base > 36)
00201 base = 10;
00202 #endif
00203
00204 s = nptr;
00205 e = nptr+l;
00206
00207 for( ; s<e && cs->isspace(*s); s++) {}
00208
00209 if (s==e)
00210 {
00211 goto noconv;
00212 }
00213
00214 if (*s == '-')
00215 {
00216 negative = 1;
00217 ++s;
00218 }
00219 else if (*s == '+')
00220 {
00221 negative = 0;
00222 ++s;
00223 }
00224 else
00225 negative = 0;
00226
00227 #ifdef NOT_USED
00228 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
00229 s += 2;
00230 #endif
00231
00232 #ifdef NOT_USED
00233 if (base == 0)
00234 {
00235 if (*s == '0')
00236 {
00237 if (s[1]=='X' || s[1]=='x')
00238 {
00239 s += 2;
00240 base = 16;
00241 }
00242 else
00243 base = 8;
00244 }
00245 else
00246 base = 10;
00247 }
00248 #endif
00249
00250 save = s;
00251 cutoff = (UINT32_MAX) / (uint32_t) base;
00252 cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
00253 overflow = 0;
00254 i = 0;
00255
00256 for (c = *s; s != e; c = *++s)
00257 {
00258 if (c>='0' && c<='9')
00259 c -= '0';
00260 else if (c>='A' && c<='Z')
00261 c = c - 'A' + 10;
00262 else if (c>='a' && c<='z')
00263 c = c - 'a' + 10;
00264 else
00265 break;
00266 if (c >= base)
00267 break;
00268 if (i > cutoff || (i == cutoff && c > cutlim))
00269 overflow = 1;
00270 else
00271 {
00272 i *= (uint32_t) base;
00273 i += c;
00274 }
00275 }
00276
00277 if (s == save)
00278 goto noconv;
00279
00280 if (endptr != NULL)
00281 *endptr = (char *) s;
00282
00283 if (overflow)
00284 {
00285 err[0]= ERANGE;
00286 return UINT32_MAX;
00287 }
00288
00289 return (negative ? -((long) i) : (long) i);
00290
00291 noconv:
00292 err[0]= EDOM;
00293 if (endptr != NULL)
00294 *endptr = (char *) nptr;
00295 return 0L;
00296 }
00297
00298
00299 int64_t my_strntoll_8bit(const charset_info_st * const cs,
00300 const char *nptr, size_t l, int base,
00301 char **endptr,int *err)
00302 {
00303 int negative;
00304 uint64_t cutoff;
00305 uint32_t cutlim;
00306 uint64_t i;
00307 const char *s, *e;
00308 const char *save;
00309 int overflow;
00310
00311 *err= 0;
00312 #ifdef NOT_USED
00313 if (base < 0 || base == 1 || base > 36)
00314 base = 10;
00315 #endif
00316
00317 s = nptr;
00318 e = nptr+l;
00319
00320 for(; s<e && cs->isspace(*s); s++) {}
00321
00322 if (s == e)
00323 {
00324 goto noconv;
00325 }
00326
00327 if (*s == '-')
00328 {
00329 negative = 1;
00330 ++s;
00331 }
00332 else if (*s == '+')
00333 {
00334 negative = 0;
00335 ++s;
00336 }
00337 else
00338 negative = 0;
00339
00340 #ifdef NOT_USED
00341 if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x'))
00342 s += 2;
00343 #endif
00344
00345 #ifdef NOT_USED
00346 if (base == 0)
00347 {
00348 if (*s == '0')
00349 {
00350 if (s[1]=='X' || s[1]=='x')
00351 {
00352 s += 2;
00353 base = 16;
00354 }
00355 else
00356 base = 8;
00357 }
00358 else
00359 base = 10;
00360 }
00361 #endif
00362
00363 save = s;
00364
00365 cutoff = (~(uint64_t) 0) / (unsigned long int) base;
00366 cutlim = (uint32_t) ((~(uint64_t) 0) % (unsigned long int) base);
00367
00368 overflow = 0;
00369 i = 0;
00370 for ( ; s != e; s++)
00371 {
00372 unsigned char c= *s;
00373 if (c>='0' && c<='9')
00374 c -= '0';
00375 else if (c>='A' && c<='Z')
00376 c = c - 'A' + 10;
00377 else if (c>='a' && c<='z')
00378 c = c - 'a' + 10;
00379 else
00380 break;
00381 if (c >= base)
00382 break;
00383 if (i > cutoff || (i == cutoff && c > cutlim))
00384 overflow = 1;
00385 else
00386 {
00387 i *= (uint64_t) base;
00388 i += c;
00389 }
00390 }
00391
00392 if (s == save)
00393 goto noconv;
00394
00395 if (endptr != NULL)
00396 *endptr = (char *) s;
00397
00398 if (negative)
00399 {
00400 if (i > (uint64_t) INT64_MIN)
00401 overflow = 1;
00402 }
00403 else if (i > (uint64_t) INT64_MAX)
00404 overflow = 1;
00405
00406 if (overflow)
00407 {
00408 err[0]= ERANGE;
00409 return negative ? INT64_MIN : INT64_MAX;
00410 }
00411
00412 return (negative ? -((int64_t) i) : (int64_t) i);
00413
00414 noconv:
00415 err[0]= EDOM;
00416 if (endptr != NULL)
00417 *endptr = (char *) nptr;
00418 return 0L;
00419 }
00420
00421
00422 uint64_t my_strntoull_8bit(const charset_info_st * const cs,
00423 const char *nptr, size_t l, int base,
00424 char **endptr, int *err)
00425 {
00426 int negative;
00427 uint64_t cutoff;
00428 uint32_t cutlim;
00429 uint64_t i;
00430 const char *s, *e;
00431 const char *save;
00432 int overflow;
00433
00434 *err= 0;
00435 #ifdef NOT_USED
00436 if (base < 0 || base == 1 || base > 36)
00437 base = 10;
00438 #endif
00439
00440 s = nptr;
00441 e = nptr+l;
00442
00443 for(; s<e && cs->isspace(*s); s++) {}
00444
00445 if (s == e)
00446 {
00447 goto noconv;
00448 }
00449
00450 if (*s == '-')
00451 {
00452 negative = 1;
00453 ++s;
00454 }
00455 else if (*s == '+')
00456 {
00457 negative = 0;
00458 ++s;
00459 }
00460 else
00461 negative = 0;
00462
00463 #ifdef NOT_USED
00464 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
00465 s += 2;
00466 #endif
00467
00468 #ifdef NOT_USED
00469 if (base == 0)
00470 {
00471 if (*s == '0')
00472 {
00473 if (s[1]=='X' || s[1]=='x')
00474 {
00475 s += 2;
00476 base = 16;
00477 }
00478 else
00479 base = 8;
00480 }
00481 else
00482 base = 10;
00483 }
00484 #endif
00485
00486 save = s;
00487
00488 cutoff = (~(uint64_t) 0) / (unsigned long int) base;
00489 cutlim = (uint32_t) ((~(uint64_t) 0) % (unsigned long int) base);
00490
00491 overflow = 0;
00492 i = 0;
00493 for ( ; s != e; s++)
00494 {
00495 unsigned char c= *s;
00496
00497 if (c>='0' && c<='9')
00498 c -= '0';
00499 else if (c>='A' && c<='Z')
00500 c = c - 'A' + 10;
00501 else if (c>='a' && c<='z')
00502 c = c - 'a' + 10;
00503 else
00504 break;
00505 if (c >= base)
00506 break;
00507 if (i > cutoff || (i == cutoff && c > cutlim))
00508 overflow = 1;
00509 else
00510 {
00511 i *= (uint64_t) base;
00512 i += c;
00513 }
00514 }
00515
00516 if (s == save)
00517 goto noconv;
00518
00519 if (endptr != NULL)
00520 *endptr = (char *) s;
00521
00522 if (overflow)
00523 {
00524 err[0]= ERANGE;
00525 return (~(uint64_t) 0);
00526 }
00527
00528 return (negative ? -((int64_t) i) : (int64_t) i);
00529
00530 noconv:
00531 err[0]= EDOM;
00532 if (endptr != NULL)
00533 *endptr = (char *) nptr;
00534 return 0L;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 double my_strntod_8bit(const charset_info_st * const,
00562 char *str, size_t length,
00563 char **end, int *err)
00564 {
00565 if (length == INT32_MAX)
00566 length= 65535;
00567 *end= str + length;
00568 return internal::my_strtod(str, end, err);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578 size_t my_long10_to_str_8bit(const charset_info_st * const,
00579 char *dst, size_t len, int radix, long int val)
00580 {
00581 char buffer[66];
00582 char *p, *e;
00583 long int new_val;
00584 uint32_t sign=0;
00585 unsigned long int uval = (unsigned long int) val;
00586
00587 e = p = &buffer[sizeof(buffer)-1];
00588 *p= 0;
00589
00590 if (radix < 0)
00591 {
00592 if (val < 0)
00593 {
00594
00595 uval= (unsigned long int)0 - uval;
00596 *dst++= '-';
00597 len--;
00598 sign= 1;
00599 }
00600 }
00601
00602 new_val = (long) (uval / 10);
00603 *--p = '0'+ (char) (uval - (unsigned long) new_val * 10);
00604 val = new_val;
00605
00606 while (val != 0)
00607 {
00608 new_val=val/10;
00609 *--p = '0' + (char) (val-new_val*10);
00610 val= new_val;
00611 }
00612
00613 len= min(len, (size_t) (e-p));
00614 memcpy(dst, p, len);
00615 return len+sign;
00616 }
00617
00618
00619 size_t my_int64_t10_to_str_8bit(const charset_info_st * const,
00620 char *dst, size_t len, int radix,
00621 int64_t val)
00622 {
00623 char buffer[65];
00624 char *p, *e;
00625 long long_val;
00626 uint32_t sign= 0;
00627 uint64_t uval = (uint64_t)val;
00628
00629 if (radix < 0)
00630 {
00631 if (val < 0)
00632 {
00633
00634 uval = (uint64_t)0 - uval;
00635 *dst++= '-';
00636 len--;
00637 sign= 1;
00638 }
00639 }
00640
00641 e = p = &buffer[sizeof(buffer)-1];
00642 *p= 0;
00643
00644 if (uval == 0)
00645 {
00646 *--p= '0';
00647 len= 1;
00648 goto cnv;
00649 }
00650
00651 while (uval > (uint64_t) LONG_MAX)
00652 {
00653 uint64_t quo= uval/(uint32_t) 10;
00654 uint32_t rem= (uint32_t) (uval- quo* (uint32_t) 10);
00655 *--p = '0' + rem;
00656 uval= quo;
00657 }
00658
00659 long_val= (long) uval;
00660 while (long_val != 0)
00661 {
00662 long quo= long_val/10;
00663 *--p = (char) ('0' + (long_val - quo*10));
00664 long_val= quo;
00665 }
00666
00667 len= min(len, (size_t) (e-p));
00668 cnv:
00669 memcpy(dst, p, len);
00670 return len+sign;
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 inline static int likeconv(const charset_info_st *cs, const char c)
00682 {
00683 #ifdef LIKE_CMP_TOUPPER
00684 return (unsigned char) cs->toupper(c);
00685 #else
00686 return cs->sort_order[(unsigned char)c];
00687 #endif
00688 }
00689
00690
00691 inline static const char* inc_ptr(const charset_info_st *cs, const char *str, const char *str_end)
00692 {
00693
00694
00695 (void)cs;
00696 (void)str_end;
00697 return str++;
00698 }
00699
00700 int my_wildcmp_8bit(const charset_info_st * const cs,
00701 const char *str,const char *str_end,
00702 const char *wildstr,const char *wildend,
00703 int escape, int w_one, int w_many)
00704 {
00705 int result= -1;
00706
00707 while (wildstr != wildend)
00708 {
00709 while (*wildstr != w_many && *wildstr != w_one)
00710 {
00711 if (*wildstr == escape && wildstr+1 != wildend)
00712 wildstr++;
00713
00714 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
00715 return 1;
00716 if (wildstr == wildend)
00717 return(str != str_end);
00718 result=1;
00719 }
00720 if (*wildstr == w_one)
00721 {
00722 do
00723 {
00724 if (str == str_end)
00725 return(result);
00726 inc_ptr(cs,str,str_end);
00727 } while (++wildstr < wildend && *wildstr == w_one);
00728 if (wildstr == wildend)
00729 break;
00730 }
00731 if (*wildstr == w_many)
00732 {
00733 unsigned char cmp;
00734
00735 wildstr++;
00736
00737 for (; wildstr != wildend ; wildstr++)
00738 {
00739 if (*wildstr == w_many)
00740 continue;
00741 if (*wildstr == w_one)
00742 {
00743 if (str == str_end)
00744 return(-1);
00745 inc_ptr(cs,str,str_end);
00746 continue;
00747 }
00748 break;
00749 }
00750 if (wildstr == wildend)
00751 return 0;
00752 if (str == str_end)
00753 return(-1);
00754
00755 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
00756 cmp= *++wildstr;
00757
00758 inc_ptr(cs,wildstr,wildend);
00759 cmp=likeconv(cs,cmp);
00760 do
00761 {
00762 while (str != str_end && (unsigned char) likeconv(cs,*str) != cmp)
00763 str++;
00764 if (str++ == str_end) return(-1);
00765 {
00766 int tmp=my_wildcmp_8bit(cs,str,str_end,wildstr,wildend,escape,w_one,
00767 w_many);
00768 if (tmp <= 0)
00769 return(tmp);
00770 }
00771 } while (str != str_end && wildstr[0] != w_many);
00772 return(-1);
00773 }
00774 }
00775 return(str != str_end ? 1 : 0);
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 bool my_like_range_simple(const charset_info_st * const cs,
00798 const char *ptr, size_t ptr_length,
00799 char escape, char w_one, char w_many,
00800 size_t res_length,
00801 char *min_str,char *max_str,
00802 size_t *min_length, size_t *max_length)
00803 {
00804 const char *end= ptr + ptr_length;
00805 char *min_org=min_str;
00806 char *min_end=min_str+res_length;
00807 size_t charlen= res_length / cs->mbmaxlen;
00808
00809 for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++, charlen--)
00810 {
00811 if (*ptr == escape && ptr+1 != end)
00812 {
00813 ptr++;
00814 *min_str++= *max_str++ = *ptr;
00815 continue;
00816 }
00817 if (*ptr == w_one)
00818 {
00819 *min_str++='\0';
00820 *max_str++= (char) cs->max_sort_char;
00821 continue;
00822 }
00823 if (*ptr == w_many)
00824 {
00825
00826 *min_length= ((cs->state & MY_CS_BINSORT) ?
00827 (size_t) (min_str - min_org) :
00828 res_length);
00829 *max_length= res_length;
00830 do
00831 {
00832 *min_str++= 0;
00833 *max_str++= (char) cs->max_sort_char;
00834 } while (min_str != min_end);
00835 return 0;
00836 }
00837 *min_str++= *max_str++ = *ptr;
00838 }
00839
00840 *min_length= *max_length = (size_t) (min_str - min_org);
00841 while (min_str != min_end)
00842 *min_str++= *max_str++ = ' ';
00843 return 0;
00844 }
00845
00846
00847 size_t my_scan_8bit(const charset_info_st * const cs, const char *str, const char *end, int sq)
00848 {
00849 const char *str0= str;
00850 switch (sq)
00851 {
00852 case MY_SEQ_INTTAIL:
00853 if (*str == '.')
00854 {
00855 for(str++ ; str != end && *str == '0' ; str++) {}
00856 return (size_t) (str - str0);
00857 }
00858 return 0;
00859
00860 case MY_SEQ_SPACES:
00861 for ( ; str < end ; str++)
00862 {
00863 if (!cs->isspace(*str))
00864 break;
00865 }
00866 return (size_t) (str - str0);
00867 default:
00868 return 0;
00869 }
00870 }
00871
00872
00873 void my_fill_8bit(const charset_info_st * const, char *s, size_t l, int fill)
00874 {
00875 memset(s, fill, l);
00876 }
00877
00878
00879 size_t my_numchars_8bit(const charset_info_st * const, const char *b, const char *e)
00880 {
00881 return (size_t) (e - b);
00882 }
00883
00884
00885 size_t my_numcells_8bit(const charset_info_st * const, const char *b, const char *e)
00886 {
00887 return (size_t) (e - b);
00888 }
00889
00890
00891 size_t my_charpos_8bit(const charset_info_st * const, const char *, const char *, size_t pos)
00892 {
00893 return pos;
00894 }
00895
00896
00897 size_t my_well_formed_len_8bit(const charset_info_st&, str_ref str, size_t nchars, int *error)
00898 {
00899 *error= 0;
00900 return min(str.size(), nchars);
00901 }
00902
00903
00904 size_t my_lengthsp_8bit(const charset_info_st * const,
00905 const char *ptr, size_t length)
00906 {
00907 const char *end;
00908 end= (const char *) internal::skip_trailing_space((const unsigned char *)ptr, length);
00909 return (size_t) (end-ptr);
00910 }
00911
00912
00913 uint32_t my_instr_simple(const charset_info_st * const cs,
00914 const char *b, size_t b_length,
00915 const char *s, size_t s_length,
00916 my_match_t *match, uint32_t nmatch)
00917 {
00918 const unsigned char *str, *search, *end, *search_end;
00919
00920 if (s_length <= b_length)
00921 {
00922 if (!s_length)
00923 {
00924 if (nmatch)
00925 {
00926 match->beg= 0;
00927 match->end= 0;
00928 match->mb_len= 0;
00929 }
00930 return 1;
00931 }
00932
00933 str= (const unsigned char*) b;
00934 search= (const unsigned char*) s;
00935 end= (const unsigned char*) b+b_length-s_length+1;
00936 search_end= (const unsigned char*) s + s_length;
00937
00938 skip:
00939 while (str != end)
00940 {
00941 if (cs->sort_order[*str++] == cs->sort_order[*search])
00942 {
00943 const unsigned char *i,*j;
00944
00945 i= str;
00946 j= search+1;
00947
00948 while (j != search_end)
00949 if (cs->sort_order[*i++] != cs->sort_order[*j++])
00950 goto skip;
00951
00952 if (nmatch > 0)
00953 {
00954 match[0].beg= 0;
00955 match[0].end= (size_t) (str- (const unsigned char*)b-1);
00956 match[0].mb_len= match[0].end;
00957
00958 if (nmatch > 1)
00959 {
00960 match[1].beg= match[0].end;
00961 match[1].end= match[0].end+s_length;
00962 match[1].mb_len= match[1].end-match[1].beg;
00963 }
00964 }
00965 return 2;
00966 }
00967 }
00968 }
00969 return 0;
00970 }
00971
00972
00973 typedef struct
00974 {
00975 int nchars;
00976 MY_UNI_IDX uidx;
00977 } uni_idx;
00978
00979 #define PLANE_SIZE 0x100
00980 #define PLANE_NUM 0x100
00981 inline static int plane_number(uint16_t x)
00982 {
00983 return ((x >> 8) % PLANE_NUM);
00984 }
00985
00986 static int pcmp(const void * f, const void * s)
00987 {
00988 const uni_idx *F= (const uni_idx*) f;
00989 const uni_idx *S= (const uni_idx*) s;
00990 int res;
00991
00992 if (!(res=((S->nchars)-(F->nchars))))
00993 res=((F->uidx.from)-(S->uidx.to));
00994 return res;
00995 }
00996
00997 static bool create_fromuni(charset_info_st *cs, cs_alloc_func alloc)
00998 {
00999 uni_idx idx[PLANE_NUM];
01000 int i,n;
01001
01002
01003
01004
01005
01006
01007
01008 if (!cs->tab_to_uni)
01009 return true;
01010
01011
01012 memset(idx, 0, sizeof(idx));
01013
01014
01015 for (i=0; i< 0x100; i++)
01016 {
01017 uint16_t wc=cs->tab_to_uni[i];
01018 int pl= plane_number(wc);
01019
01020 if (wc || !i)
01021 {
01022 if (!idx[pl].nchars)
01023 {
01024 idx[pl].uidx.from=wc;
01025 idx[pl].uidx.to=wc;
01026 }else
01027 {
01028 idx[pl].uidx.from=wc<idx[pl].uidx.from?wc:idx[pl].uidx.from;
01029 idx[pl].uidx.to=wc>idx[pl].uidx.to?wc:idx[pl].uidx.to;
01030 }
01031 idx[pl].nchars++;
01032 }
01033 }
01034
01035
01036 qsort(&idx,PLANE_NUM,sizeof(uni_idx),&pcmp);
01037
01038 for (i=0; i < PLANE_NUM; i++)
01039 {
01040 int ch,numchars;
01041
01042
01043 if (!idx[i].nchars)
01044 break;
01045
01046 numchars=idx[i].uidx.to-idx[i].uidx.from+1;
01047 if (!(idx[i].uidx.tab=(unsigned char*) alloc(numchars * sizeof(*idx[i].uidx.tab))))
01048 return true;
01049
01050 memset(idx[i].uidx.tab, 0, numchars*sizeof(*idx[i].uidx.tab));
01051
01052 for (ch=1; ch < PLANE_SIZE; ch++)
01053 {
01054 uint16_t wc=cs->tab_to_uni[ch];
01055 if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc)
01056 {
01057 int ofs= wc - idx[i].uidx.from;
01058 idx[i].uidx.tab[ofs]= ch;
01059 }
01060 }
01061 }
01062
01063
01064 n=i;
01065 if (!(cs->tab_from_uni= (MY_UNI_IDX*) alloc(sizeof(MY_UNI_IDX)*(n+1))))
01066 return true;
01067
01068 for (i=0; i< n; i++)
01069 cs->tab_from_uni[i]= idx[i].uidx;
01070
01071
01072 memset(&cs->tab_from_uni[i], 0, sizeof(MY_UNI_IDX));
01073 return false;
01074 }
01075
01076 bool my_cset_init_8bit(charset_info_st *cs, cs_alloc_func alloc)
01077 {
01078 cs->caseup_multiply= 1;
01079 cs->casedn_multiply= 1;
01080 cs->pad_char= ' ';
01081 return create_fromuni(cs, alloc);
01082 }
01083
01084 static void set_max_sort_char(charset_info_st *cs)
01085 {
01086 unsigned char max_char;
01087 uint32_t i;
01088
01089 if (!cs->sort_order)
01090 return;
01091
01092 max_char=cs->sort_order[(unsigned char) cs->max_sort_char];
01093 for (i= 0; i < 256; i++)
01094 {
01095 if ((unsigned char) cs->sort_order[i] > max_char)
01096 {
01097 max_char=(unsigned char) cs->sort_order[i];
01098 cs->max_sort_char= i;
01099 }
01100 }
01101 }
01102
01103 bool my_coll_init_simple(charset_info_st *cs, cs_alloc_func)
01104 {
01105 set_max_sort_char(cs);
01106 return false;
01107 }
01108
01109
01110 int64_t my_strtoll10_8bit(const charset_info_st * const,
01111 const char *nptr, char **endptr, int *error)
01112 {
01113 return internal::my_strtoll10(nptr, endptr, error);
01114 }
01115
01116
01117 int my_mb_ctype_8bit(const charset_info_st * const cs, int *ctype,
01118 const unsigned char *s, const unsigned char *e)
01119 {
01120 if (s >= e)
01121 {
01122 *ctype= 0;
01123 return MY_CS_TOOSMALL;
01124 }
01125 *ctype= cs->ctype[*s + 1];
01126 return 1;
01127 }
01128
01129
01130 #undef UINT64_MAX
01131 #define UINT64_MAX (~(uint64_t) 0)
01132
01133 #define CUTOFF (UINT64_MAX / 10)
01134 #define CUTLIM (UINT64_MAX % 10)
01135 #define DIGITS_IN_ULONGLONG 20
01136
01137 static uint64_t d10[DIGITS_IN_ULONGLONG]=
01138 {
01139 1,
01140 10,
01141 100,
01142 1000,
01143 10000,
01144 100000,
01145 1000000,
01146 10000000,
01147 100000000,
01148 1000000000,
01149 10000000000ULL,
01150 100000000000ULL,
01151 1000000000000ULL,
01152 10000000000000ULL,
01153 100000000000000ULL,
01154 1000000000000000ULL,
01155 10000000000000000ULL,
01156 100000000000000000ULL,
01157 1000000000000000000ULL,
01158 10000000000000000000ULL
01159 };
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 uint64_t
01219 my_strntoull10rnd_8bit(const charset_info_st * const,
01220 const char *str, size_t length, int unsigned_flag,
01221 char **endptr, int *error)
01222 {
01223 const char *dot, *end9, *beg, *end= str + length;
01224 uint64_t ull;
01225 ulong ul;
01226 unsigned char ch;
01227 int shift= 0, digits= 0, negative, addon;
01228
01229
01230 for ( ; str < end && (*str == ' ' || *str == '\t') ; str++) {}
01231
01232 if (str >= end)
01233 goto ret_edom;
01234
01235 if ((negative= (*str == '-')) || *str=='+')
01236 {
01237 if (++str == end)
01238 goto ret_edom;
01239 }
01240
01241 beg= str;
01242 end9= (str + 9) > end ? end : (str + 9);
01243
01244 for (ul= 0 ; str < end9 && (ch= (unsigned char) (*str - '0')) < 10; str++)
01245 {
01246 ul= ul * 10 + ch;
01247 }
01248
01249 if (str >= end)
01250 {
01251 *endptr= (char*) str;
01252 if (negative)
01253 {
01254 if (unsigned_flag)
01255 {
01256 *error= ul ? ERANGE : 0;
01257 return 0;
01258 }
01259 else
01260 {
01261 *error= 0;
01262 return (uint64_t) (int64_t) -(long) ul;
01263 }
01264 }
01265 else
01266 {
01267 *error=0;
01268 return (uint64_t) ul;
01269 }
01270 }
01271
01272 digits= str - beg;
01273
01274
01275 for (dot= NULL, ull= ul; str < end; str++)
01276 {
01277 if ((ch= (unsigned char) (*str - '0')) < 10)
01278 {
01279 if (ull < CUTOFF || (ull == CUTOFF && ch <= CUTLIM))
01280 {
01281 ull= ull * 10 + ch;
01282 digits++;
01283 continue;
01284 }
01285
01286
01287
01288
01289
01290 if (ull == CUTOFF)
01291 {
01292 ull= UINT64_MAX;
01293 addon= 1;
01294 str++;
01295 }
01296 else
01297 addon= (*str >= '5');
01298 if (!dot)
01299 {
01300 for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; shift++, str++) {}
01301 if (str < end && *str == '.')
01302 {
01303 str++;
01304 for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++) {}
01305 }
01306 }
01307 else
01308 {
01309 shift= dot - str;
01310 for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++) {}
01311 }
01312 goto exp;
01313 }
01314
01315 if (*str == '.')
01316 {
01317 if (dot)
01318 {
01319
01320 addon= 0;
01321 goto exp;
01322 }
01323 else
01324 {
01325 dot= str + 1;
01326 }
01327 continue;
01328 }
01329
01330
01331 break;
01332 }
01333 shift= dot ? dot - str : 0;
01334 addon= 0;
01335
01336 exp:
01337
01338 if (!digits)
01339 {
01340 str= beg;
01341 goto ret_edom;
01342 }
01343
01344 if (str < end && (*str == 'e' || *str == 'E'))
01345 {
01346 str++;
01347 if (str < end)
01348 {
01349 int negative_exp, exponent;
01350 if ((negative_exp= (*str == '-')) || *str=='+')
01351 {
01352 if (++str == end)
01353 goto ret_sign;
01354 }
01355 for (exponent= 0 ;
01356 str < end && (ch= (unsigned char) (*str - '0')) < 10;
01357 str++)
01358 {
01359 exponent= exponent * 10 + ch;
01360 }
01361 shift+= negative_exp ? -exponent : exponent;
01362 }
01363 }
01364
01365 if (shift == 0)
01366 {
01367 if (addon)
01368 {
01369 if (ull == UINT64_MAX)
01370 goto ret_too_big;
01371 ull++;
01372 }
01373 goto ret_sign;
01374 }
01375
01376 if (shift < 0)
01377 {
01378 uint64_t d, r;
01379
01380 if (-shift >= DIGITS_IN_ULONGLONG)
01381 goto ret_zero;
01382
01383 d= d10[-shift];
01384 r= (ull % d) * 2;
01385 ull /= d;
01386 if (r >= d)
01387 ull++;
01388 goto ret_sign;
01389 }
01390
01391 if (shift > DIGITS_IN_ULONGLONG)
01392 {
01393 if (!ull)
01394 goto ret_sign;
01395 goto ret_too_big;
01396 }
01397
01398 for ( ; shift > 0; shift--, ull*= 10)
01399 {
01400 if (ull > CUTOFF)
01401 goto ret_too_big;
01402 }
01403
01404 ret_sign:
01405 *endptr= (char*) str;
01406
01407 if (!unsigned_flag)
01408 {
01409 if (negative)
01410 {
01411 if (ull > (uint64_t) INT64_MIN)
01412 {
01413 *error= ERANGE;
01414 return (uint64_t) INT64_MIN;
01415 }
01416 *error= 0;
01417 return (uint64_t) -(int64_t) ull;
01418 }
01419 else
01420 {
01421 if (ull > (uint64_t) INT64_MAX)
01422 {
01423 *error= ERANGE;
01424 return (uint64_t) INT64_MAX;
01425 }
01426 *error= 0;
01427 return ull;
01428 }
01429 }
01430
01431
01432 if (negative && ull)
01433 {
01434 *error= ERANGE;
01435 return 0;
01436 }
01437 *error= 0;
01438 return ull;
01439
01440 ret_zero:
01441 *endptr= (char*) str;
01442 *error= 0;
01443 return 0;
01444
01445 ret_edom:
01446 *endptr= (char*) str;
01447 *error= EDOM;
01448 return 0;
01449
01450 ret_too_big:
01451 *endptr= (char*) str;
01452 *error= ERANGE;
01453 return unsigned_flag ?
01454 UINT64_MAX :
01455 negative ? (uint64_t) INT64_MIN : (uint64_t) INT64_MAX;
01456 }
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497 bool my_propagate_simple()
01498 {
01499 return 1;
01500 }
01501
01502 bool my_propagate_complex()
01503 {
01504 return 0;
01505 }
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531 void my_strxfrm_desc_and_reverse(unsigned char *str, unsigned char *strend,
01532 uint32_t flags, uint32_t level)
01533 {
01534 if (flags & (MY_STRXFRM_DESC_LEVEL1 << level))
01535 {
01536 if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
01537 {
01538 for (strend--; str <= strend;)
01539 {
01540 unsigned char tmp= *str;
01541 *str++= ~*strend;
01542 *strend--= ~tmp;
01543 }
01544 }
01545 else
01546 {
01547 for (; str < strend; str++)
01548 *str= ~*str;
01549 }
01550 }
01551 else if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
01552 {
01553 for (strend--; str < strend;)
01554 {
01555 unsigned char tmp= *str;
01556 *str++= *strend;
01557 *strend--= tmp;
01558 }
01559 }
01560 }
01561
01562
01563 size_t
01564 my_strxfrm_pad_desc_and_reverse(const charset_info_st * const cs,
01565 unsigned char *str, unsigned char *frmend, unsigned char *strend,
01566 uint32_t nweights, uint32_t flags, uint32_t level)
01567 {
01568 if (nweights && frmend < strend && (flags & MY_STRXFRM_PAD_WITH_SPACE))
01569 {
01570 uint32_t fill_length= min((uint32_t) (strend - frmend), nweights * cs->mbminlen);
01571 cs->cset->fill(cs, (char*) frmend, fill_length, cs->pad_char);
01572 frmend+= fill_length;
01573 }
01574 my_strxfrm_desc_and_reverse(str, frmend, flags, level);
01575 return frmend - str;
01576 }
01577
01578 }