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 CLIENT_SQL_STRING_INCLUDED
2 #define CLIENT_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"
22 #include "my_sys.h"
23 
24 class String;
25 int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs);
26 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
27 inline uint32 copy_and_convert(char *to, uint32 to_length,
28  const CHARSET_INFO *to_cs,
29  const char *from, uint32 from_length,
30  const CHARSET_INFO *from_cs, uint *errors)
31 {
32  return my_convert(to, to_length, to_cs, from, from_length, from_cs, errors);
33 }
34 
35 class String
36 {
37  char *Ptr;
38  uint32 str_length,Alloced_length;
39  bool alloced;
40  const CHARSET_INFO *str_charset;
41 public:
42  String()
43  {
44  Ptr=0; str_length=Alloced_length=0; alloced=0;
45  str_charset= &my_charset_bin;
46  }
47  String(uint32 length_arg)
48  {
49  alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
50  str_charset= &my_charset_bin;
51  }
52  String(const char *str, const CHARSET_INFO *cs)
53  {
54  Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
55  str_charset=cs;
56  }
57  String(const char *str,uint32 len, const CHARSET_INFO *cs)
58  {
59  Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
60  str_charset=cs;
61  }
62  String(char *str,uint32 len, const CHARSET_INFO *cs)
63  {
64  Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
65  str_charset=cs;
66  }
67  String(const String &str)
68  {
69  Ptr=str.Ptr ; str_length=str.str_length ;
70  Alloced_length=str.Alloced_length; alloced=0;
71  str_charset=str.str_charset;
72  }
73  static void *operator new(size_t size, MEM_ROOT *mem_root)
74  { return (void*) alloc_root(mem_root, (uint) size); }
75  static void operator delete(void *ptr_arg, size_t size)
76  {
77  (void) ptr_arg;
78  (void) size;
79  TRASH(ptr_arg, size);
80  }
81  static void operator delete(void *, MEM_ROOT *)
82  { /* never called */ }
83  ~String() { free(); }
84 
85  inline void set_charset(const CHARSET_INFO *charset_arg)
86  { str_charset= charset_arg; }
87  inline const CHARSET_INFO *charset() const { return str_charset; }
88  inline uint32 length() const { return str_length;}
89  inline uint32 alloced_length() const { return Alloced_length;}
90  inline char& operator [] (uint32 i) const { return Ptr[i]; }
91  inline void length(uint32 len) { str_length=len ; }
92  inline bool is_empty() { return (str_length == 0); }
93  inline void mark_as_const() { Alloced_length= 0;}
94  inline const char *ptr() const { return Ptr; }
95  inline char *c_ptr()
96  {
97  DBUG_ASSERT(!alloced || !Ptr || !Alloced_length ||
98  (Alloced_length >= (str_length + 1)));
99 
100  if (!Ptr || Ptr[str_length]) /* Should be safe */
101  (void) realloc(str_length);
102  return Ptr;
103  }
104  inline char *c_ptr_quick()
105  {
106  if (Ptr && str_length < Alloced_length)
107  Ptr[str_length]=0;
108  return Ptr;
109  }
110  inline char *c_ptr_safe()
111  {
112  if (Ptr && str_length < Alloced_length)
113  Ptr[str_length]=0;
114  else
115  (void) realloc(str_length);
116  return Ptr;
117  }
118 
119  void set(String &str,uint32 offset,uint32 arg_length)
120  {
121  DBUG_ASSERT(&str != this);
122  free();
123  Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
124  if (str.Alloced_length)
125  Alloced_length=str.Alloced_length-offset;
126  else
127  Alloced_length=0;
128  str_charset=str.str_charset;
129  }
130  inline void set(char *str,uint32 arg_length, const CHARSET_INFO *cs)
131  {
132  free();
133  Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
134  str_charset=cs;
135  }
136  inline void set(const char *str,uint32 arg_length, const CHARSET_INFO *cs)
137  {
138  free();
139  Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
140  str_charset=cs;
141  }
142  bool set_ascii(const char *str, uint32 arg_length);
143  inline void set_quick(char *str,uint32 arg_length, const CHARSET_INFO *cs)
144  {
145  if (!alloced)
146  {
147  Ptr=(char*) str; str_length=Alloced_length=arg_length;
148  }
149  str_charset=cs;
150  }
151  bool set(longlong num, const CHARSET_INFO *cs);
152  bool set(ulonglong num, const CHARSET_INFO *cs);
153  bool set(double num,uint decimals, const CHARSET_INFO *cs);
154 
155  /*
156  PMG 2004.11.12
157  This is a method that works the same as perl's "chop". It simply
158  drops the last character of a string. This is useful in the case
159  of the federated storage handler where I'm building a unknown
160  number, list of values and fields to be used in a sql insert
161  statement to be run on the remote server, and have a comma after each.
162  When the list is complete, I "chop" off the trailing comma
163 
164  ex.
165  String stringobj;
166  stringobj.append("VALUES ('foo', 'fi', 'fo',");
167  stringobj.chop();
168  stringobj.append(")");
169 
170  In this case, the value of string was:
171 
172  VALUES ('foo', 'fi', 'fo',
173  VALUES ('foo', 'fi', 'fo'
174  VALUES ('foo', 'fi', 'fo')
175 
176  */
177  inline void chop()
178  {
179  Ptr[str_length--]= '\0';
180  }
181 
182  inline void free()
183  {
184  if (alloced)
185  {
186  alloced=0;
187  Alloced_length=0;
188  my_free(Ptr);
189  Ptr=0;
190  str_length=0; /* Safety */
191  }
192  }
193  inline bool alloc(uint32 arg_length)
194  {
195  if (arg_length < Alloced_length)
196  return 0;
197  return real_alloc(arg_length);
198  }
199  bool real_alloc(uint32 arg_length); // Empties old string
200  bool realloc(uint32 arg_length);
201 
202  // Shrink the buffer, but only if it is allocated on the heap.
203  inline void shrink(uint32 arg_length)
204  {
205  if (!is_alloced())
206  return;
207  if (arg_length < Alloced_length)
208  {
209  char *new_ptr;
210  if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0))))
211  {
212  Alloced_length = 0;
213  real_alloc(arg_length);
214  }
215  else
216  {
217  Ptr=new_ptr;
218  Alloced_length=arg_length;
219  }
220  }
221  }
222  bool is_alloced() const { return alloced; }
223  inline String& operator = (const String &s)
224  {
225  if (&s != this)
226  {
227  /*
228  It is forbidden to do assignments like
229  some_string = substring_of_that_string
230  */
231  DBUG_ASSERT(!s.uses_buffer_owned_by(this));
232  free();
233  Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
234  str_charset=s.str_charset;
235  alloced=0;
236  }
237  return *this;
238  }
239 
240  bool copy(); // Alloc string if not alloced
241  bool copy(const String &s); // Allocate new string
243  bool copy(const char *s,uint32 arg_length, const CHARSET_INFO *cs);
244  static bool needs_conversion(uint32 arg_length,
245  const CHARSET_INFO *cs_from, const CHARSET_INFO *cs_to,
246  uint32 *offset);
247  bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
248  const CHARSET_INFO *cs);
249  bool set_or_copy_aligned(const char *s, uint32 arg_length,
250  const CHARSET_INFO *cs);
251  bool copy(const char*s,uint32 arg_length, const CHARSET_INFO *csfrom,
252  const CHARSET_INFO *csto, uint *errors);
253  bool append(const String &s);
254  bool append(const char *s);
255  bool append(const char *s,uint32 arg_length);
256  bool append(const char *s,uint32 arg_length, const CHARSET_INFO *cs);
257  bool append(IO_CACHE* file, uint32 arg_length);
258  bool append_with_prefill(const char *s, uint32 arg_length,
259  uint32 full_length, char fill_char);
260  int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
261  int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
262  bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
263  bool replace(uint32 offset,uint32 arg_length,const String &to);
264  inline bool append(char chr)
265  {
266  if (str_length < Alloced_length)
267  {
268  Ptr[str_length++]=chr;
269  }
270  else
271  {
272  if (realloc(str_length+1))
273  return 1;
274  Ptr[str_length++]=chr;
275  }
276  return 0;
277  }
278  bool fill(uint32 max_length,char fill);
279  void strip_sp();
280  friend int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs);
281  friend int stringcmp(const String *a,const String *b);
282  friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
283  uint32 numchars() const;
284  int charpos(int i,uint32 offset=0);
285 
286  int reserve(uint32 space_needed)
287  {
288  return realloc(str_length + space_needed);
289  }
290  int reserve(uint32 space_needed, uint32 grow_by);
291 
292  /*
293  The following append operations do NOT check alloced memory
294  q_*** methods writes values of parameters itself
295  qs_*** methods writes string representation of value
296  */
297  void q_append(const char c)
298  {
299  Ptr[str_length++] = c;
300  }
301  void q_append(const uint32 n)
302  {
303  int4store(Ptr + str_length, n);
304  str_length += 4;
305  }
306  void q_append(double d)
307  {
308  float8store(Ptr + str_length, d);
309  str_length += 8;
310  }
311  void q_append(double *d)
312  {
313  float8store(Ptr + str_length, *d);
314  str_length += 8;
315  }
316  void q_append(const char *data, uint32 data_len)
317  {
318  memcpy(Ptr + str_length, data, data_len);
319  str_length += data_len;
320  }
321 
322  void write_at_position(int position, uint32 value)
323  {
324  int4store(Ptr + position,value);
325  }
326 
327  void qs_append(const char *str, uint32 len);
328  void qs_append(double d);
329  void qs_append(double *d);
330  inline void qs_append(const char c)
331  {
332  Ptr[str_length]= c;
333  str_length++;
334  }
335  void qs_append(int i);
336  void qs_append(uint i);
337 
338  /* Inline (general) functions used by the protocol functions */
339 
340  inline char *prep_append(uint32 arg_length, uint32 step_alloc)
341  {
342  uint32 new_length= arg_length + str_length;
343  if (new_length > Alloced_length)
344  {
345  if (realloc(new_length + step_alloc))
346  return 0;
347  }
348  uint32 old_length= str_length;
349  str_length+= arg_length;
350  return Ptr+ old_length; /* Area to use */
351  }
352 
353  inline bool append(const char *s, uint32 arg_length, uint32 step_alloc)
354  {
355  uint32 new_length= arg_length + str_length;
356  if (new_length > Alloced_length && realloc(new_length + step_alloc))
357  return TRUE;
358  memcpy(Ptr+str_length, s, arg_length);
359  str_length+= arg_length;
360  return FALSE;
361  }
362  void print(String *print);
363 
364  /* Swap two string objects. Efficient way to exchange data without memcpy. */
365  void swap(String &s);
366 
367  inline bool uses_buffer_owned_by(const String *s) const
368  {
369  return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
370  }
371 };
372 
373 #endif /* CLIENT_SQL_STRING_INCLUDED */