20 #include <my_global.h>
24 #include <mysql_com.h>
26 #include "sql_string.h"
37 bool String::real_alloc(uint32 length)
39 uint32 arg_length= ALIGN_SIZE(length + 1);
40 DBUG_ASSERT(arg_length > length);
41 if (arg_length <= length)
44 if (Alloced_length < arg_length)
47 if (!(
Ptr=(
char*) my_malloc(arg_length,MYF(MY_WME))))
49 Alloced_length=arg_length;
64 uint32 len=ALIGN_SIZE(alloc_length+1);
65 DBUG_ASSERT(len > alloc_length);
66 if (len <= alloc_length)
68 if (Alloced_length < len)
73 if (!(new_ptr= (
char*) my_realloc(
Ptr,len,MYF(MY_WME))))
76 else if ((new_ptr= (
char*) my_malloc(len,MYF(MY_WME))))
78 if (str_length > len - 1)
81 memcpy(new_ptr,
Ptr,str_length);
82 new_ptr[str_length]=0;
96 uint l=20*cs->mbmaxlen+1;
100 str_length=(uint32) (cs->cset->longlong10_to_str)(cs,
Ptr,l,-10,num);
107 uint l=20*cs->mbmaxlen+1;
111 str_length=(uint32) (cs->cset->longlong10_to_str)(cs,
Ptr,l,10,num);
116 bool String::set(
double num,uint decimals,
const CHARSET_INFO *cs)
118 char buff[FLOATING_POINT_BUFFER];
123 if (decimals >= NOT_FIXED_DEC)
125 len= my_gcvt(num, MY_GCVT_ARG_DOUBLE,
sizeof(buff) - 1, buff, NULL);
126 return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
128 len= my_fcvt(num, decimals, buff, NULL);
129 return copy(buff, (uint32) len, &my_charset_latin1, cs,
146 if (alloc(str.str_length))
148 str_length=str.str_length;
149 bmove(
Ptr,str.Ptr,str_length);
151 str_charset=str.str_charset;
155 bool String::copy(
const char *str,uint32 arg_length,
const CHARSET_INFO *cs)
157 if (alloc(arg_length))
159 if ((str_length=arg_length))
160 memcpy(
Ptr,str,arg_length);
189 bool String::needs_conversion(uint32 arg_length,
196 (to_cs == &my_charset_bin) ||
197 (to_cs == from_cs) ||
198 my_charset_same(from_cs, to_cs) ||
199 ((from_cs == &my_charset_bin) &&
200 (!(*offset=(arg_length % to_cs->mbminlen)))))
231 bool String::copy_aligned(
const char *str,uint32 arg_length, uint32 offset,
235 offset= cs->mbmaxlen -
offset;
236 DBUG_ASSERT(offset && offset != cs->mbmaxlen);
238 uint32 aligned_length= arg_length +
offset;
239 if (alloc(aligned_length))
247 memset(
Ptr, 0, offset);
248 memcpy(
Ptr + offset, str, arg_length);
249 Ptr[aligned_length]=0;
251 str_length= aligned_length;
257 bool String::set_or_copy_aligned(
const char *str,uint32 arg_length,
261 uint32 offset= (arg_length % cs->mbminlen);
265 set(str, arg_length, cs);
268 return copy_aligned(str, arg_length, offset, cs);
273 bool String::copy(
const char *str, uint32 arg_length,
277 if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
280 return copy(str, arg_length, to_cs);
282 if ((from_cs == &my_charset_bin) && offset)
285 return copy_aligned(str, arg_length, offset, to_cs);
287 uint32 new_length= to_cs->mbmaxlen*arg_length;
288 if (alloc(new_length))
290 str_length=copy_and_convert((
char*)
Ptr, new_length, to_cs,
291 str, arg_length, from_cs, errors);
316 bool String::set_ascii(
const char *str, uint32 arg_length)
318 if (str_charset->mbminlen == 1)
320 set(str, arg_length, str_charset);
324 return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
330 bool String::fill(uint32 max_length,
char fill_char)
332 if (str_length > max_length)
333 Ptr[str_length=max_length]=0;
338 memset(
Ptr+str_length, fill_char, max_length-str_length);
339 str_length=max_length;
344 void String::strip_sp()
346 while (str_length && my_isspace(str_charset,
Ptr[str_length-1]))
350 bool String::append(
const String &s)
354 if (
realloc(str_length+s.length()))
356 memcpy(
Ptr+str_length,s.ptr(),s.length());
357 str_length+=s.length();
367 bool String::append(
const char *s,uint32 arg_length)
375 if (str_charset->mbminlen > 1)
377 uint32 add_length=arg_length * str_charset->mbmaxlen;
379 if (
realloc(str_length+ add_length))
381 str_length+= copy_and_convert(
Ptr+str_length, add_length, str_charset,
382 s, arg_length, &my_charset_latin1,
390 if (
realloc(str_length+arg_length))
392 memcpy(
Ptr+str_length,s,arg_length);
393 str_length+=arg_length;
402 bool String::append(
const char *s)
404 return append(s, (uint) strlen(s));
413 bool String::append(
const char *s,uint32 arg_length,
const CHARSET_INFO *cs)
417 if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
419 uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
421 if (
realloc(str_length + add_length))
423 str_length+= copy_and_convert(
Ptr+str_length, add_length, str_charset,
424 s, arg_length, cs, &dummy_errors);
428 if (
realloc(str_length + arg_length))
430 memcpy(
Ptr + str_length, s, arg_length);
431 str_length+= arg_length;
438 bool String::append(FILE*
file, uint32 arg_length, myf my_flags)
440 if (
realloc(str_length+arg_length))
442 if (my_fread(file, (uchar*)
Ptr + str_length, arg_length, my_flags))
447 str_length+=arg_length;
452 bool String::append(
IO_CACHE* file, uint32 arg_length)
454 if (
realloc(str_length+arg_length))
456 if (my_b_read(file, (uchar*)
Ptr + str_length, arg_length))
461 str_length+=arg_length;
465 bool String::append_with_prefill(
const char *s,uint32 arg_length,
466 uint32 full_length,
char fill_char)
468 int t_length= arg_length > full_length ? arg_length : full_length;
470 if (
realloc(str_length + t_length))
472 t_length= full_length - arg_length;
475 memset(
Ptr+str_length, fill_char, t_length);
476 str_length=str_length + t_length;
478 append(s, arg_length);
482 uint32 String::numchars()
const
484 return str_charset->cset->numchars(str_charset,
Ptr,
Ptr+str_length);
487 int String::charpos(
int i,uint32 offset)
491 return str_charset->cset->charpos(str_charset,
Ptr+offset,
Ptr+str_length,i);
494 int String::strstr(
const String &s,uint32 offset)
496 if (s.length()+offset <= str_length)
502 register const char *search=s.ptr();
503 const char *end=
Ptr+str_length-s.length()+1;
504 const char *search_end=s.ptr()+s.length();
508 if (*str++ == *search)
511 i=(
char*) str; j=(
char*) search+1;
512 while (j != search_end)
513 if (*i++ != *j++)
goto skip;
514 return (
int) (str-
Ptr) -1;
525 int String::strrstr(
const String &s,uint32 offset)
527 if (s.length() <= offset && offset <= str_length)
531 register const char *str =
Ptr+offset-1;
532 register const char *search=s.ptr()+s.length()-1;
534 const char *end=
Ptr+s.length()-2;
535 const char *search_end=s.ptr()-1;
539 if (*str-- == *search)
542 i=(
char*) str; j=(
char*) search-1;
543 while (j != search_end)
544 if (*i-- != *j--)
goto skip;
545 return (
int) (i-
Ptr) +1;
557 bool String::replace(uint32 offset,uint32 arg_length,
const String &
to)
559 return replace(offset,arg_length,to.ptr(),to.length());
562 bool String::replace(uint32 offset,uint32 arg_length,
563 const char *to, uint32 to_length)
565 long diff = (long) to_length-(
long) arg_length;
566 if (offset+arg_length <= str_length)
571 memcpy(
Ptr+offset,to,to_length);
572 bmove(
Ptr+offset+to_length,
Ptr+offset+arg_length,
573 str_length-offset-arg_length);
579 if (
realloc(str_length+(uint32) diff))
581 bmove_upp((uchar*)
Ptr+str_length+diff, (uchar*)
Ptr+str_length,
582 str_length-offset-arg_length);
585 memcpy(
Ptr+offset,to,to_length);
587 str_length+=(uint32) diff;
594 int String::reserve(uint32 space_needed, uint32 grow_by)
596 if (Alloced_length < str_length + space_needed)
598 if (
realloc(Alloced_length + max(space_needed, grow_by) - 1))
604 void String::qs_append(
const char *str, uint32 len)
606 memcpy(
Ptr + str_length, str, len + 1);
610 void String::qs_append(
double d)
612 char *buff =
Ptr + str_length;
613 str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff,
617 void String::qs_append(
double *d)
620 float8get(ld, (
char*) d);
624 void String::qs_append(
int i)
626 char *buff=
Ptr + str_length;
627 char *end= int10_to_str(i, buff, -10);
628 str_length+= (int) (end-buff);
631 void String::qs_append(uint i)
633 char *buff=
Ptr + str_length;
634 char *end= int10_to_str(i, buff, 10);
635 str_length+= (int) (end-buff);
659 return cs->coll->strnncollsp(cs,
660 (
unsigned char *) s->ptr(),s->length(),
661 (
unsigned char *) t->ptr(),t->length(), 0);
685 uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
686 int cmp= memcmp(s->ptr(), t->ptr(), len);
687 return (cmp) ? cmp : (int) (s_len - t_len);
693 if (from->Alloced_length >= from_length)
695 if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
697 (void) from->
realloc(from_length);
702 if ((to->str_length=min(from->str_length,from_length)))
703 memcpy(to->Ptr,from->Ptr,to->str_length);
704 to->str_charset=from->str_charset;
713 void String::print(
String *str)
715 char *st= (
char*)
Ptr, *end= st+str_length;
716 for (; st < end; st++)
722 str->append(STRING_WITH_LEN(
"\\\\"));
725 str->append(STRING_WITH_LEN(
"\\0"));
728 str->append(STRING_WITH_LEN(
"\\'"));
731 str->append(STRING_WITH_LEN(
"\\n"));
734 str->append(STRING_WITH_LEN(
"\\r"));
737 str->append(STRING_WITH_LEN(
"\\z"));
756 void String::swap(
String &s)
758 swap_variables(
char *,
Ptr, s.Ptr);
759 swap_variables(uint32, str_length, s.str_length);
760 swap_variables(uint32, Alloced_length, s.Alloced_length);
761 swap_variables(
bool, alloced, s.alloced);
762 swap_variables(
const CHARSET_INFO*, str_charset, s.str_charset);