18 #include <drizzled/internal/m_string.h>
19 #include <drizzled/charset.h>
36 size_t my_strnxfrmlen_simple(
const charset_info_st *
const cs,
size_t len)
38 return len * (cs->strxfrm_multiply ? cs->strxfrm_multiply : 1);
49 size_t my_snprintf_8bit(
const charset_info_st *
const,
56 result= vsnprintf(to, n, fmt, args);
62 long my_strntol_8bit(
const charset_info_st *
const cs,
63 const char *nptr,
size_t l,
int base,
64 char **endptr,
int *err)
77 if (base < 0 || base == 1 || base > 36)
84 for ( ; s<e && cs->isspace(*s) ; s++) {}
106 if (base == 16 && s[0] ==
'0' && (s[1]==
'X' || s[1]==
'x'))
115 if (s[1]==
'X' || s[1]==
'x')
129 cutoff = (UINT32_MAX) / (uint32_t) base;
130 cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
134 for (c = *s; s != e; c = *++s)
136 if (c>=
'0' && c<=
'9')
138 else if (c>=
'A' && c<=
'Z')
140 else if (c>=
'a' && c<=
'z')
146 if (i > cutoff || (i == cutoff && c > cutlim))
150 i *= (uint32_t) base;
159 *endptr = (
char *) s;
163 if (i > (uint32_t) INT32_MIN)
166 else if (i > INT32_MAX)
172 return negative ? INT32_MIN : INT32_MAX;
175 return (negative ? -((
long) i) : (
long) i);
180 *endptr = (
char *) nptr;
185 ulong my_strntoul_8bit(
const charset_info_st *
const cs,
186 const char *nptr,
size_t l,
int base,
187 char **endptr,
int *err)
195 const char *save, *e;
200 if (base < 0 || base == 1 || base > 36)
207 for( ; s<e && cs->isspace(*s); s++) {}
228 if (base == 16 && s[0] ==
'0' && (s[1]==
'X' || s[1]==
'x'))
237 if (s[1]==
'X' || s[1]==
'x')
251 cutoff = (UINT32_MAX) / (uint32_t) base;
252 cutlim = (uint32_t) ((UINT32_MAX) % (uint32_t) base);
256 for (c = *s; s != e; c = *++s)
258 if (c>=
'0' && c<=
'9')
260 else if (c>=
'A' && c<=
'Z')
262 else if (c>=
'a' && c<=
'z')
268 if (i > cutoff || (i == cutoff && c > cutlim))
272 i *= (uint32_t) base;
281 *endptr = (
char *) s;
289 return (negative ? -((
long) i) : (
long) i);
294 *endptr = (
char *) nptr;
299 int64_t my_strntoll_8bit(
const charset_info_st *
const cs,
300 const char *nptr,
size_t l,
int base,
301 char **endptr,
int *err)
313 if (base < 0 || base == 1 || base > 36)
320 for(; s<e && cs->isspace(*s); s++) {}
341 if (base == 16 && s[0] ==
'0' && (s[1]==
'X'|| s[1]==
'x'))
350 if (s[1]==
'X' || s[1]==
'x')
365 cutoff = (~(uint64_t) 0) / (
unsigned long int) base;
366 cutlim = (uint32_t) ((~(uint64_t) 0) % (
unsigned long int) base);
373 if (c>=
'0' && c<=
'9')
375 else if (c>=
'A' && c<=
'Z')
377 else if (c>=
'a' && c<=
'z')
383 if (i > cutoff || (i == cutoff && c > cutlim))
387 i *= (uint64_t) base;
396 *endptr = (
char *) s;
400 if (i > (uint64_t) INT64_MIN)
403 else if (i > (uint64_t) INT64_MAX)
409 return negative ? INT64_MIN : INT64_MAX;
412 return (negative ? -((int64_t) i) : (int64_t) i);
417 *endptr = (
char *) nptr;
422 uint64_t my_strntoull_8bit(
const charset_info_st *
const cs,
423 const char *nptr,
size_t l,
int base,
424 char **endptr,
int *err)
436 if (base < 0 || base == 1 || base > 36)
443 for(; s<e && cs->isspace(*s); s++) {}
464 if (base == 16 && s[0] ==
'0' && (s[1]==
'X' || s[1]==
'x'))
473 if (s[1]==
'X' || s[1]==
'x')
488 cutoff = (~(uint64_t) 0) / (
unsigned long int) base;
489 cutlim = (uint32_t) ((~(uint64_t) 0) % (
unsigned long int) base);
497 if (c>=
'0' && c<=
'9')
499 else if (c>=
'A' && c<=
'Z')
501 else if (c>=
'a' && c<=
'z')
507 if (i > cutoff || (i == cutoff && c > cutlim))
511 i *= (uint64_t) base;
520 *endptr = (
char *) s;
525 return (~(uint64_t) 0);
528 return (negative ? -((int64_t) i) : (int64_t) i);
533 *endptr = (
char *) nptr;
561 double my_strntod_8bit(
const charset_info_st *
const,
562 char *str,
size_t length,
563 char **end,
int *err)
565 if (length == INT32_MAX)
568 return internal::my_strtod(str, end, err);
578 size_t my_long10_to_str_8bit(
const charset_info_st *
const,
579 char *dst,
size_t len,
int radix,
long int val)
585 unsigned long int uval = (
unsigned long int) val;
587 e = p = &buffer[
sizeof(buffer)-1];
595 uval= (
unsigned long int)0 - uval;
602 new_val = (long) (uval / 10);
603 *--p =
'0'+ (char) (uval - (
unsigned long) new_val * 10);
609 *--p =
'0' + (char) (val-new_val*10);
613 len= min(len, (
size_t) (e-p));
619 size_t my_int64_t10_to_str_8bit(
const charset_info_st *
const,
620 char *dst,
size_t len,
int radix,
627 uint64_t uval = (uint64_t)val;
634 uval = (uint64_t)0 - uval;
641 e = p = &buffer[
sizeof(buffer)-1];
651 while (uval > (uint64_t) LONG_MAX)
653 uint64_t quo= uval/(uint32_t) 10;
654 uint32_t rem= (uint32_t) (uval- quo* (uint32_t) 10);
659 long_val= (long) uval;
660 while (long_val != 0)
662 long quo= long_val/10;
663 *--p = (char) (
'0' + (long_val - quo*10));
667 len= min(len, (
size_t) (e-p));
681 inline static int likeconv(
const charset_info_st *cs,
const char c)
683 #ifdef LIKE_CMP_TOUPPER
684 return (
unsigned char) cs->toupper(c);
686 return cs->sort_order[(
unsigned char)c];
691 inline static const char* inc_ptr(
const charset_info_st *cs,
const char *str,
const char *str_end)
700 int my_wildcmp_8bit(
const charset_info_st *
const cs,
701 const char *str,
const char *str_end,
702 const char *wildstr,
const char *wildend,
703 int escape,
int w_one,
int w_many)
707 while (wildstr != wildend)
709 while (*wildstr != w_many && *wildstr != w_one)
711 if (*wildstr == escape && wildstr+1 != wildend)
714 if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
716 if (wildstr == wildend)
717 return(str != str_end);
720 if (*wildstr == w_one)
726 inc_ptr(cs,str,str_end);
727 }
while (++wildstr < wildend && *wildstr == w_one);
728 if (wildstr == wildend)
731 if (*wildstr == w_many)
737 for (; wildstr != wildend ; wildstr++)
739 if (*wildstr == w_many)
741 if (*wildstr == w_one)
745 inc_ptr(cs,str,str_end);
750 if (wildstr == wildend)
755 if ((cmp= *wildstr) == escape && wildstr+1 != wildend)
758 inc_ptr(cs,wildstr,wildend);
759 cmp=likeconv(cs,cmp);
762 while (str != str_end && (
unsigned char) likeconv(cs,*str) != cmp)
764 if (str++ == str_end)
return(-1);
766 int tmp=my_wildcmp_8bit(cs,str,str_end,wildstr,wildend,escape,w_one,
771 }
while (str != str_end && wildstr[0] != w_many);
775 return(str != str_end ? 1 : 0);
797 bool my_like_range_simple(
const charset_info_st *
const cs,
798 const char *ptr,
size_t ptr_length,
799 char escape,
char w_one,
char w_many,
801 char *min_str,
char *max_str,
802 size_t *min_length,
size_t *max_length)
804 const char *end= ptr + ptr_length;
805 char *min_org=min_str;
806 char *min_end=min_str+res_length;
807 size_t charlen= res_length / cs->mbmaxlen;
809 for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++, charlen--)
811 if (*ptr == escape && ptr+1 != end)
814 *min_str++= *max_str++ = *ptr;
820 *max_str++= (char) cs->max_sort_char;
826 *min_length= ((cs->state & MY_CS_BINSORT) ?
827 (
size_t) (min_str - min_org) :
829 *max_length= res_length;
833 *max_str++= (char) cs->max_sort_char;
834 }
while (min_str != min_end);
837 *min_str++= *max_str++ = *ptr;
840 *min_length= *max_length = (size_t) (min_str - min_org);
841 while (min_str != min_end)
842 *min_str++= *max_str++ =
' ';
847 size_t my_scan_8bit(
const charset_info_st *
const cs,
const char *str,
const char *end,
int sq)
849 const char *str0= str;
855 for(str++ ; str != end && *str ==
'0' ; str++) {}
856 return (
size_t) (str - str0);
861 for ( ; str < end ; str++)
863 if (!cs->isspace(*str))
866 return (
size_t) (str - str0);
873 void my_fill_8bit(
const charset_info_st *
const,
char *s,
size_t l,
int fill)
879 size_t my_numchars_8bit(
const charset_info_st *
const,
const char *b,
const char *e)
881 return (
size_t) (e - b);
885 size_t my_numcells_8bit(
const charset_info_st *
const,
const char *b,
const char *e)
887 return (
size_t) (e - b);
891 size_t my_charpos_8bit(
const charset_info_st *
const,
const char *,
const char *,
size_t pos)
897 size_t my_well_formed_len_8bit(
const charset_info_st&,
str_ref str,
size_t nchars,
int *error)
900 return min(str.size(), nchars);
904 size_t my_lengthsp_8bit(
const charset_info_st *
const,
905 const char *ptr,
size_t length)
908 end= (
const char *) internal::skip_trailing_space((
const unsigned char *)ptr, length);
909 return (
size_t) (end-ptr);
913 uint32_t my_instr_simple(
const charset_info_st *
const cs,
914 const char *b,
size_t b_length,
915 const char *s,
size_t s_length,
916 my_match_t *match, uint32_t nmatch)
918 const unsigned char *str, *search, *end, *search_end;
920 if (s_length <= b_length)
933 str= (
const unsigned char*) b;
934 search= (
const unsigned char*) s;
935 end= (
const unsigned char*) b+b_length-s_length+1;
936 search_end= (
const unsigned char*) s + s_length;
941 if (cs->sort_order[*str++] == cs->sort_order[*search])
943 const unsigned char *i,*j;
948 while (j != search_end)
949 if (cs->sort_order[*i++] != cs->sort_order[*j++])
955 match[0].end= (size_t) (str- (
const unsigned char*)b-1);
956 match[0].mb_len= match[0].end;
960 match[1].beg= match[0].end;
961 match[1].end= match[0].end+s_length;
962 match[1].mb_len= match[1].end-match[1].beg;
979 #define PLANE_SIZE 0x100
980 #define PLANE_NUM 0x100
981 inline static int plane_number(uint16_t x)
983 return ((x >> 8) % PLANE_NUM);
986 static int pcmp(
const void * f,
const void * s)
988 const uni_idx *F= (
const uni_idx*) f;
989 const uni_idx *S= (
const uni_idx*) s;
992 if (!(res=((S->nchars)-(F->nchars))))
993 res=((F->uidx.from)-(S->uidx.to));
997 static bool create_fromuni(charset_info_st *cs, cs_alloc_func alloc)
999 uni_idx idx[PLANE_NUM];
1008 if (!cs->tab_to_uni)
1012 memset(idx, 0,
sizeof(idx));
1015 for (i=0; i< 0x100; i++)
1017 uint16_t wc=cs->tab_to_uni[i];
1018 int pl= plane_number(wc);
1022 if (!idx[pl].nchars)
1024 idx[pl].uidx.from=wc;
1028 idx[pl].uidx.from=wc<idx[pl].uidx.from?wc:idx[pl].uidx.from;
1029 idx[pl].uidx.to=wc>idx[pl].uidx.to?wc:idx[pl].uidx.to;
1036 qsort(&idx,PLANE_NUM,
sizeof(uni_idx),&pcmp);
1038 for (i=0; i < PLANE_NUM; i++)
1046 numchars=idx[i].uidx.to-idx[i].uidx.from+1;
1047 if (!(idx[i].uidx.tab=(
unsigned char*) alloc(numchars *
sizeof(*idx[i].uidx.tab))))
1050 memset(idx[i].uidx.tab, 0, numchars*
sizeof(*idx[i].uidx.tab));
1052 for (ch=1; ch < PLANE_SIZE; ch++)
1054 uint16_t wc=cs->tab_to_uni[ch];
1055 if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc)
1057 int ofs= wc - idx[i].uidx.from;
1058 idx[i].uidx.tab[ofs]= ch;
1065 if (!(cs->tab_from_uni= (MY_UNI_IDX*) alloc(
sizeof(MY_UNI_IDX)*(n+1))))
1068 for (i=0; i< n; i++)
1069 cs->tab_from_uni[i]= idx[i].uidx;
1072 memset(&cs->tab_from_uni[i], 0,
sizeof(MY_UNI_IDX));
1076 bool my_cset_init_8bit(charset_info_st *cs, cs_alloc_func alloc)
1078 cs->caseup_multiply= 1;
1079 cs->casedn_multiply= 1;
1081 return create_fromuni(cs, alloc);
1084 static void set_max_sort_char(charset_info_st *cs)
1086 unsigned char max_char;
1089 if (!cs->sort_order)
1092 max_char=cs->sort_order[(
unsigned char) cs->max_sort_char];
1093 for (i= 0; i < 256; i++)
1095 if ((
unsigned char) cs->sort_order[i] > max_char)
1097 max_char=(
unsigned char) cs->sort_order[i];
1098 cs->max_sort_char= i;
1103 bool my_coll_init_simple(charset_info_st *cs, cs_alloc_func)
1105 set_max_sort_char(cs);
1110 int64_t my_strtoll10_8bit(
const charset_info_st *
const,
1111 const char *nptr,
char **endptr,
int *error)
1113 return internal::my_strtoll10(nptr, endptr, error);
1117 int my_mb_ctype_8bit(
const charset_info_st *
const cs,
int *ctype,
1118 const unsigned char *s,
const unsigned char *e)
1123 return MY_CS_TOOSMALL;
1125 *ctype= cs->ctype[*s + 1];
1131 #define UINT64_MAX (~(uint64_t) 0)
1133 #define CUTOFF (UINT64_MAX / 10)
1134 #define CUTLIM (UINT64_MAX % 10)
1135 #define DIGITS_IN_ULONGLONG 20
1137 static uint64_t d10[DIGITS_IN_ULONGLONG]=
1154 1000000000000000ULL,
1155 10000000000000000ULL,
1156 100000000000000000ULL,
1157 1000000000000000000ULL,
1158 10000000000000000000ULL
1219 my_strntoull10rnd_8bit(
const charset_info_st *
const,
1220 const char *str,
size_t length,
int unsigned_flag,
1221 char **endptr,
int *error)
1223 const char *dot, *end9, *beg, *end= str + length;
1227 int shift= 0, digits= 0, negative, addon;
1230 for ( ; str < end && (*str ==
' ' || *str ==
'\t') ; str++) {}
1235 if ((negative= (*str ==
'-')) || *str==
'+')
1242 end9= (str + 9) > end ? end : (str + 9);
1244 for (ul= 0 ; str < end9 && (ch= (
unsigned char) (*str -
'0')) < 10; str++)
1251 *endptr= (
char*) str;
1256 *error= ul ? ERANGE : 0;
1262 return (uint64_t) (int64_t) -(
long) ul;
1268 return (uint64_t) ul;
1275 for (dot= NULL, ull= ul; str < end; str++)
1277 if ((ch= (
unsigned char) (*str -
'0')) < 10)
1279 if (ull < CUTOFF || (ull == CUTOFF && ch <= CUTLIM))
1297 addon= (*str >=
'5');
1300 for ( ; str < end && (ch= (
unsigned char) (*str -
'0')) < 10; shift++, str++) {}
1301 if (str < end && *str ==
'.')
1304 for ( ; str < end && (ch= (
unsigned char) (*str -
'0')) < 10; str++) {}
1310 for ( ; str < end && (ch= (
unsigned char) (*str -
'0')) < 10; str++) {}
1333 shift= dot ? dot - str : 0;
1344 if (str < end && (*str ==
'e' || *str ==
'E'))
1349 int negative_exp, exponent;
1350 if ((negative_exp= (*str ==
'-')) || *str==
'+')
1356 str < end && (ch= (
unsigned char) (*str -
'0')) < 10;
1359 exponent= exponent * 10 + ch;
1361 shift+= negative_exp ? -exponent : exponent;
1369 if (ull == UINT64_MAX)
1380 if (-shift >= DIGITS_IN_ULONGLONG)
1391 if (shift > DIGITS_IN_ULONGLONG)
1398 for ( ; shift > 0; shift--, ull*= 10)
1405 *endptr= (
char*) str;
1411 if (ull > (uint64_t) INT64_MIN)
1414 return (uint64_t) INT64_MIN;
1417 return (uint64_t) -(int64_t) ull;
1421 if (ull > (uint64_t) INT64_MAX)
1424 return (uint64_t) INT64_MAX;
1432 if (negative && ull)
1441 *endptr= (
char*) str;
1446 *endptr= (
char*) str;
1451 *endptr= (
char*) str;
1453 return unsigned_flag ?
1455 negative ? (uint64_t) INT64_MIN : (uint64_t) INT64_MAX;
1497 bool my_propagate_simple()
1502 bool my_propagate_complex()
1531 void my_strxfrm_desc_and_reverse(
unsigned char *str,
unsigned char *strend,
1532 uint32_t flags, uint32_t level)
1534 if (flags & (MY_STRXFRM_DESC_LEVEL1 << level))
1536 if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
1538 for (strend--; str <= strend;)
1540 unsigned char tmp= *str;
1547 for (; str < strend; str++)
1551 else if (flags & (MY_STRXFRM_REVERSE_LEVEL1 << level))
1553 for (strend--; str < strend;)
1555 unsigned char tmp= *str;
1564 my_strxfrm_pad_desc_and_reverse(
const charset_info_st *
const cs,
1565 unsigned char *str,
unsigned char *frmend,
unsigned char *strend,
1566 uint32_t nweights, uint32_t flags, uint32_t level)
1568 if (nweights && frmend < strend && (flags & MY_STRXFRM_PAD_WITH_SPACE))
1570 uint32_t fill_length= min((uint32_t) (strend - frmend), nweights * cs->mbminlen);
1571 cs->cset->fill(cs, (
char*) frmend, fill_length, cs->pad_char);
1572 frmend+= fill_length;
1574 my_strxfrm_desc_and_reverse(str, frmend, flags, level);
1575 return frmend - str;
TODO: Rename this file - func.h is stupid.