2 Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
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.
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.
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
18 /* This file is originally from the mysql distribution. Coded by monty */
20 #ifdef USE_PRAGMA_INTERFACE
21 #pragma interface /* gcc class implementation */
25 #define NOT_FIXED_DEC 31
29 int sortcmp(const String
*a
,const String
*b
, CHARSET_INFO
*cs
);
30 String
*copy_if_not_alloced(String
*a
,String
*b
,uint32 arg_length
);
31 uint32
copy_and_convert(char *to
, uint32 to_length
, CHARSET_INFO
*to_cs
,
32 const char *from
, uint32 from_length
,
33 CHARSET_INFO
*from_cs
, uint
*errors
);
34 uint32
well_formed_copy_nchars(CHARSET_INFO
*to_cs
,
35 char *to
, uint to_length
,
36 CHARSET_INFO
*from_cs
,
37 const char *from
, uint from_length
,
39 const char **well_formed_error_pos
,
40 const char **cannot_convert_error_pos
,
41 const char **from_end_pos
);
42 size_t my_copy_with_hex_escaping(CHARSET_INFO
*cs
,
43 char *dst
, size_t dstlen
,
44 const char *src
, size_t srclen
);
45 uint
convert_to_printable(char *to
, size_t to_len
,
46 const char *from
, size_t from_len
,
47 CHARSET_INFO
*from_cs
, size_t nbytes
= 0);
52 uint32 str_length
,Alloced_length
;
54 CHARSET_INFO
*str_charset
;
58 Ptr
=0; str_length
=Alloced_length
=0; alloced
=0;
59 str_charset
= &my_charset_bin
;
61 String(uint32 length_arg
)
63 alloced
=0; Alloced_length
=0; (void) real_alloc(length_arg
);
64 str_charset
= &my_charset_bin
;
66 String(const char *str
, CHARSET_INFO
*cs
)
68 Ptr
=(char*) str
; str_length
=(uint
) strlen(str
); Alloced_length
=0; alloced
=0;
71 String(const char *str
,uint32 len
, CHARSET_INFO
*cs
)
73 Ptr
=(char*) str
; str_length
=len
; Alloced_length
=0; alloced
=0;
76 String(char *str
,uint32 len
, CHARSET_INFO
*cs
)
78 Ptr
=(char*) str
; Alloced_length
=str_length
=len
; alloced
=0;
81 String(const String
&str
)
83 Ptr
=str
.Ptr
; str_length
=str
.str_length
;
84 Alloced_length
=str
.Alloced_length
; alloced
=0;
85 str_charset
=str
.str_charset
;
87 static void *operator new(size_t size
, MEM_ROOT
*mem_root
) throw ()
88 { return (void*) alloc_root(mem_root
, (uint
) size
); }
89 static void operator delete(void *ptr_arg
, size_t size
)
95 static void operator delete(void *, MEM_ROOT
*)
96 { /* never called */ }
99 inline void set_charset(CHARSET_INFO
*charset_arg
)
100 { str_charset
= charset_arg
; }
101 inline CHARSET_INFO
*charset() const { return str_charset
; }
102 inline uint32
length() const { return str_length
;}
103 inline uint32
alloced_length() const { return Alloced_length
;}
104 inline char& operator [] (uint32 i
) const { return Ptr
[i
]; }
105 inline void length(uint32 len
) { str_length
=len
; }
106 inline bool is_empty() const { return (str_length
== 0); }
107 inline void mark_as_const() { Alloced_length
= 0;}
108 inline const char *ptr() const { return Ptr
; }
111 DBUG_ASSERT(!alloced
|| !Ptr
|| !Alloced_length
||
112 (Alloced_length
>= (str_length
+ 1)));
114 if (!Ptr
|| Ptr
[str_length
]) /* Should be safe */
115 (void) realloc(str_length
);
118 inline char *c_ptr_quick()
120 if (Ptr
&& str_length
< Alloced_length
)
124 inline char *c_ptr_safe()
126 if (Ptr
&& str_length
< Alloced_length
)
129 (void) realloc(str_length
);
133 void set(String
&str
,uint32 offset
,uint32 arg_length
)
135 DBUG_ASSERT(&str
!= this);
137 Ptr
=(char*) str
.ptr()+offset
; str_length
=arg_length
; alloced
=0;
138 if (str
.Alloced_length
)
139 Alloced_length
=str
.Alloced_length
-offset
;
142 str_charset
=str
.str_charset
;
147 Points the internal buffer to the supplied one. The old buffer is freed.
148 @param str Pointer to the new buffer.
149 @param arg_length Length of the new buffer in characters, excluding any
151 @param cs Character set to use for interpreting string data.
152 @note The new buffer will not be null terminated.
154 inline void set(char *str
,uint32 arg_length
, CHARSET_INFO
*cs
)
157 Ptr
=(char*) str
; str_length
=Alloced_length
=arg_length
; alloced
=0;
160 inline void set(const char *str
,uint32 arg_length
, CHARSET_INFO
*cs
)
163 Ptr
=(char*) str
; str_length
=arg_length
; Alloced_length
=0 ; alloced
=0;
166 bool set_ascii(const char *str
, uint32 arg_length
);
167 inline void set_quick(char *str
,uint32 arg_length
, CHARSET_INFO
*cs
)
171 Ptr
=(char*) str
; str_length
=Alloced_length
=arg_length
;
175 bool set_int(longlong num
, bool unsigned_flag
, CHARSET_INFO
*cs
);
176 bool set(longlong num
, CHARSET_INFO
*cs
)
177 { return set_int(num
, false, cs
); }
178 bool set(ulonglong num
, CHARSET_INFO
*cs
)
179 { return set_int((longlong
)num
, true, cs
); }
180 bool set_real(double num
,uint decimals
, CHARSET_INFO
*cs
);
184 This is a method that works the same as perl's "chop". It simply
185 drops the last character of a string. This is useful in the case
186 of the federated storage handler where I'm building a unknown
187 number, list of values and fields to be used in a sql insert
188 statement to be run on the remote server, and have a comma after each.
189 When the list is complete, I "chop" off the trailing comma
193 stringobj.append("VALUES ('foo', 'fi', 'fo',");
195 stringobj.append(")");
197 In this case, the value of string was:
199 VALUES ('foo', 'fi', 'fo',
200 VALUES ('foo', 'fi', 'fo'
201 VALUES ('foo', 'fi', 'fo')
206 Ptr
[str_length
--]= '\0';
217 str_length
=0; /* Safety */
220 inline bool alloc(uint32 arg_length
)
222 if (arg_length
< Alloced_length
)
224 return real_alloc(arg_length
);
226 bool real_alloc(uint32 arg_length
); // Empties old string
227 bool realloc(uint32 arg_length
);
229 // Shrink the buffer, but only if it is allocated on the heap.
230 inline void shrink(uint32 arg_length
)
234 if (arg_length
< Alloced_length
)
237 if (!(new_ptr
=(char*) my_realloc(Ptr
,arg_length
,MYF(0))))
240 real_alloc(arg_length
);
245 Alloced_length
=arg_length
;
249 bool is_alloced() const { return alloced
; }
250 inline String
& operator = (const String
&s
)
255 It is forbidden to do assignments like
256 some_string = substring_of_that_string
258 DBUG_ASSERT(!s
.uses_buffer_owned_by(this));
260 Ptr
=s
.Ptr
; str_length
=s
.str_length
; Alloced_length
=s
.Alloced_length
;
261 str_charset
=s
.str_charset
;
267 bool copy(); // Alloc string if not alloced
268 bool copy(const String
&s
); // Allocate new string
269 bool copy(const char *s
,uint32 arg_length
, CHARSET_INFO
*cs
); // Allocate new string
270 static bool needs_conversion(uint32 arg_length
,
271 CHARSET_INFO
*cs_from
, CHARSET_INFO
*cs_to
,
273 bool copy_aligned(const char *s
, uint32 arg_length
, uint32 offset
,
275 bool set_or_copy_aligned(const char *s
, uint32 arg_length
, CHARSET_INFO
*cs
);
276 bool copy(const char*s
,uint32 arg_length
, CHARSET_INFO
*csfrom
,
277 CHARSET_INFO
*csto
, uint
*errors
);
278 bool append(const String
&s
);
279 bool append(const char *s
);
280 bool append(const char *s
,uint32 arg_length
);
281 bool append(const char *s
,uint32 arg_length
, CHARSET_INFO
*cs
);
282 bool append(IO_CACHE
* file
, uint32 arg_length
);
283 bool append_with_prefill(const char *s
, uint32 arg_length
,
284 uint32 full_length
, char fill_char
);
285 int strstr(const String
&search
,uint32 offset
=0); // Returns offset to substring or -1
286 int strrstr(const String
&search
,uint32 offset
=0); // Returns offset to substring or -1
287 bool replace(uint32 offset
,uint32 arg_length
,const char *to
,uint32 length
);
288 bool replace(uint32 offset
,uint32 arg_length
,const String
&to
);
289 inline bool append(char chr
)
291 if (str_length
< Alloced_length
)
293 Ptr
[str_length
++]=chr
;
297 if (realloc(str_length
+1))
299 Ptr
[str_length
++]=chr
;
303 bool fill(uint32 max_length
,char fill
);
305 friend int sortcmp(const String
*a
,const String
*b
, CHARSET_INFO
*cs
);
306 friend int stringcmp(const String
*a
,const String
*b
);
307 friend String
*copy_if_not_alloced(String
*a
,String
*b
,uint32 arg_length
);
309 int charpos(int i
,uint32 offset
=0);
311 int reserve(uint32 space_needed
)
313 return realloc(str_length
+ space_needed
);
315 int reserve(uint32 space_needed
, uint32 grow_by
);
318 The following append operations do NOT check alloced memory
319 q_*** methods writes values of parameters itself
320 qs_*** methods writes string representation of value
322 void q_append(const char c
)
324 Ptr
[str_length
++] = c
;
326 void q_append(const uint32 n
)
328 int4store(Ptr
+ str_length
, n
);
331 void q_append(double d
)
333 float8store(Ptr
+ str_length
, d
);
336 void q_append(double *d
)
338 float8store(Ptr
+ str_length
, *d
);
341 void q_append(const char *data
, uint32 data_len
)
343 memcpy(Ptr
+ str_length
, data
, data_len
);
344 str_length
+= data_len
;
347 void write_at_position(int position
, uint32 value
)
349 int4store(Ptr
+ position
,value
);
352 void qs_append(const char *str
, uint32 len
);
353 void qs_append(double d
);
354 void qs_append(double *d
);
355 inline void qs_append(const char c
)
360 void qs_append(int i
);
361 void qs_append(uint i
);
363 /* Inline (general) functions used by the protocol functions */
365 inline char *prep_append(uint32 arg_length
, uint32 step_alloc
)
367 uint32 new_length
= arg_length
+ str_length
;
368 if (new_length
> Alloced_length
)
370 if (realloc(new_length
+ step_alloc
))
373 uint32 old_length
= str_length
;
374 str_length
+= arg_length
;
375 return Ptr
+ old_length
; /* Area to use */
378 inline bool append(const char *s
, uint32 arg_length
, uint32 step_alloc
)
380 uint32 new_length
= arg_length
+ str_length
;
381 if (new_length
> Alloced_length
&& realloc(new_length
+ step_alloc
))
383 memcpy(Ptr
+str_length
, s
, arg_length
);
384 str_length
+= arg_length
;
387 void print(String
*print
);
389 /* Swap two string objects. Efficient way to exchange data without memcpy. */
390 void swap(String
&s
);
392 inline bool uses_buffer_owned_by(const String
*s
) const
394 return (s
->alloced
&& Ptr
>= s
->Ptr
&& Ptr
< s
->Ptr
+ s
->str_length
);
396 bool is_ascii() const
400 if (charset()->mbminlen
> 1)
402 for (const char *c
= ptr(), *end
= c
+ length(); c
< end
; c
++)
411 static inline bool check_if_only_end_space(CHARSET_INFO
*cs
, char *str
,
414 return str
+ cs
->cset
->scan(cs
, str
, end
, MY_SEQ_SPACES
) == end
;