18 #include <my_global.h> 
   22 #include <mysql_com.h> 
   24 #include "sql_string.h" 
   35 bool String::real_alloc(uint32 length)
 
   37   uint32 arg_length= ALIGN_SIZE(length + 1);
 
   38   DBUG_ASSERT(arg_length > length);
 
   39   if (arg_length <= length)
 
   42   if (Alloced_length < arg_length)
 
   45     if (!(
Ptr=(
char*) my_malloc(arg_length,MYF(MY_WME))))
 
   47     Alloced_length=arg_length;
 
   84   uint32 len=ALIGN_SIZE(alloc_length+1);
 
   85   DBUG_ASSERT(len > alloc_length);
 
   86   if (len <= alloc_length)
 
   88   if (Alloced_length < len)
 
   93       if (!(new_ptr= (
char*) my_realloc(
Ptr,len,MYF(MY_WME))))
 
   96     else if ((new_ptr= (
char*) my_malloc(len,MYF(MY_WME))))
 
   98       if (str_length > len - 1)
 
  101         memcpy(new_ptr,
Ptr,str_length);
 
  102       new_ptr[str_length]=0;
 
  114 bool String::set_int(longlong num, 
bool unsigned_flag, 
const CHARSET_INFO *cs)
 
  116   uint l=20*cs->mbmaxlen+1;
 
  117   int base= unsigned_flag ? 10 : -10;
 
  121   str_length=(uint32) (cs->cset->longlong10_to_str)(cs,
Ptr,l,base,num);
 
  126 bool String::set_real(
double num,uint decimals, 
const CHARSET_INFO *cs)
 
  128   char buff[FLOATING_POINT_BUFFER];
 
  133   if (decimals >= NOT_FIXED_DEC)
 
  135     len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, 
