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,
222
bool String::copy(const std::string& arg, const CHARSET_INFO * const cs) // Allocate new string
224
if (alloc(arg.size()))
227
if ((str_length= arg.size()))
228
memcpy(Ptr, arg.c_str(), arg.size());
236
bool String::copy(const char *str,size_t arg_length, const CHARSET_INFO * const cs)
147
bool String::copy(const char *str,uint32_t arg_length, const CHARSET_INFO * const cs)
238
149
if (alloc(arg_length))
288
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,
289
201
const CHARSET_INFO * const cs)
291
203
/* How many bytes are in incomplete character */
292
size_t offset= (arg_length % cs->mbminlen);
204
uint32_t offset= (arg_length % cs->mbminlen);
294
206
assert(!offset); /* All characters are complete, just copy */
300
212
/* Copy with charset conversion */
302
bool String::copy(const char *str, size_t arg_length,
214
bool String::copy(const char *str, uint32_t arg_length,
303
215
const CHARSET_INFO * const,
304
const CHARSET_INFO * const to_cs, size_t *errors)
216
const CHARSET_INFO * const to_cs, uint32_t *errors)
307
219
return copy(str, arg_length, to_cs);
330
bool String::set_ascii(const char *str, size_t arg_length)
242
bool String::set_ascii(const char *str, uint32_t arg_length)
332
244
if (str_charset->mbminlen == 1)
334
246
set(str, arg_length, str_charset);
249
uint32_t dummy_errors;
338
250
return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
417
size_t String::numchars()
329
uint32_t String::numchars()
419
331
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
422
int String::charpos(int i,size_t offset)
334
int String::charpos(int i,uint32_t offset)
426
338
return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
429
int String::strstr(const String &s,size_t offset)
341
int String::strstr(const String &s,uint32_t offset)
431
343
if (s.length()+offset <= str_length)
489
401
If wrong parameter or not enough memory, do nothing
492
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)
494
406
return replace(offset,arg_length,to.ptr(),to.length());
497
bool String::replace(size_t offset,size_t arg_length,
498
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)
500
412
long diff = (long) to_length-(long) arg_length;
501
413
if (offset+arg_length <= str_length)
514
if (realloc(str_length+(size_t) diff))
426
if (realloc(str_length+(uint32_t) diff))
516
internal::bmove_upp((unsigned char*) Ptr+str_length+diff,
517
(unsigned char*) Ptr+str_length,
518
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);
521
432
memcpy(Ptr+offset,to,to_length);
523
str_length+=(size_t) diff;
434
str_length+=(uint32_t) diff;
575
486
int stringcmp(const String *s,const String *t)
577
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);
578
489
int cmp= memcmp(s->ptr(), t->ptr(), len);
579
490
return (cmp) ? cmp : (int) (s_len - t_len);
583
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)
585
496
if (from->Alloced_length >= from_length)
603
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];
607
582
with optional character set conversion,
633
608
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
634
char *to, size_t to_length,
609
char *to, uint32_t to_length,
635
610
const CHARSET_INFO * const from_cs,
636
const char *from, size_t from_length,
611
const char *from, uint32_t from_length,
638
613
const char **well_formed_error_pos,
639
614
const char **cannot_convert_error_pos,
640
615
const char **from_end_pos)
644
619
assert((to_cs == &my_charset_bin) ||
645
620
(from_cs == &my_charset_bin) ||
802
777
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,
833
return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
836
std::ostream& operator<<(std::ostream& output, const String &str)
838
output << "String:(";
839
output << const_cast<String&>(str).c_str();
841
output << str.length();
844
return output; // for multiple << operators.
847
} /* namespace drizzled */
849
bool operator==(const drizzled::String &s1, const drizzled::String &s2)
781
bool operator==(const String &s1, const String &s2)
851
783
return stringcmp(&s1,&s2) == 0;
854
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)
786
bool operator!=(const String &s1, const String &s2)
856
788
return !(s1 == s2);