MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_string.h
1 #ifndef SQL_STRING_INCLUDED
2 #define SQL_STRING_INCLUDED
3 
4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
19 /* This file is originally from the mysql distribution. Coded by monty */
20 
21 #include "m_ctype.h" /* my_charset_bin */
22 #include "my_sys.h" /* alloc_root, my_free, my_realloc */
23 #include "m_string.h" /* TRASH */
24 
25 
38 {
39 private:
40  const char *m_str;
41  size_t m_length;
42 protected:
46  void set(const char *str_arg, size_t length_arg)
47  {
48  // NULL is allowed only with length==0
49  DBUG_ASSERT(str_arg || length_arg == 0);
50  // For non-NULL, make sure length_arg is in sync with '\0' terminator.
51  DBUG_ASSERT(!str_arg || str_arg[length_arg] == '\0');
52  m_str= str_arg;
53  m_length= length_arg;
54  }
55 public:
57  {
58  set(NULL, 0);
59  }
60  Simple_cstring(const char *str_arg, size_t length_arg)
61  {
62  set(str_arg, length_arg);
63  }
64  Simple_cstring(const LEX_STRING arg)
65  {
66  set(arg.str, arg.length);
67  }
68  void reset()
69  {
70  set(NULL, 0);
71  }
75  void set(const char *str)
76  {
77  set(str, str ? strlen(str) : 0);
78  }
82  const char *ptr() const { return m_str; }
86  bool is_set() const { return m_str != NULL; }
90  size_t length() const { return m_length; }
94  bool eq_bin(const Simple_cstring other) const
95  {
96  return m_length == other.m_length &&
97  memcmp(m_str, other.m_str, m_length) == 0;
98  }
102  void strcpy(char *buff) const
103  {
104  memcpy(buff, m_str, m_length);
105  buff[m_length]= '\0';
106  }
107 };
108 
109 
110 class String;
111 typedef struct charset_info_st CHARSET_INFO;
112 typedef struct st_io_cache IO_CACHE;
113 typedef struct st_mem_root MEM_ROOT;
114 
115 int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs);
116 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
117 inline uint32 copy_and_convert(char *to, uint32 to_length,
118  const CHARSET_INFO *to_cs,
119  const char *from, uint32 from_length,
120  const CHARSET_INFO *from_cs, uint *errors)
121 {
122  return my_convert(to, to_length, to_cs, from, from_length, from_cs, errors);
123 }
124 uint32 well_formed_copy_nchars(const CHARSET_INFO *to_cs,
125  char *to, uint to_length,
126  const CHARSET_INFO *from_cs,
127  const char *from, uint from_length,
128  uint nchars,
129  const char **well_formed_error_pos,
130  const char **cannot_convert_error_pos,
131  const char **from_end_pos);
132 size_t my_copy_with_hex_escaping(const CHARSET_INFO *cs,
133  char *dst, size_t dstlen,
134  const char *src, size_t srclen);
135 uint convert_to_printable(char *to, size_t to_len,
136  const char *from, size_t from_len,
137  const CHARSET_INFO *from_cs, size_t nbytes= 0);
138 
139 class String
140 {
141  char *Ptr;
142  uint32 str_length,Alloced_length;
143  bool alloced;
144  const CHARSET_INFO *str_charset;
145 public:
146  String()
147  {
148  Ptr=0; str_length=Alloced_length=0; alloced=0;
149  str_charset= &my_charset_bin;
150  }
151  String(uint32 length_arg)
152  {
153  alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
154  str_charset= &my_charset_bin;
155  }
156  String(const char *str, const CHARSET_INFO *cs)
157  {
158  Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
159  str_charset=cs;
160  }
161  String(const char *str,uint32 len, const CHARSET_INFO *cs)
162  {
163  Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
164  str_charset=cs;
165  }
166  String(char *str,uint32 len, const CHARSET_INFO *cs)
167  {
168  Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
169  str_charset=cs;
170  }
171  String(const String &str)
172  {
173  Ptr=str.Ptr ; str_length=str.str_length ;
174  Alloced_length=str.Alloced_length; alloced=0;
175  str_charset=str.str_charset;
176  }
177  static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
178  { return (void*) alloc_root(mem_root, (uint) size); }
179  static void operator delete(void *ptr_arg, size_t size)
180  {
181  (void) ptr_arg;
182  (void) size;
183  TRASH(ptr_arg, size);
184  }
185  static void operator delete(void *, MEM_ROOT *)
186  { /* never called */ }
187  ~String() { free(); }
188 
189  inline void set_charset(const CHARSET_INFO *charset_arg)
190  { str_charset= charset_arg; }
191  inline const CHARSET_INFO *charset() const { return str_charset; }
192  inline uint32 length() const { return str_length;}
193  inline uint32 alloced_length() const { return Alloced_length;}
194  inline char& operator [] (uint32 i) const { return Ptr[i]; }
195  inline void length(uint32 len) { str_length=len ; }
196  inline bool is_empty() const { return (str_length == 0); }
197  inline void mark_as_const() { Alloced_length= 0;}
198  inline const char *ptr() const { return Ptr; }
199  inline char *c_ptr()
200  {
201  DBUG_ASSERT(!alloced || !Ptr || !Alloced_length ||
202  (Alloced_length >= (str_length + 1)));
203 
204  if (!Ptr || Ptr[str_length]) /* Should be safe */
205  (void) realloc(str_length);
206  return Ptr;
207  }
208  inline char *c_ptr_quick()
209  {
210  if (Ptr && str_length < Alloced_length)
211  Ptr[str_length]=0;
212  return Ptr;
213  }
214  inline char *c_ptr_safe()
215  {
216  if (Ptr && str_length < Alloced_length)
217  Ptr[str_length]=0;
218  else
219  (void) realloc(str_length);
220  return Ptr;
221  }
222  LEX_STRING lex_string() const
223  {
224  LEX_STRING lex_string = { (char*) ptr(), length() };
225  return lex_string;
226  }
227 
228  void set(String &str,uint32 offset,uint32 arg_length)
229  {
230  DBUG_ASSERT(&str != this);
231  free();
232  Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
233  if (str.Alloced_length)
234  Alloced_length=str.Alloced_length-offset;
235  else
236  Alloced_length=0;
237  str_charset=str.str_charset;
238  }
239 
240 
249  inline void set(char *str,uint32 arg_length, const CHARSET_INFO *cs)
250  {
251  free();
252  Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
253  str_charset=cs;
254  }
255  inline void set(const char *str,uint32 arg_length, const CHARSET_INFO *cs)
256  {
257  free();
258  Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
259  str_charset=cs;
260  }
261  bool set_ascii(const char *str, uint32 arg_length);
262  inline void set_quick(char *str,uint32 arg_length, const CHARSET_INFO *cs)
263  {
264  if (!alloced)
265  {
266  Ptr=(char*) str; str_length=Alloced_length=arg_length;
267  }
268  str_charset=cs;
269  }
270  bool set_int(longlong num, bool unsigned_flag, const CHARSET_INFO *cs);
271  bool set(longlong num, const CHARSET_INFO *cs)
272  { return set_int(num, false, cs); }
273  bool set(ulonglong num, const CHARSET_INFO *cs)
274  { return set_int((longlong)num, true, cs); }
275  bool set_real(double num,uint decimals, const CHARSET_INFO *cs);
276 
277  /*
278  PMG 2004.11.12
279  This is a method that works the same as perl's "chop". It simply
280  drops the last character of a string. This is useful in the case
281  of the federated storage handler where I'm building a unknown
282  number, list of values and fields to be used in a sql insert
283  statement to be run on the remote server, and have a comma after each.
284  When the list is complete, I "chop" off the trailing comma
285 
286  ex.
287  String stringobj;
288  stringobj.append("VALUES ('foo', 'fi', 'fo',");
289  stringobj.chop();
290  stringobj.append(")");
291 
292  In this case, the value of string was:
293 
294  VALUES ('foo', 'fi', 'fo',
295  VALUES ('foo', 'fi', 'fo'
296  VALUES ('foo', 'fi', 'fo')
297 
298  */
299  inline void chop()
300  {
301  str_length--;
302  Ptr[str_length]= '\0';
303  DBUG_ASSERT(strlen(Ptr) == str_length);
304  }
305 
306  inline void free()
307  {
308  if (alloced)
309  {
310  alloced=0;
311  Alloced_length=0;
312  my_free(Ptr);
313  Ptr=0;
314  str_length=0; /* Safety */
315  }
316  }
317  inline bool alloc(uint32 arg_length)
318  {
319  if (arg_length < Alloced_length)
320  return 0;
321  return real_alloc(arg_length);
322  }
323  bool real_alloc(uint32 arg_length); // Empties old string
324  bool realloc(uint32 arg_length);
325 
326  // Shrink the buffer, but only if it is allocated on the heap.
327  inline void shrink(uint32 arg_length)
328  {
329  if (!is_alloced())
330  return;
331  if (arg_length < Alloced_length)
332  {
333  char *new_ptr;
334  if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
335  {
336  Alloced_length = 0;
337  real_alloc(arg_length);
338  }
339  else
340  {
341  Ptr=new_ptr;
342  Alloced_length=arg_length;
343  }
344  }
345  }
346  bool is_alloced() const { return alloced; }
347  inline String& operator = (const String &s)
348  {
349  if (&s != this)
350  {
351  /*
352  It is forbidden to do assignments like
353  some_string = substring_of_that_string
354  */
355  DBUG_ASSERT(!s.uses_buffer_owned_by(this));
356  free();
357  Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
358  str_charset=s.str_charset;
359  alloced=0;
360  }
361  return *this;
362  }
371  inline void takeover(String &s)
372  {
373  DBUG_ASSERT(this != &s);
374  // Make sure buffers of the two Strings do not overlap
375  DBUG_ASSERT(!s.uses_buffer_owned_by(this));
376  free();
377  Ptr= s.Ptr;
378  str_length= s.str_length;
379  Alloced_length= s.Alloced_length;
380  alloced= s.alloced;
381  str_charset= s.str_charset;
382  s.Ptr= NULL;
383  s.Alloced_length= 0;
384  s.str_length= 0;
385  s.alloced= 0;
386  }
387 
388  bool copy(); // Alloc string if not alloced
389  bool copy(const String &s); // Allocate new string
390  // Allocate new string
391  bool copy(const char *s,uint32 arg_length, const CHARSET_INFO *cs);
392  static bool needs_conversion(uint32 arg_length,
393  const CHARSET_INFO *cs_from, const CHARSET_INFO *cs_to,
394  uint32 *offset);
395  bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
396  const CHARSET_INFO *cs);
397  bool set_or_copy_aligned(const char *s, uint32 arg_length,
398  const CHARSET_INFO *cs);
399  bool copy(const char*s,uint32 arg_length, const CHARSET_INFO *csfrom,
400  const CHARSET_INFO *csto, uint *errors);
401  bool append(const String &s);
402  bool append(const char *s);
403  bool append(LEX_STRING *ls)
404  {
405  return append(ls->str, (uint32) ls->length);
406  }
407  bool append(Simple_cstring str)
408  {
409  return append(str.ptr(), static_cast<uint>(str.length()));
410  }
411  bool append(const char *s, uint32 arg_length);
412  bool append(const char *s, uint32 arg_length, const CHARSET_INFO *cs);
413  bool append_ulonglong(ulonglong val);
414  bool append(IO_CACHE* file, uint32 arg_length);
415  bool append_with_prefill(const char *s, uint32 arg_length,
416  uint32 full_length, char fill_char);
417  bool append_parenthesized(long nr, int radix= 10);
418  int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
419  int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
420  bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
421  bool replace(uint32 offset,uint32 arg_length,const String &to);
422  inline bool append(char chr)
423  {
424  if (str_length < Alloced_length)
425  {
426  Ptr[str_length++]=chr;
427  }
428  else
429  {
430  if (realloc(str_length+1))
431  return 1;
432  Ptr[str_length++]=chr;
433  }
434  return 0;
435  }
436  bool fill(uint32 max_length,char fill);
437  void strip_sp();
438  friend int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs);
439  friend int stringcmp(const String *a,const String *b);
440  friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
441  uint32 numchars() const;
442  int charpos(int i,uint32 offset=0);
443 
444  int reserve(uint32 space_needed)
445  {
446  return realloc(str_length + space_needed);
447  }
448  int reserve(uint32 space_needed, uint32 grow_by);
449  /*
450  The following append operations do NOT check alloced memory
451  q_*** methods writes values of parameters itself
452  qs_*** methods writes string representation of value
453  */
454  void q_append(const char c)
455  {
456  Ptr[str_length++] = c;
457  }
458  void q_append(const uint32 n)
459  {
460  int4store(Ptr + str_length, n);
461  str_length += 4;
462  }
463  void q_append(double d)
464  {
465  float8store(Ptr + str_length, d);
466  str_length += 8;
467  }
468  void q_append(double *d)
469  {
470  float8store(Ptr + str_length, *d);
471  str_length += 8;
472  }
473  void q_append(const char *data, uint32 data_len)
474  {
475  memcpy(Ptr + str_length, data, data_len);
476  str_length += data_len;
477  }
478 
479  void write_at_position(int position, uint32 value)
480  {
481  int4store(Ptr + position,value);
482  }
483 
484  void qs_append(const char *str, uint32 len);
485  void qs_append(double d);
486  void qs_append(double *d);
487  inline void qs_append(const char c)
488  {
489  Ptr[str_length]= c;
490  str_length++;
491  }
492  void qs_append(int i);
493  void qs_append(uint i);
494 
495  /* Inline (general) functions used by the protocol functions */
496 
497  inline char *prep_append(uint32 arg_length, uint32 step_alloc)
498  {
499  uint32 new_length= arg_length + str_length;
500  if (new_length > Alloced_length)
501  {
502  if (realloc(new_length + step_alloc))
503  return 0;
504  }
505  uint32 old_length= str_length;
506  str_length+= arg_length;
507  return Ptr+ old_length; /* Area to use */
508  }
509 
510  inline bool append(const char *s, uint32 arg_length, uint32 step_alloc)
511  {
512  uint32 new_length= arg_length + str_length;
513  if (new_length > Alloced_length && realloc(new_length + step_alloc))
514  return TRUE;
515  memcpy(Ptr+str_length, s, arg_length);
516  str_length+= arg_length;
517  return FALSE;
518  }
519  void print(String *print);
520 
521  /* Swap two string objects. Efficient way to exchange data without memcpy. */
522  void swap(String &s);
523 
524  inline bool uses_buffer_owned_by(const String *s) const
525  {
526  return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
527  }
528  bool is_ascii() const
529  {
530  if (length() == 0)
531  return TRUE;
532  if (charset()->mbminlen > 1)
533  return FALSE;
534  for (const char *c= ptr(), *end= c + length(); c < end; c++)
535  {
536  if (!my_isascii(*c))
537  return FALSE;
538  }
539  return TRUE;
540  }
548  char *dup(MEM_ROOT *root) const
549  {
550  if (str_length > 0 && Ptr[str_length - 1] == 0)
551  return static_cast<char *>(memdup_root(root, Ptr, str_length));
552 
553  char *ret= static_cast<char*>(alloc_root(root, str_length + 1));
554  if (ret != NULL)
555  {
556  memcpy(ret, Ptr, str_length);
557  ret[str_length]= 0;
558  }
559  return ret;
560  }
561 };
562 
563 
575 template<size_t buff_sz>
576 class StringBuffer : public String
577 {
578  char buff[buff_sz];
579 
580 public:
581  StringBuffer() : String(buff, buff_sz, &my_charset_bin) { length(0); }
582  explicit StringBuffer(const CHARSET_INFO *cs) : String(buff, buff_sz, cs)
583  {
584  length(0);
585  }
586  StringBuffer(const char *str, size_t length, const CHARSET_INFO *cs)
587  : String(buff, buff_sz, cs)
588  {
589  set(str, length, cs);
590  }
591 };
592 
593 
594 static inline bool check_if_only_end_space(const CHARSET_INFO *cs, char *str,
595  char *end)
596 {
597  return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
598 }
599 
600 #endif /* SQL_STRING_INCLUDED */