16
16
/* This file is originally from the mysql distribution. Coded by monty */
20
#include "drizzled/internal/my_sys.h"
21
#include "drizzled/internal/m_string.h"
22
#include "drizzled/charset.h"
23
#include "drizzled/global_charset_info.h"
20
#include <drizzled/definitions.h>
21
#include <drizzled/internal/my_sys.h>
22
#include <drizzled/internal/m_string.h>
23
#include <drizzled/memory/root.h>
24
#include <drizzled/charset.h>
25
26
#include <algorithm>
27
#include "drizzled/sql_string.h"
28
#include <drizzled/sql_string.h>
29
30
using namespace std;
34
// Converstion functions to and from std::string.
36
std::string String_to_std_string(String const& s)
38
return std::string(s.ptr(), s.length());
41
String* set_String_from_std_string(String* s, std::string const& cs)
43
s->set_ascii(cs.c_str(), cs.length());
48
34
/*****************************************************************************
49
35
** String functions
145
if ((new_ptr= (char*) ::realloc(Ptr,len)))
151
return true; // Signal error
129
new_ptr= (char*) ::realloc(Ptr,len);
153
else if ((new_ptr= (char*) malloc(len)))
135
new_ptr= (char*) malloc(len);
155
136
if (str_length) // Avoid bugs in memcpy on AIX
156
memcpy(new_ptr,Ptr,str_length);
137
memcpy(new_ptr,Ptr,str_length);
157
138
new_ptr[str_length]=0;
159
140
Alloced_length=len;
163
return true; // Signal error
165
144
Ptr[alloc_length]=0; // This make other funcs shorter
169
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
147
void String::set_int(int64_t num, bool unsigned_flag, const charset_info_st * const cs)
171
size_t l=20*cs->mbmaxlen+1;
172
int base= unsigned_flag ? 10 : -10;
176
str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
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);
181
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
155
void String::set_real(double num,size_t decimals, const charset_info_st * const cs)
183
157
char buff[FLOATING_POINT_BUFFER];
188
161
if (decimals >= NOT_FIXED_DEC)
190
len= internal::my_gcvt(num,
191
internal::MY_GCVT_ARG_DOUBLE,
192
sizeof(buff) - 1, buff, NULL);
193
return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
163
len= internal::my_gcvt(num, internal::MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
195
167
len= internal::my_fcvt(num, decimals, buff, NULL);
196
return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
205
176
Alloced_length=0; // Force realloc
206
return realloc(str_length);
211
bool String::copy(const String &str)
181
void String::copy(const String &str)
213
if (alloc(str.str_length))
183
alloc(str.str_length);
215
184
str_length=str.str_length;
216
185
memmove(Ptr, str.Ptr, str_length); // May be overlapping
217
186
Ptr[str_length]=0;
218
187
str_charset=str.str_charset;
222
bool String::copy(const std::string& arg, const CHARSET_INFO * const cs) // Allocate new string
190
void String::copy(const std::string& arg, const charset_info_st * const cs) // Allocate new string
224
if (alloc(arg.size()))
227
194
if ((str_length= arg.size()))
228
195
memcpy(Ptr, arg.c_str(), arg.size());
230
197
Ptr[arg.size()]= 0;
236
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
201
void String::copy(const char *str,size_t arg_length, const charset_info_st* cs)
238
if (alloc(arg_length))
240
204
if ((str_length=arg_length))
241
205
memcpy(Ptr,str,arg_length);
242
206
Ptr[arg_length]=0;
266
229
character_set_results is NULL.
269
bool String::needs_conversion(size_t arg_length,
270
const CHARSET_INFO * const from_cs,
271
const CHARSET_INFO * const to_cs,
232
bool String::needs_conversion(size_t arg_length, const charset_info_st* from_cs, const charset_info_st* to_cs)
276
(to_cs == &my_charset_bin) ||
277
(to_cs == from_cs) ||
235
to_cs == &my_charset_bin ||
278
237
my_charset_same(from_cs, to_cs) ||
279
((from_cs == &my_charset_bin) &&
280
(!(*offset=(arg_length % to_cs->mbminlen)))))
238
(from_cs == &my_charset_bin && not (arg_length % to_cs->mbminlen)))
288
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
289
const CHARSET_INFO * const cs)
291
/* How many bytes are in incomplete character */
292
size_t offset= (arg_length % cs->mbminlen);
294
assert(!offset); /* All characters are complete, just copy */
296
set(str, arg_length, cs);
300
/* Copy with charset conversion */
302
bool String::copy(const char *str, size_t arg_length,
303
const CHARSET_INFO * const,
304
const CHARSET_INFO * const to_cs, size_t *errors)
307
return copy(str, arg_length, to_cs);
312
244
Set a string to the value of a latin1-string, keeping the original charset
330
bool String::set_ascii(const char *str, size_t arg_length)
262
void String::set_ascii(const char *str, size_t arg_length)
332
264
if (str_charset->mbminlen == 1)
334
266
set(str, arg_length, str_charset);
338
return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
269
copy(str, arg_length, str_charset);
341
bool String::append(const String &s)
272
void String::append(const String &s)
345
if (realloc(str_length+s.length()))
276
realloc(str_length+s.length());
347
277
memcpy(Ptr+str_length,s.ptr(),s.length());
348
278
str_length+=s.length();
375
302
Append a 0-terminated ASCII string
378
bool String::append(const char *s)
380
return append(s, strlen(s));
385
Append a string in the given charset to the string
386
with character set recoding
389
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
391
if (realloc(str_length + arg_length))
393
memcpy(Ptr + str_length, s, arg_length);
394
str_length+= arg_length;
400
bool String::append_with_prefill(const char *s,size_t arg_length,
401
size_t full_length, char fill_char)
305
void String::append(const char *s)
307
append(s, strlen(s));
310
void String::append_with_prefill(const char *s,size_t arg_length, size_t full_length, char fill_char)
403
312
int t_length= arg_length > full_length ? arg_length : full_length;
405
if (realloc(str_length + t_length))
314
realloc(str_length + t_length);
407
315
t_length= full_length - arg_length;
408
316
if (t_length > 0)
429
336
int String::strstr(const String &s,size_t offset)
431
if (s.length()+offset <= str_length)
338
if (s.length() + offset <= str_length)
434
341
return ((int) offset); // Empty string is always found
436
register const char *str = Ptr+offset;
437
register const char *search=s.ptr();
438
const char *end=Ptr+str_length-s.length()+1;
343
const char *str = Ptr+offset;
344
const char *search=s.ptr();
345
const char *last=Ptr+str_length-s.length()+1;
439
346
const char *search_end=s.ptr()+s.length();
443
350
if (*str++ == *search)
446
i=(char*) str; j=(char*) search+1;
447
while (j != search_end)
448
if (*i++ != *j++) goto skip;
449
return (int) (str-Ptr) -1;
353
const char* j= search + 1;
354
while (j != search_end)
355
if (*i++ != *j++) goto skip;
356
return (int) (str - Ptr) - 1;
465
372
return offset; // Empty string is always found
466
register const char *str = Ptr+offset-1;
467
register const char *search=s.ptr()+s.length()-1;
373
const char *str = Ptr+offset-1;
374
const char *search=s.ptr()+s.length()-1;
469
const char *end=Ptr+s.length()-2;
376
const char *last=Ptr+s.length()-2;
470
377
const char *search_end=s.ptr()-1;
474
381
if (*str-- == *search)
477
i=(char*) str; j=(char*) search-1;
478
while (j != search_end)
479
if (*i-- != *j--) goto skip;
480
return (int) (i-Ptr) +1;
384
const char* j= search-1;
385
while (j != search_end)
386
if (*i-- != *j--) goto skip;
387
return (int) (i-Ptr) + 1;
489
396
If wrong parameter or not enough memory, do nothing
492
bool String::replace(size_t offset,size_t arg_length,const String &to)
399
void String::replace(size_t offset,size_t arg_length,const String &to)
494
return replace(offset,arg_length,to.ptr(),to.length());
401
replace(offset,arg_length,to.ptr(),to.length());
497
bool String::replace(size_t offset,size_t arg_length,
404
void String::replace(size_t offset,size_t arg_length,
498
405
const char *to, size_t to_length)
500
407
long diff = (long) to_length-(long) arg_length;
633
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
537
well_formed_copy_nchars(const charset_info_st * const to_cs,
634
538
char *to, size_t to_length,
635
const CHARSET_INFO * const from_cs,
539
const charset_info_st * const from_cs,
636
540
const char *from, size_t from_length,
638
542
const char **well_formed_error_pos,
705
void String::print(String *str)
606
void String::print(String& str) const
707
char *st= (char*)Ptr, *end= st+str_length;
708
for (; st < end; st++)
608
const char* last= Ptr + str_length;
609
for (const char* st= Ptr; st < last; st++)
710
611
unsigned char c= *st;
714
str->append("\\\\", sizeof("\\\\")-1);
615
str.append("\\\\", sizeof("\\\\")-1);
717
str->append("\\0", sizeof("\\0")-1);
618
str.append("\\0", sizeof("\\0")-1);
720
str->append("\\'", sizeof("\\'")-1);
621
str.append("\\'", sizeof("\\'")-1);
723
str->append("\\n", sizeof("\\n")-1);
624
str.append("\\n", sizeof("\\n")-1);
726
str->append("\\r", sizeof("\\r")-1);
627
str.append("\\r", sizeof("\\r")-1);
728
629
case '\032': // Ctrl-Z
729
str->append("\\Z", sizeof("\\Z")-1);
630
str.append("\\Z", sizeof("\\Z")-1);
747
648
/* Factor the extern out */
748
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
649
extern const charset_info_st *system_charset_info;
750
651
void String::append_identifier(const char *name, size_t in_length)
752
const char *name_end;
757
The identifier must be quoted as it includes a quote character or
761
reserve(in_length*2 + 2);
762
quote_char= (char) q;
763
append("e_char, 1, system_charset_info);
765
for (name_end= name+in_length ; name < name_end ; name+= in_length)
653
// The identifier must be quoted as it includes a quote character or it's a keyword
655
reserve(in_length * 2 + 2);
656
const char quote_char= '`';
657
append("e_char, 1);
659
for (const char* name_end= name+in_length ; name < name_end ; name+= in_length)
767
661
unsigned char chr= (unsigned char) *name;
768
662
in_length= my_mbcharlen(system_charset_info, chr);
778
672
if (in_length == 1 && chr == (unsigned char) quote_char)
779
append("e_char, 1, system_charset_info);
780
append(name, in_length, system_charset_info);
673
append("e_char, 1);
674
append(name, in_length);
782
append("e_char, 1, system_charset_info);
787
Exchange state of this object and argument.
793
Target string will contain state of this object and vice versa.
796
void String::swap(String &s)
798
std::swap(Ptr, s.Ptr);
799
std::swap(str_length, s.str_length);
800
std::swap(Alloced_length, s.Alloced_length);
801
std::swap(alloced, s.alloced);
802
std::swap(str_charset, s.str_charset);
805
void String::q_append(const size_t n)
807
int8store(Ptr + str_length, n);
810
void String::q_append(double d)
812
float8store(Ptr + str_length, d);
815
void String::q_append(double *d)
817
float8store(Ptr + str_length, *d);
820
void String::q_append(const char *data, size_t data_len)
822
memcpy(Ptr + str_length, data, data_len);
823
str_length += data_len;
826
void String::write_at_position(int position, size_t value)
828
int8store(Ptr + position,value);
830
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
676
append("e_char, 1);
679
bool check_if_only_end_space(const charset_info_st * const cs, char *str,
833
682
return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;