MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_string.cc
1 /*
2  Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 /* This file is originally from the mysql distribution. Coded by monty */
19 
20 #include <my_global.h>
21 #include <my_sys.h>
22 #include <m_string.h>
23 #include <m_ctype.h>
24 #include <mysql_com.h>
25 
26 #include "sql_string.h"
27 
28 #include <algorithm>
29 
30 using std::min;
31 using std::max;
32 
33 /*****************************************************************************
34 ** String functions
35 *****************************************************************************/
36 
37 bool String::real_alloc(uint32 length)
38 {
39  uint32 arg_length= ALIGN_SIZE(length + 1);
40  DBUG_ASSERT(arg_length > length);
41  if (arg_length <= length)
42  return TRUE; /* Overflow */
43  str_length=0;
44  if (Alloced_length < arg_length)
45  {
46  free();
47  if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))
48  return TRUE;
49  Alloced_length=arg_length;
50  alloced=1;
51  }
52  Ptr[0]=0;
53  return FALSE;
54 }
55 
56 
57 /*
58 ** Check that string is big enough. Set string[alloc_length] to 0
59 ** (for C functions)
60 */
61 
62 bool String::realloc(uint32 alloc_length)
63 {
64  uint32 len=ALIGN_SIZE(alloc_length+1);
65  DBUG_ASSERT(len > alloc_length);
66  if (len <= alloc_length)
67  return TRUE; /* Overflow */
68  if (Alloced_length < len)
69  {
70  char *new_ptr;
71  if (alloced)
72  {
73  if (!(new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME))))
74  return TRUE; // Signal error
75  }
76  else if ((new_ptr= (char*) my_malloc(len,MYF(MY_WME))))
77  {
78  if (str_length > len - 1)
79  str_length= 0;
80  if (str_length) // Avoid bugs in memcpy on AIX
81  memcpy(new_ptr,Ptr,str_length);
82  new_ptr[str_length]=0;
83  alloced=1;
84  }
85  else
86  return TRUE; // Signal error
87  Ptr= new_ptr;
88  Alloced_length= len;
89  }
90  Ptr[alloc_length]=0; // This make other funcs shorter
91  return FALSE;
92 }
93 
94 bool String::set(longlong num, const CHARSET_INFO *cs)
95 {
96  uint l=20*cs->mbmaxlen+1;
97 
98  if (alloc(l))
99  return TRUE;
100  str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,-10,num);
101  str_charset=cs;
102  return FALSE;
103 }
104 
105 bool String::set(ulonglong num, const CHARSET_INFO *cs)
106 {
107  uint l=20*cs->mbmaxlen+1;
108 
109  if (alloc(l))
110  return TRUE;
111  str_length=(uint32) (cs->cset->longlong10_to_str)(cs,Ptr,l,10,num);
112  str_charset=cs;
113  return FALSE;
114 }
115 
116 bool String::set(double num,uint decimals, const CHARSET_INFO *cs)
117 {
118  char buff[FLOATING_POINT_BUFFER];
119  uint dummy_errors;
120  size_t len;
121 
122  str_charset=cs;
123  if (decimals >= NOT_FIXED_DEC)
124  {
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);
127  }
128  len= my_fcvt(num, decimals, buff, NULL);
129  return copy(buff, (uint32) len, &my_charset_latin1, cs,
130  &dummy_errors);
131 }
132 
133 
134 bool String::copy()
135 {
136  if (!alloced)
137  {
138  Alloced_length=0; // Force realloc
139  return realloc(str_length);
140  }
141  return FALSE;
142 }
143 
144 bool String::copy(const String &str)
145 {
146  if (alloc(str.str_length))
147  return TRUE;
148  str_length=str.str_length;
149  bmove(Ptr,str.Ptr,str_length); // May be overlapping
150  Ptr[str_length]=0;
151  str_charset=str.str_charset;
152  return FALSE;
153 }
154 
155 bool String::copy(const char *str,uint32 arg_length, const CHARSET_INFO *cs)
156 {
157  if (alloc(arg_length))
158  return TRUE;
159  if ((str_length=arg_length))
160  memcpy(Ptr,str,arg_length);
161  Ptr[arg_length]=0;
162  str_charset=cs;
163  return FALSE;
164 }
165 
166 
167 /*
168  Checks that the source string can be just copied to the destination string
169  without conversion.
170 
171  SYNPOSIS
172 
173  needs_conversion()
174  arg_length Length of string to copy.
175  from_cs Character set to copy from
176  to_cs Character set to copy to
177  uint32 *offset Returns number of unaligned characters.
178 
179  RETURN
180  0 No conversion needed
181  1 Either character set conversion or adding leading zeros
182  (e.g. for UCS-2) must be done
183 
184  NOTE
185  to_cs may be NULL for "no conversion" if the system variable
186  character_set_results is NULL.
187 */
188 
189 bool String::needs_conversion(uint32 arg_length,
190  const CHARSET_INFO *from_cs,
191  const CHARSET_INFO *to_cs,
192  uint32 *offset)
193 {
194  *offset= 0;
195  if (!to_cs ||
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)))))
201  return FALSE;
202  return TRUE;
203 }
204 
205 
206 /*
207  Copy a multi-byte character sets with adding leading zeros.
208 
209  SYNOPSIS
210 
211  copy_aligned()
212  str String to copy
213  arg_length Length of string. This should NOT be dividable with
214  cs->mbminlen.
215  offset arg_length % cs->mb_minlength
216  cs Character set for 'str'
217 
218  NOTES
219  For real multi-byte, ascii incompatible charactser sets,
220  like UCS-2, add leading zeros if we have an incomplete character.
221  Thus,
222  SELECT _ucs2 0xAA
223  will automatically be converted into
224  SELECT _ucs2 0x00AA
225 
226  RETURN
227  0 ok
228  1 error
229 */
230 
231 bool String::copy_aligned(const char *str,uint32 arg_length, uint32 offset,
232  const CHARSET_INFO *cs)
233 {
234  /* How many bytes are in incomplete character */
235  offset= cs->mbmaxlen - offset; /* How many zeros we should prepend */
236  DBUG_ASSERT(offset && offset != cs->mbmaxlen);
237 
238  uint32 aligned_length= arg_length + offset;
239  if (alloc(aligned_length))
240  return TRUE;
241 
242  /*
243  Note, this is only safe for little-endian UCS-2.
244  If we add big-endian UCS-2 sometimes, this code
245  will be more complicated. But it's OK for now.
246  */
247  memset(Ptr, 0, offset);
248  memcpy(Ptr + offset, str, arg_length);
249  Ptr[aligned_length]=0;
250  /* str_length is always >= 0 as arg_length is != 0 */
251  str_length= aligned_length;
252  str_charset= cs;
253  return FALSE;
254 }
255 
256 
257 bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
258  const CHARSET_INFO *cs)
259 {
260  /* How many bytes are in incomplete character */
261  uint32 offset= (arg_length % cs->mbminlen);
262 
263  if (!offset) /* All characters are complete, just copy */
264  {
265  set(str, arg_length, cs);
266  return FALSE;
267  }
268  return copy_aligned(str, arg_length, offset, cs);
269 }
270 
271  /* Copy with charset convertion */
272 
273 bool String::copy(const char *str, uint32 arg_length,
274  const CHARSET_INFO *from_cs, const CHARSET_INFO *to_cs, uint *errors)
275 {
276  uint32 offset;
277  if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
278  {
279  *errors= 0;
280  return copy(str, arg_length, to_cs);
281  }
282  if ((from_cs == &my_charset_bin) && offset)
283  {
284  *errors= 0;
285  return copy_aligned(str, arg_length, offset, to_cs);
286  }
287  uint32 new_length= to_cs->mbmaxlen*arg_length;
288  if (alloc(new_length))
289  return TRUE;
290  str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
291  str, arg_length, from_cs, errors);
292  str_charset=to_cs;
293  return FALSE;
294 }
295 
296 
297 /*
298  Set a string to the value of a latin1-string, keeping the original charset
299 
300  SYNOPSIS
301  copy_or_set()
302  str String of a simple charset (latin1)
303  arg_length Length of string
304 
305  IMPLEMENTATION
306  If string object is of a simple character set, set it to point to the
307  given string.
308  If not, make a copy and convert it to the new character set.
309 
310  RETURN
311  0 ok
312  1 Could not allocate result buffer
313 
314 */
315 
316 bool String::set_ascii(const char *str, uint32 arg_length)
317 {
318  if (str_charset->mbminlen == 1)
319  {
320  set(str, arg_length, str_charset);
321  return 0;
322  }
323  uint dummy_errors;
324  return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
325 }
326 
327 
328 /* This is used by mysql.cc */
329 
330 bool String::fill(uint32 max_length,char fill_char)
331 {
332  if (str_length > max_length)
333  Ptr[str_length=max_length]=0;
334  else
335  {
336  if (realloc(max_length))
337  return TRUE;
338  memset(Ptr+str_length, fill_char, max_length-str_length);
339  str_length=max_length;
340  }
341  return FALSE;
342 }
343 
344 void String::strip_sp()
345 {
346  while (str_length && my_isspace(str_charset,Ptr[str_length-1]))
347  str_length--;
348 }
349 
350 bool String::append(const String &s)
351 {
352  if (s.length())
353  {
354  if (realloc(str_length+s.length()))
355  return TRUE;
356  memcpy(Ptr+str_length,s.ptr(),s.length());
357  str_length+=s.length();
358  }
359  return FALSE;
360 }
361 
362 
363 /*
364  Append an ASCII string to the a string of the current character set
365 */
366 
367 bool String::append(const char *s,uint32 arg_length)
368 {
369  if (!arg_length)
370  return FALSE;
371 
372  /*
373  For an ASCII incompatible string, e.g. UCS-2, we need to convert
374  */
375  if (str_charset->mbminlen > 1)
376  {
377  uint32 add_length=arg_length * str_charset->mbmaxlen;
378  uint dummy_errors;
379  if (realloc(str_length+ add_length))
380  return TRUE;
381  str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
382  s, arg_length, &my_charset_latin1,
383  &dummy_errors);
384  return FALSE;
385  }
386 
387  /*
388  For an ASCII compatinble string we can just append.
389  */
390  if (realloc(str_length+arg_length))
391  return TRUE;
392  memcpy(Ptr+str_length,s,arg_length);
393  str_length+=arg_length;
394  return FALSE;
395 }
396 
397 
398 /*
399  Append a 0-terminated ASCII string
400 */
401 
402 bool String::append(const char *s)
403 {
404  return append(s, (uint) strlen(s));
405 }
406 
407 
408 /*
409  Append a string in the given charset to the string
410  with character set recoding
411 */
412 
413 bool String::append(const char *s,uint32 arg_length, const CHARSET_INFO *cs)
414 {
415  uint32 dummy_offset;
416 
417  if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
418  {
419  uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
420  uint dummy_errors;
421  if (realloc(str_length + add_length))
422  return TRUE;
423  str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
424  s, arg_length, cs, &dummy_errors);
425  }
426  else
427  {
428  if (realloc(str_length + arg_length))
429  return TRUE;
430  memcpy(Ptr + str_length, s, arg_length);
431  str_length+= arg_length;
432  }
433  return FALSE;
434 }
435 
436 
437 #ifdef TO_BE_REMOVED
438 bool String::append(FILE* file, uint32 arg_length, myf my_flags)
439 {
440  if (realloc(str_length+arg_length))
441  return TRUE;
442  if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags))
443  {
444  shrink(str_length);
445  return TRUE;
446  }
447  str_length+=arg_length;
448  return FALSE;
449 }
450 #endif
451 
452 bool String::append(IO_CACHE* file, uint32 arg_length)
453 {
454  if (realloc(str_length+arg_length))
455  return TRUE;
456  if (my_b_read(file, (uchar*) Ptr + str_length, arg_length))
457  {
458  shrink(str_length);
459  return TRUE;
460  }
461  str_length+=arg_length;
462  return FALSE;
463 }
464 
465 bool String::append_with_prefill(const char *s,uint32 arg_length,
466  uint32 full_length, char fill_char)
467 {
468  int t_length= arg_length > full_length ? arg_length : full_length;
469 
470  if (realloc(str_length + t_length))
471  return TRUE;
472  t_length= full_length - arg_length;
473  if (t_length > 0)
474  {
475  memset(Ptr+str_length, fill_char, t_length);
476  str_length=str_length + t_length;
477  }
478  append(s, arg_length);
479  return FALSE;
480 }
481 
482 uint32 String::numchars() const
483 {
484  return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
485 }
486 
487 int String::charpos(int i,uint32 offset)
488 {
489  if (i <= 0)
490  return i;
491  return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
492 }
493 
494 int String::strstr(const String &s,uint32 offset)
495 {
496  if (s.length()+offset <= str_length)
497  {
498  if (!s.length())
499  return ((int) offset); // Empty string is always found
500 
501  register const char *str = Ptr+offset;
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();
505 skip:
506  while (str != end)
507  {
508  if (*str++ == *search)
509  {
510  register char *i,*j;
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;
515  }
516  }
517  }
518  return -1;
519 }
520 
521 /*
522 ** Search string from end. Offset is offset to the end of string
523 */
524 
525 int String::strrstr(const String &s,uint32 offset)
526 {
527  if (s.length() <= offset && offset <= str_length)
528  {
529  if (!s.length())
530  return offset; // Empty string is always found
531  register const char *str = Ptr+offset-1;
532  register const char *search=s.ptr()+s.length()-1;
533 
534  const char *end=Ptr+s.length()-2;
535  const char *search_end=s.ptr()-1;
536 skip:
537  while (str != end)
538  {
539  if (*str-- == *search)
540  {
541  register char *i,*j;
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;
546  }
547  }
548  }
549  return -1;
550 }
551 
552 /*
553  Replace substring with string
554  If wrong parameter or not enough memory, do nothing
555 */
556 
557 bool String::replace(uint32 offset,uint32 arg_length,const String &to)
558 {
559  return replace(offset,arg_length,to.ptr(),to.length());
560 }
561 
562 bool String::replace(uint32 offset,uint32 arg_length,
563  const char *to, uint32 to_length)
564 {
565  long diff = (long) to_length-(long) arg_length;
566  if (offset+arg_length <= str_length)
567  {
568  if (diff < 0)
569  {
570  if (to_length)
571  memcpy(Ptr+offset,to,to_length);
572  bmove(Ptr+offset+to_length,Ptr+offset+arg_length,
573  str_length-offset-arg_length);
574  }
575  else
576  {
577  if (diff)
578  {
579  if (realloc(str_length+(uint32) diff))
580  return TRUE;
581  bmove_upp((uchar*) Ptr+str_length+diff, (uchar*) Ptr+str_length,
582  str_length-offset-arg_length);
583  }
584  if (to_length)
585  memcpy(Ptr+offset,to,to_length);
586  }
587  str_length+=(uint32) diff;
588  }
589  return FALSE;
590 }
591 
592 
593 // added by Holyfoot for "geometry" needs
594 int String::reserve(uint32 space_needed, uint32 grow_by)
595 {
596  if (Alloced_length < str_length + space_needed)
597  {
598  if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
599  return TRUE;
600  }
601  return FALSE;
602 }
603 
604 void String::qs_append(const char *str, uint32 len)
605 {
606  memcpy(Ptr + str_length, str, len + 1);
607  str_length += len;
608 }
609 
610 void String::qs_append(double d)
611 {
612  char *buff = Ptr + str_length;
613  str_length+= my_gcvt(d, MY_GCVT_ARG_DOUBLE, FLOATING_POINT_BUFFER - 1, buff,
614  NULL);
615 }
616 
617 void String::qs_append(double *d)
618 {
619  double ld;
620  float8get(ld, (char*) d);
621  qs_append(ld);
622 }
623 
624 void String::qs_append(int i)
625 {
626  char *buff= Ptr + str_length;
627  char *end= int10_to_str(i, buff, -10);
628  str_length+= (int) (end-buff);
629 }
630 
631 void String::qs_append(uint i)
632 {
633  char *buff= Ptr + str_length;
634  char *end= int10_to_str(i, buff, 10);
635  str_length+= (int) (end-buff);
636 }
637 
638 /*
639  Compare strings according to collation, without end space.
640 
641  SYNOPSIS
642  sortcmp()
643  s First string
644  t Second string
645  cs Collation
646 
647  NOTE:
648  Normally this is case sensitive comparison
649 
650  RETURN
651  < 0 s < t
652  0 s == t
653  > 0 s > t
654 */
655 
656 
657 int sortcmp(const String *s,const String *t, const CHARSET_INFO *cs)
658 {
659  return cs->coll->strnncollsp(cs,
660  (unsigned char *) s->ptr(),s->length(),
661  (unsigned char *) t->ptr(),t->length(), 0);
662 }
663 
664 
665 /*
666  Compare strings byte by byte. End spaces are also compared.
667 
668  SYNOPSIS
669  stringcmp()
670  s First string
671  t Second string
672 
673  NOTE:
674  Strings are compared as a stream of unsigned chars
675 
676  RETURN
677  < 0 s < t
678  0 s == t
679  > 0 s > t
680 */
681 
682 
683 int stringcmp(const String *s,const String *t)
684 {
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);
688 }
689 
690 
691 String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
692 {
693  if (from->Alloced_length >= from_length)
694  return from;
695  if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
696  {
697  (void) from->realloc(from_length);
698  return from;
699  }
700  if (to->realloc(from_length))
701  return from; // Actually an error
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;
705  return to;
706 }
707 
708 
709 /****************************************************************************
710  Help functions
711 ****************************************************************************/
712 
713 void String::print(String *str)
714 {
715  char *st= (char*)Ptr, *end= st+str_length;
716  for (; st < end; st++)
717  {
718  uchar c= *st;
719  switch (c)
720  {
721  case '\\':
722  str->append(STRING_WITH_LEN("\\\\"));
723  break;
724  case '\0':
725  str->append(STRING_WITH_LEN("\\0"));
726  break;
727  case '\'':
728  str->append(STRING_WITH_LEN("\\'"));
729  break;
730  case '\n':
731  str->append(STRING_WITH_LEN("\\n"));
732  break;
733  case '\r':
734  str->append(STRING_WITH_LEN("\\r"));
735  break;
736  case 26: //Ctrl-Z
737  str->append(STRING_WITH_LEN("\\z"));
738  break;
739  default:
740  str->append(c);
741  }
742  }
743 }
744 
745 
746 /*
747  Exchange state of this object and argument.
748 
749  SYNOPSIS
750  String::swap()
751 
752  RETURN
753  Target string will contain state of this object and vice versa.
754 */
755 
756 void String::swap(String &s)
757 {
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);
763 }