sizeof(buff) - 1, buff, NULL);
 
  136     return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
 
  138   len= my_fcvt(num, decimals, buff, NULL);
 
  139   return copy(buff, (uint32) len, &my_charset_latin1, cs,
 
  165 bool String::copy(
const String &str)
 
  167   if (alloc(str.str_length))
 
  169   str_length=str.str_length;
 
  170   bmove(
Ptr,str.Ptr,str_length);                
 
  172   str_charset=str.str_charset;
 
  176 bool String::copy(
const char *str,uint32 arg_length,
 
  179   if (alloc(arg_length))
 
  181   if ((str_length=arg_length))
 
  182     memcpy(
Ptr,str,arg_length);
 
  211 bool String::needs_conversion(uint32 arg_length,
 
  218       (to_cs == &my_charset_bin) || 
 
  219       (to_cs == from_cs) ||
 
  220       my_charset_same(from_cs, to_cs) ||
 
  221       ((from_cs == &my_charset_bin) &&
 
  222        (!(*offset=(arg_length % to_cs->mbminlen)))))
 
  253 bool String::copy_aligned(
const char *str,uint32 arg_length, uint32 offset,
 
  257   offset= cs->mbminlen - 
offset; 
 
  258   DBUG_ASSERT(offset && offset != cs->mbminlen);
 
  260   uint32 aligned_length= arg_length + 
offset;
 
  261   if (alloc(aligned_length))
 
  269   memset(
Ptr, 0, offset);
 
  270   memcpy(
Ptr + offset, str, arg_length);
 
  271   Ptr[aligned_length]=0;
 
  273   str_length= aligned_length;
 
  279 bool String::set_or_copy_aligned(
const char *str,uint32 arg_length,
 
  283   uint32 offset= (arg_length % cs->mbminlen); 
 
  287     set(str, arg_length, cs);
 
  290   return copy_aligned(str, arg_length, offset, cs);
 
  304 bool String::copy(
const char *str, uint32 arg_length,
 
  309   DBUG_ASSERT(!str || str != 
Ptr);
 
  311   if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
 
  314     return copy(str, arg_length, to_cs);
 
  316   if ((from_cs == &my_charset_bin) && offset)
 
  319     return copy_aligned(str, arg_length, offset, to_cs);
 
  321   uint32 new_length= to_cs->mbmaxlen*arg_length;
 
  322   if (alloc(new_length))
 
  324   str_length=copy_and_convert((
char*) 
Ptr, new_length, to_cs,
 
  325                               str, arg_length, from_cs, errors);
 
  350 bool String::set_ascii(
const char *str, uint32 arg_length)
 
  352   if (str_charset->mbminlen == 1)
 
  354     set(str, arg_length, str_charset);
 
  358   return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
 
  364 bool String::fill(uint32 max_length,
char fill_char)
 
  366   if (str_length > max_length)
 
  367     Ptr[str_length=max_length]=0;
 
  372     memset(
Ptr+str_length, fill_char, max_length-str_length);
 
  373     str_length=max_length;
 
  378 void String::strip_sp()
 
  380    while (str_length && my_isspace(str_charset,
Ptr[str_length-1]))
 
  384 bool String::append(
const String &s)
 
  388     if (
realloc(str_length+s.length()))
 
  390     memcpy(
Ptr+str_length,s.ptr(),s.length());
 
  391     str_length+=s.length();
 
  401 bool String::append(
const char *s,uint32 arg_length)
 
  409   if (str_charset->mbminlen > 1)
 
  411     uint32 add_length=arg_length * str_charset->mbmaxlen;
 
  413     if (
realloc(str_length+ add_length))
 
  415     str_length+= copy_and_convert(
Ptr+str_length, add_length, str_charset,
 
  416                                   s, arg_length, &my_charset_latin1,
 
  424   if (
realloc(str_length+arg_length))
 
  426   memcpy(
Ptr+str_length,s,arg_length);
 
  427   str_length+=arg_length;
 
  436 bool String::append(
const char *s)
 
  438   return append(s, (uint) strlen(s));
 
  443 bool String::append_ulonglong(ulonglong val)
 
  445   if (
realloc(str_length+MAX_BIGINT_WIDTH+2))
 
  447   char *end= (
char*) longlong10_to_str(val, (
char*) 
Ptr + str_length, 10);
 
  448   str_length= end - 
Ptr;
 
  457 bool String::append(
const char *s,uint32 arg_length, 
const CHARSET_INFO *cs)
 
  461   if (needs_conversion(arg_length, cs, str_charset, &offset))
 
  464     if ((cs == &my_charset_bin) && offset)
 
  466       DBUG_ASSERT(str_charset->mbminlen > offset);
 
  467       offset= str_charset->mbminlen - 
offset; 
 
  468       add_length= arg_length + 
offset;
 
  469       if (
realloc(str_length + add_length))
 
  471       memset(
Ptr + str_length, 0, offset);
 
  472       memcpy(
Ptr + str_length + offset, s, arg_length);
 
  473       str_length+= add_length;
 
  477     add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
 
  479     if (
realloc(str_length + add_length)) 
 
  481     str_length+= copy_and_convert(
Ptr+str_length, add_length, str_charset,
 
  482                                   s, arg_length, cs, &dummy_errors);
 
  486     if (
realloc(str_length + arg_length)) 
 
  488     memcpy(
Ptr + str_length, s, arg_length);
 
  489     str_length+= arg_length;
 
  496   if (
realloc(str_length+arg_length))
 
  498   if (my_b_read(file, (uchar*) 
Ptr + str_length, arg_length))
 
  503   str_length+=arg_length;
 
  519   end= int10_to_str(nr, buff + 1, radix);
 
  521   return append(buff, (uint) (end - buff));
 
  525 bool String::append_with_prefill(
const char *s,uint32 arg_length,
 
  526                  uint32 full_length, 
char fill_char)
 
  528   int t_length= arg_length > full_length ? arg_length : full_length;
 
  530   if (
realloc(str_length + t_length))
 
  532   t_length= full_length - arg_length;
 
  535     memset(
Ptr+str_length, fill_char, t_length);
 
  536     str_length=str_length + t_length;
 
  538   append(s, arg_length);
 
  542 uint32 String::numchars()
 const 
  544   return str_charset->cset->numchars(str_charset, 
Ptr, 
Ptr+str_length);
 
  547 int String::charpos(
int i,uint32 offset)
 
  551   return str_charset->cset->charpos(str_charset,
Ptr+offset,
Ptr+str_length,i);
 
  554 int String::strstr(
const String &s,uint32 offset)
 
  556   if (s.length()+offset <= str_length)
 
  562     register const char *search=s.ptr();
 
  563     const char *end=
Ptr+str_length-s.length()+1;
 
  564     const char *search_end=s.ptr()+s.length();
 
  568       if (*str++ == *search)
 
  571         i=(
char*) str; j=(
char*) search+1;
 
  572         while (j != search_end)
 
  573           if (*i++ != *j++) 
goto skip;
 
  574         return (
int) (str-
Ptr) -1;
 
  585 int String::strrstr(
const String &s,uint32 offset)
 
  587   if (s.length() <= offset && offset <= str_length)
 
  591     register const char *str = 
Ptr+offset-1;
 
  592     register const char *search=s.ptr()+s.length()-1;
 
  594     const char *end=
Ptr+s.length()-2;
 
  595     const char *search_end=s.ptr()-1;
 
  599       if (*str-- == *search)
 
  602         i=(
char*) str; j=(
char*) search-1;
 
  603         while (j != search_end)
 
  604           if (*i-- != *j--) 
goto skip;
 
  605         return (
int) (i-
Ptr) +1;
 
  617 bool String::replace(uint32 offset,uint32 arg_length,
const String &
to)
 
  619   return replace(offset,arg_length,to.ptr(),to.length());
 
  622 bool String::replace(uint32 offset,uint32 arg_length,
 
  623                      const char *to, uint32 to_length)
 
  625   long diff = (long) to_length-(
long) arg_length;
 
  626   if (offset+arg_length <= str_length)
 
  631         memcpy(
Ptr+offset,to,to_length);
 
  632       bmove(
Ptr+offset+to_length,
Ptr+offset+arg_length,
 
  633             str_length-offset-arg_length);
 
  639         if (
realloc(str_length+(uint32) diff))
 
  641         bmove_upp((uchar*) 
Ptr+str_length+diff, (uchar*) 
Ptr+str_length,
 
  642                   str_length-offset-arg_length);
 
  645         memcpy(
Ptr+offset,to,to_length);
 
  647     str_length+=(uint32) diff;
 
  654 int String::reserve(uint32 space_needed, uint32 grow_by)
 
  656   if (Alloced_length < str_length + space_needed)
 
  658     if (
realloc(Alloced_length + max(space_needed, grow_by) - 1))
 
  664 void String::qs_append(
const char *str, uint32 len)
 
  666   memcpy(
Ptr + str_length, str, len + 1);
 
  670 void String::qs_append(
double d)
 
  672   char *buff = 
Ptr + str_length;
 
  673   str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff,
 
  677 void String::qs_append(
double *d)
 
  680   float8get(ld, (
char*) d);
 
  684 void String::qs_append(
int i)
 
  686   char *buff= 
Ptr + str_length;
 
  687   char *end= int10_to_str(i, buff, -10);
 
  688   str_length+= (int) (end-buff);
 
  691 void String::qs_append(uint i)
 
  693   char *buff= 
Ptr + str_length;
 
  694   char *end= int10_to_str(i, buff, 10);
 
  695   str_length+= (int) (end-buff);
 
  719  return cs->coll->strnncollsp(cs,
 
  720                               (uchar *) s->ptr(),s->length(),
 
  721                               (uchar *) t->ptr(),t->length(), 0);
 
  745   uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
 
  746   int cmp= memcmp(s->ptr(), t->ptr(), len);
 
  747   return (cmp) ? cmp : (int) (s_len - t_len);
 
  753   if (from->Alloced_length >= from_length)
 
  755   if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
 
  757     (void) from->
realloc(from_length);
 
  762   if ((to->str_length=min(from->str_length,from_length)))
 
  763     memcpy(to->Ptr,from->Ptr,to->str_length);
 
  764   to->str_charset=from->str_charset;
 
  795                           char *dst, 
size_t dstlen,
 
  796                           const char *src, 
size_t srclen)
 
  798   const char *srcend= src + srclen;
 
  801   for ( ; src < srcend ; )
 
  804     if ((chlen= my_ismbchar(cs, src, srcend)))
 
  808       memcpy(dst, src, chlen);
 
  813     else if (*src & 0x80)
 
  819       *dst++= _dig_vec_upper[((
unsigned char) *src) >> 4];
 
  820       *dst++= _dig_vec_upper[((
unsigned char) *src) & 15];
 
  864                         char *to, uint to_length,
 
  866                         const char *from, uint from_length,
 
  868                         const char **well_formed_error_pos,
 
  869                         const char **cannot_convert_error_pos,
 
  870                         const char **from_end_pos)
 
  874   if ((to_cs == &my_charset_bin) || 
 
  875       (from_cs == &my_charset_bin) ||
 
  876       (to_cs == from_cs) ||
 
  877       my_charset_same(from_cs, to_cs))
 
  879     if (to_length < to_cs->mbminlen || !nchars)
 
  882       *cannot_convert_error_pos= NULL;
 
  883       *well_formed_error_pos= NULL;
 
  887     if (to_cs == &my_charset_bin)
 
  889       res= min(min(nchars, to_length), from_length);
 
  890       memmove(to, from, res);
 
  891       *from_end_pos= from + res;
 
  892       *well_formed_error_pos= NULL;
 
  893       *cannot_convert_error_pos= NULL;
 
  897       int well_formed_error;
 
  900       if ((from_offset= (from_length % to_cs->mbminlen)) &&
 
  901           (from_cs == &my_charset_bin))
 
  908         uint pad_length= to_cs->mbminlen - from_offset;
 
  909         memset(to, 0, pad_length);
 
  910         memmove(to + pad_length, from, from_offset);
 
  920         if (to_cs->cset->well_formed_len(to_cs,
 
  921                                          to, to + to_cs->mbminlen, 1,
 
  922                                          &well_formed_error) !=
 
  925           *from_end_pos= *well_formed_error_pos= from;
 
  926           *cannot_convert_error_pos= NULL;
 
  931         from_length-= from_offset;
 
  932         to+= to_cs->mbminlen;
 
  933         to_length-= to_cs->mbminlen;
 
  936       set_if_smaller(from_length, to_length);
 
  937       res= to_cs->cset->well_formed_len(to_cs, from, from + from_length,
 
  938                                         nchars, &well_formed_error);
 
  939       memmove(to, from, res);
 
  940       *from_end_pos= from + res;
 
  941       *well_formed_error_pos= well_formed_error ? from + res : NULL;
 
  942       *cannot_convert_error_pos= NULL;
 
  944         res+= to_cs->mbminlen;
 
  951     my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
 
  952     my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
 
  953     const uchar *from_end= (
const uchar*) from + from_length;
 
  954     uchar *to_end= (uchar*) to + to_length;
 
  956     *well_formed_error_pos= NULL;
 
  957     *cannot_convert_error_pos= NULL;
 
  959     for ( ; nchars; nchars--)
 
  961       const char *from_prev= from;
 
  962       if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, from_end)) > 0)
 
  964       else if (cnvres == MY_CS_ILSEQ)
 
  966         if (!*well_formed_error_pos)
 
  967           *well_formed_error_pos= from;
 
  971       else if (cnvres > MY_CS_TOOSMALL)
 
  977         if (!*cannot_convert_error_pos)
 
  978           *cannot_convert_error_pos= from;
 
  986       if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
 
  988       else if (cnvres == MY_CS_ILUNI && wc != 
'?')
 
  990         if (!*cannot_convert_error_pos)
 
  991           *cannot_convert_error_pos= from_prev;
 
 1001     *from_end_pos= from;
 
 1002     res= (uint) (to - to_start);
 
 1004   return (uint32) res;
 
 1010 void String::print(
String *str)
 
 1012   char *st= (
char*)
Ptr, *end= st+str_length;
 
 1013   for (; st < end; st++)
 
 1019       str->append(STRING_WITH_LEN(
"\\\\"));
 
 1022       str->append(STRING_WITH_LEN(
"\\0"));
 
 1025       str->append(STRING_WITH_LEN(
"\\'"));
 
 1028       str->append(STRING_WITH_LEN(
"\\n"));
 
 1031       str->append(STRING_WITH_LEN(
"\\r"));
 
 1034       str->append(STRING_WITH_LEN(
"\\Z"));
 
 1053 void String::swap(
String &s)
 
 1055   swap_variables(
char *, 
Ptr, s.Ptr);
 
 1056   swap_variables(uint32, str_length, s.str_length);
 
 1057   swap_variables(uint32, Alloced_length, s.Alloced_length);
 
 1058   swap_variables(
bool, alloced, s.alloced);
 
 1059   swap_variables(
const CHARSET_INFO *, str_charset, s.str_charset);
 
 1083 uint convert_to_printable(
char *to, 
size_t to_len,
 
 1084                           const char *from, 
size_t from_len,
 
 1088   DBUG_ASSERT(to_len >= 8);
 
 1091   char *t_end= to + to_len - 1; 
 
 1092   const char *f= from;
 
 1093   const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
 
 1096   if (!f || t == t_end)
 
 1099   for (; t < t_end && f < f_end; f++)
 
 1110     if (((
unsigned char) *f) >= 0x20 &&
 
 1111         ((
unsigned char) *f) <= 0x7F &&
 
 1112         from_cs->mbminlen == 1)
 
 1122       *t++= _dig_vec_upper[((
unsigned char) *f) >> 4];
 
 1123       *t++= _dig_vec_upper[((
unsigned char) *f) & 0x0F];
 
 1128   if (f < from + from_len)
 
 1129     memcpy(dots, STRING_WITH_LEN(
"...\0"));