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"
29
24
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());
27
The following extern declarations are ok as these are interface functions
28
required by the string function
31
extern unsigned char* sql_alloc(unsigned size);
32
extern void sql_element_free(void *ptr);
34
#include "sql_string.h"
48
36
/*****************************************************************************
49
37
** String functions
50
38
*****************************************************************************/
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
40
String::~String() { free(); }
114
bool String::real_alloc(size_t arg_length)
42
bool String::real_alloc(uint32_t arg_length)
116
44
arg_length=ALIGN_SIZE(arg_length+1);
118
46
if (Alloced_length < arg_length)
120
if (Alloced_length > 0)
122
49
if (!(Ptr=(char*) malloc(arg_length)))
124
51
Alloced_length=arg_length;
169
96
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
171
size_t l=20*cs->mbmaxlen+1;
98
uint32_t l=20*cs->mbmaxlen+1;
172
99
int base= unsigned_flag ? 10 : -10;
176
str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
103
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)
108
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
183
110
char buff[FLOATING_POINT_BUFFER];
111
uint32_t dummy_errors;
188
115
if (decimals >= NOT_FIXED_DEC)
190
len= internal::my_gcvt(num,
191
internal::MY_GCVT_ARG_DOUBLE,
192
sizeof(buff) - 1, buff, NULL);
117
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
193
118
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,
120
len= my_fcvt(num, decimals, buff, NULL);
121
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,
200
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
275
201
const CHARSET_INFO * const cs)
277
203
/* How many bytes are in incomplete character */
278
size_t offset= (arg_length % cs->mbminlen);
204
uint32_t offset= (arg_length % cs->mbminlen);
280
206
assert(!offset); /* All characters are complete, just copy */
286
212
/* Copy with charset conversion */
288
bool String::copy(const char *str, size_t arg_length,
214
bool String::copy(const char *str, uint32_t arg_length,
289
215
const CHARSET_INFO * const,
290
const CHARSET_INFO * const to_cs, size_t *errors)
216
const CHARSET_INFO * const to_cs, uint32_t *errors)
293
219
return copy(str, arg_length, to_cs);
316
bool String::set_ascii(const char *str, size_t arg_length)
242
bool String::set_ascii(const char *str, uint32_t arg_length)
318
244
if (str_charset->mbminlen == 1)
320
246
set(str, arg_length, str_charset);
249
uint32_t dummy_errors;
324
250
return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
403
size_t String::numchars()
329
uint32_t String::numchars()
405
331
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
408
int String::charpos(int i,size_t offset)
334
int String::charpos(int i,uint32_t offset)
412
338
return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
415
int String::strstr(const String &s,size_t offset)
341
int String::strstr(const String &s,uint32_t offset)
417
343
if (s.length()+offset <= str_length)
475
401
If wrong parameter or not enough memory, do nothing
478
bool String::replace(size_t offset,size_t arg_length,const String &to)
404
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
480
406
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)
409
bool String::replace(uint32_t offset,uint32_t arg_length,
410
const char *to, uint32_t to_length)
486
412
long diff = (long) to_length-(long) arg_length;
487
413
if (offset+arg_length <= str_length)
500
if (realloc(str_length+(size_t) diff))
426
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);
428
bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
429
str_length-offset-arg_length);
507
432
memcpy(Ptr+offset,to,to_length);
509
str_length+=(size_t) diff;
434
str_length+=(uint32_t) diff;
561
486
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);
488
uint32_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
564
489
int cmp= memcmp(s->ptr(), t->ptr(), len);
565
490
return (cmp) ? cmp : (int) (s_len - t_len);
569
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
494
String *copy_if_not_alloced(String *to,String *from,uint32_t from_length)
571
496
if (from->Alloced_length >= from_length)
589
514
****************************************************************************/
519
Copy string with HEX-encoding of "bad" characters.
521
@details This functions copies the string pointed by "src"
522
to the string pointed by "dst". Not more than "srclen" bytes
523
are read from "src". Any sequences of bytes representing
524
a not-well-formed substring (according to cs) are hex-encoded,
525
and all well-formed substrings (according to cs) are copied as is.
526
Not more than "dstlen" bytes are written to "dst". The number
527
of bytes written to "dst" is returned.
529
@param cs character set pointer of the destination string
530
@param[out] dst destination string
531
@param dstlen size of dst
532
@param src source string
533
@param srclen length of src
535
@retval result length
539
my_copy_with_hex_escaping(const CHARSET_INFO * const cs,
540
char *dst, size_t dstlen,
541
const char *src, size_t srclen)
543
const char *srcend= src + srclen;
546
for ( ; src < srcend ; )
549
if ((chlen= my_ismbchar(cs, src, srcend)))
553
memcpy(dst, src, chlen);
558
else if (*src & 0x80)
564
*dst++= _dig_vec_upper[((unsigned char) *src) >> 4];
565
*dst++= _dig_vec_upper[((unsigned char) *src) & 15];
593
582
with optional character set conversion,
619
608
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
620
char *to, size_t to_length,
609
char *to, uint32_t to_length,
621
610
const CHARSET_INFO * const from_cs,
622
const char *from, size_t from_length,
611
const char *from, uint32_t from_length,
624
613
const char **well_formed_error_pos,
625
614
const char **cannot_convert_error_pos,
626
615
const char **from_end_pos)
630
619
assert((to_cs == &my_charset_bin) ||
631
620
(from_cs == &my_charset_bin) ||
788
777
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)
781
bool operator==(const String &s1, const String &s2)
826
783
return stringcmp(&s1,&s2) == 0;
829
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
786
bool operator!=(const String &s1, const String &s2)
831
788
return !(s1 == s2);