21 #include <drizzled/internal/my_sys.h>
22 #include <drizzled/internal/m_string.h>
24 #include <drizzled/charset.h>
28 #include <drizzled/sql_string.h>
43 str_charset(&my_charset_bin)
47 String::String(
size_t length_arg)
52 str_charset(&my_charset_bin)
54 (void) real_alloc(length_arg);
57 String::String(
const char *str,
const charset_info_st *
const cs)
58 : Ptr(const_cast<char *>(str)),
59 str_length(static_cast<size_t>(strlen(str))),
66 String::String(
const char *str,
size_t len,
const charset_info_st *
const cs)
67 : Ptr(const_cast<char *>(str)),
75 String::String(
char *str,
size_t len,
const charset_info_st *
const cs)
84 String::String(
const String &str)
86 str_length(str.str_length),
87 Alloced_length(str.Alloced_length),
89 str_charset(str.str_charset)
93 void *String::operator
new(
size_t size, memory::Root *mem_root)
95 return mem_root->alloc(size);
98 String::~String() { free(); }
100 void String::real_alloc(
size_t arg_length)
102 arg_length=ALIGN_SIZE(arg_length+1);
104 if (Alloced_length < arg_length)
106 if (Alloced_length > 0)
108 Ptr=(
char*) malloc(arg_length);
109 Alloced_length=arg_length;
121 void String::realloc(
size_t alloc_length)
123 size_t len=ALIGN_SIZE(alloc_length+1);
124 if (Alloced_length < len)
129 new_ptr= (
char*) ::realloc(Ptr,len);
135 new_ptr= (
char*) malloc(len);
137 memcpy(new_ptr,Ptr,str_length);
138 new_ptr[str_length]=0;
147 void String::set_int(int64_t num,
bool unsigned_flag,
const charset_info_st *
const cs)
149 size_t l= 20 * cs->mbmaxlen + 1;
151 str_length=(size_t) (cs->cset->int64_t10_to_str)(cs, Ptr, l, unsigned_flag ? 10 : -10,num);
155 void String::set_real(
double num,
size_t decimals,
const charset_info_st *
const cs)
157 char buff[FLOATING_POINT_BUFFER];
161 if (decimals >= NOT_FIXED_DEC)
163 len= internal::my_gcvt(num, internal::MY_GCVT_ARG_DOUBLE,
sizeof(buff) - 1, buff, NULL);
167 len= internal::my_fcvt(num, decimals, buff, NULL);
181 void String::copy(
const String &str)
183 alloc(str.str_length);
184 str_length=str.str_length;
185 memmove(Ptr, str.Ptr, str_length);
187 str_charset= str.str_charset;
190 void String::copy(
const std::string& arg,
const charset_info_st* cs)
193 str_length= arg.size();
194 memcpy(Ptr, arg.c_str(), arg.size());
199 void String::copy(
const char *str,
size_t arg_length,
const charset_info_st* cs)
202 if ((str_length=arg_length))
203 memcpy(Ptr,str,arg_length);
230 bool String::needs_conversion(
size_t arg_length,
const charset_info_st* from_cs,
const charset_info_st* to_cs)
233 to_cs == &my_charset_bin ||
235 my_charset_same(from_cs, to_cs) ||
236 (from_cs == &my_charset_bin && not (arg_length % to_cs->mbminlen)))
260 void String::set_ascii(
const char *str,
size_t arg_length)
262 if (str_charset->mbminlen == 1)
264 set(str, arg_length, str_charset);
267 copy(str, arg_length, str_charset);
275 void String::append(
const char *s,
size_t arg_length)
285 realloc(str_length + arg_length);
286 memcpy(Ptr + str_length, s, arg_length);
287 str_length+= arg_length;
292 append(s.data(), s.size());
295 void String::append_with_prefill(
const char *s,
size_t arg_length,
size_t full_length,
char fill_char)
297 int t_length= arg_length > full_length ? arg_length : full_length;
299 realloc(str_length + t_length);
300 t_length= full_length - arg_length;
303 memset(Ptr+str_length, fill_char, t_length);
304 str_length=str_length + t_length;
306 append(s, arg_length);
309 size_t String::numchars()
const
311 return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
314 int String::charpos(
int i,
size_t offset)
const
316 return i <= 0 ? i : str_charset->cset->charpos(str_charset, Ptr + offset, Ptr + str_length, i);
319 int String::strstr(
const String &s,
size_t offset)
321 if (s.length() + offset <= str_length)
324 return ((
int) offset);
326 const char *str = Ptr+offset;
327 const char *search=s.ptr();
328 const char *last=Ptr+str_length-s.length()+1;
329 const char *search_end=s.ptr()+s.length();
333 if (*str++ == *search)
336 const char* j= search + 1;
337 while (j != search_end)
338 if (*i++ != *j++)
goto skip;
339 return (
int) (str - Ptr) - 1;
350 int String::strrstr(
const String &s,
size_t offset)
352 if (s.length() <= offset && offset <= str_length)
356 const char *str = Ptr+offset-1;
357 const char *search=s.ptr()+s.length()-1;
359 const char *last=Ptr+s.length()-2;
360 const char *search_end=s.ptr()-1;
364 if (*str-- == *search)
367 const char* j= search-1;
368 while (j != search_end)
369 if (*i-- != *j--)
goto skip;
370 return (
int) (i-Ptr) + 1;
382 void String::replace(
size_t offset,
size_t arg_length,
const String &to)
384 replace(offset,arg_length,to.ptr(),to.length());
387 void String::replace(
size_t offset,
size_t arg_length,
388 const char *to,
size_t to_length)
390 long diff = (long) to_length-(
long) arg_length;
391 if (offset+arg_length <= str_length)
396 memcpy(Ptr+offset,to,to_length);
397 memmove(Ptr+offset+to_length, Ptr+offset+arg_length,
398 str_length-offset-arg_length);
404 realloc(str_length+(
size_t) diff);
405 internal::bmove_upp((
unsigned char*) Ptr+str_length+diff,
406 (
unsigned char*) Ptr+str_length,
407 str_length-offset-arg_length);
410 memcpy(Ptr+offset,to,to_length);
412 str_length+=(size_t) diff;
437 int sortcmp(
const String *s,
const String *t,
const charset_info_st *
const cs)
439 return cs->coll->strnncollsp(cs,
440 (
unsigned char *) s->ptr(),s->length(),
441 (
unsigned char *) t->ptr(),t->length(), 0);
463 int stringcmp(
const String *s,
const String *t)
465 size_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
466 int cmp= memcmp(s->ptr(), t->ptr(), len);
467 return (cmp) ? cmp : (int) (s_len - t_len);
471 String *copy_if_not_alloced(String *to,String *from,
size_t from_length)
473 if (from->Alloced_length >= from_length)
475 if (from->alloced || !to || from == to)
477 (void) from->realloc(from_length);
480 to->realloc(from_length);
481 if ((to->str_length= min(from->str_length,from_length)))
482 memcpy(to->Ptr,from->Ptr,to->str_length);
483 to->str_charset=from->str_charset;
520 well_formed_copy_nchars(
const charset_info_st *
const to_cs,
521 char *to,
size_t to_length,
522 const charset_info_st *
const from_cs,
523 const char *from,
size_t from_length,
525 const char **well_formed_error_pos,
526 const char **cannot_convert_error_pos,
527 const char **from_end_pos)
531 assert((to_cs == &my_charset_bin) ||
532 (from_cs == &my_charset_bin) ||
533 (to_cs == from_cs) ||
534 my_charset_same(from_cs, to_cs));
536 if (to_length < to_cs->mbminlen || !nchars)
539 *cannot_convert_error_pos= NULL;
540 *well_formed_error_pos= NULL;
544 if (to_cs == &my_charset_bin)
546 res= min(min(nchars, to_length), from_length);
547 memmove(to, from, res);
548 *from_end_pos= from + res;
549 *well_formed_error_pos= NULL;
550 *cannot_convert_error_pos= NULL;
554 int well_formed_error;
557 if ((from_offset= (from_length % to_cs->mbminlen)) &&
558 (from_cs == &my_charset_bin))
565 size_t pad_length= to_cs->mbminlen - from_offset;
566 memset(to, 0, pad_length);
567 memmove(to + pad_length, from, from_offset);
570 from_length-= from_offset;
571 to+= to_cs->mbminlen;
572 to_length-= to_cs->mbminlen;
575 set_if_smaller(from_length, to_length);
576 res= to_cs->cset->well_formed_len(*to_cs,
str_ref(from, from_length), nchars, &well_formed_error);
577 memmove(to, from, res);
578 *from_end_pos= from + res;
579 *well_formed_error_pos= well_formed_error ? from + res : NULL;
580 *cannot_convert_error_pos= NULL;
582 res+= to_cs->mbminlen;
588 void String::print(String& str)
const
590 const char* last= Ptr + str_length;
591 for (
const char* st= Ptr; st < last; st++)
593 unsigned char c= *st;
597 str.append(
"\\\\",
sizeof(
"\\\\")-1);
600 str.append(
"\\0",
sizeof(
"\\0")-1);
603 str.append(
"\\'",
sizeof(
"\\'")-1);
606 str.append(
"\\n",
sizeof(
"\\n")-1);
609 str.append(
"\\r",
sizeof(
"\\r")-1);
612 str.append(
"\\Z",
sizeof(
"\\Z")-1);
631 extern const charset_info_st *system_charset_info;
633 void String::append_identifier(
const char *name,
size_t in_length)
637 reserve(in_length * 2 + 2);
638 const char quote_char=
'`';
639 append("e_char, 1);
641 for (
const char* name_end= name+in_length ; name < name_end ; name+= in_length)
643 unsigned char chr= (
unsigned char) *name;
644 in_length= my_mbcharlen(system_charset_info, chr);
654 if (in_length == 1 && chr == (
unsigned char) quote_char)
655 append("e_char, 1);
656 append(name, in_length);
658 append("e_char, 1);
661 void String::append_identifier(
str_ref v)
663 append_identifier(v.data(), v.size());
666 bool check_if_only_end_space(
const charset_info_st *
const cs,
char *str,
char *end)
668 return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
671 std::ostream& operator<<(std::ostream& output,
const String &str)
673 output <<
"String:(";
674 output << const_cast<String&>(str).c_str();
676 output << str.length();
686 return stringcmp(&s1,&s2) == 0;
Memory root declarations.