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
20
#include "drizzled/internal/my_sys.h"
21
21
#include "drizzled/internal/m_string.h"
22
22
#include "drizzled/charset.h"
23
#include "drizzled/global_charset_info.h"
25
24
#include <algorithm>
27
26
#include "drizzled/sql_string.h"
28
using namespace drizzled;
29
29
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
31
/*****************************************************************************
49
32
** String functions
50
33
*****************************************************************************/
71
54
String::String(const char *str, const CHARSET_INFO * const cs)
72
55
: Ptr(const_cast<char *>(str)),
73
str_length(static_cast<size_t>(strlen(str))),
56
str_length(static_cast<uint32_t>(strlen(str))),
80
String::String(const char *str, size_t len, const CHARSET_INFO * const cs)
63
String::String(const char *str, uint32_t len, const CHARSET_INFO * const cs)
81
64
: Ptr(const_cast<char *>(str)),
107
90
void *String::operator new(size_t size, memory::Root *mem_root)
109
return mem_root->alloc_root(static_cast<size_t>(size));
92
return alloc_root(mem_root, static_cast<uint32_t>(size));
112
95
String::~String() { free(); }
114
bool String::real_alloc(size_t arg_length)
97
bool String::real_alloc(uint32_t arg_length)
116
99
arg_length=ALIGN_SIZE(arg_length+1);
118
101
if (Alloced_length < arg_length)
120
if (Alloced_length > 0)
122
104
if (!(Ptr=(char*) malloc(arg_length)))
124
106
Alloced_length=arg_length;
134
116
** (for C functions)
137
bool String::realloc(size_t alloc_length)
119
bool String::realloc(uint32_t alloc_length)
139
size_t len=ALIGN_SIZE(alloc_length+1);
121
uint32_t len=ALIGN_SIZE(alloc_length+1);
140
122
if (Alloced_length < len)
169
151
bool String::set_int(int64_t num, bool unsigned_flag, const CHARSET_INFO * const cs)
171
size_t l=20*cs->mbmaxlen+1;
153
uint32_t l=20*cs->mbmaxlen+1;
172
154
int base= unsigned_flag ? 10 : -10;
176
str_length=(size_t) (cs->cset->int64_t10_to_str)(cs,Ptr,l,base,num);
158
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)
163
bool String::set_real(double num,uint32_t decimals, const CHARSET_INFO * const cs)
183
165
char buff[FLOATING_POINT_BUFFER];
166
uint32_t dummy_errors;
188
170
if (decimals >= NOT_FIXED_DEC)
190
len= internal::my_gcvt(num,
191
internal::MY_GCVT_ARG_DOUBLE,
192
sizeof(buff) - 1, buff, NULL);
172
len= my_gcvt(num, MY_GCVT_ARG_DOUBLE, sizeof(buff) - 1, buff, NULL);
193
173
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,
175
len= my_fcvt(num, decimals, buff, NULL);
176
return copy(buff, (uint32_t) len, &my_charset_utf8_general_ci, cs,
240
221
arg_length Length of string to copy.
241
222
from_cs Character set to copy from
242
223
to_cs Character set to copy to
243
size_t *offset Returns number of unaligned characters.
224
uint32_t *offset Returns number of unaligned characters.
246
227
0 No conversion needed
252
233
character_set_results is NULL.
255
bool String::needs_conversion(size_t arg_length,
236
bool String::needs_conversion(uint32_t arg_length,
256
237
const CHARSET_INFO * const from_cs,
257
238
const CHARSET_INFO * const to_cs,
274
bool String::set_or_copy_aligned(const char *str,size_t arg_length,
255
bool String::set_or_copy_aligned(const char *str,uint32_t arg_length,
275
256
const CHARSET_INFO * const cs)
277
258
/* How many bytes are in incomplete character */
278
size_t offset= (arg_length % cs->mbminlen);
259
uint32_t offset= (arg_length % cs->mbminlen);
280
261
assert(!offset); /* All characters are complete, just copy */
286
267
/* Copy with charset conversion */
288
bool String::copy(const char *str, size_t arg_length,
269
bool String::copy(const char *str, uint32_t arg_length,
289
270
const CHARSET_INFO * const,
290
const CHARSET_INFO * const to_cs, size_t *errors)
271
const CHARSET_INFO * const to_cs, uint32_t *errors)
293
274
return copy(str, arg_length, to_cs);
316
bool String::set_ascii(const char *str, size_t arg_length)
297
bool String::set_ascii(const char *str, uint32_t arg_length)
318
299
if (str_charset->mbminlen == 1)
320
301
set(str, arg_length, str_charset);
304
uint32_t dummy_errors;
324
305
return copy(str, arg_length, &my_charset_utf8_general_ci, str_charset, &dummy_errors);
372
353
with character set recoding
375
bool String::append(const char *s,size_t arg_length, const CHARSET_INFO * const)
356
bool String::append(const char *s,uint32_t arg_length, const CHARSET_INFO * const)
377
358
if (realloc(str_length + arg_length))
386
bool String::append_with_prefill(const char *s,size_t arg_length,
387
size_t full_length, char fill_char)
367
bool String::append_with_prefill(const char *s,uint32_t arg_length,
368
uint32_t full_length, char fill_char)
389
370
int t_length= arg_length > full_length ? arg_length : full_length;
403
size_t String::numchars()
384
uint32_t String::numchars()
405
386
return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length);
408
int String::charpos(int i,size_t offset)
389
int String::charpos(int i,uint32_t offset)
412
393
return str_charset->cset->charpos(str_charset,Ptr+offset,Ptr+str_length,i);
415
int String::strstr(const String &s,size_t offset)
396
int String::strstr(const String &s,uint32_t offset)
417
398
if (s.length()+offset <= str_length)
443
424
** Search string from end. Offset is offset to the end of string
446
int String::strrstr(const String &s,size_t offset)
427
int String::strrstr(const String &s,uint32_t offset)
448
429
if (s.length() <= offset && offset <= str_length)
475
456
If wrong parameter or not enough memory, do nothing
478
bool String::replace(size_t offset,size_t arg_length,const String &to)
459
bool String::replace(uint32_t offset,uint32_t arg_length,const String &to)
480
461
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)
464
bool String::replace(uint32_t offset,uint32_t arg_length,
465
const char *to, uint32_t to_length)
486
467
long diff = (long) to_length-(long) arg_length;
487
468
if (offset+arg_length <= str_length)
500
if (realloc(str_length+(size_t) diff))
481
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);
483
bmove_upp((unsigned char*) Ptr+str_length+diff, (unsigned char*) Ptr+str_length,
484
str_length-offset-arg_length);
507
487
memcpy(Ptr+offset,to,to_length);
509
str_length+=(size_t) diff;
489
str_length+=(uint32_t) diff;
561
541
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);
543
uint32_t s_len= s->length(), t_len= t->length(), len= min(s_len,t_len);
564
544
int cmp= memcmp(s->ptr(), t->ptr(), len);
565
545
return (cmp) ? cmp : (int) (s_len - t_len);
569
String *copy_if_not_alloced(String *to,String *from,size_t from_length)
549
String *copy_if_not_alloced(String *to,String *from,uint32_t from_length)
571
551
if (from->Alloced_length >= from_length)
619
599
well_formed_copy_nchars(const CHARSET_INFO * const to_cs,
620
char *to, size_t to_length,
600
char *to, uint32_t to_length,
621
601
const CHARSET_INFO * const from_cs,
622
const char *from, size_t from_length,
602
const char *from, uint32_t from_length,
624
604
const char **well_formed_error_pos,
625
605
const char **cannot_convert_error_pos,
626
606
const char **from_end_pos)
630
610
assert((to_cs == &my_charset_bin) ||
631
611
(from_cs == &my_charset_bin) ||
661
641
INSERT INTO t1 (ucs2_column) VALUES (0x01);
664
size_t pad_length= to_cs->mbminlen - from_offset;
644
uint32_t pad_length= to_cs->mbminlen - from_offset;
665
645
memset(to, 0, pad_length);
666
646
memmove(to + pad_length, from, from_offset);
733
713
/* Factor the extern out */
734
714
extern const CHARSET_INFO *system_charset_info, *files_charset_info;
736
void String::append_identifier(const char *name, size_t in_length)
716
void String::append_identifier(const char *name, uint32_t in_length)
738
718
const char *name_end;
788
768
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);
772
bool operator==(const String &s1, const String &s2)
774
return stringcmp(&s1,&s2) == 0;
777
bool operator!=(const String &s1, const String &s2)
816
782
bool check_if_only_end_space(const CHARSET_INFO * const cs, char *str,
819
785
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)
826
return stringcmp(&s1,&s2) == 0;
829
bool operator!=(const drizzled::String &s1, const drizzled::String &s2)