12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
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"
19
#include <mysys/my_sys.h>
20
#include <mystrings/m_string.h>
25
22
#include <algorithm>
27
#include "drizzled/sql_string.h"
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());
25
The following extern declarations are ok as these are interface functions
26
required by the string function
29
extern unsigned char* sql_alloc(unsigned size);
30
extern void sql_element_free(void *ptr);
32
#include "sql_string.h"
48
34
/*****************************************************************************
49
35
** String functions
50
36
*****************************************************************************/
57
str_charset(&my_charset_bin)
61
String::String(size_t length_arg)
66
str_charset(&my_charset_bin)
68
(void) real_alloc(length_arg);
71
String::String(const char *str, const CHARSET_INFO * const cs)
72
: Ptr(const_cast<char *>(str)),
73
str_length(static_cast<size_t>(strlen(str))),
80
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
81
: Ptr(const_cast<char *>(str)),
89
String::String(char *str, size_t len, const CHARSET_INFO * const cs)
98
String::String(const String &str)
100
str_length(str.str_length),
101
Alloced_length(str.Alloced_length),
103
str_charset(str.str_charset)
107
void *String::operator new(size_t size, memory::Root *mem_root)
109
return mem_root->alloc_root(static_cast<size_t>(size));
112
38
String::~String() { free(); }
114
bool String::real_alloc(size_t arg_length)
40
bool String::real_alloc(uint32_t arg_length)
116
42
arg_length=ALIGN_SIZE(arg_length+1);
118
44
if (Alloced_length < arg_length)
120
if (Alloced_length > 0)
122
47
if (!(Ptr=(char*) malloc(arg_length)))
124
49
Alloced_length=arg_length;
169
94
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
171
size_t l=20*cs->mbmaxlen+1;
96
uint32_t l=20*cs->mbmaxlen+1;
172
97
int base= unsigned_flag ? 10 : -10;
176
str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
101
str_length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
181
bool String::set_real(double num,size_t decimals, const CHARSET_INFO * const cs)
106
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
183
108
char buff[FLOATING_POINT_BUFFER];
109
uint32_t dummy_errors;
188
113
if (decimals >= NOT_FIXED_DEC)
190
len= internal::my_gcvt(num,
191
internal::MY_GCVT_ARG_DOUBLE,
192
sizeof(buff) - 1, buff, NULL);
115
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
193
116
return copy(buff, len, &my_charset_utf8_general_ci, cs, &dummy_errors);
195
len= internal::my_fcvt(num, decimals, buff, NULL);
196
return copy(buff, (size_t) len, &my_charset_utf8_general_ci, cs,
118
len= my_fcvt(num, decimals, buff, NULL);
119
return copy(buff, (uint32_t) len, &my_charset_utf8_general_ci, cs,
274
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
198
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
275
199
const CHARSET_INFO * const cs)
277
201
/* How many bytes are in incomplete character */
278
size_t offset= (arg_length % cs->mbminlen);
202
uint32_t offset= (arg_length % cs->mbminlen);
280
204
assert(!offset); /* All characters are complete, just copy */
286
210
/* Copy with charset conversion */
288
bool String::copy(const char *str, size_t arg_length,
212
bool String::copy(const char *str, uint32_t arg_length,
289
213
const CHARSET_INFO * const,
290
const CHARSET_INFO * const to_cs, size_t *errors)
214
const CHARSET_INFO * const to_cs, uint32_t *errors)
293
217
return copy(str, arg_length, to_cs);
316
bool String::set_ascii(const char *str, size_t arg_length)
240
bool String::set_ascii(const char *str, uint32_t arg_length)
318
242
if (str_charset->mbminlen == 1)
320
244
set(str, arg_length, str_charset);
247
uint32_t dummy_errors;
324
248
return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
403
size_t String::numchars()
327
uint32_t String::numchars()
405
329
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
408
int String::charpos(int i,size_t offset)
332
int String::charpos(int i,uint32_t offset)
412
336
return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
415
int String::strstr(const String &s,size_t offset)
339
int String::strstr(const String &s,uint32_t offset)
417
341
if (s.length()+offset <= str_length)
475
399
If wrong parameter or not enough memory, do nothing
478
bool String::replace(size_t offset,size_t arg_length,const String &to)
402
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
480
404
return replace(offset,arg_length,to.ptr(),to.length());
483
bool String::replace(size_t offset,size_t arg_length,
484
const char *to, size_t to_length)
407
bool String::replace(uint32_t offset,uint32_t arg_length,
408
const char *to, uint32_t to_length)
486
410
long diff = (long) to_length-(long) arg_length;
487
411
if (offset+arg_length <= str_length)
500
if (realloc(str_length+(size_t) diff))
424
if (realloc(str_length+(uint32_t) diff))
502
internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
503
(unsigned char*) Ptr+str_length,
504
str_length-offset-arg_length);
426
bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
427
str_length-offset-arg_length);
507
430
memcpy(Ptr+offset,to,to_length);
509
str_length+=(size_t) diff;
432
str_length+=(uint32_t) diff;
561
484
int stringcmp(const String *s,const String *t)
563
size_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
486
uint32_t s_len=s->length(),t_len=t->length(),len=cmin(s_len,t_len);
564
487
int cmp= memcmp(s->ptr(), t->ptr(), len);
565
488
return (cmp) ? cmp : (int) (s_len - t_len);
569
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
492
String *copy_if_not_alloced(String *to,String *from,uint32_t from_length)
571
494
if (from->Alloced_length >= from_length)
589
512
****************************************************************************/
517
Copy string with HEX-encoding of "bad" characters.
519
@details This functions copies the string pointed by "src"
520
to the string pointed by "dst". Not more than "srclen" bytes
521
are read from "src". Any sequences of bytes representing
522
a not-well-formed substring (according to cs) are hex-encoded,
523
and all well-formed substrings (according to cs) are copied as is.
524
Not more than "dstlen" bytes are written to "dst". The number
525
of bytes written to "dst" is returned.
527
@param cs character set pointer of the destination string
528
@param[out] dst destination string
529
@param dstlen size of dst
530
@param src source string
531
@param srclen length of src
533
@retval result length
537
my_copy_with_hex_escaping(const CHARSET_INFO * const cs,
538
char *dst, size_t dstlen,
539
const char *src, size_t srclen)
541
const char *srcend= src + srclen;
544
for ( ; src < srcend ; )
547
if ((chlen= my_ismbchar(cs, src, srcend)))
550
break; /* purecov: inspected */
551
memcpy(dst, src, chlen);
556
else if (*src & 0x80)
559
break; /* purecov: inspected */
562
*dst++= _dig_vec_upper[((unsigned char) *src) >> 4];
563
*dst++= _dig_vec_upper[((unsigned char) *src) & 15];
570
break; /* purecov: inspected */
593
580
with optional character set conversion,
619
606
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
620
char *to, size_t to_length,
607
char *to, uint32_t to_length,
621
608
const CHARSET_INFO * const from_cs,
622
const char *from, size_t from_length,
609
const char *from, uint32_t from_length,
624
611
const char **well_formed_error_pos,
625
612
const char **cannot_convert_error_pos,
626
613
const char **from_end_pos)
630
617
assert((to_cs == &my_charset_bin) ||
631
618
(from_cs == &my_charset_bin) ||
788
775
std::swap(str_charset, s.str_charset);
791
void String::q_append(const size_t n)
793
int8store(Ptr + str_length, n);
796
void String::q_append(double d)
798
float8store(Ptr + str_length, d);
801
void String::q_append(double *d)
803
float8store(Ptr + str_length, *d);
806
void String::q_append(const char *data, size_t data_len)
808
memcpy(Ptr + str_length, data, data_len);
809
str_length += data_len;
812
void String::write_at_position(int position, size_t value)
814
int8store(Ptr + position,value);
816
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
819
return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
822
} /* namespace drizzled */
824
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
779
bool operator==(const String &s1, const String &s2)
826
781
return stringcmp(&s1,&s2) == 0;
829
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
784
bool operator!=(const String &s1, const String &s2)
831
786
return !(s1 == s2);